c143b27fbf31c0ee0ecce983dedc26a291a20119
[m6w6/libmemcached] / test / tests / memcached / errors.cpp
1 #include "test/lib/common.hpp"
2 #include "test/lib/MemcachedCluster.hpp"
3 #include "test/lib/Retry.hpp"
4
5 TEST_CASE("memcached_errors") {
6 SECTION("NO_SERVERS") {
7 MemcachedPtr memc;
8 memcached_return_t rc;
9 auto key = "key";
10 size_t len = 3;
11
12 REQUIRE(MEMCACHED_NO_SERVERS == memcached_flush(*memc, 0));
13 REQUIRE(MEMCACHED_NO_SERVERS == memcached_set(*memc, S(__func__), S(__func__), 0, 0));
14 REQUIRE_FALSE(memcached_get(*memc, S(__func__), nullptr, nullptr, &rc));
15 REQUIRE(MEMCACHED_NO_SERVERS == rc);
16 REQUIRE(MEMCACHED_NO_SERVERS == memcached_mget(*memc, &key, &len, 1));
17 }
18
19 SECTION("dead servers") {
20 MemcachedCluster test{Cluster{vector<Server>{Server{MEMCACHED_BINARY, {"-p", random_port_string("-p")}}}}};
21 auto memc = &test.memc;
22
23 REQUIRE_SUCCESS(memcached_set(memc, S("foo"), nullptr, 0, 0, 0));
24 memcached_quit(memc);
25
26 test.cluster.stop(
27 #if __FreeBSD__
28 true // graceful
29 #endif
30 );
31 Retry cluster_is_stopped{[&cluster = test.cluster]{
32 return cluster.isStopped();
33 }};
34 REQUIRE(cluster_is_stopped());
35
36 SECTION("TEMPORARILY_DISABLED") {
37 REQUIRE_SUCCESS(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 3));
38 REQUIRE_RC(MEMCACHED_CONNECTION_FAILURE, memcached_set(memc, S("foo"), nullptr, 0, 0, 0));
39 REQUIRE_RC(MEMCACHED_SERVER_TEMPORARILY_DISABLED, memcached_set(memc, S("foo"), nullptr, 0, 0, 0));
40 }
41
42 SECTION("recovers from TEMPORARILY_DISABLED") {
43 REQUIRE_SUCCESS(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 1));
44 REQUIRE_RC(MEMCACHED_CONNECTION_FAILURE, memcached_set(memc, S("foo"), nullptr, 0, 0, 0));
45 REQUIRE_RC(MEMCACHED_SERVER_TEMPORARILY_DISABLED, memcached_set(memc, S("foo"), nullptr, 0, 0, 0));
46
47 REQUIRE(test.cluster.start());
48 REQUIRE(test.isListening());
49
50 Retry recovers{[memc]{
51 return MEMCACHED_SUCCESS == memcached_set(memc, S("foo"), nullptr, 0, 0, 0);
52 }, 50, 100ms};
53 REQUIRE(recovers());
54 }
55
56 SECTION("MARKED_DEAD") {
57 SECTION("immediately") {
58 REQUIRE_SUCCESS(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_REMOVE_FAILED_SERVERS, true));
59 REQUIRE_SUCCESS(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, 1));
60
61 REQUIRE_RC(MEMCACHED_CONNECTION_FAILURE, memcached_set(memc, S("foo"), nullptr, 0, 0, 0));
62 REQUIRE_RC(MEMCACHED_SERVER_MARKED_DEAD, memcached_set(memc, S("foo"), nullptr, 0, 0, 0));
63 }
64 SECTION("with retry") {
65 REQUIRE_SUCCESS(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_REMOVE_FAILED_SERVERS, true));
66 REQUIRE_SUCCESS(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, 2));
67 REQUIRE_SUCCESS(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 1));
68
69 REQUIRE_RC(MEMCACHED_CONNECTION_FAILURE, memcached_set(memc, S("foo"), nullptr, 0, 0, 0));
70 REQUIRE_RC(MEMCACHED_SERVER_TEMPORARILY_DISABLED, memcached_set(memc, S("foo"), nullptr, 0, 0, 0));
71
72 Retry server_is_marked_dead{[memc] {
73 return MEMCACHED_SERVER_MARKED_DEAD == memcached_set(memc, S("foo"), nullptr, 0, 0, 0);
74 },50, 100ms};
75 REQUIRE(server_is_marked_dead());
76 }
77 }
78 }
79 }