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