1 #include "test/lib/common.hpp"
2 #include "test/lib/MemcachedCluster.hpp"
4 #include "libmemcached/instance.hpp"
6 TEST_CASE("memcached_replication") {
7 MemcachedCluster test
= MemcachedCluster::network();
8 auto memc
= &test
.memc
;
10 test
.enableBinaryProto();
11 test
.enableReplication();
13 SECTION("replicates one key to all servers") {
14 REQUIRE_SUCCESS(memcached_set(memc
, S(__func__
), S(__func__
), 0, 0));
17 for (const auto &server
: test
.cluster
.getServers()) {
20 REQUIRE_SUCCESS(memcached_server_add(*check
, "localhost", get
<int>(server
.getSocketOrPort())));
22 memcached_return_t rc
;
23 Malloced
val(memcached_get(*check
, S(__func__
), nullptr, nullptr, &rc
));
25 REQUIRE(string(__func__
) == *val
);
31 SECTION("replicates many keys to all servers") {
32 array
<string
, NUM_KEYS
> str
;
33 array
<char *, NUM_KEYS
> chr
;
34 array
<size_t, NUM_KEYS
> len
;
36 for (auto i
= 0U; i
< NUM_KEYS
; ++i
) {
37 str
[i
] = random_binary_string(12) + to_string(i
);
38 chr
[i
] = str
[i
].data();
39 len
[i
] = str
[i
].length();
41 REQUIRE_SUCCESS(memcached_set(memc
, chr
[i
], len
[i
], chr
[i
], len
[i
], 0, 0));
45 for (auto i
= 0U; i
< memcached_server_count(memc
); ++i
) {
46 auto pos
= i
% memcached_server_count(memc
);
47 auto ins
= memcached_server_instance_by_position(memc
, pos
);
49 memcached_result_st r
;
50 memcached_return_t rc
;
52 REQUIRE(memcached_result_create(*single
, &r
));
53 REQUIRE_SUCCESS(memcached_server_add(*single
, "localhost", ins
->port()));
54 REQUIRE_SUCCESS(memcached_behavior_set(*single
, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL
, 1));
55 REQUIRE_SUCCESS(memcached_mget(*single
, chr
.data(), len
.data(), NUM_KEYS
));
58 while (memcached_fetch_result(*single
, &r
, &rc
)) {
63 REQUIRE_RC(MEMCACHED_END
, rc
);
64 memcached_result_free(&r
);
67 SECTION("deletes and randomize reads") {
68 REQUIRE_SUCCESS(memcached_behavior_set(memc
, MEMCACHED_BEHAVIOR_RANDOMIZE_REPLICA_READ
, 1));
69 for (auto i
= 0; i
< NUM_KEYS
; ++i
) {
70 memcached_return_t rc
;
71 auto result
= memcached_result_create(memc
, nullptr);
74 REQUIRE_SUCCESS(memcached_mget_by_key(memc
, chr
[i
], len
[i
], chr
.data(), len
.data(), NUM_KEYS
));
77 while (memcached_fetch_result(memc
, result
, &rc
)) {
81 CHECK(n
+ i
== NUM_KEYS
);
82 REQUIRE_RC(MEMCACHED_END
, rc
);
84 REQUIRE_SUCCESS(memcached_delete(memc
, chr
[i
], len
[i
], 0));
89 # warning I think the old test is bogus and the functionality does not exist as advertised
91 SECTION("deleted from primary") {
92 for (auto i
= 0; i
< NUM_KEYS
; ++i
) {
93 memcached_return_t rc
;
95 CHECK(MEMCACHED_SUCCESS
== memcached_delete(memc
, chr
[i
], len
[i
], 0));
96 Malloced
val(memcached_get(memc
, chr
[i
], len
[i
], nullptr, nullptr, &rc
));
97 CHECK(MEMCACHED_SUCCESS
== rc
);
101 SECTION("dead replica") {
102 test
.killOneServer();
104 for (auto i
= 0; i
< NUM_KEYS
; ++i
) {
105 memcached_return_t rc
;
107 Malloced
val(memcached_get(memc
, chr
[i
], len
[i
], nullptr, nullptr, &rc
));
108 CHECK(MEMCACHED_SUCCESS
== rc
);