mirror of
https://github.com/KingDuckZ/incredis
synced 2024-11-23 00:33:46 +00:00
Import catch and write a first integration test.
This commit is contained in:
parent
20edb06241
commit
f74473bf07
8 changed files with 310 additions and 0 deletions
3
.gitmodules
vendored
3
.gitmodules
vendored
|
@ -4,3 +4,6 @@
|
|||
[submodule "lib/better-enums"]
|
||||
path = lib/better-enums
|
||||
url = https://github.com/aantron/better-enums.git
|
||||
[submodule "lib/catch"]
|
||||
path = lib/catch
|
||||
url = https://github.com/philsquared/Catch.git
|
||||
|
|
|
@ -3,6 +3,7 @@ project(incredis CXX)
|
|||
list (APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules)
|
||||
|
||||
include(shared_git_project)
|
||||
include(CTest)
|
||||
|
||||
find_package(hiredis 0.11.0 REQUIRED)
|
||||
find_package(CryptoPP 5.6)
|
||||
|
@ -59,6 +60,7 @@ if (CryptoPP_FOUND)
|
|||
else()
|
||||
set (has_cryptopp_lib OFF)
|
||||
endif()
|
||||
set(INCREDIS_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
|
||||
install(TARGETS ${PROJECT_NAME}
|
||||
LIBRARY DESTINATION lib
|
||||
|
@ -79,3 +81,7 @@ target_compile_features(${PROJECT_NAME}
|
|||
PUBLIC cxx_noexcept
|
||||
PUBLIC cxx_rvalue_references
|
||||
)
|
||||
|
||||
if (BUILD_TESTING)
|
||||
add_subdirectory(test/integration)
|
||||
endif()
|
||||
|
|
1
lib/catch
Submodule
1
lib/catch
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit 30cebd617788f6b399297725f97317f9bc462114
|
52
test/integration/CMakeLists.txt
Normal file
52
test/integration/CMakeLists.txt
Normal file
|
@ -0,0 +1,52 @@
|
|||
project(integration CXX)
|
||||
|
||||
find_package(Boost 1.53.0 REQUIRED COMPONENTS program_options)
|
||||
|
||||
set(INCREDIS_TEST_HOSTNAME "127.0.0.1" CACHE STRING "Hostname for the integration test to connect to")
|
||||
set(INCREDIS_TEST_PORT "6379" CACHE STRING "Port on the host")
|
||||
set(INCREDIS_TEST_SOCKET "" CACHE STRING "Socket name, leave empty to use hostname:port")
|
||||
set(INCREDIS_TEST_DB "0" CACHE STRING "Number of the database to run the tests in - all data in it will be destroyed")
|
||||
|
||||
add_executable(${PROJECT_NAME}
|
||||
main.cpp
|
||||
redis_connection_fixture.cpp
|
||||
test_insert_retrieve.cpp
|
||||
)
|
||||
|
||||
target_include_directories(${PROJECT_NAME}
|
||||
PRIVATE ${INCREDIS_SOURCE_DIR}/lib/catch/single_include
|
||||
)
|
||||
target_include_directories(${PROJECT_NAME} SYSTEM
|
||||
PRIVATE ${Boost_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME}
|
||||
PRIVATE ${Boost_LIBRARIES}
|
||||
PRIVATE incredis
|
||||
)
|
||||
|
||||
if ("${INCREDIS_TEST_HOSTNAME}" STREQUAL "")
|
||||
set(hostname_param "")
|
||||
else()
|
||||
set(hostname_param --hostname ${INCREDIS_TEST_HOSTNAME})
|
||||
endif()
|
||||
if ("${INCREDIS_TEST_PORT}" STREQUAL "")
|
||||
set(port_param "")
|
||||
else()
|
||||
set(port_param --port ${INCREDIS_TEST_PORT})
|
||||
endif()
|
||||
if ("${INCREDIS_TEST_SOCKET}" STREQUAL "")
|
||||
set(socket_param "")
|
||||
else()
|
||||
set(socket_param --socket ${INCREDIS_TEST_SOCKET})
|
||||
endif()
|
||||
if ("${INCREDIS_TEST_DB}" STREQUAL "")
|
||||
set(db_param "")
|
||||
else()
|
||||
set(db_param --db ${INCREDIS_TEST_DB})
|
||||
endif()
|
||||
add_test(
|
||||
NAME redis_integration
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
COMMAND ${PROJECT_NAME} ${hostname_param} ${port_param} ${socket_param} ${db_param}
|
||||
)
|
95
test/integration/main.cpp
Normal file
95
test/integration/main.cpp
Normal file
|
@ -0,0 +1,95 @@
|
|||
#define CATCH_CONFIG_RUNNER
|
||||
|
||||
#include "catch.hpp"
|
||||
#include <boost/program_options.hpp>
|
||||
#include <string>
|
||||
#include <cstdint>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <cassert>
|
||||
#include <functional>
|
||||
|
||||
namespace po = boost::program_options;
|
||||
|
||||
namespace incredis {
|
||||
namespace test {
|
||||
std::string g_hostname = "127.0.0.1";
|
||||
uint16_t g_port = 6379;
|
||||
std::string g_socket = "";
|
||||
uint32_t g_db = 0;
|
||||
} //namespace test
|
||||
} //namespace incredis
|
||||
|
||||
namespace {
|
||||
const char* const unknown_options_key = "unknown_options";
|
||||
|
||||
void parse_commandline (int parArgc, const char* const* parArgv, po::variables_map& parVM) {
|
||||
po::options_description connection_options("Redis connection options");
|
||||
connection_options.add_options()
|
||||
("hostname,h", po::value<std::string>(), "Server hostname")
|
||||
("port,p", po::value<uint16_t>(), "Server port")
|
||||
("socket,s", po::value<std::string>(), "Server socket (overrides hostname and port)")
|
||||
("db,n", po::value<uint32_t>(), "Database number")
|
||||
;
|
||||
po::options_description positional_options("Catch test suite options");
|
||||
positional_options.add_options()
|
||||
(unknown_options_key, po::value<std::vector<std::string>>(), "List of options that will be passed to Catch")
|
||||
;
|
||||
|
||||
po::options_description all("Available options");
|
||||
all.add(connection_options).add(positional_options);
|
||||
po::positional_options_description pd;
|
||||
pd.add(unknown_options_key, -1);
|
||||
|
||||
po::store(po::command_line_parser(parArgc, parArgv).options(all).positional(pd).run(), parVM);
|
||||
po::notify(parVM);
|
||||
}
|
||||
|
||||
std::vector<const char*> stringlist_to_charlist (const std::vector<std::string>& parList) {
|
||||
std::vector<const char*> retval;
|
||||
retval.reserve(parList.size());
|
||||
std::transform(parList.begin(), parList.end(), back_inserter(retval), std::bind(&std::string::c_str, std::placeholders::_1));
|
||||
assert(parList.size() == retval.size());
|
||||
return retval;
|
||||
}
|
||||
|
||||
void set_global_connection_params (const po::variables_map& parVM) {
|
||||
using namespace incredis::test;
|
||||
|
||||
if (parVM.count("hostname"))
|
||||
g_hostname = parVM["hostname"].as<decltype(g_hostname)>();
|
||||
if (parVM.count("port"))
|
||||
g_port = parVM["port"].as<decltype(g_port)>();
|
||||
if (parVM.count("socket"))
|
||||
g_socket = parVM["socket"].as<decltype(g_socket)>();
|
||||
if (parVM.count("db"))
|
||||
g_db = parVM["db"].as<decltype(g_db)>();
|
||||
}
|
||||
} //unnamed namespace
|
||||
|
||||
int main (int parArgc, char* const parArgv[]) {
|
||||
po::variables_map vm;
|
||||
parse_commandline(parArgc, parArgv, vm);
|
||||
|
||||
const std::vector<std::string> unparsed_params_str(
|
||||
vm.count(unknown_options_key) ?
|
||||
vm[unknown_options_key].as<std::vector<std::string>>() :
|
||||
std::vector<std::string>()
|
||||
);
|
||||
|
||||
std::vector<const char*> unparsed_params =
|
||||
stringlist_to_charlist(unparsed_params_str);
|
||||
assert(parArgc);
|
||||
unparsed_params.insert(unparsed_params.begin(), parArgv[0]);
|
||||
|
||||
//bleah
|
||||
set_global_connection_params(vm);
|
||||
|
||||
Catch::Session session;
|
||||
|
||||
const int retcode = session.applyCommandLine(unparsed_params.size(), unparsed_params.data());
|
||||
if (0 != retcode)
|
||||
return retcode;
|
||||
|
||||
return session.run();
|
||||
}
|
44
test/integration/redis_connection_fixture.cpp
Normal file
44
test/integration/redis_connection_fixture.cpp
Normal file
|
@ -0,0 +1,44 @@
|
|||
#include "redis_connection_fixture.hpp"
|
||||
#include "catch.hpp"
|
||||
#include "incredis/incredis.hpp"
|
||||
#include <ciso646>
|
||||
|
||||
namespace incredis {
|
||||
namespace test {
|
||||
extern std::string g_hostname;
|
||||
extern uint16_t g_port;
|
||||
extern std::string g_socket;
|
||||
extern uint32_t g_db;
|
||||
|
||||
RedisConnectionFixture::RedisConnectionFixture() :
|
||||
m_hostname(g_hostname),
|
||||
m_socket(g_socket),
|
||||
m_db(g_db),
|
||||
m_port(g_port)
|
||||
{
|
||||
if (use_socket_connection())
|
||||
m_incredis.reset(new redis::IncRedis(std::string(m_socket)));
|
||||
else
|
||||
m_incredis.reset(new redis::IncRedis(std::string(m_hostname), m_port));
|
||||
m_incredis->connect();
|
||||
m_incredis->wait_for_connect();
|
||||
REQUIRE_FALSE(not m_incredis->is_connected());
|
||||
|
||||
auto batch = m_incredis->make_batch();
|
||||
batch.select(m_db);
|
||||
batch.client_setname("IncredisIntegrationTest");
|
||||
batch.script_flush();
|
||||
REQUIRE_NOTHROW(batch.throw_if_failed());
|
||||
}
|
||||
|
||||
RedisConnectionFixture::~RedisConnectionFixture() noexcept = default;
|
||||
|
||||
bool RedisConnectionFixture::use_socket_connection() const {
|
||||
return not m_socket.empty();
|
||||
}
|
||||
|
||||
redis::IncRedis& RedisConnectionFixture::incredis() {
|
||||
return *m_incredis;
|
||||
}
|
||||
} //namespace test
|
||||
} //namespace incredis
|
28
test/integration/redis_connection_fixture.hpp
Normal file
28
test/integration/redis_connection_fixture.hpp
Normal file
|
@ -0,0 +1,28 @@
|
|||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
namespace redis {
|
||||
class IncRedis;
|
||||
} //namespace redis
|
||||
|
||||
namespace incredis {
|
||||
namespace test {
|
||||
class RedisConnectionFixture {
|
||||
public:
|
||||
RedisConnectionFixture();
|
||||
~RedisConnectionFixture() noexcept;
|
||||
|
||||
redis::IncRedis& incredis();
|
||||
|
||||
private:
|
||||
bool use_socket_connection() const;
|
||||
|
||||
std::unique_ptr<redis::IncRedis> m_incredis;
|
||||
std::string m_hostname;
|
||||
std::string m_socket;
|
||||
uint32_t m_db;
|
||||
uint16_t m_port;
|
||||
};
|
||||
} //namespace test
|
||||
} //namespac incredis
|
81
test/integration/test_insert_retrieve.cpp
Normal file
81
test/integration/test_insert_retrieve.cpp
Normal file
|
@ -0,0 +1,81 @@
|
|||
#include "redis_connection_fixture.hpp"
|
||||
#include "catch.hpp"
|
||||
#include "incredis/incredis.hpp"
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
|
||||
using incredis::test::RedisConnectionFixture;
|
||||
|
||||
TEST_CASE_METHOD(RedisConnectionFixture, "Batch insert elements in the db and expect to be able to read the same values back", "[set][get]") {
|
||||
using redis::IncRedisBatch;
|
||||
|
||||
REQUIRE_FALSE(not incredis().flushdb());
|
||||
REQUIRE(incredis().dbsize() == 0);
|
||||
|
||||
auto batch = incredis().make_batch();
|
||||
const std::unordered_map<std::string, std::string> sample_values {
|
||||
{"個人と対話", "プロセスやツール"},
|
||||
{"動くソフトウェア", "包括的なドキュメント"},
|
||||
{"顧客との協調", "契約交渉"},
|
||||
{"変化への対応", "計画に従うこと"},
|
||||
{"erase", "erases elements"},
|
||||
{"swap", "swaps the contents"},
|
||||
{"extract", "extracts nodes from the container"},
|
||||
{"merge", "splices nodes from another container"}
|
||||
};
|
||||
|
||||
for (auto& value : sample_values) {
|
||||
batch.set(value.first, value.second, IncRedisBatch::ADD_NX);
|
||||
}
|
||||
REQUIRE_NOTHROW(batch.throw_if_failed());
|
||||
|
||||
REQUIRE(incredis().dbsize() == static_cast<redis::RedisInt>(sample_values.size()));
|
||||
|
||||
{
|
||||
redis::RedisInt scanned_items = 0;
|
||||
for (auto& key : incredis().scan()) {
|
||||
REQUIRE(sample_values.count(key) == 1);
|
||||
redis::IncRedis::opt_string value = incredis().get(key);
|
||||
REQUIRE_FALSE(not value);
|
||||
REQUIRE(*value == sample_values.at(key));
|
||||
++scanned_items;
|
||||
}
|
||||
REQUIRE(static_cast<redis::RedisInt>(sample_values.size()) == scanned_items);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(RedisConnectionFixture, "Insert elements in the db and expect to be able to read the same values back", "[set][get]") {
|
||||
using redis::IncRedisBatch;
|
||||
|
||||
REQUIRE_FALSE(not incredis().flushdb());
|
||||
REQUIRE(incredis().dbsize() == 0);
|
||||
|
||||
incredis().set("個人と対話", "プロセスやツール");
|
||||
incredis().set("動くソフトウェア", "包括的なドキュメント");
|
||||
incredis().set("顧客との協調", "契約交渉");
|
||||
incredis().set("変化への対応", "計画に従うこと");
|
||||
incredis().set("erase", "erases elements");
|
||||
incredis().set("swap", "swaps the contents");
|
||||
incredis().set("extract", "extracts nodes from the container");
|
||||
incredis().set("merge", "splices nodes from another container");
|
||||
|
||||
REQUIRE(incredis().dbsize() == 8);
|
||||
|
||||
REQUIRE_FALSE(not incredis().get("個人と対話"));
|
||||
REQUIRE_FALSE(not incredis().get("動くソフトウェア"));
|
||||
REQUIRE_FALSE(not incredis().get("顧客との協調"));
|
||||
REQUIRE_FALSE(not incredis().get("変化への対応"));
|
||||
REQUIRE_FALSE(not incredis().get("erase"));
|
||||
REQUIRE_FALSE(not incredis().get("swap"));
|
||||
REQUIRE_FALSE(not incredis().get("extract"));
|
||||
REQUIRE_FALSE(not incredis().get("merge"));
|
||||
|
||||
REQUIRE(*incredis().get("個人と対話") == "プロセスやツール");
|
||||
REQUIRE(*incredis().get("動くソフトウェア") == "包括的なドキュメント");
|
||||
REQUIRE(*incredis().get("顧客との協調") == "契約交渉");
|
||||
REQUIRE(*incredis().get("変化への対応") == "計画に従うこと");
|
||||
REQUIRE(*incredis().get("erase") == "erases elements");
|
||||
REQUIRE(*incredis().get("swap") == "swaps the contents");
|
||||
REQUIRE(*incredis().get("extract") == "extracts nodes from the container");
|
||||
REQUIRE(*incredis().get("merge") == "splices nodes from another container");
|
||||
}
|
Loading…
Reference in a new issue