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();
}}};
}
+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{
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));
+}
optional<string> Server::handleArg(vector<char *> &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") {
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;
--- /dev/null
+#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<char>(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));
+ }
+ }
+ }
+}