tests: cleanup tests ported so far
[awesomized/libmemcached] / tests / libmemcached-1.0 / mem_functions.cc
1 /* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
2 *
3 * Libmemcached library
4 *
5 * Copyright (C) 2011 Data Differential, http://datadifferential.com/
6 * Copyright (C) 2006-2009 Brian Aker All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are
10 * met:
11 *
12 * * Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * * Redistributions in binary form must reproduce the above
16 * copyright notice, this list of conditions and the following disclaimer
17 * in the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * * The names of its contributors may not be used to endorse or
21 * promote products derived from this software without specific prior
22 * written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 *
36 */
37
38 #include "mem_config.h"
39 #include "libtest/test.hpp"
40
41 #if defined(HAVE_LIBUUID) && HAVE_LIBUUID
42 # include <uuid/uuid.h>
43 #endif
44
45 /*
46 Test cases
47 */
48
49 #include "libmemcached-1.0/memcached.h"
50 #include "libmemcached/is.h"
51 #include "libmemcached/server_instance.h"
52
53 #include "libhashkit-1.0/hashkit.h"
54
55 #include "libtest/memcached.hpp"
56
57 #include <cerrno>
58 #include <memory>
59 #include <pthread.h>
60 #include <semaphore.h>
61 #include <signal.h>
62 #include <sys/stat.h>
63 #include <sys/time.h>
64 #include <sys/types.h>
65 #include <unistd.h>
66
67 #include <iostream>
68
69 #include "libtest/server.h"
70
71 #include "bin/generator.h"
72
73 #define SMALL_STRING_LEN 1024
74
75 #include "libtest/test.hpp"
76
77 using namespace libtest;
78
79 #include "libmemcachedutil-1.0/util.h"
80
81 #include "tests/hash_results.h"
82
83 #include "tests/libmemcached-1.0/callback_counter.h"
84 #include "tests/libmemcached-1.0/fetch_all_results.h"
85 #include "tests/libmemcached-1.0/mem_functions.h"
86 #include "tests/libmemcached-1.0/setup_and_teardowns.h"
87 #include "tests/print.h"
88 #include "tests/debug.h"
89 #include "tests/memc.hpp"
90
91 #define UUID_STRING_MAXLENGTH 36
92
93 #include "tests/keys.hpp"
94
95 #include "libmemcached/instance.hpp"
96
97
98 test_return_t libmemcached_string_behavior_test(memcached_st *)
99 {
100 for (int x= MEMCACHED_BEHAVIOR_NO_BLOCK; x < int(MEMCACHED_BEHAVIOR_MAX); ++x)
101 {
102 test_true(libmemcached_string_behavior(memcached_behavior_t(x)));
103 }
104 test_compare(38, int(MEMCACHED_BEHAVIOR_MAX));
105
106 return TEST_SUCCESS;
107 }
108
109 test_return_t libmemcached_string_distribution_test(memcached_st *)
110 {
111 for (int x= MEMCACHED_DISTRIBUTION_MODULA; x < int(MEMCACHED_DISTRIBUTION_CONSISTENT_MAX); ++x)
112 {
113 test_true(libmemcached_string_distribution(memcached_server_distribution_t(x)));
114 }
115 test_compare(7, int(MEMCACHED_DISTRIBUTION_CONSISTENT_MAX));
116
117 return TEST_SUCCESS;
118 }
119
120 test_return_t memcached_return_t_TEST(memcached_st *memc)
121 {
122 uint32_t values[] = { 851992627U, 2337886783U, 4109241422U, 4001849190U,
123 982370485U, 1263635348U, 4242906218U, 3829656100U,
124 1891735253U, 334139633U, 2257084983U, 3351789013U,
125 13199785U, 2542027183U, 1097051614U, 199566778U,
126 2748246961U, 2465192557U, 1664094137U, 2405439045U,
127 1842224848U, 692413798U, 3479807801U, 919913813U,
128 4269430871U, 610793021U, 527273862U, 1437122909U,
129 2300930706U, 2943759320U, 674306647U, 2400528935U,
130 54481931U, 4186304426U, 1741088401U, 2979625118U,
131 4159057246U, 3425930182U, 2593724503U, 1868899624U,
132 1769812374U, 2302537950U, 1110330676U, 3365377466U,
133 1336171666U, 3021258493U, 2334992265U, 3861994737U,
134 3582734124U, 3889811103, 3365377466U };
135
136 // You have updated the memcache_error messages but not updated docs/tests.
137 for (int rc= int(MEMCACHED_SUCCESS); rc < int(MEMCACHED_MAXIMUM_RETURN); ++rc)
138 {
139 uint32_t hash_val;
140 const char *msg= memcached_strerror(memc, memcached_return_t(rc));
141 hash_val= memcached_generate_hash_value(msg, strlen(msg),
142 MEMCACHED_HASH_JENKINS);
143 if (values[rc] != hash_val)
144 {
145 fprintf(stderr, "\n\nYou have updated memcached_return_t without updating the memcached_return_t_TEST\n");
146 fprintf(stderr, "%u, %s, (%u)\n\n", (uint32_t)rc, memcached_strerror(memc, memcached_return_t(rc)), hash_val);
147 }
148 test_compare(values[rc], hash_val);
149 }
150 test_compare(50, int(MEMCACHED_MAXIMUM_RETURN));
151
152 return TEST_SUCCESS;
153 }
154
155 test_return_t mget_end(memcached_st *memc)
156 {
157 const char *keys[]= { "foo", "foo2" };
158 size_t lengths[]= { 3, 4 };
159 const char *values[]= { "fjord", "41" };
160
161 // Set foo and foo2
162 for (size_t x= 0; x < test_array_length(keys); x++)
163 {
164 test_compare(MEMCACHED_SUCCESS,
165 memcached_set(memc,
166 keys[x], lengths[x],
167 values[x], strlen(values[x]),
168 time_t(0), uint32_t(0)));
169 }
170
171 char *string;
172 size_t string_length;
173 uint32_t flags;
174
175 // retrieve both via mget
176 test_compare(MEMCACHED_SUCCESS,
177 memcached_mget(memc,
178 keys, lengths,
179 test_array_length(keys)));
180
181 char key[MEMCACHED_MAX_KEY];
182 size_t key_length;
183 memcached_return_t rc;
184
185 // this should get both
186 for (size_t x= 0; x < test_array_length(keys); x++)
187 {
188 string= memcached_fetch(memc, key, &key_length, &string_length,
189 &flags, &rc);
190 test_compare(MEMCACHED_SUCCESS, rc);
191 int val = 0;
192 if (key_length == 4)
193 {
194 val= 1;
195 }
196
197 test_compare(string_length, strlen(values[val]));
198 test_true(strncmp(values[val], string, string_length) == 0);
199 free(string);
200 }
201
202 // this should indicate end
203 string= memcached_fetch(memc, key, &key_length, &string_length, &flags, &rc);
204 test_compare(MEMCACHED_END, rc);
205 test_null(string);
206
207 // now get just one
208 test_compare(MEMCACHED_SUCCESS,
209 memcached_mget(memc, keys, lengths, 1));
210
211 string= memcached_fetch(memc, key, &key_length, &string_length, &flags, &rc);
212 test_compare(key_length, lengths[0]);
213 test_true(strncmp(keys[0], key, key_length) == 0);
214 test_compare(string_length, strlen(values[0]));
215 test_true(strncmp(values[0], string, string_length) == 0);
216 test_compare(MEMCACHED_SUCCESS, rc);
217 free(string);
218
219 // this should indicate end
220 string= memcached_fetch(memc, key, &key_length, &string_length, &flags, &rc);
221 test_compare(MEMCACHED_END, rc);
222 test_null(string);
223
224 return TEST_SUCCESS;
225 }
226
227 /* Do not copy the style of this code, I just access hosts to testthis function */
228 test_return_t stats_servername_test(memcached_st *memc)
229 {
230 memcached_stat_st memc_stat;
231 const memcached_instance_st * instance=
232 memcached_server_instance_by_position(memc, 0);
233
234 if (LIBMEMCACHED_WITH_SASL_SUPPORT and memcached_get_sasl_callbacks(memc))
235 {
236 return TEST_SKIPPED;
237 }
238
239 test_compare(MEMCACHED_SUCCESS, memcached_stat_servername(&memc_stat, NULL,
240 memcached_server_name(instance),
241 memcached_server_port(instance)));
242
243 return TEST_SUCCESS;
244 }
245
246 test_return_t mget_result_test(memcached_st *memc)
247 {
248 const char *keys[]= {"fudge", "son", "food"};
249 size_t key_length[]= {5, 3, 4};
250
251 memcached_result_st results_obj;
252 memcached_result_st *results= memcached_result_create(memc, &results_obj);
253 test_true(results);
254 test_true(&results_obj == results);
255
256 /* We need to empty the server before continueing test */
257 test_compare(MEMCACHED_SUCCESS,
258 memcached_flush(memc, 0));
259
260 test_compare(MEMCACHED_SUCCESS,
261 memcached_mget(memc, keys, key_length, 3));
262
263 memcached_return_t rc;
264 while ((results= memcached_fetch_result(memc, &results_obj, &rc)))
265 {
266 test_true(results);
267 }
268
269 while ((results= memcached_fetch_result(memc, &results_obj, &rc))) { test_true(false); /* We should never see a value returned */ };
270 test_false(results);
271 test_compare(MEMCACHED_NOTFOUND, rc);
272
273 for (uint32_t x= 0; x < 3; x++)
274 {
275 rc= memcached_set(memc, keys[x], key_length[x],
276 keys[x], key_length[x],
277 (time_t)50, (uint32_t)9);
278 test_true(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED);
279 }
280
281 test_compare(MEMCACHED_SUCCESS,
282 memcached_mget(memc, keys, key_length, 3));
283
284 while ((results= memcached_fetch_result(memc, &results_obj, &rc)))
285 {
286 test_true(results);
287 test_true(&results_obj == results);
288 test_compare(MEMCACHED_SUCCESS, rc);
289 test_memcmp(memcached_result_key_value(results),
290 memcached_result_value(results),
291 memcached_result_length(results));
292 test_compare(memcached_result_key_length(results), memcached_result_length(results));
293 }
294
295 memcached_result_free(&results_obj);
296
297 return TEST_SUCCESS;
298 }
299
300 test_return_t mget_result_alloc_test(memcached_st *memc)
301 {
302 const char *keys[]= {"fudge", "son", "food"};
303 size_t key_length[]= {5, 3, 4};
304
305 memcached_result_st *results;
306
307 /* We need to empty the server before continueing test */
308 test_compare(MEMCACHED_SUCCESS,
309 memcached_flush(memc, 0));
310
311 test_compare(MEMCACHED_SUCCESS,
312 memcached_mget(memc, keys, key_length, 3));
313
314 memcached_return_t rc;
315 while ((results= memcached_fetch_result(memc, NULL, &rc)))
316 {
317 test_true(results);
318 }
319 test_false(results);
320 test_compare(MEMCACHED_NOTFOUND, rc);
321
322 for (uint32_t x= 0; x < 3; x++)
323 {
324 rc= memcached_set(memc, keys[x], key_length[x],
325 keys[x], key_length[x],
326 (time_t)50, (uint32_t)9);
327 test_true(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED);
328 }
329
330 test_compare(MEMCACHED_SUCCESS,
331 memcached_mget(memc, keys, key_length, 3));
332
333 uint32_t x= 0;
334 while ((results= memcached_fetch_result(memc, NULL, &rc)))
335 {
336 test_true(results);
337 test_compare(MEMCACHED_SUCCESS, rc);
338 test_compare(memcached_result_key_length(results), memcached_result_length(results));
339 test_memcmp(memcached_result_key_value(results),
340 memcached_result_value(results),
341 memcached_result_length(results));
342 memcached_result_free(results);
343 x++;
344 }
345
346 return TEST_SUCCESS;
347 }
348
349 test_return_t mget_result_function(memcached_st *memc)
350 {
351 const char *keys[]= {"fudge", "son", "food"};
352 size_t key_length[]= {5, 3, 4};
353 size_t counter;
354 memcached_execute_fn callbacks[1];
355
356 for (uint32_t x= 0; x < 3; x++)
357 {
358 test_compare(return_value_based_on_buffering(memc),
359 memcached_set(memc, keys[x], key_length[x],
360 keys[x], key_length[x],
361 time_t(50), uint32_t(9)));
362 }
363 test_compare(MEMCACHED_SUCCESS, memcached_flush_buffers(memc));
364 memcached_quit(memc);
365
366 test_compare(MEMCACHED_SUCCESS,
367 memcached_mget(memc, keys, key_length, 3));
368
369 callbacks[0]= &callback_counter;
370 counter= 0;
371
372 test_compare(MEMCACHED_SUCCESS,
373 memcached_fetch_execute(memc, callbacks, (void *)&counter, 1));
374
375 test_compare(size_t(3), counter);
376
377 return TEST_SUCCESS;
378 }
379
380 test_return_t mget_test(memcached_st *memc)
381 {
382 const char *keys[]= {"fudge", "son", "food"};
383 size_t key_length[]= {5, 3, 4};
384
385 char return_key[MEMCACHED_MAX_KEY];
386 size_t return_key_length;
387 char *return_value;
388 size_t return_value_length;
389
390 test_compare(MEMCACHED_SUCCESS,
391 memcached_mget(memc, keys, key_length, 3));
392
393 uint32_t flags;
394 memcached_return_t rc;
395 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
396 &return_value_length, &flags, &rc)))
397 {
398 test_true(return_value);
399 }
400 test_false(return_value);
401 test_zero(return_value_length);
402 test_compare(MEMCACHED_NOTFOUND, rc);
403
404 for (uint32_t x= 0; x < 3; x++)
405 {
406 rc= memcached_set(memc, keys[x], key_length[x],
407 keys[x], key_length[x],
408 (time_t)50, (uint32_t)9);
409 test_true(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED);
410 }
411 test_compare(MEMCACHED_SUCCESS,
412 memcached_mget(memc, keys, key_length, 3));
413
414 uint32_t x= 0;
415 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
416 &return_value_length, &flags, &rc)))
417 {
418 test_true(return_value);
419 test_compare(MEMCACHED_SUCCESS, rc);
420 if (not memc->_namespace)
421 {
422 test_compare(return_key_length, return_value_length);
423 test_memcmp(return_value, return_key, return_value_length);
424 }
425 free(return_value);
426 x++;
427 }
428
429 return TEST_SUCCESS;
430 }
431
432 test_return_t mget_execute(memcached_st *original_memc)
433 {
434 test_skip(true, memcached_behavior_get(original_memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL));
435
436 memcached_st *memc= create_single_instance_memcached(original_memc, "--BINARY-PROTOCOL");
437 test_true(memc);
438
439 keys_st keys(20480);
440
441 /* First add all of the items.. */
442 char blob[1024] = {0};
443
444 for (size_t x= 0; x < keys.size(); ++x)
445 {
446 uint64_t query_id= memcached_query_id(memc);
447 memcached_return_t rc= memcached_add(memc,
448 keys.key_at(x), keys.length_at(x),
449 blob, sizeof(blob),
450 0, 0);
451 ASSERT_TRUE_(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED, "Returned %s", memcached_strerror(NULL, rc));
452 test_compare(query_id +1, memcached_query_id(memc));
453 }
454
455 /* Try to get all of them with a large multiget */
456 size_t counter= 0;
457 memcached_execute_fn callbacks[]= { &callback_counter };
458 test_compare(MEMCACHED_SUCCESS,
459 memcached_mget_execute(memc,
460 keys.keys_ptr(), keys.lengths_ptr(),
461 keys.size(), callbacks, &counter, 1));
462
463 {
464 uint64_t query_id= memcached_query_id(memc);
465 test_compare(MEMCACHED_SUCCESS,
466 memcached_fetch_execute(memc, callbacks, (void *)&counter, 1));
467 test_compare(query_id, memcached_query_id(memc));
468
469 /* Verify that we got all of the items */
470 test_compare(keys.size(), counter);
471 }
472
473 memcached_free(memc);
474
475 return TEST_SUCCESS;
476 }
477
478 test_return_t MEMCACHED_BEHAVIOR_IO_KEY_PREFETCH_TEST(memcached_st *original_memc)
479 {
480 test_skip(true, memcached_behavior_get(original_memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL));
481
482 memcached_st *memc= create_single_instance_memcached(original_memc, "--BINARY-PROTOCOL");
483 test_true(memc);
484
485 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_IO_KEY_PREFETCH, 8));
486
487 keys_st keys(20480);
488
489 /* First add all of the items.. */
490 char blob[1024] = {0};
491
492 for (size_t x= 0; x < keys.size(); ++x)
493 {
494 uint64_t query_id= memcached_query_id(memc);
495 memcached_return_t rc= memcached_add(memc,
496 keys.key_at(x), keys.length_at(x),
497 blob, sizeof(blob),
498 0, 0);
499 test_true(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED);
500 test_compare(query_id +1, memcached_query_id(memc));
501 }
502
503 /* Try to get all of them with a large multiget */
504 size_t counter= 0;
505 memcached_execute_fn callbacks[]= { &callback_counter };
506 test_compare(MEMCACHED_SUCCESS,
507 memcached_mget_execute(memc,
508 keys.keys_ptr(), keys.lengths_ptr(),
509 keys.size(), callbacks, &counter, 1));
510
511 {
512 uint64_t query_id= memcached_query_id(memc);
513 test_compare(MEMCACHED_SUCCESS,
514 memcached_fetch_execute(memc, callbacks, (void *)&counter, 1));
515 test_compare(query_id, memcached_query_id(memc));
516
517 /* Verify that we got all of the items */
518 test_compare(keys.size(), counter);
519 }
520
521 memcached_free(memc);
522
523 return TEST_SUCCESS;
524 }
525
526
527 test_return_t get_stats_keys(memcached_st *memc)
528 {
529 char **stat_list;
530 char **ptr;
531 memcached_stat_st memc_stat;
532 memcached_return_t rc;
533
534 stat_list= memcached_stat_get_keys(memc, &memc_stat, &rc);
535 test_compare(MEMCACHED_SUCCESS, rc);
536 for (ptr= stat_list; *ptr; ptr++)
537 test_true(*ptr);
538
539 free(stat_list);
540
541 return TEST_SUCCESS;
542 }
543
544
545 test_return_t get_stats(memcached_st *memc)
546 {
547 memcached_return_t rc;
548
549 memcached_stat_st *memc_stat= memcached_stat(memc, NULL, &rc);
550 test_compare(MEMCACHED_SUCCESS, rc);
551 test_true(memc_stat);
552
553 for (uint32_t x= 0; x < memcached_server_count(memc); x++)
554 {
555 char **stat_list= memcached_stat_get_keys(memc, memc_stat+x, &rc);
556 test_compare(MEMCACHED_SUCCESS, rc);
557 for (char **ptr= stat_list; *ptr; ptr++) {};
558
559 free(stat_list);
560 }
561
562 memcached_stat_free(NULL, memc_stat);
563
564 return TEST_SUCCESS;
565 }
566
567 test_return_t memcached_fetch_result_NOT_FOUND(memcached_st *memc)
568 {
569 memcached_return_t rc;
570
571 const char *key= "not_found";
572 size_t key_length= test_literal_param_size("not_found");
573
574 test_compare(MEMCACHED_SUCCESS,
575 memcached_mget(memc, &key, &key_length, 1));
576
577 memcached_result_st *result= memcached_fetch_result(memc, NULL, &rc);
578 test_null(result);
579 test_compare(MEMCACHED_NOTFOUND, rc);
580
581 memcached_result_free(result);
582
583 return TEST_SUCCESS;
584 }
585
586 /* We don't test the behavior itself, we test the switches */
587 test_return_t behavior_test(memcached_st *memc)
588 {
589 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 1);
590 test_compare(true, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NO_BLOCK));
591
592 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 1);
593 test_compare(true, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY));
594
595 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, MEMCACHED_HASH_MD5);
596 test_compare(uint64_t(MEMCACHED_HASH_MD5), memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH));
597
598 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
599 test_zero(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NO_BLOCK));
600
601 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 0);
602 test_zero(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY));
603
604 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, MEMCACHED_HASH_DEFAULT);
605 test_compare(uint64_t(MEMCACHED_HASH_DEFAULT), memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH));
606
607 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, MEMCACHED_HASH_CRC);
608 test_compare(uint64_t(MEMCACHED_HASH_CRC), memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH));
609
610 test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE));
611
612 test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE));
613
614 uint64_t value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS);
615 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, value +1);
616 test_compare((value +1), memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS));
617
618 return TEST_SUCCESS;
619 }
620
621 test_return_t MEMCACHED_BEHAVIOR_CORK_test(memcached_st *memc)
622 {
623 test_compare(MEMCACHED_DEPRECATED,
624 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_CORK, true));
625
626 // Platform dependent
627 #if 0
628 bool value= (bool)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_CORK);
629 test_false(value);
630 #endif
631
632 return TEST_SUCCESS;
633 }
634
635
636 test_return_t MEMCACHED_BEHAVIOR_TCP_KEEPALIVE_test(memcached_st *memc)
637 {
638 memcached_return_t rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_KEEPALIVE, true);
639 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_NOT_SUPPORTED);
640
641 bool value= (bool)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_TCP_KEEPALIVE);
642
643 if (memcached_success(rc))
644 {
645 test_true(value);
646 }
647 else
648 {
649 test_false(value);
650 }
651
652 return TEST_SUCCESS;
653 }
654
655
656 test_return_t MEMCACHED_BEHAVIOR_TCP_KEEPIDLE_test(memcached_st *memc)
657 {
658 memcached_return_t rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_KEEPIDLE, true);
659 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_NOT_SUPPORTED);
660
661 bool value= (bool)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_TCP_KEEPIDLE);
662
663 if (memcached_success(rc))
664 {
665 test_true(value);
666 }
667 else
668 {
669 test_false(value);
670 }
671
672 return TEST_SUCCESS;
673 }
674
675 /* Make sure we behave properly if server list has no values */
676 test_return_t user_supplied_bug4(memcached_st *memc)
677 {
678 const char *keys[]= {"fudge", "son", "food"};
679 size_t key_length[]= {5, 3, 4};
680
681 /* Here we free everything before running a bunch of mget tests */
682 memcached_servers_reset(memc);
683
684
685 /* We need to empty the server before continueing test */
686 test_compare(MEMCACHED_NO_SERVERS,
687 memcached_flush(memc, 0));
688
689 test_compare(MEMCACHED_NO_SERVERS,
690 memcached_mget(memc, keys, key_length, 3));
691
692 {
693 unsigned int keys_returned;
694 memcached_return_t rc;
695 test_compare(TEST_SUCCESS, fetch_all_results(memc, keys_returned, rc));
696 test_compare(MEMCACHED_NOTFOUND, rc);
697 test_zero(keys_returned);
698 }
699
700 for (uint32_t x= 0; x < 3; x++)
701 {
702 test_compare(MEMCACHED_NO_SERVERS,
703 memcached_set(memc, keys[x], key_length[x],
704 keys[x], key_length[x],
705 (time_t)50, (uint32_t)9));
706 }
707
708 test_compare(MEMCACHED_NO_SERVERS,
709 memcached_mget(memc, keys, key_length, 3));
710
711 {
712 char *return_value;
713 char return_key[MEMCACHED_MAX_KEY];
714 memcached_return_t rc;
715 size_t return_key_length;
716 size_t return_value_length;
717 uint32_t flags;
718 uint32_t x= 0;
719 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
720 &return_value_length, &flags, &rc)))
721 {
722 test_true(return_value);
723 test_compare(MEMCACHED_SUCCESS, rc);
724 test_true(return_key_length == return_value_length);
725 test_memcmp(return_value, return_key, return_value_length);
726 free(return_value);
727 x++;
728 }
729 }
730
731 return TEST_SUCCESS;
732 }
733
734 #define VALUE_SIZE_BUG5 1048064
735 test_return_t user_supplied_bug5(memcached_st *memc)
736 {
737 const char *keys[]= {"036790384900", "036790384902", "036790384904", "036790384906"};
738 size_t key_length[]= {strlen("036790384900"), strlen("036790384902"), strlen("036790384904"), strlen("036790384906")};
739 char *value;
740 size_t value_length;
741 uint32_t flags;
742 char *insert_data= new (std::nothrow) char[VALUE_SIZE_BUG5];
743
744 for (uint32_t x= 0; x < VALUE_SIZE_BUG5; x++)
745 {
746 insert_data[x]= (signed char)rand();
747 }
748
749 test_compare(MEMCACHED_SUCCESS,
750 memcached_flush(memc, 0));
751
752 memcached_return_t rc;
753 test_null(memcached_get(memc, keys[0], key_length[0], &value_length, &flags, &rc));
754 test_compare(MEMCACHED_SUCCESS,
755 memcached_mget(memc, keys, key_length, 4));
756
757 unsigned int count;
758 test_compare(TEST_SUCCESS, fetch_all_results(memc, count, rc));
759 test_compare(MEMCACHED_NOTFOUND, rc);
760 test_zero(count);
761
762 for (uint32_t x= 0; x < 4; x++)
763 {
764 test_compare(MEMCACHED_SUCCESS,
765 memcached_set(memc, keys[x], key_length[x],
766 insert_data, VALUE_SIZE_BUG5,
767 (time_t)0, (uint32_t)0));
768 }
769
770 for (uint32_t x= 0; x < 10; x++)
771 {
772 value= memcached_get(memc, keys[0], key_length[0],
773 &value_length, &flags, &rc);
774 test_compare(rc, MEMCACHED_SUCCESS);
775 test_true(value);
776 ::free(value);
777
778 test_compare(MEMCACHED_SUCCESS,
779 memcached_mget(memc, keys, key_length, 4));
780
781 test_compare(TEST_SUCCESS, fetch_all_results(memc, count));
782 test_compare(4U, count);
783 }
784 delete [] insert_data;
785
786 return TEST_SUCCESS;
787 }
788
789 test_return_t user_supplied_bug6(memcached_st *memc)
790 {
791 const char *keys[]= {"036790384900", "036790384902", "036790384904", "036790384906"};
792 size_t key_length[]= {strlen("036790384900"), strlen("036790384902"), strlen("036790384904"), strlen("036790384906")};
793 char return_key[MEMCACHED_MAX_KEY];
794 size_t return_key_length;
795 char *value;
796 size_t value_length;
797 uint32_t flags;
798 char *insert_data= new (std::nothrow) char[VALUE_SIZE_BUG5];
799
800 for (uint32_t x= 0; x < VALUE_SIZE_BUG5; x++)
801 {
802 insert_data[x]= (signed char)rand();
803 }
804
805 test_compare(MEMCACHED_SUCCESS, memcached_flush(memc, 0));
806
807 test_compare(TEST_SUCCESS, confirm_keys_dont_exist(memc, keys, test_array_length(keys)));
808
809 // We will now confirm that memcached_mget() returns success, but we will
810 // then check to make sure that no actual keys are returned.
811 test_compare(MEMCACHED_SUCCESS,
812 memcached_mget(memc, keys, key_length, 4));
813
814 memcached_return_t rc;
815 uint32_t count= 0;
816 while ((value= memcached_fetch(memc, return_key, &return_key_length,
817 &value_length, &flags, &rc)))
818 {
819 count++;
820 }
821 test_zero(count);
822 test_compare(MEMCACHED_NOTFOUND, rc);
823
824 for (uint32_t x= 0; x < test_array_length(keys); x++)
825 {
826 test_compare(MEMCACHED_SUCCESS,
827 memcached_set(memc, keys[x], key_length[x],
828 insert_data, VALUE_SIZE_BUG5,
829 (time_t)0, (uint32_t)0));
830 }
831 test_compare(TEST_SUCCESS, confirm_keys_exist(memc, keys, test_array_length(keys)));
832
833 for (uint32_t x= 0; x < 2; x++)
834 {
835 value= memcached_get(memc, keys[0], key_length[0],
836 &value_length, &flags, &rc);
837 test_true(value);
838 free(value);
839
840 test_compare(MEMCACHED_SUCCESS,
841 memcached_mget(memc, keys, key_length, 4));
842 /* We test for purge of partial complete fetches */
843 for (count= 3; count; count--)
844 {
845 value= memcached_fetch(memc, return_key, &return_key_length,
846 &value_length, &flags, &rc);
847 test_compare(MEMCACHED_SUCCESS, rc);
848 test_memcmp(value, insert_data, value_length);
849 test_true(value_length);
850 free(value);
851 }
852 }
853 delete [] insert_data;
854
855 return TEST_SUCCESS;
856 }
857
858 test_return_t user_supplied_bug8(memcached_st *)
859 {
860 memcached_return_t rc;
861 memcached_st *mine;
862 memcached_st *memc_clone;
863
864 memcached_server_st *servers;
865 const char *server_list= "memcache1.memcache.bk.sapo.pt:11211, memcache1.memcache.bk.sapo.pt:11212, memcache1.memcache.bk.sapo.pt:11213, memcache1.memcache.bk.sapo.pt:11214, memcache2.memcache.bk.sapo.pt:11211, memcache2.memcache.bk.sapo.pt:11212, memcache2.memcache.bk.sapo.pt:11213, memcache2.memcache.bk.sapo.pt:11214";
866
867 servers= memcached_servers_parse(server_list);
868 test_true(servers);
869
870 mine= memcached_create(NULL);
871 rc= memcached_server_push(mine, servers);
872 test_compare(MEMCACHED_SUCCESS, rc);
873 memcached_server_list_free(servers);
874
875 test_true(mine);
876 memc_clone= memcached_clone(NULL, mine);
877
878 memcached_quit(mine);
879 memcached_quit(memc_clone);
880
881
882 memcached_free(mine);
883 memcached_free(memc_clone);
884
885 return TEST_SUCCESS;
886 }
887
888 /* Test flag store/retrieve */
889 test_return_t user_supplied_bug7(memcached_st *memc)
890 {
891 char *insert_data= new (std::nothrow) char[VALUE_SIZE_BUG5];
892 test_true(insert_data);
893
894 for (size_t x= 0; x < VALUE_SIZE_BUG5; x++)
895 {
896 insert_data[x]= (signed char)rand();
897 }
898
899 memcached_flush(memc, 0);
900
901 const char *keys= "036790384900";
902 size_t key_length= strlen(keys);
903 test_compare(MEMCACHED_SUCCESS, memcached_set(memc, keys, key_length,
904 insert_data, VALUE_SIZE_BUG5,
905 time_t(0), 245U));
906
907 memcached_return_t rc;
908 size_t value_length;
909 uint32_t flags= 0;
910 char *value= memcached_get(memc, keys, key_length,
911 &value_length, &flags, &rc);
912 test_compare(245U, flags);
913 test_true(value);
914 free(value);
915
916 test_compare(MEMCACHED_SUCCESS, memcached_mget(memc, &keys, &key_length, 1));
917
918 char return_key[MEMCACHED_MAX_KEY];
919 size_t return_key_length;
920 flags= 0;
921 value= memcached_fetch(memc, return_key, &return_key_length,
922 &value_length, &flags, &rc);
923 test_compare(uint32_t(245), flags);
924 test_true(value);
925 free(value);
926 delete [] insert_data;
927
928
929 return TEST_SUCCESS;
930 }
931
932 test_return_t user_supplied_bug9(memcached_st *memc)
933 {
934 const char *keys[]= {"UDATA:edevil@sapo.pt", "fudge&*@#", "for^#@&$not"};
935 size_t key_length[3];
936 uint32_t flags;
937 unsigned count= 0;
938
939 char return_key[MEMCACHED_MAX_KEY];
940 size_t return_key_length;
941 char *return_value;
942 size_t return_value_length;
943
944
945 key_length[0]= strlen("UDATA:edevil@sapo.pt");
946 key_length[1]= strlen("fudge&*@#");
947 key_length[2]= strlen("for^#@&$not");
948
949
950 for (unsigned int x= 0; x < 3; x++)
951 {
952 memcached_return_t rc= memcached_set(memc, keys[x], key_length[x],
953 keys[x], key_length[x],
954 (time_t)50, (uint32_t)9);
955 test_compare(MEMCACHED_SUCCESS, rc);
956 }
957
958 memcached_return_t rc= memcached_mget(memc, keys, key_length, 3);
959 test_compare(MEMCACHED_SUCCESS, rc);
960
961 /* We need to empty the server before continueing test */
962 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
963 &return_value_length, &flags, &rc)) != NULL)
964 {
965 test_true(return_value);
966 free(return_value);
967 count++;
968 }
969 test_compare(3U, count);
970
971 return TEST_SUCCESS;
972 }
973
974 /* We are testing with aggressive timeout to get failures */
975 test_return_t user_supplied_bug10(memcached_st *memc)
976 {
977 test_skip(memc->servers[0].type, MEMCACHED_CONNECTION_TCP);
978
979 size_t value_length= 512;
980 unsigned int set= 1;
981 memcached_st *mclone= memcached_clone(NULL, memc);
982
983 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_NO_BLOCK, set);
984 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_TCP_NODELAY, set);
985 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, uint64_t(0));
986
987 libtest::vchar_t value;
988 value.reserve(value_length);
989 for (uint32_t x= 0; x < value_length; x++)
990 {
991 value.push_back(char(x % 127));
992 }
993
994 for (unsigned int x= 1; x <= 100000; ++x)
995 {
996 memcached_return_t rc= memcached_set(mclone,
997 test_literal_param("foo"),
998 &value[0], value.size(),
999 0, 0);
1000
1001 test_true((rc == MEMCACHED_SUCCESS or rc == MEMCACHED_WRITE_FAILURE or rc == MEMCACHED_BUFFERED or rc == MEMCACHED_TIMEOUT or rc == MEMCACHED_CONNECTION_FAILURE
1002 or rc == MEMCACHED_SERVER_TEMPORARILY_DISABLED));
1003
1004 if (rc == MEMCACHED_WRITE_FAILURE or rc == MEMCACHED_TIMEOUT)
1005 {
1006 x--;
1007 }
1008 }
1009
1010 memcached_free(mclone);
1011
1012 return TEST_SUCCESS;
1013 }
1014
1015 /*
1016 We are looking failures in the async protocol
1017 */
1018 test_return_t user_supplied_bug11(memcached_st *memc)
1019 {
1020 (void)memc;
1021 #ifndef __APPLE__
1022 test::Memc mclone(memc);
1023
1024 memcached_behavior_set(&mclone, MEMCACHED_BEHAVIOR_NO_BLOCK, true);
1025 memcached_behavior_set(&mclone, MEMCACHED_BEHAVIOR_TCP_NODELAY, true);
1026 memcached_behavior_set(&mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, size_t(-1));
1027
1028 test_compare(-1, int32_t(memcached_behavior_get(&mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT)));
1029
1030 libtest::vchar_t value;
1031 value.reserve(512);
1032 for (unsigned int x= 0; x < 512; x++)
1033 {
1034 value.push_back(char(x % 127));
1035 }
1036
1037 for (unsigned int x= 1; x <= 100000; ++x)
1038 {
1039 memcached_return_t rc= memcached_set(&mclone, test_literal_param("foo"), &value[0], value.size(), 0, 0);
1040 (void)rc;
1041 }
1042
1043 #endif
1044
1045 return TEST_SUCCESS;
1046 }
1047
1048 /*
1049 Bug found where incr was not returning MEMCACHED_NOTFOUND when object did not exist.
1050 */
1051 test_return_t user_supplied_bug12(memcached_st *memc)
1052 {
1053 memcached_return_t rc;
1054 uint32_t flags;
1055 size_t value_length;
1056 char *value;
1057 uint64_t number_value;
1058
1059 value= memcached_get(memc, "autoincrement", strlen("autoincrement"),
1060 &value_length, &flags, &rc);
1061 test_null(value);
1062 test_compare(MEMCACHED_NOTFOUND, rc);
1063
1064 rc= memcached_increment(memc, "autoincrement", strlen("autoincrement"),
1065 1, &number_value);
1066 test_null(value);
1067 /* The binary protocol will set the key if it doesn't exist */
1068 if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 1)
1069 {
1070 test_compare(MEMCACHED_SUCCESS, rc);
1071 }
1072 else
1073 {
1074 test_compare(MEMCACHED_NOTFOUND, rc);
1075 }
1076
1077 test_compare(MEMCACHED_SUCCESS,
1078 memcached_set(memc, "autoincrement", strlen("autoincrement"), "1", 1, 0, 0));
1079
1080 value= memcached_get(memc, "autoincrement", strlen("autoincrement"), &value_length, &flags, &rc);
1081 test_true(value);
1082 free(value);
1083
1084 test_compare(MEMCACHED_SUCCESS,
1085 memcached_increment(memc, "autoincrement", strlen("autoincrement"), 1, &number_value));
1086 test_compare(2UL, number_value);
1087
1088 return TEST_SUCCESS;
1089 }
1090
1091 /*
1092 Bug found where command total one more than MEMCACHED_MAX_BUFFER
1093 set key34567890 0 0 8169 \r\n is sent followed by buffer of size 8169, followed by 8169
1094 */
1095 test_return_t user_supplied_bug13(memcached_st *memc)
1096 {
1097 char key[] = "key34567890";
1098
1099 char commandFirst[]= "set key34567890 0 0 ";
1100 char commandLast[] = " \r\n"; /* first line of command sent to server */
1101 size_t commandLength;
1102
1103 commandLength = strlen(commandFirst) + strlen(commandLast) + 4; /* 4 is number of characters in size, probably 8196 */
1104
1105 size_t overflowSize = MEMCACHED_MAX_BUFFER - commandLength;
1106
1107 for (size_t testSize= overflowSize - 1; testSize < overflowSize + 1; testSize++)
1108 {
1109 char *overflow= new (std::nothrow) char[testSize];
1110 test_true(overflow);
1111
1112 memset(overflow, 'x', testSize);
1113 test_compare(MEMCACHED_SUCCESS,
1114 memcached_set(memc, key, strlen(key),
1115 overflow, testSize, 0, 0));
1116 delete [] overflow;
1117 }
1118
1119 return TEST_SUCCESS;
1120 }
1121
1122
1123 /*
1124 Test values of many different sizes
1125 Bug found where command total one more than MEMCACHED_MAX_BUFFER
1126 set key34567890 0 0 8169 \r\n
1127 is sent followed by buffer of size 8169, followed by 8169
1128 */
1129 test_return_t user_supplied_bug14(memcached_st *memc)
1130 {
1131 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, true);
1132
1133 libtest::vchar_t value;
1134 value.reserve(18000);
1135 for (ptrdiff_t x= 0; x < 18000; x++)
1136 {
1137 value.push_back((char) (x % 127));
1138 }
1139
1140 for (size_t current_length= 1; current_length < value.size(); current_length++)
1141 {
1142 memcached_return_t rc= memcached_set(memc, test_literal_param("foo"),
1143 &value[0], current_length,
1144 (time_t)0, (uint32_t)0);
1145 ASSERT_TRUE_(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED, "Instead got %s", memcached_strerror(NULL, rc));
1146
1147 size_t string_length;
1148 uint32_t flags;
1149 char *string= memcached_get(memc, test_literal_param("foo"),
1150 &string_length, &flags, &rc);
1151
1152 test_compare(MEMCACHED_SUCCESS, rc);
1153 test_compare(string_length, current_length);
1154 char buffer[1024];
1155 snprintf(buffer, sizeof(buffer), "%u", uint32_t(string_length));
1156 test_memcmp(string, &value[0], string_length);
1157
1158 free(string);
1159 }
1160
1161 return TEST_SUCCESS;
1162 }
1163
1164 /*
1165 Look for zero length value problems
1166 */
1167 test_return_t user_supplied_bug15(memcached_st *memc)
1168 {
1169 for (uint32_t x= 0; x < 2; x++)
1170 {
1171 memcached_return_t rc= memcached_set(memc, test_literal_param("mykey"),
1172 NULL, 0,
1173 (time_t)0, (uint32_t)0);
1174
1175 test_compare(MEMCACHED_SUCCESS, rc);
1176
1177 size_t length;
1178 uint32_t flags;
1179 char *value= memcached_get(memc, test_literal_param("mykey"),
1180 &length, &flags, &rc);
1181
1182 test_compare(MEMCACHED_SUCCESS, rc);
1183 test_false(value);
1184 test_zero(length);
1185 test_zero(flags);
1186
1187 value= memcached_get(memc, test_literal_param("mykey"),
1188 &length, &flags, &rc);
1189
1190 test_compare(MEMCACHED_SUCCESS, rc);
1191 test_null(value);
1192 test_zero(length);
1193 test_zero(flags);
1194 }
1195
1196 return TEST_SUCCESS;
1197 }
1198
1199 /* Check the return sizes on FLAGS to make sure it stores 32bit unsigned values correctly */
1200 test_return_t user_supplied_bug16(memcached_st *memc)
1201 {
1202 test_compare(MEMCACHED_SUCCESS, memcached_set(memc, test_literal_param("mykey"),
1203 NULL, 0,
1204 (time_t)0, UINT32_MAX));
1205
1206
1207 size_t length;
1208 uint32_t flags;
1209 memcached_return_t rc;
1210 char *value= memcached_get(memc, test_literal_param("mykey"),
1211 &length, &flags, &rc);
1212
1213 test_compare(MEMCACHED_SUCCESS, rc);
1214 test_null(value);
1215 test_zero(length);
1216 test_compare(flags, UINT32_MAX);
1217
1218 return TEST_SUCCESS;
1219 }
1220
1221 #if !defined(__sun) && !defined(__OpenBSD__)
1222 /* Check the validity of chinese key*/
1223 test_return_t user_supplied_bug17(memcached_st *memc)
1224 {
1225 const char *key= "豆瓣";
1226 const char *value="我们在炎热抑郁的夏天无法停止豆瓣";
1227 memcached_return_t rc= memcached_set(memc, key, strlen(key),
1228 value, strlen(value),
1229 (time_t)0, 0);
1230
1231 test_compare(MEMCACHED_SUCCESS, rc);
1232
1233 size_t length;
1234 uint32_t flags;
1235 char *value2= memcached_get(memc, key, strlen(key),
1236 &length, &flags, &rc);
1237
1238 test_compare(length, strlen(value));
1239 test_compare(MEMCACHED_SUCCESS, rc);
1240 test_memcmp(value, value2, length);
1241 free(value2);
1242
1243 return TEST_SUCCESS;
1244 }
1245 #endif
1246
1247 /*
1248 From Andrei on IRC
1249 */
1250
1251 test_return_t user_supplied_bug19(memcached_st *)
1252 {
1253 memcached_return_t res;
1254
1255 memcached_st *memc= memcached(test_literal_param("--server=localhost:11311/?100 --server=localhost:11312/?100"));
1256
1257 const memcached_instance_st * server= memcached_server_by_key(memc, "a", 1, &res);
1258 test_true(server);
1259
1260 memcached_free(memc);
1261
1262 return TEST_SUCCESS;
1263 }
1264
1265 /* CAS test from Andei */
1266 test_return_t user_supplied_bug20(memcached_st *memc)
1267 {
1268 const char *key= "abc";
1269 size_t key_len= strlen("abc");
1270
1271 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, true));
1272
1273 test_compare(MEMCACHED_SUCCESS,
1274 memcached_set(memc,
1275 test_literal_param("abc"),
1276 test_literal_param("foobar"),
1277 (time_t)0, (uint32_t)0));
1278
1279 test_compare(MEMCACHED_SUCCESS,
1280 memcached_mget(memc, &key, &key_len, 1));
1281
1282 memcached_result_st result_obj;
1283 memcached_result_st *result= memcached_result_create(memc, &result_obj);
1284 test_true(result);
1285
1286 memcached_result_create(memc, &result_obj);
1287 memcached_return_t status;
1288 result= memcached_fetch_result(memc, &result_obj, &status);
1289
1290 test_true(result);
1291 test_compare(MEMCACHED_SUCCESS, status);
1292
1293 memcached_result_free(result);
1294
1295 return TEST_SUCCESS;
1296 }
1297
1298 /* Large mget() of missing keys with binary proto
1299 *
1300 * If many binary quiet commands (such as getq's in an mget) fill the output
1301 * buffer and the server chooses not to respond, memcached_flush hangs. See
1302 * http://lists.tangent.org/pipermail/libmemcached/2009-August/000918.html
1303 */
1304
1305 /* sighandler_t function that always asserts false */
1306 static __attribute__((noreturn)) void fail(int)
1307 {
1308 fatal_assert(0);
1309 }
1310
1311
1312 test_return_t _user_supplied_bug21(memcached_st* memc, size_t key_count)
1313 {
1314 #ifdef WIN32
1315 (void)memc;
1316 (void)key_count;
1317 return TEST_SKIPPED;
1318 #else
1319 void (*oldalarm)(int);
1320
1321 memcached_st *memc_clone= memcached_clone(NULL, memc);
1322 test_true(memc_clone);
1323
1324 /* only binproto uses getq for mget */
1325 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, true));
1326
1327 /* empty the cache to ensure misses (hence non-responses) */
1328 test_compare(MEMCACHED_SUCCESS, memcached_flush(memc_clone, 0));
1329
1330 keys_st keys(key_count);
1331
1332 oldalarm= signal(SIGALRM, fail);
1333 alarm(5);
1334
1335 test_compare_got(MEMCACHED_SUCCESS,
1336 memcached_mget(memc_clone, keys.keys_ptr(), keys.lengths_ptr(), keys.size()),
1337 memcached_last_error_message(memc_clone));
1338
1339 alarm(0);
1340 signal(SIGALRM, oldalarm);
1341
1342 memcached_return_t rc;
1343 uint32_t flags;
1344 char return_key[MEMCACHED_MAX_KEY];
1345 size_t return_key_length;
1346 char *return_value;
1347 size_t return_value_length;
1348 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
1349 &return_value_length, &flags, &rc)))
1350 {
1351 test_false(return_value); // There are no keys to fetch, so the value should never be returned
1352 }
1353 test_compare(MEMCACHED_NOTFOUND, rc);
1354 test_zero(return_value_length);
1355 test_zero(return_key_length);
1356 test_false(return_key[0]);
1357 test_false(return_value);
1358
1359 memcached_free(memc_clone);
1360
1361 return TEST_SUCCESS;
1362 #endif
1363 }
1364
1365 test_return_t user_supplied_bug21(memcached_st *memc)
1366 {
1367 test_skip(TEST_SUCCESS, pre_binary(memc));
1368
1369 /* should work as of r580 */
1370 test_compare(TEST_SUCCESS,
1371 _user_supplied_bug21(memc, 10));
1372
1373 /* should fail as of r580 */
1374 test_compare(TEST_SUCCESS,
1375 _user_supplied_bug21(memc, 1000));
1376
1377 return TEST_SUCCESS;
1378 }
1379
1380 test_return_t comparison_operator_memcached_st_and__memcached_return_t_TEST(memcached_st *)
1381 {
1382 test::Memc memc_;
1383
1384 memcached_st *memc= &memc_;
1385
1386 ASSERT_EQ(memc, MEMCACHED_SUCCESS);
1387 test_compare(memc, MEMCACHED_SUCCESS);
1388
1389 ASSERT_NEQ(memc, MEMCACHED_FAILURE);
1390
1391 return TEST_SUCCESS;
1392 }
1393
1394 test_return_t result_static(memcached_st *memc)
1395 {
1396 memcached_result_st result;
1397 memcached_result_st *result_ptr= memcached_result_create(memc, &result);
1398 test_false(result.options.is_allocated);
1399 test_true(memcached_is_initialized(&result));
1400 test_true(result_ptr);
1401 test_true(result_ptr == &result);
1402
1403 memcached_result_free(&result);
1404
1405 test_false(result.options.is_allocated);
1406 test_false(memcached_is_initialized(&result));
1407
1408 return TEST_SUCCESS;
1409 }
1410
1411 test_return_t result_alloc(memcached_st *memc)
1412 {
1413 memcached_result_st *result_ptr= memcached_result_create(memc, NULL);
1414 test_true(result_ptr);
1415 test_true(result_ptr->options.is_allocated);
1416 test_true(memcached_is_initialized(result_ptr));
1417 memcached_result_free(result_ptr);
1418
1419 return TEST_SUCCESS;
1420 }
1421
1422
1423 test_return_t add_host_test1(memcached_st *memc)
1424 {
1425 memcached_return_t rc;
1426 char servername[]= "0.example.com";
1427
1428 memcached_server_st *servers= memcached_server_list_append_with_weight(NULL, servername, 400, 0, &rc);
1429 test_true(servers);
1430 test_compare(1U, memcached_server_list_count(servers));
1431
1432 for (uint32_t x= 2; x < 20; x++)
1433 {
1434 char buffer[SMALL_STRING_LEN];
1435
1436 snprintf(buffer, SMALL_STRING_LEN, "%lu.example.com", (unsigned long)(400 +x));
1437 servers= memcached_server_list_append_with_weight(servers, buffer, 401, 0,
1438 &rc);
1439 test_compare(MEMCACHED_SUCCESS, rc);
1440 test_compare(x, memcached_server_list_count(servers));
1441 }
1442
1443 test_compare(MEMCACHED_SUCCESS, memcached_server_push(memc, servers));
1444 test_compare(MEMCACHED_SUCCESS, memcached_server_push(memc, servers));
1445
1446 memcached_server_list_free(servers);
1447
1448 return TEST_SUCCESS;
1449 }
1450
1451
1452 static void my_free(const memcached_st *ptr, void *mem, void *context)
1453 {
1454 (void)context;
1455 (void)ptr;
1456 #ifdef HARD_MALLOC_TESTS
1457 void *real_ptr= (mem == NULL) ? mem : (void*)((caddr_t)mem - 8);
1458 free(real_ptr);
1459 #else
1460 free(mem);
1461 #endif
1462 }
1463
1464
1465 static void *my_malloc(const memcached_st *ptr, const size_t size, void *context)
1466 {
1467 (void)context;
1468 (void)ptr;
1469 #ifdef HARD_MALLOC_TESTS
1470 void *ret= malloc(size + 8);
1471 if (ret != NULL)
1472 {
1473 ret= (void*)((caddr_t)ret + 8);
1474 }
1475 #else
1476 void *ret= malloc(size);
1477 #endif
1478
1479 if (ret != NULL)
1480 {
1481 memset(ret, 0xff, size);
1482 }
1483
1484 return ret;
1485 }
1486
1487
1488 static void *my_realloc(const memcached_st *ptr, void *mem, const size_t size, void *)
1489 {
1490 #ifdef HARD_MALLOC_TESTS
1491 void *real_ptr= (mem == NULL) ? NULL : (void*)((caddr_t)mem - 8);
1492 void *nmem= realloc(real_ptr, size + 8);
1493
1494 void *ret= NULL;
1495 if (nmem != NULL)
1496 {
1497 ret= (void*)((caddr_t)nmem + 8);
1498 }
1499
1500 return ret;
1501 #else
1502 (void)ptr;
1503 return realloc(mem, size);
1504 #endif
1505 }
1506
1507
1508 static void *my_calloc(const memcached_st *ptr, size_t nelem, const size_t size, void *)
1509 {
1510 #ifdef HARD_MALLOC_TESTS
1511 void *mem= my_malloc(ptr, nelem * size);
1512 if (mem)
1513 {
1514 memset(mem, 0, nelem * size);
1515 }
1516
1517 return mem;
1518 #else
1519 (void)ptr;
1520 return calloc(nelem, size);
1521 #endif
1522 }
1523
1524 #ifdef MEMCACHED_ENABLE_DEPRECATED
1525 test_return_t deprecated_set_memory_alloc(memcached_st *memc)
1526 {
1527 void *test_ptr= NULL;
1528 void *cb_ptr= NULL;
1529 {
1530 memcached_malloc_fn malloc_cb= (memcached_malloc_fn)my_malloc;
1531 cb_ptr= *(void **)&malloc_cb;
1532 memcached_return_t rc;
1533
1534 test_compare(MEMCACHED_SUCCESS,
1535 memcached_callback_set(memc, MEMCACHED_CALLBACK_MALLOC_FUNCTION, cb_ptr));
1536 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_MALLOC_FUNCTION, &rc);
1537 test_compare(MEMCACHED_SUCCESS, rc);
1538 test_true(test_ptr == cb_ptr);
1539 }
1540
1541 {
1542 memcached_realloc_fn realloc_cb=
1543 (memcached_realloc_fn)my_realloc;
1544 cb_ptr= *(void **)&realloc_cb;
1545 memcached_return_t rc;
1546
1547 test_compare(MEMCACHED_SUCCESS,
1548 memcached_callback_set(memc, MEMCACHED_CALLBACK_REALLOC_FUNCTION, cb_ptr));
1549 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_REALLOC_FUNCTION, &rc);
1550 test_compare(MEMCACHED_SUCCESS, rc);
1551 test_true(test_ptr == cb_ptr);
1552 }
1553
1554 {
1555 memcached_free_fn free_cb=
1556 (memcached_free_fn)my_free;
1557 cb_ptr= *(void **)&free_cb;
1558 memcached_return_t rc;
1559
1560 test_compare(MEMCACHED_SUCCESS,
1561 memcached_callback_set(memc, MEMCACHED_CALLBACK_FREE_FUNCTION, cb_ptr));
1562 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_FREE_FUNCTION, &rc);
1563 test_compare(MEMCACHED_SUCCESS, rc);
1564 test_true(test_ptr == cb_ptr);
1565 }
1566
1567 return TEST_SUCCESS;
1568 }
1569 #endif
1570
1571
1572 test_return_t set_memory_alloc(memcached_st *memc)
1573 {
1574 test_compare(MEMCACHED_INVALID_ARGUMENTS,
1575 memcached_set_memory_allocators(memc, NULL, my_free,
1576 my_realloc, my_calloc, NULL));
1577
1578 test_compare(MEMCACHED_SUCCESS,
1579 memcached_set_memory_allocators(memc, my_malloc, my_free,
1580 my_realloc, my_calloc, NULL));
1581
1582 memcached_malloc_fn mem_malloc;
1583 memcached_free_fn mem_free;
1584 memcached_realloc_fn mem_realloc;
1585 memcached_calloc_fn mem_calloc;
1586 memcached_get_memory_allocators(memc, &mem_malloc, &mem_free,
1587 &mem_realloc, &mem_calloc);
1588
1589 test_true(mem_malloc == my_malloc);
1590 test_true(mem_realloc == my_realloc);
1591 test_true(mem_calloc == my_calloc);
1592 test_true(mem_free == my_free);
1593
1594 return TEST_SUCCESS;
1595 }
1596
1597 test_return_t enable_consistent_crc(memcached_st *memc)
1598 {
1599 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, MEMCACHED_DISTRIBUTION_CONSISTENT));
1600 test_compare(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION), uint64_t(MEMCACHED_DISTRIBUTION_CONSISTENT));
1601
1602 test_return_t rc;
1603 if ((rc= pre_crc(memc)) != TEST_SUCCESS)
1604 {
1605 return rc;
1606 }
1607
1608 test_compare(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION), uint64_t(MEMCACHED_DISTRIBUTION_CONSISTENT));
1609
1610 if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH) != MEMCACHED_HASH_CRC)
1611 {
1612 return TEST_SKIPPED;
1613 }
1614
1615 return TEST_SUCCESS;
1616 }
1617
1618 test_return_t enable_consistent_hsieh(memcached_st *memc)
1619 {
1620 test_return_t rc;
1621 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, MEMCACHED_DISTRIBUTION_CONSISTENT);
1622 if ((rc= pre_hsieh(memc)) != TEST_SUCCESS)
1623 {
1624 return rc;
1625 }
1626
1627 test_compare(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION), uint64_t(MEMCACHED_DISTRIBUTION_CONSISTENT));
1628
1629 if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH) != MEMCACHED_HASH_HSIEH)
1630 {
1631 return TEST_SKIPPED;
1632 }
1633
1634 return TEST_SUCCESS;
1635 }
1636
1637 test_return_t enable_cas(memcached_st *memc)
1638 {
1639 if (libmemcached_util_version_check(memc, 1, 2, 4))
1640 {
1641 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, true);
1642
1643 return TEST_SUCCESS;
1644 }
1645
1646 return TEST_SKIPPED;
1647 }
1648
1649 test_return_t check_for_1_2_3(memcached_st *memc)
1650 {
1651 memcached_version(memc);
1652
1653 const memcached_instance_st * instance=
1654 memcached_server_instance_by_position(memc, 0);
1655
1656 if ((instance->major_version >= 1 && (instance->minor_version == 2 && instance->micro_version >= 4))
1657 or instance->minor_version > 2)
1658 {
1659 return TEST_SUCCESS;
1660 }
1661
1662 return TEST_SKIPPED;
1663 }
1664
1665 test_return_t MEMCACHED_BEHAVIOR_POLL_TIMEOUT_test(memcached_st *memc)
1666 {
1667 const uint64_t timeout= 100; // Not using, just checking that it sets
1668
1669 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, timeout);
1670
1671 test_compare(timeout, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT));
1672
1673 return TEST_SUCCESS;
1674 }
1675
1676 test_return_t analyzer_test(memcached_st *memc)
1677 {
1678 memcached_analysis_st *report;
1679 memcached_return_t rc;
1680
1681 memcached_stat_st *memc_stat= memcached_stat(memc, NULL, &rc);
1682 test_compare(MEMCACHED_SUCCESS, rc);
1683 test_true(memc_stat);
1684
1685 report= memcached_analyze(memc, memc_stat, &rc);
1686 test_compare(MEMCACHED_SUCCESS, rc);
1687 test_true(report);
1688
1689 free(report);
1690 memcached_stat_free(NULL, memc_stat);
1691
1692 return TEST_SUCCESS;
1693 }
1694
1695 test_return_t hsieh_avaibility_test (memcached_st *memc)
1696 {
1697 test_skip(true, libhashkit_has_algorithm(HASHKIT_HASH_HSIEH));
1698
1699 test_compare(MEMCACHED_SUCCESS,
1700 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH,
1701 (uint64_t)MEMCACHED_HASH_HSIEH));
1702
1703 return TEST_SUCCESS;
1704 }
1705
1706 test_return_t murmur_avaibility_test (memcached_st *memc)
1707 {
1708 test_skip(true, libhashkit_has_algorithm(HASHKIT_HASH_MURMUR));
1709
1710 test_compare(MEMCACHED_SUCCESS,
1711 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MURMUR));
1712
1713 return TEST_SUCCESS;
1714 }
1715
1716 /*
1717 Test case adapted from John Gorman <johngorman2@gmail.com>
1718
1719 We are testing the error condition when we connect to a server via memcached_get()
1720 but find that the server is not available.
1721 */
1722 test_return_t memcached_get_MEMCACHED_ERRNO(memcached_st *)
1723 {
1724 size_t len;
1725 uint32_t flags;
1726 memcached_return rc;
1727
1728 // Create a handle.
1729 memcached_st *tl_memc_h= memcached(test_literal_param("--server=localhost:9898 --server=localhost:9899")); // This server should not exist
1730
1731 // See if memcached is reachable.
1732 char *value= memcached_get(tl_memc_h,
1733 test_literal_param(__func__),
1734 &len, &flags, &rc);
1735
1736 test_false(value);
1737 test_zero(len);
1738 test_true(memcached_failed(rc));
1739
1740 memcached_free(tl_memc_h);
1741
1742 return TEST_SUCCESS;
1743 }
1744
1745 /*
1746 We connect to a server which exists, but search for a key that does not exist.
1747 */
1748 test_return_t memcached_get_MEMCACHED_NOTFOUND(memcached_st *memc)
1749 {
1750 size_t len;
1751 uint32_t flags;
1752 memcached_return rc;
1753
1754 // See if memcached is reachable.
1755 char *value= memcached_get(memc,
1756 test_literal_param(__func__),
1757 &len, &flags, &rc);
1758
1759 test_false(value);
1760 test_zero(len);
1761 test_compare(MEMCACHED_NOTFOUND, rc);
1762
1763 return TEST_SUCCESS;
1764 }
1765
1766 /*
1767 Test case adapted from John Gorman <johngorman2@gmail.com>
1768
1769 We are testing the error condition when we connect to a server via memcached_get_by_key()
1770 but find that the server is not available.
1771 */
1772 test_return_t memcached_get_by_key_MEMCACHED_ERRNO(memcached_st *)
1773 {
1774 size_t len;
1775 uint32_t flags;
1776 memcached_return rc;
1777
1778 // Create a handle.
1779 memcached_st *tl_memc_h= memcached_create(NULL);
1780 memcached_server_st *servers= memcached_servers_parse("localhost:9898,localhost:9899"); // This server should not exist
1781 memcached_server_push(tl_memc_h, servers);
1782 memcached_server_list_free(servers);
1783
1784 // See if memcached is reachable.
1785 char *value= memcached_get_by_key(tl_memc_h,
1786 test_literal_param(__func__), // Key
1787 test_literal_param(__func__), // Value
1788 &len, &flags, &rc);
1789
1790 test_false(value);
1791 test_zero(len);
1792 test_true(memcached_failed(rc));
1793
1794 memcached_free(tl_memc_h);
1795
1796 return TEST_SUCCESS;
1797 }
1798
1799 /*
1800 We connect to a server which exists, but search for a key that does not exist.
1801 */
1802 test_return_t memcached_get_by_key_MEMCACHED_NOTFOUND(memcached_st *memc)
1803 {
1804 size_t len;
1805 uint32_t flags;
1806 memcached_return rc;
1807
1808 // See if memcached is reachable.
1809 char *value= memcached_get_by_key(memc,
1810 test_literal_param(__func__), // Key
1811 test_literal_param(__func__), // Value
1812 &len, &flags, &rc);
1813
1814 test_false(value);
1815 test_zero(len);
1816 test_compare(MEMCACHED_NOTFOUND, rc);
1817
1818 return TEST_SUCCESS;
1819 }
1820
1821 test_return_t regression_bug_421108(memcached_st *memc)
1822 {
1823 memcached_return_t rc;
1824 memcached_stat_st *memc_stat= memcached_stat(memc, NULL, &rc);
1825 test_compare(MEMCACHED_SUCCESS, rc);
1826
1827 char *bytes_str= memcached_stat_get_value(memc, memc_stat, "bytes", &rc);
1828 test_compare(MEMCACHED_SUCCESS, rc);
1829 test_true(bytes_str);
1830 char *bytes_read_str= memcached_stat_get_value(memc, memc_stat,
1831 "bytes_read", &rc);
1832 test_compare(MEMCACHED_SUCCESS, rc);
1833 test_true(bytes_read_str);
1834
1835 char *bytes_written_str= memcached_stat_get_value(memc, memc_stat,
1836 "bytes_written", &rc);
1837 test_compare(MEMCACHED_SUCCESS, rc);
1838 test_true(bytes_written_str);
1839
1840 unsigned long long bytes= strtoull(bytes_str, 0, 10);
1841 unsigned long long bytes_read= strtoull(bytes_read_str, 0, 10);
1842 unsigned long long bytes_written= strtoull(bytes_written_str, 0, 10);
1843
1844 test_true(bytes != bytes_read);
1845 test_true(bytes != bytes_written);
1846
1847 /* Release allocated resources */
1848 free(bytes_str);
1849 free(bytes_read_str);
1850 free(bytes_written_str);
1851 memcached_stat_free(NULL, memc_stat);
1852
1853 return TEST_SUCCESS;
1854 }
1855
1856
1857 /* Test memcached_server_get_last_disconnect
1858 * For a working server set, shall be NULL
1859 * For a set of non existing server, shall not be NULL
1860 */
1861 test_return_t test_get_last_disconnect(memcached_st *memc)
1862 {
1863 memcached_return_t rc;
1864 const memcached_instance_st * disconnected_server;
1865
1866 /* With the working set of server */
1867 const char *key= "marmotte";
1868 const char *value= "milka";
1869
1870 memcached_reset_last_disconnected_server(memc);
1871 test_false(memc->last_disconnected_server);
1872 rc= memcached_set(memc, key, strlen(key),
1873 value, strlen(value),
1874 (time_t)0, (uint32_t)0);
1875 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1876
1877 disconnected_server = memcached_server_get_last_disconnect(memc);
1878 test_false(disconnected_server);
1879
1880 /* With a non existing server */
1881 memcached_st *mine;
1882 memcached_server_st *servers;
1883
1884 const char *server_list= "localhost:9";
1885
1886 servers= memcached_servers_parse(server_list);
1887 test_true(servers);
1888 mine= memcached_create(NULL);
1889 rc= memcached_server_push(mine, servers);
1890 test_compare(MEMCACHED_SUCCESS, rc);
1891 memcached_server_list_free(servers);
1892 test_true(mine);
1893
1894 rc= memcached_set(mine, key, strlen(key),
1895 value, strlen(value),
1896 (time_t)0, (uint32_t)0);
1897 test_true(memcached_failed(rc));
1898
1899 disconnected_server= memcached_server_get_last_disconnect(mine);
1900 test_true_got(disconnected_server, memcached_strerror(mine, rc));
1901 test_compare(in_port_t(9), memcached_server_port(disconnected_server));
1902 test_false(strncmp(memcached_server_name(disconnected_server),"localhost",9));
1903
1904 memcached_quit(mine);
1905 memcached_free(mine);
1906
1907 return TEST_SUCCESS;
1908 }
1909
1910 test_return_t test_multiple_get_last_disconnect(memcached_st *)
1911 {
1912 const char *server_string= "--server=localhost:8888 --server=localhost:8889 --server=localhost:8890 --server=localhost:8891 --server=localhost:8892";
1913 char buffer[BUFSIZ];
1914
1915 test_compare(MEMCACHED_SUCCESS,
1916 libmemcached_check_configuration(server_string, strlen(server_string), buffer, sizeof(buffer)));
1917
1918 memcached_st *memc= memcached(server_string, strlen(server_string));
1919 test_true(memc);
1920
1921 // We will just use the error strings as our keys
1922 uint32_t counter= 100;
1923 while (--counter)
1924 {
1925 for (int x= int(MEMCACHED_SUCCESS); x < int(MEMCACHED_MAXIMUM_RETURN); ++x)
1926 {
1927 const char *msg= memcached_strerror(memc, memcached_return_t(x));
1928 memcached_return_t ret= memcached_set(memc, msg, strlen(msg), NULL, 0, (time_t)0, (uint32_t)0);
1929 test_true_got((ret == MEMCACHED_CONNECTION_FAILURE or ret == MEMCACHED_SERVER_TEMPORARILY_DISABLED), memcached_last_error_message(memc));
1930
1931 const memcached_instance_st * disconnected_server= memcached_server_get_last_disconnect(memc);
1932 test_true(disconnected_server);
1933 test_strcmp("localhost", memcached_server_name(disconnected_server));
1934 test_true(memcached_server_port(disconnected_server) >= 8888 and memcached_server_port(disconnected_server) <= 8892);
1935
1936 if (random() % 2)
1937 {
1938 memcached_reset_last_disconnected_server(memc);
1939 }
1940 }
1941 }
1942
1943 memcached_free(memc);
1944
1945 return TEST_SUCCESS;
1946 }
1947
1948 test_return_t test_verbosity(memcached_st *memc)
1949 {
1950 test_compare(MEMCACHED_SUCCESS, memcached_verbosity(memc, 0));
1951
1952 return TEST_SUCCESS;
1953 }
1954
1955
1956 static memcached_return_t stat_printer(const memcached_instance_st * server,
1957 const char *key, size_t key_length,
1958 const char *value, size_t value_length,
1959 void *context)
1960 {
1961 (void)server;
1962 (void)context;
1963 (void)key;
1964 (void)key_length;
1965 (void)value;
1966 (void)value_length;
1967
1968 return MEMCACHED_SUCCESS;
1969 }
1970
1971 test_return_t memcached_stat_execute_test(memcached_st *memc)
1972 {
1973 memcached_return_t rc= memcached_stat_execute(memc, NULL, stat_printer, NULL);
1974 test_compare(MEMCACHED_SUCCESS, rc);
1975
1976 test_compare(MEMCACHED_SUCCESS,
1977 memcached_stat_execute(memc, "slabs", stat_printer, NULL));
1978
1979 test_compare(MEMCACHED_SUCCESS,
1980 memcached_stat_execute(memc, "items", stat_printer, NULL));
1981
1982 test_compare(MEMCACHED_SUCCESS,
1983 memcached_stat_execute(memc, "sizes", stat_printer, NULL));
1984
1985 return TEST_SUCCESS;
1986 }
1987
1988 /*
1989 * This test ensures that the failure counter isn't incremented during
1990 * normal termination of the memcached instance.
1991 */
1992 test_return_t wrong_failure_counter_test(memcached_st *original_memc)
1993 {
1994 memcached_st* memc= create_single_instance_memcached(original_memc, NULL);
1995
1996 /* Ensure that we are connected to the server by setting a value */
1997 memcached_return_t rc= memcached_set(memc,
1998 test_literal_param(__func__), // Key
1999 test_literal_param(__func__), // Value
2000 time_t(0), uint32_t(0));
2001 test_true(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED);
2002
2003
2004 const memcached_instance_st * instance= memcached_server_instance_by_position(memc, 0);
2005
2006 /* The test is to see that the memcached_quit doesn't increase the
2007 * the server failure conter, so let's ensure that it is zero
2008 * before sending quit
2009 */
2010 ((memcached_server_write_instance_st)instance)->server_failure_counter= 0;
2011
2012 memcached_quit(memc);
2013
2014 /* Verify that it memcached_quit didn't increment the failure counter
2015 * Please note that this isn't bullet proof, because an error could
2016 * occur...
2017 */
2018 test_zero(instance->server_failure_counter);
2019
2020 memcached_free(memc);
2021
2022 return TEST_SUCCESS;
2023 }
2024
2025 /*
2026 * This tests ensures expected disconnections (for some behavior changes
2027 * for instance) do not wrongly increase failure counter
2028 */
2029 test_return_t wrong_failure_counter_two_test(memcached_st *memc)
2030 {
2031 /* Set value to force connection to the server */
2032 const char *key= "marmotte";
2033 const char *value= "milka";
2034
2035 test_compare_hint(MEMCACHED_SUCCESS,
2036 memcached_set(memc, key, strlen(key),
2037 value, strlen(value),
2038 (time_t)0, (uint32_t)0),
2039 memcached_last_error_message(memc));
2040
2041
2042 /* put failure limit to 1 */
2043 test_compare(MEMCACHED_SUCCESS,
2044 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, true));
2045
2046 /* Put a retry timeout to effectively activate failure_limit effect */
2047 test_compare(MEMCACHED_SUCCESS,
2048 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 1));
2049
2050 /* change behavior that triggers memcached_quit()*/
2051 test_compare(MEMCACHED_SUCCESS,
2052 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, true));
2053
2054
2055 /* Check if we still are connected */
2056 uint32_t flags;
2057 size_t string_length;
2058 memcached_return rc;
2059 char *string= memcached_get(memc, key, strlen(key),
2060 &string_length, &flags, &rc);
2061
2062 test_compare_got(MEMCACHED_SUCCESS, rc, memcached_strerror(NULL, rc));
2063 test_true(string);
2064 free(string);
2065
2066 return TEST_SUCCESS;
2067 }
2068
2069
2070 test_return_t regression_1021819_TEST(memcached_st *original)
2071 {
2072 memcached_st *memc= memcached_clone(NULL, original);
2073 test_true(memc);
2074
2075 test_compare(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SND_TIMEOUT, 2000000), MEMCACHED_SUCCESS);
2076 test_compare(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RCV_TIMEOUT, 3000000), MEMCACHED_SUCCESS);
2077
2078 memcached_return_t rc;
2079
2080 memcached_get(memc,
2081 test_literal_param(__func__),
2082 NULL, NULL, &rc);
2083
2084 test_compare(rc, MEMCACHED_NOTFOUND);
2085
2086 memcached_free(memc);
2087
2088 return TEST_SUCCESS;
2089 }
2090
2091 test_return_t regression_bug_583031(memcached_st *)
2092 {
2093 memcached_st *memc= memcached_create(NULL);
2094 test_true(memc);
2095 test_compare(MEMCACHED_SUCCESS, memcached_server_add(memc, "10.2.251.4", 11211));
2096
2097 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT, 3000);
2098 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 1000);
2099 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SND_TIMEOUT, 1000);
2100 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RCV_TIMEOUT, 1000);
2101 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, 1000);
2102 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, 3);
2103
2104 memcached_return_t rc;
2105 size_t length;
2106 uint32_t flags;
2107
2108 const char *value= memcached_get(memc, "dsf", 3, &length, &flags, &rc);
2109 test_false(value);
2110 test_zero(length);
2111
2112 test_compare(MEMCACHED_TIMEOUT, memc);
2113
2114 memcached_free(memc);
2115
2116 return TEST_SUCCESS;
2117 }
2118
2119 test_return_t regression_bug_581030(memcached_st *)
2120 {
2121 #ifndef DEBUG
2122 memcached_stat_st *local_stat= memcached_stat(NULL, NULL, NULL);
2123 test_false(local_stat);
2124
2125 memcached_stat_free(NULL, NULL);
2126 #endif
2127
2128 return TEST_SUCCESS;
2129 }
2130
2131 #define regression_bug_655423_COUNT 6000
2132 test_return_t regression_bug_655423(memcached_st *memc)
2133 {
2134 memcached_st *clone= memcached_clone(NULL, memc);
2135 memc= NULL; // Just to make sure it is not used
2136 test_true(clone);
2137 char payload[100];
2138
2139 #ifdef __APPLE__
2140 return TEST_SKIPPED;
2141 #endif
2142
2143 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1));
2144 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(clone, MEMCACHED_BEHAVIOR_SUPPORT_CAS, 1));
2145 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(clone, MEMCACHED_BEHAVIOR_TCP_NODELAY, 1));
2146 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(clone, MEMCACHED_BEHAVIOR_IO_KEY_PREFETCH, 1));
2147
2148 memset(payload, int('x'), sizeof(payload));
2149
2150 keys_st keys(regression_bug_655423_COUNT);
2151
2152 for (size_t x= 0; x < keys.size(); x++)
2153 {
2154 test_compare(MEMCACHED_SUCCESS, memcached_set(clone,
2155 keys.key_at(x),
2156 keys.length_at(x),
2157 payload, sizeof(payload), 0, 0));
2158 }
2159
2160 for (size_t x= 0; x < keys.size(); x++)
2161 {
2162 size_t value_length;
2163 memcached_return_t rc;
2164 char *value= memcached_get(clone,
2165 keys.key_at(x),
2166 keys.length_at(x),
2167 &value_length, NULL, &rc);
2168
2169 if (rc == MEMCACHED_NOTFOUND)
2170 {
2171 test_false(value);
2172 test_zero(value_length);
2173 continue;
2174 }
2175
2176 test_compare(MEMCACHED_SUCCESS, rc);
2177 test_true(value);
2178 test_compare(100LLU, value_length);
2179 free(value);
2180 }
2181
2182 test_compare(MEMCACHED_SUCCESS,
2183 memcached_mget(clone,
2184 keys.keys_ptr(), keys.lengths_ptr(),
2185 keys.size()));
2186
2187 uint32_t count= 0;
2188 memcached_result_st *result= NULL;
2189 while ((result= memcached_fetch_result(clone, result, NULL)))
2190 {
2191 test_compare(size_t(100), memcached_result_length(result));
2192 count++;
2193 }
2194
2195 test_true(count > 100); // If we don't get back atleast this, something is up
2196
2197 memcached_free(clone);
2198
2199 return TEST_SUCCESS;
2200 }
2201
2202 /*
2203 * Test that ensures that buffered set to not trigger problems during io_flush
2204 */
2205 #define regression_bug_490520_COUNT 200480
2206 test_return_t regression_bug_490520(memcached_st *original_memc)
2207 {
2208 memcached_st* memc= create_single_instance_memcached(original_memc, NULL);
2209
2210 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK,1);
2211 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS,1);
2212 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, 1000);
2213 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT,1);
2214 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 3600);
2215
2216 /* First add all of the items.. */
2217 char blob[3333] = {0};
2218 for (uint32_t x= 0; x < regression_bug_490520_COUNT; ++x)
2219 {
2220 char key[251];
2221 int key_length= snprintf(key, sizeof(key), "0200%u", x);
2222
2223 memcached_return rc= memcached_set(memc, key, key_length, blob, sizeof(blob), 0, 0);
2224 test_true_got(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED, memcached_last_error_message(memc));
2225 }
2226
2227 memcached_free(memc);
2228
2229 return TEST_SUCCESS;
2230 }
2231
2232 test_return_t regression_bug_1251482(memcached_st*)
2233 {
2234 test::Memc memc("--server=localhost:5");
2235
2236 memcached_behavior_set(&memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 0);
2237
2238 for (size_t x= 0; x < 5; ++x)
2239 {
2240 size_t value_length;
2241 memcached_return_t rc;
2242 char *value= memcached_get(&memc,
2243 test_literal_param(__func__),
2244 &value_length, NULL, &rc);
2245
2246 test_false(value);
2247 test_compare(0LLU, value_length);
2248 if (x) {
2249 test_ne_compare(MEMCACHED_SUCCESS, rc);
2250 } else {
2251 test_compare(MEMCACHED_CONNECTION_FAILURE, rc);
2252 }
2253 }
2254
2255 return TEST_SUCCESS;
2256 }
2257
2258 test_return_t regression_1009493_TEST(memcached_st*)
2259 {
2260 memcached_st* memc= memcached_create(NULL);
2261 test_true(memc);
2262 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA, true));
2263
2264 memcached_st* clone= memcached_clone(NULL, memc);
2265 test_true(clone);
2266
2267 test_compare(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED),
2268 memcached_behavior_get(clone, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED));
2269
2270 memcached_free(memc);
2271 memcached_free(clone);
2272
2273 return TEST_SUCCESS;
2274 }
2275
2276 test_return_t regression_994772_TEST(memcached_st* memc)
2277 {
2278 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1));
2279
2280 test_compare(MEMCACHED_SUCCESS,
2281 memcached_set(memc,
2282 test_literal_param(__func__), // Key
2283 test_literal_param(__func__), // Value
2284 time_t(0), uint32_t(0)));
2285
2286 const char *keys[] = { __func__ };
2287 size_t key_length[]= { strlen(__func__) };
2288 test_compare(MEMCACHED_SUCCESS,
2289 memcached_mget(memc, keys, key_length, 1));
2290
2291 memcached_return_t rc;
2292 memcached_result_st *results= memcached_fetch_result(memc, NULL, &rc);
2293 test_true(results);
2294 test_compare(MEMCACHED_SUCCESS, rc);
2295
2296 test_strcmp(__func__, memcached_result_value(results));
2297 uint64_t cas_value= memcached_result_cas(results);
2298 test_true(cas_value);
2299
2300 char* take_value= memcached_result_take_value(results);
2301 test_strcmp(__func__, take_value);
2302 free(take_value);
2303
2304 memcached_result_free(results);
2305
2306 // Bad cas value, sanity check
2307 test_true(cas_value != 9999);
2308 test_compare(MEMCACHED_END,
2309 memcached_cas(memc,
2310 test_literal_param(__func__), // Key
2311 test_literal_param(__FILE__), // Value
2312 time_t(0), uint32_t(0), 9999));
2313
2314 test_compare(MEMCACHED_SUCCESS, memcached_set(memc,
2315 "different", strlen("different"), // Key
2316 test_literal_param(__FILE__), // Value
2317 time_t(0), uint32_t(0)));
2318
2319 return TEST_SUCCESS;
2320 }
2321
2322 test_return_t regression_bug_854604(memcached_st *)
2323 {
2324 char buffer[1024];
2325
2326 test_compare(MEMCACHED_INVALID_ARGUMENTS, libmemcached_check_configuration(0, 0, buffer, 0));
2327
2328 test_compare(MEMCACHED_PARSE_ERROR, libmemcached_check_configuration(test_literal_param("syntax error"), buffer, 0));
2329
2330 test_compare(MEMCACHED_PARSE_ERROR, libmemcached_check_configuration(test_literal_param("syntax error"), buffer, 1));
2331 test_compare(buffer[0], 0);
2332
2333 test_compare(MEMCACHED_PARSE_ERROR, libmemcached_check_configuration(test_literal_param("syntax error"), buffer, 10));
2334 test_true(strlen(buffer));
2335
2336 test_compare(MEMCACHED_PARSE_ERROR, libmemcached_check_configuration(test_literal_param("syntax error"), buffer, sizeof(buffer)));
2337 test_true(strlen(buffer));
2338
2339 return TEST_SUCCESS;
2340 }
2341
2342 static void die_message(memcached_st* mc, memcached_return error, const char* what, uint32_t it)
2343 {
2344 fprintf(stderr, "Iteration #%u: ", it);
2345
2346 if (error == MEMCACHED_ERRNO)
2347 {
2348 fprintf(stderr, "system error %d from %s: %s\n",
2349 errno, what, strerror(errno));
2350 }
2351 else
2352 {
2353 fprintf(stderr, "error %d from %s: %s\n", error, what,
2354 memcached_strerror(mc, error));
2355 }
2356 }