1 #include "test/lib/common.hpp"
2 #include "test/lib/MemcachedCluster.hpp"
4 static memcached_return_t
delete_trigger(memcached_st
*, const char *, size_t) {
5 return MEMCACHED_SUCCESS
;
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"));
12 static memcached_return_t
clone_callback(memcached_st
*, memcached_st
*) {
13 return MEMCACHED_SUCCESS
;
16 static memcached_return_t
cleanup_callback(memcached_st
*) {
17 return MEMCACHED_SUCCESS
;
20 TEST_CASE("memcached_callbacks") {
21 auto test
{MemcachedCluster::mixed()};
22 auto memc
= &test
.memc
;
23 memcached_return_t rc
;
25 SECTION("user data") {
29 REQUIRE_SUCCESS(memcached_callback_set(memc
, MEMCACHED_CALLBACK_USER_DATA
, data
));
30 REQUIRE(data
== memcached_callback_get(memc
, MEMCACHED_CALLBACK_USER_DATA
, &rc
));
34 SECTION("delete callback") {
35 void *dptr
= reinterpret_cast<void *>(reinterpret_cast<intptr_t>(&delete_trigger
));
37 REQUIRE_SUCCESS(memcached_callback_set(memc
, MEMCACHED_CALLBACK_DELETE_TRIGGER
, dptr
));
38 REQUIRE(memcached_callback_get(memc
, MEMCACHED_CALLBACK_DELETE_TRIGGER
, &rc
) == dptr
);
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
));
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
);
53 REQUIRE_SUCCESS(memcached_callback_set(memc
, MEMCACHED_CALLBACK_GET_FAILURE
, gptr
));
54 REQUIRE(gptr
== memcached_callback_get(memc
, MEMCACHED_CALLBACK_GET_FAILURE
, &rc
));
57 for (int twice
= 0; twice
< 2; ++twice
) {
60 Malloced
val(memcached_get(memc
, S(__func__
), &len
, &flags
, &rc
));
63 REQUIRE(string("updated by read through trigger") == string(*val
, len
));
64 REQUIRE_FALSE((*val
)[len
]);
67 SECTION("clone callback") {
68 void *cptr
= reinterpret_cast<void *>(reinterpret_cast<intptr_t>(&clone_callback
));
70 REQUIRE_SUCCESS(memcached_callback_set(memc
, MEMCACHED_CALLBACK_CLONE_FUNCTION
, cptr
));
71 REQUIRE(cptr
== memcached_callback_get(memc
, MEMCACHED_CALLBACK_CLONE_FUNCTION
, &rc
));
75 SECTION("cleanup callback") {
76 void *cptr
= reinterpret_cast<void *>(reinterpret_cast<intptr_t>(cleanup_callback
));
78 REQUIRE_SUCCESS(memcached_callback_set(memc
, MEMCACHED_CALLBACK_CLEANUP_FUNCTION
, cptr
));
79 REQUIRE(cptr
== memcached_callback_get(memc
, MEMCACHED_CALLBACK_CLEANUP_FUNCTION
, &rc
));
83 SECTION("namespace") {
86 REQUIRE_SUCCESS(memcached_callback_set(memc
, MEMCACHED_CALLBACK_NAMESPACE
, "ns"));
87 ns
= memcached_callback_get(memc
, MEMCACHED_CALLBACK_NAMESPACE
, &rc
);
89 REQUIRE("ns"s
== static_cast<char *>(ns
));
91 REQUIRE_SUCCESS(memcached_callback_set(memc
, MEMCACHED_CALLBACK_NAMESPACE
, nullptr));
92 ns
= memcached_callback_get(memc
, MEMCACHED_CALLBACK_NAMESPACE
, &rc
);
94 REQUIRE(nullptr == ns
);
97 uint64_t binary
= GENERATE(0, 1);
98 REQUIRE_SUCCESS(memcached_behavior_set(memc
, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL
, binary
));
100 DYNAMIC_SECTION("too long (binary=" << binary
<< ")") {
103 blob
= random_ascii_string(MEMCACHED_MAX_NAMESPACE
-1, '@', 'Z');
104 REQUIRE_SUCCESS(memcached_callback_set(memc
, MEMCACHED_CALLBACK_NAMESPACE
, blob
.c_str()));
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()));
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"));