update TODO
[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{Server{MEMCACHED_BINARY, {"-p", random_port_string("-p")}}, 1}};
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 REQUIRE(test.cluster.ensureListening());
45
46 Retry recovers{[memc]{
47 return MEMCACHED_SUCCESS == memcached_set(memc, S("foo"), nullptr, 0, 0, 0);
48 }, 50, 100ms};
49 REQUIRE(recovers());
50 }
51
52 SECTION("MARKED_DEAD") {
53 SECTION("immediately") {
54 REQUIRE_SUCCESS(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_REMOVE_FAILED_SERVERS, true));
55 REQUIRE_SUCCESS(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, 1));
56
57 REQUIRE_RC(MEMCACHED_CONNECTION_FAILURE, memcached_set(memc, S("foo"), nullptr, 0, 0, 0));
58 REQUIRE_RC(MEMCACHED_SERVER_MARKED_DEAD, memcached_set(memc, S("foo"), nullptr, 0, 0, 0));
59 }
60 SECTION("with retry") {
61 REQUIRE_SUCCESS(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_REMOVE_FAILED_SERVERS, true));
62 REQUIRE_SUCCESS(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, 2));
63 REQUIRE_SUCCESS(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 1));
64
65 REQUIRE_RC(MEMCACHED_CONNECTION_FAILURE, memcached_set(memc, S("foo"), nullptr, 0, 0, 0));
66 REQUIRE_RC(MEMCACHED_SERVER_TEMPORARILY_DISABLED, memcached_set(memc, S("foo"), nullptr, 0, 0, 0));
67
68 Retry server_is_marked_dead{[memc] {
69 return MEMCACHED_SERVER_MARKED_DEAD == memcached_set(memc, S("foo"), nullptr, 0, 0, 0);
70 },50, 100ms};
71 REQUIRE(server_is_marked_dead());
72 }
73 }
74 }
75 }