1 #include "test/lib/common.hpp"
2 #include "test/lib/MemcachedCluster.hpp"
3 #include "test/fixtures/callbacks.hpp"
5 TEST_CASE("memcached_callbacks") {
6 auto test
{MemcachedCluster::mixed()};
7 auto memc
= &test
.memc
;
10 SECTION("user data") {
14 REQUIRE_SUCCESS(memcached_callback_set(memc
, MEMCACHED_CALLBACK_USER_DATA
, data
));
15 REQUIRE(data
== memcached_callback_get(memc
, MEMCACHED_CALLBACK_USER_DATA
, &rc
));
19 SECTION("delete callback") {
20 void *dptr
= reinterpret_cast<void *>(reinterpret_cast<intptr_t>(&delete_trigger
));
22 REQUIRE_SUCCESS(memcached_callback_set(memc
, MEMCACHED_CALLBACK_DELETE_TRIGGER
, dptr
));
23 REQUIRE(memcached_callback_get(memc
, MEMCACHED_CALLBACK_DELETE_TRIGGER
, &rc
) == dptr
);
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
));
32 SECTION("get_failure callback") {
33 void *gptr
= reinterpret_cast<void *>(reinterpret_cast<intptr_t>(&read_through_trigger
));
34 Malloced
empty(memcached_get(memc
, S(__func__
), nullptr, nullptr, &rc
));
35 REQUIRE_FALSE(*empty
);
36 REQUIRE_RC(MEMCACHED_NOTFOUND
, rc
);
38 REQUIRE_SUCCESS(memcached_callback_set(memc
, MEMCACHED_CALLBACK_GET_FAILURE
, gptr
));
39 REQUIRE(gptr
== memcached_callback_get(memc
, MEMCACHED_CALLBACK_GET_FAILURE
, &rc
));
42 for (int twice
= 0; twice
< 2; ++twice
) {
45 Malloced
val(memcached_get(memc
, S(__func__
), &len
, &flags
, &rc
));
48 REQUIRE(string("updated by read through trigger") == string(*val
, len
));
49 REQUIRE_FALSE((*val
)[len
]);
52 SECTION("clone callback") {
53 void *cptr
= reinterpret_cast<void *>(reinterpret_cast<intptr_t>(&clone_callback
));
55 REQUIRE_SUCCESS(memcached_callback_set(memc
, MEMCACHED_CALLBACK_CLONE_FUNCTION
, cptr
));
56 REQUIRE(cptr
== memcached_callback_get(memc
, MEMCACHED_CALLBACK_CLONE_FUNCTION
, &rc
));
60 SECTION("cleanup callback") {
61 void *cptr
= reinterpret_cast<void *>(reinterpret_cast<intptr_t>(cleanup_callback
));
63 REQUIRE_SUCCESS(memcached_callback_set(memc
, MEMCACHED_CALLBACK_CLEANUP_FUNCTION
, cptr
));
64 REQUIRE(cptr
== memcached_callback_get(memc
, MEMCACHED_CALLBACK_CLEANUP_FUNCTION
, &rc
));
68 SECTION("namespace") {
71 REQUIRE_SUCCESS(memcached_callback_set(memc
, MEMCACHED_CALLBACK_NAMESPACE
, "ns"));
72 ns
= memcached_callback_get(memc
, MEMCACHED_CALLBACK_NAMESPACE
, &rc
);
74 REQUIRE("ns"s
== static_cast<char *>(ns
));
76 REQUIRE_SUCCESS(memcached_callback_set(memc
, MEMCACHED_CALLBACK_NAMESPACE
, nullptr));
77 ns
= memcached_callback_get(memc
, MEMCACHED_CALLBACK_NAMESPACE
, &rc
);
79 REQUIRE(nullptr == ns
);
82 uint64_t binary
= GENERATE(0, 1);
83 REQUIRE_SUCCESS(memcached_behavior_set(memc
, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL
, binary
));
85 DYNAMIC_SECTION("too long (binary=" << binary
<< ")") {
88 blob
= random_ascii_string(MEMCACHED_MAX_NAMESPACE
-1, '@', 'Z');
89 REQUIRE_SUCCESS(memcached_callback_set(memc
, MEMCACHED_CALLBACK_NAMESPACE
, blob
.c_str()));
91 blob
= random_ascii_string(MEMCACHED_MAX_NAMESPACE
, '@', 'Z');
92 REQUIRE_RC(MEMCACHED_KEY_TOO_BIG
,memcached_callback_set(memc
, MEMCACHED_CALLBACK_NAMESPACE
, blob
.c_str()));
95 DYNAMIC_SECTION("verify key (binary=" << binary
<< ")") {
96 REQUIRE_RC(binary
? MEMCACHED_INVALID_ARGUMENTS
: MEMCACHED_SUCCESS
,
97 memcached_behavior_set(memc
, MEMCACHED_BEHAVIOR_VERIFY_KEY
, 1));
98 REQUIRE_RC(binary
? MEMCACHED_SUCCESS
: MEMCACHED_BAD_KEY_PROVIDED
,
99 memcached_callback_set(memc
, MEMCACHED_CALLBACK_NAMESPACE
, "with spaces"));