75ba019aba085c1adf457a64a715b3e29aa97888
[awesomized/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 Retry cluster_is_stopped{[&cluster = test.cluster]{
28 return cluster.isStopped();
29 }};
30 REQUIRE(cluster_is_stopped());
31
32 SECTION("TEMPORARILY_DISABLED") {
33 REQUIRE_SUCCESS(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 3));
34 REQUIRE_RC(MEMCACHED_CONNECTION_FAILURE, memcached_set(memc, S("foo"), nullptr, 0, 0, 0));
35 REQUIRE_RC(MEMCACHED_SERVER_TEMPORARILY_DISABLED, memcached_set(memc, S("foo"), nullptr, 0, 0, 0));
36 }
37
38 SECTION("recovers from TEMPORARILY_DISABLED") {
39 REQUIRE_SUCCESS(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 1));
40 REQUIRE_RC(MEMCACHED_CONNECTION_FAILURE, memcached_set(memc, S("foo"), nullptr, 0, 0, 0));
41 REQUIRE_RC(MEMCACHED_SERVER_TEMPORARILY_DISABLED, memcached_set(memc, S("foo"), nullptr, 0, 0, 0));
42
43 REQUIRE(test.cluster.start());
44 Retry cluster_is_listening{[&cluster = test.cluster] {
45 return cluster.isListening();
46 }};
47 REQUIRE(cluster_is_listening());
48
49 Retry recovers{[memc]{
50 return MEMCACHED_SUCCESS == memcached_set(memc, S("foo"), nullptr, 0, 0, 0);
51 }, 50, 100ms};
52 REQUIRE(recovers());
53 }
54
55 SECTION("MARKED_DEAD") {
56 SECTION("immediately") {
57 REQUIRE_SUCCESS(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_REMOVE_FAILED_SERVERS, true));
58 REQUIRE_SUCCESS(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, 1));
59
60 REQUIRE_RC(MEMCACHED_CONNECTION_FAILURE, memcached_set(memc, S("foo"), nullptr, 0, 0, 0));
61 REQUIRE_RC(MEMCACHED_SERVER_MARKED_DEAD, memcached_set(memc, S("foo"), nullptr, 0, 0, 0));
62 }
63 SECTION("with retry") {
64 REQUIRE_SUCCESS(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_REMOVE_FAILED_SERVERS, true));
65 REQUIRE_SUCCESS(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, 2));
66 REQUIRE_SUCCESS(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 1));
67
68 REQUIRE_RC(MEMCACHED_CONNECTION_FAILURE, memcached_set(memc, S("foo"), nullptr, 0, 0, 0));
69 REQUIRE_RC(MEMCACHED_SERVER_TEMPORARILY_DISABLED, memcached_set(memc, S("foo"), nullptr, 0, 0, 0));
70
71 Retry server_is_marked_dead{[memc] {
72 return MEMCACHED_SERVER_MARKED_DEAD == memcached_set(memc, S("foo"), nullptr, 0, 0, 0);
73 },50, 100ms};
74 REQUIRE(server_is_marked_dead());
75 }
76 }
77 }
78 }