testing: replication
[awesomized/libmemcached] / test / lib / MemcachedCluster.cpp
1 #include "MemcachedCluster.hpp"
2 #include "Retry.hpp"
3
4 const memcached_st MemcachedCluster::empty_memc{};
5
6 void MemcachedCluster::init() {
7 REQUIRE(cluster.start());
8
9 Retry cluster_is_listening([this]() {
10 return cluster.isListening();
11 });
12 while (!cluster_is_listening()) {
13 cluster.stop();
14 cluster.wait();
15 cluster.start();
16 }
17
18 if (auto br = getenv_else("MEMCACHED_BREAK", "0")) {
19 if (*br && *br != '0') {
20 string in;
21
22 cout << "Started servers:\n";
23 for (const auto &server : cluster.getServers()) {
24 cout << server.getPid() << " ";
25 }
26 cout << "\nPress ENTER to continue... " << ::flush;
27 cin.get();
28 }
29 }
30
31 REQUIRE(memcached_create(&memc));
32 for (const auto &server : cluster.getServers()) {
33 auto target = server.getSocketOrPort();
34 if (holds_alternative<string>(target)) {
35 REQUIRE(MEMCACHED_SUCCESS == memcached_server_add_unix_socket(&memc, get<string>(target).c_str()));
36 } else {
37 REQUIRE(MEMCACHED_SUCCESS == memcached_server_add(&memc, "localhost", get<int>(target)));
38 }
39 }
40
41 }
42
43 MemcachedCluster::~MemcachedCluster() {
44 if (memcmp(&memc, &empty_memc, sizeof(memc))) {
45 memcached_free(&memc);
46 }
47 }
48
49 void MemcachedCluster::flush() {
50 REQUIRE(MEMCACHED_SUCCESS == memcached_flush(&memc, 0));
51 }
52
53 MemcachedCluster::MemcachedCluster()
54 : cluster{Server{
55 MEMCACHED_BINARY,
56 {random_socket_or_port_arg()}
57 }}
58 {
59 init();
60 }
61
62 MemcachedCluster::MemcachedCluster(Cluster &&cluster_)
63 : cluster{move(cluster_)}
64 {
65 init();
66 }
67
68 MemcachedCluster::MemcachedCluster(MemcachedCluster &&mc)
69 : cluster{Server{}}
70 {
71 *this = move(mc);
72 }
73
74 MemcachedCluster &MemcachedCluster::operator=(MemcachedCluster &&mc) {
75 cluster = move(mc.cluster);
76 memcached_clone(&memc, &mc.memc);
77 returns = ReturnMatcher{&memc};
78 return *this;
79 }
80
81 MemcachedCluster MemcachedCluster::mixed() {
82 return MemcachedCluster{};
83 }
84
85 MemcachedCluster MemcachedCluster::network() {
86 return MemcachedCluster{Cluster{Server{
87 MEMCACHED_BINARY,
88 {"-p", random_socket_or_port_string}
89 }}};
90 }
91
92 MemcachedCluster MemcachedCluster::socket() {
93 return MemcachedCluster{Cluster{Server{
94 MEMCACHED_BINARY,
95 {"-s", random_socket_or_port_string}
96 }}};
97 }
98
99 MemcachedCluster MemcachedCluster::udp() {
100 return MemcachedCluster{Cluster{Server{
101 MEMCACHED_BINARY,
102 {
103 Server::arg_pair_t{"-U", random_socket_or_port_string},
104 Server::arg_t{"-v"}
105 }
106 }}};
107 }
108
109 #if LIBMEMCACHED_WITH_SASL_SUPPORT
110 MemcachedCluster MemcachedCluster::sasl() {
111 auto mc = MemcachedCluster{Cluster{Server{
112 MEMCACHED_BINARY,
113 {
114 Server::arg_pair_t{"-p", random_socket_or_port_string},
115 Server::arg_t{"-S"}
116 }
117 }}};
118 mc.enableBinaryProto();
119 REQUIRE(MEMCACHED_SUCCESS == memcached_set_sasl_auth_data(&mc.memc,
120 "memcached", "memcached"));
121 return mc;
122 }
123 #endif
124
125 void MemcachedCluster::enableBinaryProto(bool enable) {
126 REQUIRE(MEMCACHED_SUCCESS == memcached_behavior_set(&memc,
127 MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, enable));
128 }
129
130 void MemcachedCluster::enableBuffering(bool enable) {
131 REQUIRE(MEMCACHED_SUCCESS == memcached_behavior_set(&memc,
132 MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, enable));
133 }
134
135 void MemcachedCluster::enableReplication() {
136 REQUIRE(MEMCACHED_SUCCESS == memcached_behavior_set(&memc,
137 MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, memcached_server_count(&memc) - 1));
138 }
139
140 void MemcachedCluster::enableUdp(bool enable) {
141 REQUIRE(MEMCACHED_SUCCESS == memcached_behavior_set(&memc,
142 MEMCACHED_BEHAVIOR_USE_UDP, enable));
143 }
144
145 void MemcachedCluster::killOneServer() {
146 const auto &servers = cluster.getServers();
147 const auto &victim = servers[random_num(0UL, servers.size() - 1)];
148 ::kill(victim.getPid(), SIGKILL);
149 }