fix #95
[awesomized/libmemcached] / test / tests / memcached / callbacks.cpp
1 #include "test/lib/common.hpp"
2 #include "test/lib/MemcachedCluster.hpp"
3 #include "test/fixtures/callbacks.hpp"
4
5 TEST_CASE("memcached_callbacks") {
6 auto test{MemcachedCluster::mixed()};
7 auto memc = &test.memc;
8 memcached_return_t rc;
9
10 SECTION("user data") {
11 int temp = 123;
12 void *data = &temp;
13
14 REQUIRE_SUCCESS(memcached_callback_set(memc, MEMCACHED_CALLBACK_USER_DATA, data));
15 REQUIRE(data == memcached_callback_get(memc, MEMCACHED_CALLBACK_USER_DATA, &rc));
16 REQUIRE_SUCCESS(rc);
17 }
18
19 SECTION("delete callback") {
20 void *dptr = reinterpret_cast<void *>(reinterpret_cast<intptr_t>(&delete_trigger));
21
22 REQUIRE_SUCCESS(memcached_callback_set(memc, MEMCACHED_CALLBACK_DELETE_TRIGGER, dptr));
23 REQUIRE(memcached_callback_get(memc, MEMCACHED_CALLBACK_DELETE_TRIGGER, &rc) == dptr);
24 REQUIRE_SUCCESS(rc);
25
26 SECTION("fails w/ NOREPLY") {
27 REQUIRE_SUCCESS(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, true));
28 REQUIRE_RC(MEMCACHED_INVALID_ARGUMENTS, memcached_callback_set(memc, MEMCACHED_CALLBACK_DELETE_TRIGGER, dptr));
29 }
30 }
31
32 SECTION("get_failure callback") {
33 void *gptr = reinterpret_cast<void *>(reinterpret_cast<intptr_t>(&get_failure));
34 Malloced empty(memcached_get(memc, S(__func__), nullptr, nullptr, &rc));
35 REQUIRE_FALSE(*empty);
36 REQUIRE_RC(MEMCACHED_NOTFOUND, rc);
37
38 uint64_t buffering = GENERATE(0, 1);
39
40 DYNAMIC_SECTION("buffering: " << buffering) {
41 REQUIRE_SUCCESS(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, buffering));
42 REQUIRE_SUCCESS(memcached_callback_set(memc, MEMCACHED_CALLBACK_GET_FAILURE, gptr));
43 REQUIRE(gptr == memcached_callback_get(memc, MEMCACHED_CALLBACK_GET_FAILURE, &rc));
44 REQUIRE_SUCCESS(rc);
45
46 for (int twice = 0; twice < 2; ++twice) {
47 uint32_t flags;
48 size_t len;
49 Malloced val(memcached_get(memc, S(__func__), &len, &flags, &rc));
50
51 REQUIRE_SUCCESS(rc);
52 REQUIRE(string("updated by read through trigger") == string(*val, len));
53 REQUIRE_FALSE((*val)[len]);
54 }
55
56 REQUIRE_SUCCESS(memcached_set(memc, S(__func__), S("changed"), 0, 0));
57 memcached_quit(memc);
58 Malloced val(memcached_get(memc, S(__func__), nullptr, nullptr, &rc));
59 REQUIRE_SUCCESS(rc);
60 REQUIRE("changed"s == *val);
61 }
62 }
63
64 SECTION("clone callback") {
65 void *cptr = reinterpret_cast<void *>(reinterpret_cast<intptr_t>(&clone_callback));
66
67 REQUIRE_SUCCESS(memcached_callback_set(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION, cptr));
68 REQUIRE(cptr == memcached_callback_get(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION, &rc));
69 REQUIRE_SUCCESS(rc);
70 }
71
72 SECTION("cleanup callback") {
73 void *cptr = reinterpret_cast<void *>(reinterpret_cast<intptr_t>(cleanup_callback));
74
75 REQUIRE_SUCCESS(memcached_callback_set(memc, MEMCACHED_CALLBACK_CLEANUP_FUNCTION, cptr));
76 REQUIRE(cptr == memcached_callback_get(memc, MEMCACHED_CALLBACK_CLEANUP_FUNCTION, &rc));
77 REQUIRE_SUCCESS(rc);
78 }
79
80 SECTION("namespace") {
81 void *ns;
82
83 REQUIRE_SUCCESS(memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, "ns"));
84 ns = memcached_callback_get(memc, MEMCACHED_CALLBACK_NAMESPACE, &rc);
85 REQUIRE_SUCCESS(rc);
86 REQUIRE("ns"s == static_cast<char *>(ns));
87
88 REQUIRE_SUCCESS(memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, nullptr));
89 ns = memcached_callback_get(memc, MEMCACHED_CALLBACK_NAMESPACE, &rc);
90 REQUIRE_SUCCESS(rc);
91 REQUIRE(nullptr == ns);
92
93
94 uint64_t binary = GENERATE(0, 1);
95 REQUIRE_SUCCESS(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, binary));
96
97 DYNAMIC_SECTION("too long (binary=" << binary << ")") {
98 string blob;
99
100 blob = random_ascii_string(MEMCACHED_MAX_NAMESPACE-1, '@', 'Z');
101 REQUIRE_SUCCESS(memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, blob.c_str()));
102
103 blob = random_ascii_string(MEMCACHED_MAX_NAMESPACE, '@', 'Z');
104 REQUIRE_RC(MEMCACHED_KEY_TOO_BIG,memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, blob.c_str()));
105 }
106
107 DYNAMIC_SECTION("verify key (binary=" << binary << ")") {
108 REQUIRE_RC(binary ? MEMCACHED_INVALID_ARGUMENTS : MEMCACHED_SUCCESS,
109 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_VERIFY_KEY, 1));
110 REQUIRE_RC(binary ? MEMCACHED_SUCCESS : MEMCACHED_BAD_KEY_PROVIDED,
111 memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, "with spaces"));
112 }
113 }
114 }