From: Michael Wallner Date: Wed, 30 Sep 2020 10:00:57 +0000 (+0200) Subject: testing: UDP test X-Git-Tag: 1.1.0-beta1~236^2~29 X-Git-Url: https://git.m6w6.name/?a=commitdiff_plain;h=e9b1c46e3490e2940ec36cfa53ffcee5945a27d2;p=m6w6%2Flibmemcached testing: UDP test --- diff --git a/TODO b/TODO index 013aa85d..60a1d884 100644 --- a/TODO +++ b/TODO @@ -3,6 +3,11 @@ - convert to proper C++ where applicable - Stats: - redo +-Deprecations: + - UDP, disabled by default from memcached-1.5.6 + soft (maybe only discourage in docs) + - API: + - memcached_delete(): expires param is obsolete ## Legacy: diff --git a/test/lib/Cluster.cpp b/test/lib/Cluster.cpp index a4f8a3ae..e1375bfd 100644 --- a/test/lib/Cluster.cpp +++ b/test/lib/Cluster.cpp @@ -8,7 +8,10 @@ Cluster::Cluster(Server serv, uint16_t cnt) , proto{move(serv)} { if (count < 4) { - count = 4; + count = stoi(getenv_else("MEMCACHED_CLUSTER", "4")); + } + if (!count) { + count = 1; } reset(); } diff --git a/test/lib/MemcachedCluster.cpp b/test/lib/MemcachedCluster.cpp index 63155e94..573dddf3 100644 --- a/test/lib/MemcachedCluster.cpp +++ b/test/lib/MemcachedCluster.cpp @@ -15,6 +15,19 @@ void MemcachedCluster::init() { cluster.start(); } + if (auto br = getenv_else("MEMCACHED_BREAK", "0")) { + if (*br && *br != '0') { + string in; + + cout << "Started servers:\n"; + for (const auto &server : cluster.getServers()) { + cout << server.getPid() << " "; + } + cout << "\nPress ENTER to continue... " << ::flush; + cin.get(); + } + } + REQUIRE(memcached_create(&memc)); for (const auto &server : cluster.getServers()) { auto target = server.getSocketOrPort(); @@ -83,6 +96,16 @@ MemcachedCluster MemcachedCluster::socket() { }}}; } +MemcachedCluster MemcachedCluster::udp() { + return MemcachedCluster{Cluster{Server{ + MEMCACHED_BINARY, + { + Server::arg_pair_t{"-U", random_socket_or_port_string}, + Server::arg_t{"-v"} + } + }}}; +} + #if LIBMEMCACHED_WITH_SASL_SUPPORT MemcachedCluster MemcachedCluster::sasl() { auto mc = MemcachedCluster{Cluster{Server{ @@ -114,3 +137,7 @@ void MemcachedCluster::enableReplication() { MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, memcached_server_count(&memc))); } +void MemcachedCluster::enableUdp(bool enable) { + REQUIRE(MEMCACHED_SUCCESS == memcached_behavior_set(&memc, + MEMCACHED_BEHAVIOR_USE_UDP, enable)); +} diff --git a/test/lib/MemcachedCluster.hpp b/test/lib/MemcachedCluster.hpp index 39859b7d..8e438580 100644 --- a/test/lib/MemcachedCluster.hpp +++ b/test/lib/MemcachedCluster.hpp @@ -25,11 +25,13 @@ public: void enableBinaryProto(bool enable = true); void enableBuffering(bool enable = true); void enableReplication(); + void enableUdp(bool enable = true); void flush(); static MemcachedCluster mixed(); static MemcachedCluster network(); static MemcachedCluster socket(); + static MemcachedCluster udp(); #if LIBMEMCACHED_WITH_SASL_SUPPORT static MemcachedCluster sasl(); diff --git a/test/lib/Server.cpp b/test/lib/Server.cpp index 8666b690..af6e41ba 100644 --- a/test/lib/Server.cpp +++ b/test/lib/Server.cpp @@ -39,11 +39,16 @@ static inline void pushArg(vector &arr, const string &arg) { optional Server::handleArg(vector &arr, const string &arg, const arg_func_t &next_arg) { pushArg(arr, arg); - if (arg == "-p" || arg == "--port") { + if (arg == "-U" || arg == "--udp-port") { + auto port = next_arg(arg); + pushArg(arr, port); + pushArg(arr, "-p"); + pushArg(arr, port); + socket_or_port = stoi(port); + return port; + } else if (arg == "-p" || arg == "--port") { auto port = next_arg(arg); pushArg(arr, port); -// pushArg(arr, "-U"); -// pushArg(arr, port); socket_or_port = stoi(port); return port; } else if (arg == "-s" || arg == "--unix-socket") { @@ -180,8 +185,19 @@ bool Server::check() { bool Server::wait(int flags) { if (pid && pid == waitpid(pid, &status, flags)) { - if (drain().length()) { - cerr << "Ouput of " << *this << ":\n" << output << endl; + if (drain().length() && output != "Signal handled: Terminated.\n") { + cerr << "Output of " << *this << ":\n"; + + istringstream iss{output}; + string line; + + while (getline(iss, line)) { + cerr << " " << line << "\n"; + } + + if (output.back() != '\n') { + cerr << endl; + } output.clear(); } pid = 0; diff --git a/test/lib/common.hpp b/test/lib/common.hpp index 24ec3a48..ecfa07d4 100644 --- a/test/lib/common.hpp +++ b/test/lib/common.hpp @@ -97,15 +97,15 @@ public: ~MemcachedPtr() { memcached_free(memc); } - memcached_st *operator * () { + memcached_st *operator * () const { return memc; } - auto operator ->() { + auto operator ->() const{ return memc; } }; -template +template class Malloced { T *ptr; public: @@ -115,7 +115,7 @@ public: {} ~Malloced() { if(ptr) - free(ptr); + F(ptr); } auto operator *() { return ptr; diff --git a/test/tests/memcached/udp.cpp b/test/tests/memcached/udp.cpp new file mode 100644 index 00000000..0c76f535 --- /dev/null +++ b/test/tests/memcached/udp.cpp @@ -0,0 +1,92 @@ +#include "test/lib/common.hpp" +#include "test/lib/MemcachedCluster.hpp" + +TEST_CASE("memcached_udp") { + auto test = MemcachedCluster::udp(); + auto memc = &test.memc; + + SECTION("sets reply flag") { + // FIXME: bad internals test + REQUIRE(memc->flags.reply); + REQUIRE_FALSE(memc->flags.use_udp); + REQUIRE_FALSE(memc->flags.use_udp == memc->flags.reply); + test.enableUdp(); + REQUIRE_FALSE(memc->flags.reply); + REQUIRE(memc->flags.use_udp); + REQUIRE_FALSE(memc->flags.use_udp == memc->flags.reply); + test.enableUdp(false); + REQUIRE(memc->flags.reply); + REQUIRE_FALSE(memc->flags.use_udp); + REQUIRE_FALSE(memc->flags.use_udp == memc->flags.reply); + } + + test.enableUdp(); + + SECTION("compat") { + memcached_return_t rc; + REQUIRE_RC(MEMCACHED_INVALID_ARGUMENTS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, true)); + REQUIRE_RC(MEMCACHED_NOT_SUPPORTED, memcached_version(memc)); + REQUIRE_SUCCESS(memcached_verbosity(memc, 0)); + REQUIRE(nullptr == memcached_get(memc, S(__func__), 0, 0, &rc)); + REQUIRE_RC(MEMCACHED_NOT_SUPPORTED, rc); + REQUIRE_RC(MEMCACHED_NOT_SUPPORTED, memcached_mget_execute_by_key(memc, S(__func__), nullptr, nullptr, 0, nullptr, nullptr, 0)); + REQUIRE(nullptr == memcached_stat(memc, nullptr, &rc)); + REQUIRE_RC(MEMCACHED_NOT_SUPPORTED, rc); + } + + SECTION("io") { + const auto max = 1025; // request id rolls over at 1024 + auto binary = GENERATE(0,1); + + test.enableBinaryProto(binary); + + DYNAMIC_SECTION("binary=" << binary) { + SECTION("set") { + for (auto i = 0; i < max; ++i) { + auto s = to_string(i); + INFO("i=" << i); + REQUIRE_SUCCESS(memcached_set(memc, s.c_str(), s.length(), s.c_str(), s.length(), 0, 0)); + } + // FIXME: check request id + memcached_quit(memc); + REQUIRE_SUCCESS(memcached_last_error(memc)); + } + + SECTION("set too big") { + const auto len = 1'234'567; + auto blob = make_unique(len); + REQUIRE_RC(MEMCACHED_WRITE_FAILURE, memcached_set(memc, S(__func__), blob.get(), len, 0, 0)); + memcached_quit(memc); + REQUIRE_SUCCESS(memcached_last_error(memc)); + } + + SECTION("delete") { + for (auto i = 0; i < max; ++i) { + auto s = to_string(i); + INFO("i=" << i); + REQUIRE_SUCCESS(memcached_delete(memc, s.c_str(), s.length(), 0)); + } + memcached_quit(memc); + REQUIRE_SUCCESS(memcached_last_error(memc)); + } + + SECTION("verbosity") { + for (auto i = 0; i < max; ++i) { + INFO("i=" << i); + REQUIRE_SUCCESS(memcached_verbosity(memc, 0)); + } + memcached_quit(memc); + REQUIRE_SUCCESS(memcached_last_error(memc)); + } + + SECTION("flush") { + for (auto i = 0; i < max; ++i) { + INFO("i=" << i); + REQUIRE_SUCCESS(memcached_flush(memc, 0)); + } + memcached_quit(memc); + REQUIRE_SUCCESS(memcached_last_error(memc)); + } + } + } +}