Merge in all of libtest updates.
[m6w6/libmemcached] / tests / 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 <config.h>
39 #include <libtest/test.hpp>
40
41 /*
42 Test cases
43 */
44
45 #define BUILDING_LIBMEMCACHED
46 // !NEVER use common.h, always use memcached.h in your own apps
47 #include <libmemcached/common.h>
48
49 #include <cassert>
50 #include <memory>
51 #include <signal.h>
52 #include <sys/stat.h>
53 #include <sys/time.h>
54 #include <sys/types.h>
55 #include <unistd.h>
56
57 #include <iostream>
58
59 #include <libtest/server.h>
60
61 #include "clients/generator.h"
62 #include "clients/execute.h"
63
64 #define SMALL_STRING_LEN 1024
65
66 #include <libtest/test.hpp>
67 #include "tests/deprecated.h"
68 #include "tests/parser.h"
69 #include "tests/pool.h"
70 #include "tests/namespace.h"
71 #include "tests/string.h"
72 #include "tests/replication.h"
73 #include "tests/debug.h"
74 #include "tests/basic.h"
75 #include "tests/error_conditions.h"
76 #include "tests/print.h"
77 #include "tests/virtual_buckets.h"
78
79 using namespace libtest;
80
81 #ifdef HAVE_LIBMEMCACHEDUTIL
82 #include <pthread.h>
83 #include "libmemcached/memcached_util.h"
84 #endif
85
86 #include "hash_results.h"
87
88 #define GLOBAL_COUNT 10000
89 #define GLOBAL2_COUNT 100
90 #define SERVERS_TO_CREATE 5
91 static uint32_t global_count;
92
93 static pairs_st *global_pairs;
94 static const char *global_keys[GLOBAL_COUNT];
95 static size_t global_keys_length[GLOBAL_COUNT];
96
97 // Prototype
98 static test_return_t pre_binary(memcached_st *memc);
99
100
101 static test_return_t init_test(memcached_st *not_used)
102 {
103 memcached_st memc;
104 (void)not_used;
105
106 (void)memcached_create(&memc);
107 memcached_free(&memc);
108
109 return TEST_SUCCESS;
110 }
111
112 #define TEST_PORT_COUNT 7
113 in_port_t test_ports[TEST_PORT_COUNT];
114
115 static memcached_return_t server_display_function(const memcached_st *ptr,
116 const memcached_server_st *server,
117 void *context)
118 {
119 /* Do Nothing */
120 size_t bigger= *((size_t *)(context));
121 (void)ptr;
122 assert(bigger <= memcached_server_port(server));
123 *((size_t *)(context))= memcached_server_port(server);
124
125 return MEMCACHED_SUCCESS;
126 }
127
128 static memcached_return_t dump_server_information(const memcached_st *ptr,
129 const memcached_server_st *instance,
130 void *context)
131 {
132 /* Do Nothing */
133 FILE *stream= (FILE *)context;
134 (void)ptr;
135
136 fprintf(stream, "Memcached Server: %s %u Version %u.%u.%u\n",
137 memcached_server_name(instance),
138 memcached_server_port(instance),
139 instance->major_version,
140 instance->minor_version,
141 instance->micro_version);
142
143 return MEMCACHED_SUCCESS;
144 }
145
146 static test_return_t server_sort_test(memcached_st *ptr)
147 {
148 size_t bigger= 0; /* Prime the value for the test_true in server_display_function */
149
150 memcached_return_t rc;
151 memcached_server_fn callbacks[1];
152 memcached_st *local_memc;
153 (void)ptr;
154
155 local_memc= memcached_create(NULL);
156 test_true(local_memc);
157 memcached_behavior_set(local_memc, MEMCACHED_BEHAVIOR_SORT_HOSTS, 1);
158
159 for (uint32_t x= 0; x < TEST_PORT_COUNT; x++)
160 {
161 test_ports[x]= (in_port_t)random() % 64000;
162 rc= memcached_server_add_with_weight(local_memc, "localhost", test_ports[x], 0);
163 test_compare(memcached_server_count(local_memc), x +1);
164 #if 0 // Rewrite
165 test_true(memcached_server_list_count(memcached_server_list(local_memc)) == x+1);
166 #endif
167 test_compare(MEMCACHED_SUCCESS, rc);
168 }
169
170 callbacks[0]= server_display_function;
171 memcached_server_cursor(local_memc, callbacks, (void *)&bigger, 1);
172
173
174 memcached_free(local_memc);
175
176 return TEST_SUCCESS;
177 }
178
179 static test_return_t server_sort2_test(memcached_st *ptr)
180 {
181 size_t bigger= 0; /* Prime the value for the test_true in server_display_function */
182 memcached_server_fn callbacks[1];
183 memcached_st *local_memc;
184 memcached_server_instance_st instance;
185 (void)ptr;
186
187 local_memc= memcached_create(NULL);
188 test_true(local_memc);
189 test_compare(MEMCACHED_SUCCESS,
190 memcached_behavior_set(local_memc, MEMCACHED_BEHAVIOR_SORT_HOSTS, 1));
191
192 test_compare(MEMCACHED_SUCCESS,
193 memcached_server_add_with_weight(local_memc, "MEMCACHED_BEHAVIOR_SORT_HOSTS", 43043, 0));
194 instance= memcached_server_instance_by_position(local_memc, 0);
195 test_compare(in_port_t(43043), memcached_server_port(instance));
196
197 test_compare(MEMCACHED_SUCCESS,
198 memcached_server_add_with_weight(local_memc, "MEMCACHED_BEHAVIOR_SORT_HOSTS", 43042, 0));
199
200 instance= memcached_server_instance_by_position(local_memc, 0);
201 test_compare(in_port_t(43042), memcached_server_port(instance));
202
203 instance= memcached_server_instance_by_position(local_memc, 1);
204 test_compare(in_port_t(43043), memcached_server_port(instance));
205
206 callbacks[0]= server_display_function;
207 memcached_server_cursor(local_memc, callbacks, (void *)&bigger, 1);
208
209
210 memcached_free(local_memc);
211
212 return TEST_SUCCESS;
213 }
214
215 static test_return_t memcached_server_remove_test(memcached_st*)
216 {
217 const char *server_string= "--server=localhost:4444 --server=localhost:4445 --server=localhost:4446 --server=localhost:4447 --server=localhost --server=memcache1.memcache.bk.sapo.pt:11211 --server=memcache1.memcache.bk.sapo.pt:11212 --server=memcache1.memcache.bk.sapo.pt:11213 --server=memcache1.memcache.bk.sapo.pt:11214 --server=memcache2.memcache.bk.sapo.pt:11211 --server=memcache2.memcache.bk.sapo.pt:11212 --server=memcache2.memcache.bk.sapo.pt:11213 --server=memcache2.memcache.bk.sapo.pt:11214";
218 char buffer[BUFSIZ];
219
220 test_compare(MEMCACHED_SUCCESS,
221 libmemcached_check_configuration(server_string, strlen(server_string), buffer, sizeof(buffer)));
222 memcached_st *memc= memcached(server_string, strlen(server_string));
223 test_true(memc);
224
225 memcached_server_fn callbacks[1];
226 callbacks[0]= server_print_callback;
227 memcached_server_cursor(memc, callbacks, NULL, 1);
228
229 memcached_free(memc);
230
231 return TEST_SUCCESS;
232 }
233
234 static memcached_return_t server_display_unsort_function(const memcached_st*,
235 const memcached_server_st *server,
236 void *context)
237 {
238 /* Do Nothing */
239 uint32_t x= *((uint32_t *)(context));
240
241 if (! (test_ports[x] == server->port))
242 {
243 fprintf(stderr, "%lu -> %lu\n", (unsigned long)test_ports[x], (unsigned long)server->port);
244 return MEMCACHED_FAILURE;
245 }
246
247 *((uint32_t *)(context))= ++x;
248
249 return MEMCACHED_SUCCESS;
250 }
251
252 static test_return_t server_unsort_test(memcached_st *ptr)
253 {
254 size_t counter= 0; /* Prime the value for the test_true in server_display_function */
255 size_t bigger= 0; /* Prime the value for the test_true in server_display_function */
256 memcached_server_fn callbacks[1];
257 memcached_st *local_memc;
258 (void)ptr;
259
260 local_memc= memcached_create(NULL);
261 test_true(local_memc);
262
263 for (uint32_t x= 0; x < TEST_PORT_COUNT; x++)
264 {
265 test_ports[x]= (in_port_t)(random() % 64000);
266 test_compare(MEMCACHED_SUCCESS,
267 memcached_server_add_with_weight(local_memc, "localhost", test_ports[x], 0));
268 test_compare(memcached_server_count(local_memc), x +1);
269 #if 0 // Rewrite
270 test_true(memcached_server_list_count(memcached_server_list(local_memc)) == x+1);
271 #endif
272 }
273
274 callbacks[0]= server_display_unsort_function;
275 memcached_server_cursor(local_memc, callbacks, (void *)&counter, 1);
276
277 /* Now we sort old data! */
278 memcached_behavior_set(local_memc, MEMCACHED_BEHAVIOR_SORT_HOSTS, 1);
279 callbacks[0]= server_display_function;
280 memcached_server_cursor(local_memc, callbacks, (void *)&bigger, 1);
281
282
283 memcached_free(local_memc);
284
285 return TEST_SUCCESS;
286 }
287
288 static test_return_t allocation_test(memcached_st *not_used)
289 {
290 (void)not_used;
291 memcached_st *memc;
292 memc= memcached_create(NULL);
293 test_true(memc);
294 memcached_free(memc);
295
296 return TEST_SUCCESS;
297 }
298
299 static test_return_t clone_test(memcached_st *memc)
300 {
301 /* All null? */
302 {
303 memcached_st *memc_clone;
304 memc_clone= memcached_clone(NULL, NULL);
305 test_true(memc_clone);
306 memcached_free(memc_clone);
307 }
308
309 /* Can we init from null? */
310 {
311 memcached_st *memc_clone;
312 memc_clone= memcached_clone(NULL, memc);
313 test_true(memc_clone);
314
315 { // Test allocators
316 test_true(memc_clone->allocators.free == memc->allocators.free);
317 test_true(memc_clone->allocators.malloc == memc->allocators.malloc);
318 test_true(memc_clone->allocators.realloc == memc->allocators.realloc);
319 test_true(memc_clone->allocators.calloc == memc->allocators.calloc);
320 }
321
322 test_true(memc_clone->connect_timeout == memc->connect_timeout);
323 test_true(memc_clone->delete_trigger == memc->delete_trigger);
324 test_true(memc_clone->distribution == memc->distribution);
325 { // Test all of the flags
326 test_true(memc_clone->flags.no_block == memc->flags.no_block);
327 test_true(memc_clone->flags.tcp_nodelay == memc->flags.tcp_nodelay);
328 test_true(memc_clone->flags.support_cas == memc->flags.support_cas);
329 test_true(memc_clone->flags.buffer_requests == memc->flags.buffer_requests);
330 test_true(memc_clone->flags.use_sort_hosts == memc->flags.use_sort_hosts);
331 test_true(memc_clone->flags.verify_key == memc->flags.verify_key);
332 test_true(memc_clone->ketama.weighted == memc->ketama.weighted);
333 test_true(memc_clone->flags.binary_protocol == memc->flags.binary_protocol);
334 test_true(memc_clone->flags.hash_with_namespace == memc->flags.hash_with_namespace);
335 test_true(memc_clone->flags.no_reply == memc->flags.no_reply);
336 test_true(memc_clone->flags.use_udp == memc->flags.use_udp);
337 test_true(memc_clone->flags.auto_eject_hosts == memc->flags.auto_eject_hosts);
338 test_true(memc_clone->flags.randomize_replica_read == memc->flags.randomize_replica_read);
339 }
340 test_true(memc_clone->get_key_failure == memc->get_key_failure);
341 test_true(hashkit_compare(&memc_clone->hashkit, &memc->hashkit));
342 test_true(memc_clone->io_bytes_watermark == memc->io_bytes_watermark);
343 test_true(memc_clone->io_msg_watermark == memc->io_msg_watermark);
344 test_true(memc_clone->io_key_prefetch == memc->io_key_prefetch);
345 test_true(memc_clone->on_cleanup == memc->on_cleanup);
346 test_true(memc_clone->on_clone == memc->on_clone);
347 test_true(memc_clone->poll_timeout == memc->poll_timeout);
348 test_true(memc_clone->rcv_timeout == memc->rcv_timeout);
349 test_true(memc_clone->recv_size == memc->recv_size);
350 test_true(memc_clone->retry_timeout == memc->retry_timeout);
351 test_true(memc_clone->send_size == memc->send_size);
352 test_true(memc_clone->server_failure_limit == memc->server_failure_limit);
353 test_true(memc_clone->snd_timeout == memc->snd_timeout);
354 test_true(memc_clone->user_data == memc->user_data);
355
356 memcached_free(memc_clone);
357 }
358
359 /* Can we init from struct? */
360 {
361 memcached_st declared_clone;
362 memcached_st *memc_clone;
363 memset(&declared_clone, 0 , sizeof(memcached_st));
364 memc_clone= memcached_clone(&declared_clone, NULL);
365 test_true(memc_clone);
366 memcached_free(memc_clone);
367 }
368
369 /* Can we init from struct? */
370 {
371 memcached_st declared_clone;
372 memcached_st *memc_clone;
373 memset(&declared_clone, 0 , sizeof(memcached_st));
374 memc_clone= memcached_clone(&declared_clone, memc);
375 test_true(memc_clone);
376 memcached_free(memc_clone);
377 }
378
379 return TEST_SUCCESS;
380 }
381
382 static test_return_t userdata_test(memcached_st *memc)
383 {
384 void* foo= NULL;
385 test_false(memcached_set_user_data(memc, foo));
386 test_true(memcached_get_user_data(memc) == foo);
387 test_true(memcached_set_user_data(memc, NULL) == foo);
388
389 return TEST_SUCCESS;
390 }
391
392 static test_return_t connection_test(memcached_st *memc)
393 {
394 test_compare(MEMCACHED_SUCCESS,
395 memcached_server_add_with_weight(memc, "localhost", 0, 0));
396
397 return TEST_SUCCESS;
398 }
399
400 static test_return_t libmemcached_string_behavior_test(memcached_st *)
401 {
402 for (int x= MEMCACHED_BEHAVIOR_NO_BLOCK; x < int(MEMCACHED_BEHAVIOR_MAX); ++x)
403 {
404 test_true(libmemcached_string_behavior(memcached_behavior_t(x)));
405 }
406 test_compare(36, int(MEMCACHED_BEHAVIOR_MAX));
407
408 return TEST_SUCCESS;
409 }
410
411 static test_return_t libmemcached_string_distribution_test(memcached_st *)
412 {
413 for (int x= MEMCACHED_DISTRIBUTION_MODULA; x < int(MEMCACHED_DISTRIBUTION_CONSISTENT_MAX); ++x)
414 {
415 test_true(libmemcached_string_distribution(memcached_server_distribution_t(x)));
416 }
417 test_compare(7, int(MEMCACHED_DISTRIBUTION_CONSISTENT_MAX));
418
419 return TEST_SUCCESS;
420 }
421
422 static test_return_t error_test(memcached_st *memc)
423 {
424 uint32_t values[] = { 851992627U, 2337886783U, 4109241422U, 4001849190U,
425 982370485U, 1263635348U, 4242906218U, 3829656100U,
426 1891735253U, 334139633U, 2257084983U, 3088286104U,
427 13199785U, 2542027183U, 1097051614U, 199566778U,
428 2748246961U, 2465192557U, 1664094137U, 2405439045U,
429 1842224848U, 692413798U, 3479807801U, 919913813U,
430 4269430871U, 610793021U, 527273862U, 1437122909U,
431 2300930706U, 2943759320U, 674306647U, 2400528935U,
432 54481931U, 4186304426U, 1741088401U, 2979625118U,
433 4159057246U, 3425930182U, 2593724503U, 1868899624U,
434 1769812374U, 2302537950U, 1110330676U, 3365377466U,
435 1336171666U, 3021258493U, 2334992265U, 3365377466U };
436
437 // You have updated the memcache_error messages but not updated docs/tests.
438 for (int rc= int(MEMCACHED_SUCCESS); rc < int(MEMCACHED_MAXIMUM_RETURN); ++rc)
439 {
440 uint32_t hash_val;
441 const char *msg= memcached_strerror(memc, memcached_return_t(rc));
442 hash_val= memcached_generate_hash_value(msg, strlen(msg),
443 MEMCACHED_HASH_JENKINS);
444 if (values[rc] != hash_val)
445 {
446 fprintf(stderr, "\n\nYou have updated memcached_return_t without updating the error_test\n");
447 fprintf(stderr, "%u, %s, (%u)\n\n", (uint32_t)rc, memcached_strerror(memc, memcached_return_t(rc)), hash_val);
448 }
449 test_compare(values[rc], hash_val);
450 }
451 test_compare(47, int(MEMCACHED_MAXIMUM_RETURN));
452
453 return TEST_SUCCESS;
454 }
455
456 static test_return_t set_test(memcached_st *memc)
457 {
458 memcached_return_t rc= memcached_set(memc,
459 memcached_literal_param("foo"),
460 memcached_literal_param("when we sanitize"),
461 time_t(0), (uint32_t)0);
462 test_true_got(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED, memcached_strerror(NULL, rc));
463
464 return TEST_SUCCESS;
465 }
466
467 static test_return_t append_test(memcached_st *memc)
468 {
469 memcached_return_t rc;
470 const char *key= "fig";
471 const char *in_value= "we";
472 char *out_value= NULL;
473 size_t value_length;
474 uint32_t flags;
475
476 rc= memcached_flush(memc, 0);
477 test_compare(MEMCACHED_SUCCESS, rc);
478
479 rc= memcached_set(memc, key, strlen(key),
480 in_value, strlen(in_value),
481 (time_t)0, (uint32_t)0);
482 test_compare(MEMCACHED_SUCCESS, rc);
483
484 rc= memcached_append(memc, key, strlen(key),
485 " the", strlen(" the"),
486 (time_t)0, (uint32_t)0);
487 test_compare(MEMCACHED_SUCCESS, rc);
488
489 rc= memcached_append(memc, key, strlen(key),
490 " people", strlen(" people"),
491 (time_t)0, (uint32_t)0);
492 test_compare(MEMCACHED_SUCCESS, rc);
493
494 out_value= memcached_get(memc, key, strlen(key),
495 &value_length, &flags, &rc);
496 test_memcmp(out_value, "we the people", strlen("we the people"));
497 test_compare(strlen("we the people"), value_length);
498 test_compare(MEMCACHED_SUCCESS, rc);
499 free(out_value);
500
501 return TEST_SUCCESS;
502 }
503
504 static test_return_t append_binary_test(memcached_st *memc)
505 {
506 memcached_return_t rc;
507 const char *key= "numbers";
508 uint32_t store_list[] = { 23, 56, 499, 98, 32847, 0 };
509 uint32_t *value;
510 size_t value_length;
511 uint32_t flags;
512 uint32_t x;
513
514 rc= memcached_flush(memc, 0);
515 test_compare(MEMCACHED_SUCCESS, rc);
516
517 rc= memcached_set(memc,
518 key, strlen(key),
519 NULL, 0,
520 (time_t)0, (uint32_t)0);
521 test_compare_got(MEMCACHED_SUCCESS, rc, memcached_strerror(NULL, rc));
522
523 for (x= 0; store_list[x] ; x++)
524 {
525 rc= memcached_append(memc,
526 key, strlen(key),
527 (char *)&store_list[x], sizeof(uint32_t),
528 (time_t)0, (uint32_t)0);
529 test_compare(MEMCACHED_SUCCESS, rc);
530 }
531
532 value= (uint32_t *)memcached_get(memc, key, strlen(key),
533 &value_length, &flags, &rc);
534 test_compare(value_length, sizeof(uint32_t) * x);
535 test_compare(MEMCACHED_SUCCESS, rc);
536
537 for (uint32_t counter= x, *ptr= value; counter; counter--)
538 {
539 test_compare(*ptr, store_list[x - counter]);
540 ptr++;
541 }
542 free(value);
543
544 return TEST_SUCCESS;
545 }
546
547 static test_return_t cas2_test(memcached_st *memc)
548 {
549 memcached_return_t rc;
550 const char *keys[]= {"fudge", "son", "food"};
551 size_t key_length[]= {5, 3, 4};
552 const char *value= "we the people";
553 size_t value_length= strlen("we the people");
554 memcached_result_st results_obj;
555 memcached_result_st *results;
556 unsigned int set= 1;
557
558 test_compare(MEMCACHED_SUCCESS, memcached_flush(memc, 0));
559
560 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, set);
561
562 for (uint32_t x= 0; x < 3; x++)
563 {
564 rc= memcached_set(memc, keys[x], key_length[x],
565 keys[x], key_length[x],
566 (time_t)50, (uint32_t)9);
567 test_compare(MEMCACHED_SUCCESS, rc);
568 }
569
570 rc= memcached_mget(memc, keys, key_length, 3);
571
572 results= memcached_result_create(memc, &results_obj);
573
574 results= memcached_fetch_result(memc, &results_obj, &rc);
575 test_true(results);
576 test_true(results->item_cas);
577 test_compare(MEMCACHED_SUCCESS, rc);
578 test_true(memcached_result_cas(results));
579
580 test_memcmp(value, "we the people", strlen("we the people"));
581 test_compare(strlen("we the people"), value_length);
582 test_compare(MEMCACHED_SUCCESS, rc);
583
584 memcached_result_free(&results_obj);
585
586 return TEST_SUCCESS;
587 }
588
589 static test_return_t cas_test(memcached_st *memc)
590 {
591 memcached_return_t rc;
592 const char *key= "fun";
593 size_t key_length= strlen(key);
594 const char *value= "we the people";
595 const char* keys[2] = { key, NULL };
596 size_t keylengths[2] = { strlen(key), 0 };
597 size_t value_length= strlen(value);
598 const char *value2= "change the value";
599 size_t value2_length= strlen(value2);
600
601 memcached_result_st results_obj;
602 memcached_result_st *results;
603 unsigned int set= 1;
604
605 rc= memcached_flush(memc, 0);
606 test_compare(MEMCACHED_SUCCESS, rc);
607
608 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, set);
609
610 rc= memcached_set(memc, key, strlen(key),
611 value, strlen(value),
612 (time_t)0, (uint32_t)0);
613 test_compare(MEMCACHED_SUCCESS, rc);
614
615 rc= memcached_mget(memc, keys, keylengths, 1);
616
617 results= memcached_result_create(memc, &results_obj);
618
619 results= memcached_fetch_result(memc, &results_obj, &rc);
620 test_true(results);
621 test_compare(MEMCACHED_SUCCESS, rc);
622 test_true(memcached_result_cas(results));
623 test_memcmp(value, memcached_result_value(results), value_length);
624 test_compare(strlen(memcached_result_value(results)), value_length);
625 test_compare(MEMCACHED_SUCCESS, rc);
626 uint64_t cas = memcached_result_cas(results);
627
628 #if 0
629 results= memcached_fetch_result(memc, &results_obj, &rc);
630 test_true(rc == MEMCACHED_END);
631 test_true(results == NULL);
632 #endif
633
634 rc= memcached_cas(memc, key, key_length, value2, value2_length, 0, 0, cas);
635 test_compare(MEMCACHED_SUCCESS, rc);
636
637 /*
638 * The item will have a new cas value, so try to set it again with the old
639 * value. This should fail!
640 */
641 rc= memcached_cas(memc, key, key_length, value2, value2_length, 0, 0, cas);
642 test_compare(MEMCACHED_DATA_EXISTS, rc);
643
644 memcached_result_free(&results_obj);
645
646 return TEST_SUCCESS;
647 }
648
649 static test_return_t prepend_test(memcached_st *memc)
650 {
651 memcached_return_t rc;
652 const char *key= "fig";
653 const char *value= "people";
654 char *out_value= NULL;
655 size_t value_length;
656 uint32_t flags;
657
658 rc= memcached_flush(memc, 0);
659 test_compare(MEMCACHED_SUCCESS, rc);
660
661 rc= memcached_set(memc, key, strlen(key),
662 value, strlen(value),
663 (time_t)0, (uint32_t)0);
664 test_compare(MEMCACHED_SUCCESS, rc);
665
666 rc= memcached_prepend(memc, key, strlen(key),
667 "the ", strlen("the "),
668 (time_t)0, (uint32_t)0);
669 test_compare(MEMCACHED_SUCCESS, rc);
670
671 rc= memcached_prepend(memc, key, strlen(key),
672 "we ", strlen("we "),
673 (time_t)0, (uint32_t)0);
674 test_compare(MEMCACHED_SUCCESS, rc);
675
676 out_value= memcached_get(memc, key, strlen(key),
677 &value_length, &flags, &rc);
678 test_memcmp(out_value, "we the people", strlen("we the people"));
679 test_compare(strlen("we the people"), value_length);
680 test_compare(MEMCACHED_SUCCESS, rc);
681 free(out_value);
682
683 return TEST_SUCCESS;
684 }
685
686 /*
687 Set the value, then quit to make sure it is flushed.
688 Come back in and test that add fails.
689 */
690 static test_return_t add_test(memcached_st *memc)
691 {
692 memcached_return_t rc;
693 const char *key= "foo";
694 const char *value= "when we sanitize";
695 unsigned long long setting_value;
696
697 setting_value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NO_BLOCK);
698
699 rc= memcached_set(memc, key, strlen(key),
700 value, strlen(value),
701 (time_t)0, (uint32_t)0);
702 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
703 memcached_quit(memc);
704 rc= memcached_add(memc, key, strlen(key),
705 value, strlen(value),
706 (time_t)0, (uint32_t)0);
707
708 /* Too many broken OS'es have broken loopback in async, so we can't be sure of the result */
709 if (setting_value)
710 {
711 test_true(rc == MEMCACHED_NOTSTORED || rc == MEMCACHED_STORED);
712 }
713 else
714 {
715 test_true(rc == MEMCACHED_NOTSTORED || rc == MEMCACHED_DATA_EXISTS);
716 }
717
718 return TEST_SUCCESS;
719 }
720
721 /*
722 ** There was a problem of leaking filedescriptors in the initial release
723 ** of MacOSX 10.5. This test case triggers the problem. On some Solaris
724 ** systems it seems that the kernel is slow on reclaiming the resources
725 ** because the connects starts to time out (the test doesn't do much
726 ** anyway, so just loop 10 iterations)
727 */
728 static test_return_t add_wrapper(memcached_st *memc)
729 {
730 unsigned int max= 10000;
731 #ifdef __sun
732 max= 10;
733 #endif
734 #ifdef __APPLE__
735 max= 10;
736 #endif
737
738 for (uint32_t x= 0; x < max; x++)
739 add_test(memc);
740
741 return TEST_SUCCESS;
742 }
743
744 static test_return_t replace_test(memcached_st *memc)
745 {
746 memcached_return_t rc;
747 const char *key= "foo";
748 const char *value= "when we sanitize";
749 const char *original= "first we insert some data";
750
751 rc= memcached_set(memc, key, strlen(key),
752 original, strlen(original),
753 (time_t)0, (uint32_t)0);
754 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
755
756 test_compare(MEMCACHED_SUCCESS,
757 memcached_replace(memc, key, strlen(key),
758 value, strlen(value),
759 (time_t)0, (uint32_t)0));
760
761 return TEST_SUCCESS;
762 }
763
764 static test_return_t delete_test(memcached_st *memc)
765 {
766 memcached_return_t rc;
767 const char *key= "foo";
768 const char *value= "when we sanitize";
769
770 rc= memcached_set(memc, key, strlen(key),
771 value, strlen(value),
772 (time_t)0, (uint32_t)0);
773 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
774
775 rc= memcached_delete(memc, key, strlen(key), (time_t)0);
776 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
777
778 return TEST_SUCCESS;
779 }
780
781 static test_return_t flush_test(memcached_st *memc)
782 {
783 uint64_t query_id= memcached_query_id(memc);
784 test_compare(MEMCACHED_SUCCESS,
785 memcached_flush(memc, 0));
786 test_compare(query_id +1, memcached_query_id(memc));
787
788 return TEST_SUCCESS;
789 }
790
791 static memcached_return_t server_function(const memcached_st *ptr,
792 const memcached_server_st *server,
793 void *context)
794 {
795 (void)ptr; (void)server; (void)context;
796 /* Do Nothing */
797
798 return MEMCACHED_SUCCESS;
799 }
800
801 static test_return_t memcached_server_cursor_test(memcached_st *memc)
802 {
803 char context[10];
804 strncpy(context, "foo bad", sizeof(context));
805 memcached_server_fn callbacks[1];
806
807 callbacks[0]= server_function;
808 memcached_server_cursor(memc, callbacks, context, 1);
809 return TEST_SUCCESS;
810 }
811
812 static test_return_t bad_key_test(memcached_st *memc)
813 {
814 memcached_return_t rc;
815 const char *key= "foo bad";
816 char *string;
817 size_t string_length;
818 uint32_t flags;
819 memcached_st *memc_clone;
820 unsigned int set= 1;
821 size_t max_keylen= 0xffff;
822
823 // Just skip if we are in binary mode.
824 uint64_t query_id= memcached_query_id(memc);
825 if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL))
826 return TEST_SKIPPED;
827 test_compare(query_id, memcached_query_id(memc)); // We should not increase the query_id for memcached_behavior_get()
828
829 memc_clone= memcached_clone(NULL, memc);
830 test_true(memc_clone);
831
832 query_id= memcached_query_id(memc_clone);
833 test_compare(MEMCACHED_SUCCESS,
834 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_VERIFY_KEY, set));
835 test_compare(query_id, memcached_query_id(memc_clone)); // We should not increase the query_id for memcached_behavior_set()
836
837 /* All keys are valid in the binary protocol (except for length) */
838 if (not memcached_behavior_get(memc_clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL))
839 {
840 query_id= memcached_query_id(memc_clone);
841 string= memcached_get(memc_clone, key, strlen(key),
842 &string_length, &flags, &rc);
843 test_compare(MEMCACHED_BAD_KEY_PROVIDED, rc);
844 test_zero(string_length);
845 test_false(string);
846
847 set= 0;
848 query_id= memcached_query_id(memc_clone);
849 test_compare(MEMCACHED_SUCCESS,
850 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_VERIFY_KEY, set));
851 test_compare(query_id, memcached_query_id(memc_clone)); // We should not increase the query_id for memcached_behavior_set()
852 string= memcached_get(memc_clone, key, strlen(key),
853 &string_length, &flags, &rc);
854 test_compare_got(MEMCACHED_NOTFOUND, rc, memcached_strerror(NULL, rc));
855 test_zero(string_length);
856 test_false(string);
857
858 /* Test multi key for bad keys */
859 const char *keys[] = { "GoodKey", "Bad Key", "NotMine" };
860 size_t key_lengths[] = { 7, 7, 7 };
861 set= 1;
862 query_id= memcached_query_id(memc_clone);
863 test_compare(MEMCACHED_SUCCESS,
864 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_VERIFY_KEY, set));
865 test_compare(query_id, memcached_query_id(memc_clone));
866
867 query_id= memcached_query_id(memc_clone);
868 test_compare(MEMCACHED_BAD_KEY_PROVIDED,
869 memcached_mget(memc_clone, keys, key_lengths, 3));
870 test_compare(query_id +1, memcached_query_id(memc_clone));
871
872 query_id= memcached_query_id(memc_clone);
873 test_compare(MEMCACHED_BAD_KEY_PROVIDED,
874 memcached_mget_by_key(memc_clone, "foo daddy", 9, keys, key_lengths, 1));
875 test_compare(query_id +1, memcached_query_id(memc_clone));
876
877 max_keylen= 250;
878
879 /* The following test should be moved to the end of this function when the
880 memcached server is updated to allow max size length of the keys in the
881 binary protocol
882 */
883 test_compare(MEMCACHED_SUCCESS,
884 memcached_callback_set(memc_clone, MEMCACHED_CALLBACK_NAMESPACE, NULL));
885
886 char *longkey= (char *)malloc(max_keylen + 1);
887 if (longkey)
888 {
889 memset(longkey, 'a', max_keylen + 1);
890 string= memcached_get(memc_clone, longkey, max_keylen,
891 &string_length, &flags, &rc);
892 test_compare(MEMCACHED_NOTFOUND, rc);
893 test_zero(string_length);
894 test_false(string);
895
896 string= memcached_get(memc_clone, longkey, max_keylen + 1,
897 &string_length, &flags, &rc);
898 test_compare(MEMCACHED_BAD_KEY_PROVIDED, rc);
899 test_zero(string_length);
900 test_false(string);
901
902 free(longkey);
903 }
904 }
905
906 /* Make sure zero length keys are marked as bad */
907 set= 1;
908 test_compare(MEMCACHED_SUCCESS,
909 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_VERIFY_KEY, set));
910 string= memcached_get(memc_clone, key, 0,
911 &string_length, &flags, &rc);
912 test_compare(MEMCACHED_BAD_KEY_PROVIDED, rc);
913 test_zero(string_length);
914 test_false(string);
915
916 memcached_free(memc_clone);
917
918 return TEST_SUCCESS;
919 }
920
921 #define READ_THROUGH_VALUE "set for me"
922 static memcached_return_t read_through_trigger(memcached_st *memc,
923 char *key,
924 size_t key_length,
925 memcached_result_st *result)
926 {
927 (void)memc;(void)key;(void)key_length;
928 return memcached_result_set_value(result, READ_THROUGH_VALUE, strlen(READ_THROUGH_VALUE));
929 }
930
931 #ifndef __INTEL_COMPILER
932 #pragma GCC diagnostic ignored "-Wstrict-aliasing"
933 #endif
934
935 static test_return_t read_through(memcached_st *memc)
936 {
937 memcached_return_t rc;
938 const char *key= "foo";
939 char *string;
940 size_t string_length;
941 uint32_t flags;
942 memcached_trigger_key_fn cb= (memcached_trigger_key_fn)read_through_trigger;
943
944 string= memcached_get(memc, key, strlen(key),
945 &string_length, &flags, &rc);
946
947 test_compare(MEMCACHED_NOTFOUND, rc);
948 test_false(string_length);
949 test_false(string);
950
951 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_GET_FAILURE, *(void **)&cb);
952 test_compare(MEMCACHED_SUCCESS, rc);
953
954 string= memcached_get(memc, key, strlen(key),
955 &string_length, &flags, &rc);
956
957 test_compare(MEMCACHED_SUCCESS, rc);
958 test_compare(string_length, sizeof(READ_THROUGH_VALUE) -1);
959 test_true(string[sizeof(READ_THROUGH_VALUE) -1] == 0);
960 test_strcmp(READ_THROUGH_VALUE, string);
961 free(string);
962
963 string= memcached_get(memc, key, strlen(key),
964 &string_length, &flags, &rc);
965
966 test_compare(MEMCACHED_SUCCESS, rc);
967 test_true(string);
968 test_compare(string_length, sizeof(READ_THROUGH_VALUE) -1);
969 test_true(string[sizeof(READ_THROUGH_VALUE) -1] == 0);
970 test_strcmp(READ_THROUGH_VALUE, string);
971 free(string);
972
973 return TEST_SUCCESS;
974 }
975
976 static memcached_return_t delete_trigger(memcached_st *,
977 const char *key,
978 size_t key_length)
979 {
980 assert(key);
981 assert(key_length);
982
983 return MEMCACHED_SUCCESS;
984 }
985
986 static test_return_t delete_through(memcached_st *memc)
987 {
988 memcached_trigger_delete_key_fn callback;
989 memcached_return_t rc;
990
991 callback= (memcached_trigger_delete_key_fn)delete_trigger;
992
993 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_DELETE_TRIGGER, *(void**)&callback);
994 test_compare(MEMCACHED_SUCCESS, rc);
995
996 return TEST_SUCCESS;
997 }
998
999 static test_return_t get_test(memcached_st *memc)
1000 {
1001 memcached_return_t rc;
1002 const char *key= "foo";
1003 char *string;
1004 size_t string_length;
1005 uint32_t flags;
1006
1007 uint64_t query_id= memcached_query_id(memc);
1008 rc= memcached_delete(memc, key, strlen(key), (time_t)0);
1009 test_true(rc == MEMCACHED_BUFFERED || rc == MEMCACHED_NOTFOUND);
1010 test_compare(query_id +1, memcached_query_id(memc));
1011
1012 string= memcached_get(memc, key, strlen(key),
1013 &string_length, &flags, &rc);
1014
1015 test_compare_got(MEMCACHED_NOTFOUND, rc, memcached_strerror(NULL, rc));
1016 test_false(string_length);
1017 test_false(string);
1018
1019 return TEST_SUCCESS;
1020 }
1021
1022 static test_return_t get_test2(memcached_st *memc)
1023 {
1024 const char *key= "foo";
1025 const char *value= "when we sanitize";
1026
1027 uint64_t query_id= memcached_query_id(memc);
1028 memcached_return_t rc= memcached_set(memc, key, strlen(key),
1029 value, strlen(value),
1030 (time_t)0, (uint32_t)0);
1031 test_true(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED);
1032 test_compare(query_id +1, memcached_query_id(memc));
1033
1034 query_id= memcached_query_id(memc);
1035 test_true(query_id);
1036
1037 uint32_t flags;
1038 size_t string_length;
1039 char *string= memcached_get(memc, key, strlen(key),
1040 &string_length, &flags, &rc);
1041 test_compare(query_id +1, memcached_query_id(memc));
1042
1043 test_compare_got(MEMCACHED_SUCCESS, rc, memcached_strerror(NULL, rc));
1044 test_compare_got(MEMCACHED_SUCCESS, memcached_last_error(memc), memcached_last_error_message(memc));
1045 test_true(string);
1046 test_compare(strlen(value), string_length);
1047 test_memcmp(string, value, string_length);
1048
1049 free(string);
1050
1051 return TEST_SUCCESS;
1052 }
1053
1054 static test_return_t set_test2(memcached_st *memc)
1055 {
1056 const char *key= "foo";
1057 const char *value= "train in the brain";
1058 size_t value_length= strlen(value);
1059
1060 for (uint32_t x= 0; x < 10; x++)
1061 {
1062 memcached_return_t rc= memcached_set(memc, key, strlen(key),
1063 value, value_length,
1064 (time_t)0, (uint32_t)0);
1065 test_true(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED);
1066 }
1067
1068 return TEST_SUCCESS;
1069 }
1070
1071 static test_return_t set_test3(memcached_st *memc)
1072 {
1073 size_t value_length= 8191;
1074
1075 char *value= (char*)malloc(value_length);
1076 test_true(value);
1077
1078 for (uint32_t x= 0; x < value_length; x++)
1079 {
1080 value[x] = (char) (x % 127);
1081 }
1082
1083 /* The dump test relies on there being at least 32 items in memcached */
1084 for (uint32_t x= 0; x < 32; x++)
1085 {
1086 char key[16];
1087
1088 snprintf(key, sizeof(key), "foo%u", x);
1089
1090 uint64_t query_id= memcached_query_id(memc);
1091 memcached_return_t rc= memcached_set(memc, key, strlen(key),
1092 value, value_length,
1093 (time_t)0, (uint32_t)0);
1094 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1095 test_compare(query_id +1, memcached_query_id(memc));
1096 }
1097
1098 free(value);
1099
1100 return TEST_SUCCESS;
1101 }
1102
1103 static test_return_t get_test3(memcached_st *memc)
1104 {
1105 const char *key= "foo";
1106 size_t value_length= 8191;
1107
1108 char *value= (char*)malloc(value_length);
1109 test_true(value);
1110
1111 for (uint32_t x= 0; x < value_length; x++)
1112 {
1113 value[x] = (char) (x % 127);
1114 }
1115
1116 memcached_return_t rc;
1117 rc= memcached_set(memc, key, strlen(key),
1118 value, value_length,
1119 (time_t)0, (uint32_t)0);
1120 test_true(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED);
1121
1122 size_t string_length;
1123 uint32_t flags;
1124 char *string= memcached_get(memc, key, strlen(key),
1125 &string_length, &flags, &rc);
1126
1127 test_compare(MEMCACHED_SUCCESS, rc);
1128 test_true(string);
1129 test_compare(string_length, value_length);
1130 test_memcmp(string, value, string_length);
1131
1132 free(string);
1133 free(value);
1134
1135 return TEST_SUCCESS;
1136 }
1137
1138 static test_return_t get_test4(memcached_st *memc)
1139 {
1140 const char *key= "foo";
1141 size_t value_length= 8191;
1142
1143 char *value= (char*)malloc(value_length);
1144 test_true(value);
1145
1146 for (uint32_t x= 0; x < value_length; x++)
1147 {
1148 value[x] = (char) (x % 127);
1149 }
1150
1151 memcached_return_t rc= memcached_set(memc, key, strlen(key),
1152 value, value_length,
1153 (time_t)0, (uint32_t)0);
1154 test_true(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED);
1155
1156 for (uint32_t x= 0; x < 10; x++)
1157 {
1158 uint32_t flags;
1159 size_t string_length;
1160 char *string= memcached_get(memc, key, strlen(key),
1161 &string_length, &flags, &rc);
1162
1163 test_compare(MEMCACHED_SUCCESS, rc);
1164 test_true(string);
1165 test_compare(string_length, value_length);
1166 test_memcmp(string, value, string_length);
1167 free(string);
1168 }
1169
1170 free(value);
1171
1172 return TEST_SUCCESS;
1173 }
1174
1175 /*
1176 * This test verifies that memcached_read_one_response doesn't try to
1177 * dereference a NIL-pointer if you issue a multi-get and don't read out all
1178 * responses before you execute a storage command.
1179 */
1180 static test_return_t get_test5(memcached_st *memc)
1181 {
1182 /*
1183 ** Request the same key twice, to ensure that we hash to the same server
1184 ** (so that we have multiple response values queued up) ;-)
1185 */
1186 const char *keys[]= { "key", "key" };
1187 size_t lengths[]= { 3, 3 };
1188 uint32_t flags;
1189 size_t rlen;
1190
1191 memcached_return_t rc= memcached_set(memc, keys[0], lengths[0],
1192 keys[0], lengths[0], 0, 0);
1193 test_compare(MEMCACHED_SUCCESS, memcached_mget(memc, keys, lengths, test_array_length(keys)));
1194
1195 memcached_result_st results_obj;
1196 memcached_result_st *results= memcached_result_create(memc, &results_obj);
1197 test_true(results);
1198
1199 results= memcached_fetch_result(memc, &results_obj, &rc);
1200 test_true(results);
1201
1202 memcached_result_free(&results_obj);
1203
1204 /* Don't read out the second result, but issue a set instead.. */
1205 test_compare(MEMCACHED_SUCCESS, memcached_set(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0));
1206
1207 char *val= memcached_get_by_key(memc, keys[0], lengths[0], "yek", 3,
1208 &rlen, &flags, &rc);
1209 test_false(val);
1210 test_compare(MEMCACHED_NOTFOUND, rc);
1211 val= memcached_get(memc, keys[0], lengths[0], &rlen, &flags, &rc);
1212 test_true(val);
1213 test_compare(MEMCACHED_SUCCESS, rc);
1214 free(val);
1215
1216 return TEST_SUCCESS;
1217 }
1218
1219 static test_return_t mget_end(memcached_st *memc)
1220 {
1221 const char *keys[]= { "foo", "foo2" };
1222 size_t lengths[]= { 3, 4 };
1223 const char *values[]= { "fjord", "41" };
1224
1225 memcached_return_t rc;
1226
1227 // Set foo and foo2
1228 for (size_t x= 0; x < test_array_length(keys); x++)
1229 {
1230 test_compare(MEMCACHED_SUCCESS, memcached_set(memc, keys[x], lengths[x], values[x], strlen(values[x]), (time_t)0, (uint32_t)0));
1231 }
1232
1233 char *string;
1234 size_t string_length;
1235 uint32_t flags;
1236
1237 // retrieve both via mget
1238 test_compare(MEMCACHED_SUCCESS, memcached_mget(memc, keys, lengths, test_array_length(keys)));
1239
1240 char key[MEMCACHED_MAX_KEY];
1241 size_t key_length;
1242
1243 // this should get both
1244 for (size_t x= 0; x < test_array_length(keys); x++)
1245 {
1246 string= memcached_fetch(memc, key, &key_length, &string_length,
1247 &flags, &rc);
1248 test_compare(MEMCACHED_SUCCESS, rc);
1249 int val = 0;
1250 if (key_length == 4)
1251 {
1252 val= 1;
1253 }
1254
1255 test_compare(string_length, strlen(values[val]));
1256 test_true(strncmp(values[val], string, string_length) == 0);
1257 free(string);
1258 }
1259
1260 // this should indicate end
1261 string= memcached_fetch(memc, key, &key_length, &string_length, &flags, &rc);
1262 test_compare(MEMCACHED_END, rc);
1263
1264 // now get just one
1265 rc= memcached_mget(memc, keys, lengths, 1);
1266 test_compare(MEMCACHED_SUCCESS, rc);
1267
1268 string= memcached_fetch(memc, key, &key_length, &string_length, &flags, &rc);
1269 test_compare(key_length, lengths[0]);
1270 test_true(strncmp(keys[0], key, key_length) == 0);
1271 test_compare(string_length, strlen(values[0]));
1272 test_true(strncmp(values[0], string, string_length) == 0);
1273 test_compare(MEMCACHED_SUCCESS, rc);
1274 free(string);
1275
1276 // this should indicate end
1277 string= memcached_fetch(memc, key, &key_length, &string_length, &flags, &rc);
1278 test_true(rc == MEMCACHED_END);
1279
1280 return TEST_SUCCESS;
1281 }
1282
1283 /* Do not copy the style of this code, I just access hosts to testthis function */
1284 static test_return_t stats_servername_test(memcached_st *memc)
1285 {
1286 memcached_return_t rc;
1287 memcached_stat_st memc_stat;
1288 memcached_server_instance_st instance=
1289 memcached_server_instance_by_position(memc, 0);
1290
1291 #ifdef LIBMEMCACHED_WITH_SASL_SUPPORT
1292 if (memcached_get_sasl_callbacks(memc) != NULL)
1293 return TEST_SKIPPED;
1294 #endif
1295 rc= memcached_stat_servername(&memc_stat, NULL,
1296 memcached_server_name(instance),
1297 memcached_server_port(instance));
1298
1299 return TEST_SUCCESS;
1300 }
1301
1302 static test_return_t increment_test(memcached_st *memc)
1303 {
1304 uint64_t new_number;
1305
1306 test_compare(MEMCACHED_SUCCESS,
1307 memcached_set(memc,
1308 test_literal_param("number"),
1309 test_literal_param("0"),
1310 (time_t)0, (uint32_t)0));
1311
1312 test_compare(MEMCACHED_SUCCESS,
1313 memcached_increment(memc, test_literal_param("number"), 1, &new_number));
1314 test_compare(uint64_t(1), new_number);
1315
1316 test_compare(MEMCACHED_SUCCESS,
1317 memcached_increment(memc, test_literal_param("number"), 1, &new_number));
1318 test_compare(uint64_t(2), new_number);
1319
1320 return TEST_SUCCESS;
1321 }
1322
1323 static test_return_t increment_with_initial_test(memcached_st *memc)
1324 {
1325 test_skip(true, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL));
1326
1327 uint64_t new_number;
1328 uint64_t initial= 0;
1329
1330 test_compare(MEMCACHED_SUCCESS, memcached_flush_buffers(memc));
1331
1332 test_compare(MEMCACHED_SUCCESS,
1333 memcached_increment_with_initial(memc, test_literal_param("number"), 1, initial, 0, &new_number));
1334 test_compare(new_number, initial);
1335
1336 test_compare(MEMCACHED_SUCCESS,
1337 memcached_increment_with_initial(memc, test_literal_param("number"), 1, initial, 0, &new_number));
1338 test_compare(new_number, (initial +1));
1339
1340 return TEST_SUCCESS;
1341 }
1342
1343 static test_return_t decrement_test(memcached_st *memc)
1344 {
1345 uint64_t new_number;
1346 memcached_return_t rc;
1347 const char *value= "3";
1348
1349 rc= memcached_set(memc,
1350 test_literal_param("number"),
1351 value, strlen(value),
1352 (time_t)0, (uint32_t)0);
1353 test_true(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED);
1354
1355 test_compare(MEMCACHED_SUCCESS,
1356 memcached_decrement(memc,
1357 test_literal_param("number"),
1358 1, &new_number));
1359 test_compare(uint64_t(2), new_number);
1360
1361 test_compare(MEMCACHED_SUCCESS,
1362 memcached_decrement(memc,
1363 test_literal_param("number"),
1364 1, &new_number));
1365 test_compare(uint64_t(1), new_number);
1366
1367 return TEST_SUCCESS;
1368 }
1369
1370 static test_return_t decrement_with_initial_test(memcached_st *memc)
1371 {
1372 test_skip(true, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL));
1373
1374 uint64_t new_number;
1375 uint64_t initial= 3;
1376
1377 test_compare(MEMCACHED_SUCCESS, memcached_flush_buffers(memc));
1378
1379 test_compare(MEMCACHED_SUCCESS,
1380 memcached_decrement_with_initial(memc,
1381 test_literal_param("number"),
1382 1, initial, 0, &new_number));
1383 test_compare(new_number, initial);
1384
1385 test_compare(MEMCACHED_SUCCESS,
1386 memcached_decrement_with_initial(memc,
1387 test_literal_param("number"),
1388 1, initial, 0, &new_number));
1389 test_compare(new_number, (initial - 1));
1390
1391 return TEST_SUCCESS;
1392 }
1393
1394 static test_return_t increment_by_key_test(memcached_st *memc)
1395 {
1396 uint64_t new_number;
1397 memcached_return_t rc;
1398 const char *master_key= "foo";
1399 const char *key= "number";
1400 const char *value= "0";
1401
1402 rc= memcached_set_by_key(memc, master_key, strlen(master_key),
1403 key, strlen(key),
1404 value, strlen(value),
1405 (time_t)0, (uint32_t)0);
1406 test_true(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED);
1407
1408 test_compare(MEMCACHED_SUCCESS,
1409 memcached_increment_by_key(memc, master_key, strlen(master_key), key, strlen(key), 1, &new_number));
1410 test_compare(uint64_t(1), new_number);
1411
1412 test_compare(MEMCACHED_SUCCESS,
1413 memcached_increment_by_key(memc, master_key, strlen(master_key), key, strlen(key), 1, &new_number));
1414 test_compare(uint64_t(2), new_number);
1415
1416 return TEST_SUCCESS;
1417 }
1418
1419 static test_return_t increment_with_initial_by_key_test(memcached_st *memc)
1420 {
1421 test_skip(true, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL));
1422
1423 uint64_t new_number;
1424 memcached_return_t rc;
1425 const char *master_key= "foo";
1426 const char *key= "number";
1427 uint64_t initial= 0;
1428
1429 rc= memcached_increment_with_initial_by_key(memc, master_key, strlen(master_key),
1430 key, strlen(key),
1431 1, initial, 0, &new_number);
1432 test_compare(MEMCACHED_SUCCESS, rc);
1433 test_compare(new_number, initial);
1434
1435 rc= memcached_increment_with_initial_by_key(memc, master_key, strlen(master_key),
1436 key, strlen(key),
1437 1, initial, 0, &new_number);
1438 test_compare(MEMCACHED_SUCCESS, rc);
1439 test_compare(new_number, (initial +1));
1440
1441 return TEST_SUCCESS;
1442 }
1443
1444 static test_return_t decrement_by_key_test(memcached_st *memc)
1445 {
1446 uint64_t new_number;
1447 memcached_return_t rc;
1448 const char *value= "3";
1449
1450 rc= memcached_set_by_key(memc,
1451 test_literal_param("foo"),
1452 test_literal_param("number"),
1453 value, strlen(value),
1454 (time_t)0, (uint32_t)0);
1455 test_true(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED);
1456
1457 test_compare(MEMCACHED_SUCCESS,
1458 memcached_decrement_by_key(memc,
1459 test_literal_param("foo"),
1460 test_literal_param("number"),
1461 1, &new_number));
1462 test_compare(uint64_t(2), new_number);
1463
1464 test_compare(MEMCACHED_SUCCESS,
1465 memcached_decrement_by_key(memc,
1466 test_literal_param("foo"),
1467 test_literal_param("number"),
1468 1, &new_number));
1469 test_compare(uint64_t(1), new_number);
1470
1471 return TEST_SUCCESS;
1472 }
1473
1474 static test_return_t decrement_with_initial_by_key_test(memcached_st *memc)
1475 {
1476 test_skip(true, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL));
1477
1478 uint64_t new_number;
1479 uint64_t initial= 3;
1480
1481 test_compare(MEMCACHED_SUCCESS,
1482 memcached_decrement_with_initial_by_key(memc,
1483 test_literal_param("foo"),
1484 test_literal_param("number"),
1485 1, initial, 0, &new_number));
1486 test_compare(new_number, initial);
1487
1488 test_compare(MEMCACHED_SUCCESS,
1489 memcached_decrement_with_initial_by_key(memc,
1490 test_literal_param("foo"),
1491 test_literal_param("number"),
1492 1, initial, 0, &new_number));
1493 test_compare(new_number, (initial - 1));
1494
1495 return TEST_SUCCESS;
1496 }
1497
1498 static test_return_t quit_test(memcached_st *memc)
1499 {
1500 memcached_return_t rc;
1501 const char *key= "fudge";
1502 const char *value= "sanford and sun";
1503
1504 rc= memcached_set(memc, key, strlen(key),
1505 value, strlen(value),
1506 (time_t)10, (uint32_t)3);
1507 test_true(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED);
1508 memcached_quit(memc);
1509
1510 rc= memcached_set(memc, key, strlen(key),
1511 value, strlen(value),
1512 (time_t)50, (uint32_t)9);
1513 test_true(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED);
1514
1515 return TEST_SUCCESS;
1516 }
1517
1518 static test_return_t mget_result_test(memcached_st *memc)
1519 {
1520 const char *keys[]= {"fudge", "son", "food"};
1521 size_t key_length[]= {5, 3, 4};
1522
1523 memcached_result_st results_obj;
1524 memcached_result_st *results;
1525
1526 results= memcached_result_create(memc, &results_obj);
1527 test_true(results);
1528 test_true(&results_obj == results);
1529
1530 /* We need to empty the server before continueing test */
1531 test_compare(MEMCACHED_SUCCESS,
1532 memcached_flush(memc, 0));
1533
1534 test_compare(MEMCACHED_SUCCESS,
1535 memcached_mget(memc, keys, key_length, 3));
1536
1537 memcached_return_t rc;
1538 while ((results= memcached_fetch_result(memc, &results_obj, &rc)))
1539 {
1540 test_true(results);
1541 }
1542
1543 while ((results= memcached_fetch_result(memc, &results_obj, &rc))) { test_true(false); /* We should never see a value returned */ };
1544 test_false(results);
1545 test_compare_got(MEMCACHED_NOTFOUND, rc, memcached_strerror(NULL, rc));
1546
1547 for (uint32_t x= 0; x < 3; x++)
1548 {
1549 rc= memcached_set(memc, keys[x], key_length[x],
1550 keys[x], key_length[x],
1551 (time_t)50, (uint32_t)9);
1552 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1553 }
1554
1555 test_compare(MEMCACHED_SUCCESS,
1556 memcached_mget(memc, keys, key_length, 3));
1557
1558 while ((results= memcached_fetch_result(memc, &results_obj, &rc)))
1559 {
1560 test_true(results);
1561 test_true(&results_obj == results);
1562 test_compare(MEMCACHED_SUCCESS, rc);
1563 test_memcmp(memcached_result_key_value(results),
1564 memcached_result_value(results),
1565 memcached_result_length(results));
1566 test_compare(memcached_result_key_length(results), memcached_result_length(results));
1567 }
1568
1569 memcached_result_free(&results_obj);
1570
1571 return TEST_SUCCESS;
1572 }
1573
1574 static test_return_t mget_result_alloc_test(memcached_st *memc)
1575 {
1576 const char *keys[]= {"fudge", "son", "food"};
1577 size_t key_length[]= {5, 3, 4};
1578
1579 memcached_result_st *results;
1580
1581 /* We need to empty the server before continueing test */
1582 test_compare(MEMCACHED_SUCCESS,
1583 memcached_flush(memc, 0));
1584
1585 test_compare(MEMCACHED_SUCCESS,
1586 memcached_mget(memc, keys, key_length, 3));
1587
1588 memcached_return_t rc;
1589 while ((results= memcached_fetch_result(memc, NULL, &rc)))
1590 {
1591 test_true(results);
1592 }
1593 test_false(results);
1594 test_compare_got(MEMCACHED_NOTFOUND, rc, memcached_strerror(NULL, rc));
1595
1596 for (uint32_t x= 0; x < 3; x++)
1597 {
1598 rc= memcached_set(memc, keys[x], key_length[x],
1599 keys[x], key_length[x],
1600 (time_t)50, (uint32_t)9);
1601 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1602 }
1603
1604 test_compare(MEMCACHED_SUCCESS,
1605 memcached_mget(memc, keys, key_length, 3));
1606
1607 uint32_t x= 0;
1608 while ((results= memcached_fetch_result(memc, NULL, &rc)))
1609 {
1610 test_true(results);
1611 test_compare(MEMCACHED_SUCCESS, rc);
1612 test_compare(memcached_result_key_length(results), memcached_result_length(results));
1613 test_memcmp(memcached_result_key_value(results),
1614 memcached_result_value(results),
1615 memcached_result_length(results));
1616 memcached_result_free(results);
1617 x++;
1618 }
1619
1620 return TEST_SUCCESS;
1621 }
1622
1623 /* Count the results */
1624 static memcached_return_t callback_counter(const memcached_st*, memcached_result_st*, void *context)
1625 {
1626 size_t *counter= (size_t *)context;
1627
1628 *counter= *counter + 1;
1629
1630 return MEMCACHED_SUCCESS;
1631 }
1632
1633 static test_return_t mget_result_function(memcached_st *memc)
1634 {
1635 const char *keys[]= {"fudge", "son", "food"};
1636 size_t key_length[]= {5, 3, 4};
1637 size_t counter;
1638 memcached_execute_fn callbacks[1];
1639
1640 /* We need to empty the server before continueing test */
1641 test_compare(MEMCACHED_SUCCESS,
1642 memcached_flush(memc, 0));
1643 for (uint32_t x= 0; x < 3; x++)
1644 {
1645 memcached_return_t rc= memcached_set(memc, keys[x], key_length[x],
1646 keys[x], key_length[x],
1647 (time_t)50, (uint32_t)9);
1648 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1649 }
1650
1651 test_compare(MEMCACHED_SUCCESS,
1652 memcached_mget(memc, keys, key_length, 3));
1653
1654 callbacks[0]= &callback_counter;
1655 counter= 0;
1656
1657 test_compare(MEMCACHED_SUCCESS,
1658 memcached_fetch_execute(memc, callbacks, (void *)&counter, 1));
1659
1660 test_compare(size_t(3), counter);
1661
1662 return TEST_SUCCESS;
1663 }
1664
1665 static test_return_t mget_test(memcached_st *memc)
1666 {
1667 const char *keys[]= {"fudge", "son", "food"};
1668 size_t key_length[]= {5, 3, 4};
1669
1670 char return_key[MEMCACHED_MAX_KEY];
1671 size_t return_key_length;
1672 char *return_value;
1673 size_t return_value_length;
1674
1675 /* We need to empty the server before continueing test */
1676 test_compare(MEMCACHED_SUCCESS,
1677 memcached_flush(memc, 0));
1678
1679 test_compare(MEMCACHED_SUCCESS,
1680 memcached_mget(memc, keys, key_length, 3));
1681
1682 uint32_t flags;
1683 memcached_return_t rc;
1684 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
1685 &return_value_length, &flags, &rc)))
1686 {
1687 test_true(return_value);
1688 }
1689 test_false(return_value);
1690 test_zero(return_value_length);
1691 test_compare(MEMCACHED_NOTFOUND, rc);
1692
1693 for (uint32_t x= 0; x < 3; x++)
1694 {
1695 rc= memcached_set(memc, keys[x], key_length[x],
1696 keys[x], key_length[x],
1697 (time_t)50, (uint32_t)9);
1698 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1699 }
1700 test_compare(MEMCACHED_SUCCESS,
1701 memcached_mget(memc, keys, key_length, 3));
1702
1703 uint32_t x= 0;
1704 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
1705 &return_value_length, &flags, &rc)))
1706 {
1707 test_true(return_value);
1708 test_compare(MEMCACHED_SUCCESS, rc);
1709 if (not memc->_namespace)
1710 {
1711 test_compare(return_key_length, return_value_length);
1712 test_memcmp(return_value, return_key, return_value_length);
1713 }
1714 free(return_value);
1715 x++;
1716 }
1717
1718 return TEST_SUCCESS;
1719 }
1720
1721 static test_return_t mget_execute(memcached_st *memc)
1722 {
1723 bool binary= false;
1724
1725 if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) != 0)
1726 binary= true;
1727
1728 /*
1729 * I only want to hit _one_ server so I know the number of requests I'm
1730 * sending in the pipeline.
1731 */
1732 uint32_t number_of_hosts= memc->number_of_hosts;
1733 memc->number_of_hosts= 1;
1734
1735 size_t max_keys= 20480;
1736
1737
1738 char **keys= static_cast<char **>(calloc(max_keys, sizeof(char*)));
1739 size_t *key_length=static_cast<size_t *>(calloc(max_keys, sizeof(size_t)));
1740
1741 /* First add all of the items.. */
1742 char blob[1024] = {0};
1743 memcached_return_t rc;
1744
1745 for (size_t x= 0; x < max_keys; ++x)
1746 {
1747 char k[251];
1748
1749 key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%lu", (unsigned long)x);
1750 keys[x]= strdup(k);
1751 test_true(keys[x] != NULL);
1752 uint64_t query_id= memcached_query_id(memc);
1753 rc= memcached_add(memc, keys[x], key_length[x], blob, sizeof(blob), 0, 0);
1754 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1755 test_compare(query_id +1, memcached_query_id(memc));
1756 }
1757
1758 /* Try to get all of them with a large multiget */
1759 size_t counter= 0;
1760 memcached_execute_fn callbacks[]= { &callback_counter };
1761 rc= memcached_mget_execute(memc, (const char**)keys, key_length,
1762 max_keys, callbacks, &counter, 1);
1763
1764 if (memcached_success(rc))
1765 {
1766 test_true(binary);
1767 uint64_t query_id= memcached_query_id(memc);
1768 test_compare(MEMCACHED_SUCCESS,
1769 memcached_fetch_execute(memc, callbacks, (void *)&counter, 1));
1770 test_compare(query_id, memcached_query_id(memc));
1771
1772 /* Verify that we got all of the items */
1773 test_true(counter == max_keys);
1774 }
1775 else if (rc == MEMCACHED_NOT_SUPPORTED)
1776 {
1777 test_true(counter == 0);
1778 }
1779 else
1780 {
1781 test_fail("note: this test functions differently when in binary mode");
1782 }
1783
1784 /* Release all allocated resources */
1785 for (size_t x= 0; x < max_keys; ++x)
1786 {
1787 free(keys[x]);
1788 }
1789 free(keys);
1790 free(key_length);
1791
1792 memc->number_of_hosts= number_of_hosts;
1793 return TEST_SUCCESS;
1794 }
1795
1796 #define REGRESSION_BINARY_VS_BLOCK_COUNT 20480
1797
1798 static test_return_t key_setup(memcached_st *memc)
1799 {
1800 test_skip(TEST_SUCCESS, pre_binary(memc));
1801
1802 global_pairs= pairs_generate(REGRESSION_BINARY_VS_BLOCK_COUNT, 0);
1803
1804 return TEST_SUCCESS;
1805 }
1806
1807 static test_return_t key_teardown(memcached_st *memc)
1808 {
1809 (void)memc;
1810 pairs_free(global_pairs);
1811
1812 return TEST_SUCCESS;
1813 }
1814
1815 static test_return_t block_add_regression(memcached_st *memc)
1816 {
1817 /* First add all of the items.. */
1818 for (size_t x= 0; x < REGRESSION_BINARY_VS_BLOCK_COUNT; ++x)
1819 {
1820 memcached_return_t rc;
1821 char blob[1024] = {0};
1822
1823 rc= memcached_add_by_key(memc, "bob", 3, global_pairs[x].key, global_pairs[x].key_length, blob, sizeof(blob), 0, 0);
1824 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1825 }
1826
1827 return TEST_SUCCESS;
1828 }
1829
1830 static test_return_t binary_add_regression(memcached_st *memc)
1831 {
1832 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
1833 test_return_t rc= block_add_regression(memc);
1834 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 0);
1835 return rc;
1836 }
1837
1838 static test_return_t get_stats_keys(memcached_st *memc)
1839 {
1840 char **stat_list;
1841 char **ptr;
1842 memcached_stat_st memc_stat;
1843 memcached_return_t rc;
1844
1845 stat_list= memcached_stat_get_keys(memc, &memc_stat, &rc);
1846 test_compare(MEMCACHED_SUCCESS, rc);
1847 for (ptr= stat_list; *ptr; ptr++)
1848 test_true(*ptr);
1849
1850 free(stat_list);
1851
1852 return TEST_SUCCESS;
1853 }
1854
1855 static test_return_t version_string_test(memcached_st *memc)
1856 {
1857 const char *version_string;
1858 (void)memc;
1859
1860 version_string= memcached_lib_version();
1861
1862 test_strcmp(version_string, LIBMEMCACHED_VERSION_STRING);
1863
1864 return TEST_SUCCESS;
1865 }
1866
1867 static test_return_t get_stats(memcached_st *memc)
1868 {
1869 memcached_return_t rc;
1870
1871 memcached_stat_st *memc_stat= memcached_stat(memc, NULL, &rc);
1872 test_compare(MEMCACHED_SUCCESS, rc);
1873 test_true(memc_stat);
1874
1875 for (uint32_t x= 0; x < memcached_server_count(memc); x++)
1876 {
1877 char **stat_list= memcached_stat_get_keys(memc, memc_stat+x, &rc);
1878 test_compare(MEMCACHED_SUCCESS, rc);
1879 for (char **ptr= stat_list; *ptr; ptr++) {};
1880
1881 free(stat_list);
1882 }
1883
1884 memcached_stat_free(NULL, memc_stat);
1885
1886 return TEST_SUCCESS;
1887 }
1888
1889 static test_return_t add_host_test(memcached_st *memc)
1890 {
1891 unsigned int x;
1892 memcached_server_st *servers;
1893 memcached_return_t rc;
1894 char servername[]= "0.example.com";
1895
1896 servers= memcached_server_list_append_with_weight(NULL, servername, 400, 0, &rc);
1897 test_true(servers);
1898 test_true(1 == memcached_server_list_count(servers));
1899
1900 for (x= 2; x < 20; x++)
1901 {
1902 char buffer[SMALL_STRING_LEN];
1903
1904 snprintf(buffer, SMALL_STRING_LEN, "%u.example.com", 400+x);
1905 servers= memcached_server_list_append_with_weight(servers, buffer, 401, 0,
1906 &rc);
1907 test_compare(MEMCACHED_SUCCESS, rc);
1908 test_true(x == memcached_server_list_count(servers));
1909 }
1910
1911 rc= memcached_server_push(memc, servers);
1912 test_compare(MEMCACHED_SUCCESS, rc);
1913 rc= memcached_server_push(memc, servers);
1914 test_compare(MEMCACHED_SUCCESS, rc);
1915
1916 memcached_server_list_free(servers);
1917
1918 return TEST_SUCCESS;
1919 }
1920
1921 static test_return_t memcached_fetch_result_NOT_FOUND(memcached_st *memc)
1922 {
1923 memcached_return_t rc;
1924 const char *key= "not_found";
1925 size_t key_len= strlen(key);
1926
1927 test_compare(MEMCACHED_SUCCESS,
1928 memcached_mget(memc, &key, &key_len, 1));
1929
1930 memcached_result_st *result= NULL;
1931 result= memcached_fetch_result(memc, result, &rc);
1932 test_false(result);
1933 test_compare_got(MEMCACHED_NOTFOUND, rc, memcached_strerror(NULL, rc));
1934
1935 memcached_result_free(result);
1936
1937 return TEST_SUCCESS;
1938 }
1939
1940 static memcached_return_t clone_test_callback(memcached_st *parent, memcached_st *memc_clone)
1941 {
1942 (void)parent;(void)memc_clone;
1943 return MEMCACHED_SUCCESS;
1944 }
1945
1946 static memcached_return_t cleanup_test_callback(memcached_st *ptr)
1947 {
1948 (void)ptr;
1949 return MEMCACHED_SUCCESS;
1950 }
1951
1952 static test_return_t callback_test(memcached_st *memc)
1953 {
1954 /* Test User Data */
1955 {
1956 int x= 5;
1957 int *test_ptr;
1958 memcached_return_t rc;
1959
1960 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_USER_DATA, &x);
1961 test_compare(MEMCACHED_SUCCESS, rc);
1962 test_ptr= (int *)memcached_callback_get(memc, MEMCACHED_CALLBACK_USER_DATA, &rc);
1963 test_true(*test_ptr == x);
1964 }
1965
1966 /* Test Clone Callback */
1967 {
1968 memcached_clone_fn clone_cb= (memcached_clone_fn)clone_test_callback;
1969 void *clone_cb_ptr= *(void **)&clone_cb;
1970 void *temp_function= NULL;
1971 memcached_return_t rc;
1972
1973 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION,
1974 clone_cb_ptr);
1975 test_compare(MEMCACHED_SUCCESS, rc);
1976 temp_function= memcached_callback_get(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION, &rc);
1977 test_true(temp_function == clone_cb_ptr);
1978 }
1979
1980 /* Test Cleanup Callback */
1981 {
1982 memcached_cleanup_fn cleanup_cb=
1983 (memcached_cleanup_fn)cleanup_test_callback;
1984 void *cleanup_cb_ptr= *(void **)&cleanup_cb;
1985 void *temp_function= NULL;
1986 memcached_return_t rc;
1987
1988 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION,
1989 cleanup_cb_ptr);
1990 test_compare(MEMCACHED_SUCCESS, rc);
1991 temp_function= memcached_callback_get(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION, &rc);
1992 test_true(temp_function == cleanup_cb_ptr);
1993 }
1994
1995 return TEST_SUCCESS;
1996 }
1997
1998 /* We don't test the behavior itself, we test the switches */
1999 static test_return_t behavior_test(memcached_st *memc)
2000 {
2001 uint64_t value;
2002 uint32_t set= 1;
2003
2004 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, set);
2005 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NO_BLOCK);
2006 test_true(value == 1);
2007
2008 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, set);
2009 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY);
2010 test_true(value == 1);
2011
2012 set= MEMCACHED_HASH_MD5;
2013 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, set);
2014 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
2015 test_true(value == MEMCACHED_HASH_MD5);
2016
2017 set= 0;
2018
2019 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, set);
2020 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NO_BLOCK);
2021 test_true(value == 0);
2022
2023 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, set);
2024 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY);
2025 test_true(value == 0);
2026
2027 set= MEMCACHED_HASH_DEFAULT;
2028 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, set);
2029 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
2030 test_true(value == MEMCACHED_HASH_DEFAULT);
2031
2032 set= MEMCACHED_HASH_CRC;
2033 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, set);
2034 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
2035 test_true(value == MEMCACHED_HASH_CRC);
2036
2037 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE);
2038 test_true(value > 0);
2039
2040 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE);
2041 test_true(value > 0);
2042
2043 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS);
2044 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, value + 1);
2045 test_true((value + 1) == memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS));
2046
2047 return TEST_SUCCESS;
2048 }
2049
2050 static test_return_t MEMCACHED_BEHAVIOR_CORK_test(memcached_st *memc)
2051 {
2052 memcached_return_t rc;
2053 bool set= true;
2054
2055 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_CORK, set);
2056 test_true(rc == MEMCACHED_DEPRECATED);
2057
2058 // Platform dependent
2059 #if 0
2060 bool value= (bool)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_CORK);
2061 test_false(value);
2062 #endif
2063
2064 return TEST_SUCCESS;
2065 }
2066
2067
2068 static test_return_t MEMCACHED_BEHAVIOR_TCP_KEEPALIVE_test(memcached_st *memc)
2069 {
2070 memcached_return_t rc;
2071 bool set= true;
2072 bool value;
2073
2074 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_KEEPALIVE, set);
2075 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_NOT_SUPPORTED);
2076
2077 value= (bool)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_TCP_KEEPALIVE);
2078
2079 if (rc == MEMCACHED_SUCCESS)
2080 {
2081 test_true((bool)value == set);
2082 }
2083 else
2084 {
2085 test_false((bool)value == set);
2086 }
2087
2088 return TEST_SUCCESS;
2089 }
2090
2091
2092 static test_return_t MEMCACHED_BEHAVIOR_TCP_KEEPIDLE_test(memcached_st *memc)
2093 {
2094 memcached_return_t rc;
2095 bool set= true;
2096 bool value;
2097
2098 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_KEEPIDLE, set);
2099 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_NOT_SUPPORTED);
2100
2101 value= (bool)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_TCP_KEEPIDLE);
2102
2103 if (rc == MEMCACHED_SUCCESS)
2104 {
2105 test_true((bool)value == set);
2106 }
2107 else
2108 {
2109 test_false((bool)value == set);
2110 }
2111
2112 return TEST_SUCCESS;
2113 }
2114
2115 static test_return_t fetch_all_results(memcached_st *memc, unsigned int &keys_returned, const memcached_return_t expect)
2116 {
2117 memcached_return_t rc;
2118 char return_key[MEMCACHED_MAX_KEY];
2119 size_t return_key_length;
2120 char *return_value;
2121 size_t return_value_length;
2122 uint32_t flags;
2123
2124 keys_returned= 0;
2125 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
2126 &return_value_length, &flags, &rc)))
2127 {
2128 test_true(return_value);
2129 test_compare_got(MEMCACHED_SUCCESS, rc, memcached_strerror(NULL, rc));
2130 free(return_value);
2131 keys_returned+= 1;
2132 }
2133
2134 if (memcached_success(expect) and memcached_success(rc))
2135 {
2136 return TEST_SUCCESS;
2137 }
2138 else if (expect == rc)
2139 {
2140 return TEST_SUCCESS;
2141 }
2142 fprintf(stderr, "\n%s:%u %s(#%u)\n", __FILE__, __LINE__, memcached_strerror(NULL, rc), keys_returned);
2143
2144 return TEST_FAILURE;
2145 }
2146
2147 /* Test case provided by Cal Haldenbrand */
2148 #define HALDENBRAND_KEY_COUNT 3000U // * 1024576
2149 #define HALDENBRAND_FLAG_KEY 99 // * 1024576
2150 static test_return_t user_supplied_bug1(memcached_st *memc)
2151 {
2152 /* We just keep looking at the same values over and over */
2153 srandom(10);
2154
2155 unsigned int setter= 1;
2156 test_compare(MEMCACHED_SUCCESS,
2157 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, setter));
2158 test_compare(MEMCACHED_SUCCESS,
2159 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, setter));
2160
2161
2162 /* add key */
2163 unsigned long long total= 0;
2164 for (uint32_t x= 0 ; total < 20 * 1024576 ; x++ )
2165 {
2166 uint32_t size= (uint32_t)(rand() % ( 5 * 1024 ) ) + 400;
2167 char randomstuff[6 * 1024];
2168 memset(randomstuff, 0, 6 * 1024);
2169 test_true(size < 6 * 1024); /* Being safe here */
2170
2171 for (uint32_t j= 0 ; j < size ;j++)
2172 {
2173 randomstuff[j] = (signed char) ((rand() % 26) + 97);
2174 }
2175
2176 total+= size;
2177 char key[22];
2178 int key_length= snprintf(key, sizeof(key), "%u", x);
2179 test_compare(MEMCACHED_SUCCESS,
2180 memcached_set(memc, key, key_length, randomstuff, strlen(randomstuff), time_t(0), HALDENBRAND_FLAG_KEY));
2181 }
2182 test_true(total > HALDENBRAND_KEY_COUNT);
2183
2184 return TEST_SUCCESS;
2185 }
2186
2187 /* Test case provided by Cal Haldenbrand */
2188 static test_return_t user_supplied_bug2(memcached_st *memc)
2189 {
2190 unsigned int setter= 1;
2191
2192 test_compare(MEMCACHED_SUCCESS,
2193 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, setter));
2194
2195 test_compare(MEMCACHED_SUCCESS,
2196 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, setter));
2197
2198 #ifdef NOT_YET
2199 setter = 20 * 1024576;
2200 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE, setter);
2201 setter = 20 * 1024576;
2202 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE, setter);
2203 getter = memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE);
2204 getter = memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE);
2205
2206 for (x= 0, errors= 0; total < 20 * 1024576 ; x++)
2207 #endif
2208
2209 size_t total_value_length= 0;
2210 for (uint32_t x= 0, errors= 0; total_value_length < 24576 ; x++)
2211 {
2212 uint32_t flags= 0;
2213 size_t val_len= 0;
2214
2215 char key[MEMCACHED_MAXIMUM_INTEGER_DISPLAY_LENGTH +1];
2216 int key_length= snprintf(key, sizeof(key), "%u", x);
2217
2218 memcached_return_t rc;
2219 char *getval= memcached_get(memc, key, key_length, &val_len, &flags, &rc);
2220 if (memcached_failed(rc))
2221 {
2222 if (rc == MEMCACHED_NOTFOUND)
2223 {
2224 errors++;
2225 }
2226 else
2227 {
2228 test_true(rc);
2229 }
2230
2231 continue;
2232 }
2233 test_compare(uint32_t(HALDENBRAND_FLAG_KEY), flags);
2234
2235 total_value_length+= val_len;
2236 errors= 0;
2237 free(getval);
2238 }
2239
2240 return TEST_SUCCESS;
2241 }
2242
2243 /* Do a large mget() over all the keys we think exist */
2244 static test_return_t user_supplied_bug3(memcached_st *memc)
2245 {
2246 unsigned int setter= 1;
2247 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, setter);
2248 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, setter);
2249 #ifdef NOT_YET
2250 setter = 20 * 1024576;
2251 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE, setter);
2252 setter = 20 * 1024576;
2253 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE, setter);
2254 getter = memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE);
2255 getter = memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE);
2256 #endif
2257
2258 size_t key_lengths[HALDENBRAND_KEY_COUNT];
2259 char **keys= static_cast<char **>(calloc(HALDENBRAND_KEY_COUNT, sizeof(char *)));
2260 test_true(keys);
2261 for (uint32_t x= 0; x < HALDENBRAND_KEY_COUNT; x++)
2262 {
2263 char key[MEMCACHED_MAXIMUM_INTEGER_DISPLAY_LENGTH +1];
2264 int key_length= snprintf(key, sizeof(key), "%u", x);
2265 keys[x]= strdup(key);
2266 test_true(keys[x]);
2267 key_lengths[x]= key_length;
2268 test_compare(size_t(key_length), strlen(keys[x]));
2269 }
2270
2271 test_compare(MEMCACHED_SUCCESS,
2272 memcached_mget(memc, (const char **)keys, key_lengths, HALDENBRAND_KEY_COUNT));
2273
2274 unsigned int keys_returned;
2275 test_compare(TEST_SUCCESS, fetch_all_results(memc, keys_returned, MEMCACHED_SUCCESS));
2276 test_compare(HALDENBRAND_KEY_COUNT, keys_returned);
2277
2278 for (uint32_t x= 0; x < HALDENBRAND_KEY_COUNT; x++)
2279 {
2280 free(keys[x]);
2281 }
2282 free(keys);
2283
2284 return TEST_SUCCESS;
2285 }
2286
2287 /* Make sure we behave properly if server list has no values */
2288 static test_return_t user_supplied_bug4(memcached_st *memc)
2289 {
2290 const char *keys[]= {"fudge", "son", "food"};
2291 size_t key_length[]= {5, 3, 4};
2292
2293 /* Here we free everything before running a bunch of mget tests */
2294 memcached_servers_reset(memc);
2295
2296
2297 /* We need to empty the server before continueing test */
2298 test_compare(MEMCACHED_NO_SERVERS,
2299 memcached_flush(memc, 0));
2300
2301 test_compare(MEMCACHED_NO_SERVERS,
2302 memcached_mget(memc, keys, key_length, 3));
2303
2304 unsigned int keys_returned;
2305 test_compare(TEST_SUCCESS, fetch_all_results(memc, keys_returned, MEMCACHED_NOTFOUND));
2306 test_zero(keys_returned);
2307
2308 for (uint32_t x= 0; x < 3; x++)
2309 {
2310 test_compare(MEMCACHED_NO_SERVERS,
2311 memcached_set(memc, keys[x], key_length[x],
2312 keys[x], key_length[x],
2313 (time_t)50, (uint32_t)9));
2314 }
2315
2316 test_compare(MEMCACHED_NO_SERVERS,
2317 memcached_mget(memc, keys, key_length, 3));
2318
2319 {
2320 char *return_value;
2321 char return_key[MEMCACHED_MAX_KEY];
2322 memcached_return_t rc;
2323 size_t return_key_length;
2324 size_t return_value_length;
2325 uint32_t flags;
2326 uint32_t x= 0;
2327 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
2328 &return_value_length, &flags, &rc)))
2329 {
2330 test_true(return_value);
2331 test_compare(MEMCACHED_SUCCESS, rc);
2332 test_true(return_key_length == return_value_length);
2333 test_memcmp(return_value, return_key, return_value_length);
2334 free(return_value);
2335 x++;
2336 }
2337 }
2338
2339 return TEST_SUCCESS;
2340 }
2341
2342 #define VALUE_SIZE_BUG5 1048064
2343 static test_return_t user_supplied_bug5(memcached_st *memc)
2344 {
2345 const char *keys[]= {"036790384900", "036790384902", "036790384904", "036790384906"};
2346 size_t key_length[]= {strlen("036790384900"), strlen("036790384902"), strlen("036790384904"), strlen("036790384906")};
2347 char *value;
2348 size_t value_length;
2349 uint32_t flags;
2350 char *insert_data= new (std::nothrow) char[VALUE_SIZE_BUG5];
2351
2352 for (uint32_t x= 0; x < VALUE_SIZE_BUG5; x++)
2353 {
2354 insert_data[x]= (signed char)rand();
2355 }
2356
2357 test_compare(MEMCACHED_SUCCESS,
2358 memcached_flush(memc, 0));
2359
2360 memcached_return_t rc;
2361 value= memcached_get(memc, keys[0], key_length[0],
2362 &value_length, &flags, &rc);
2363 test_false(value);
2364 test_compare(MEMCACHED_SUCCESS,
2365 memcached_mget(memc, keys, key_length, 4));
2366
2367 unsigned int count;
2368 test_compare(TEST_SUCCESS, fetch_all_results(memc, count, MEMCACHED_NOTFOUND));
2369 test_zero(count);
2370
2371 for (uint32_t x= 0; x < 4; x++)
2372 {
2373 test_compare(MEMCACHED_SUCCESS,
2374 memcached_set(memc, keys[x], key_length[x],
2375 insert_data, VALUE_SIZE_BUG5,
2376 (time_t)0, (uint32_t)0));
2377 }
2378
2379 for (uint32_t x= 0; x < 10; x++)
2380 {
2381 value= memcached_get(memc, keys[0], key_length[0],
2382 &value_length, &flags, &rc);
2383 test_compare(rc, MEMCACHED_SUCCESS);
2384 test_true(value);
2385 free(value);
2386
2387 test_compare(MEMCACHED_SUCCESS,
2388 memcached_mget(memc, keys, key_length, 4));
2389
2390 test_compare(TEST_SUCCESS, fetch_all_results(memc, count, MEMCACHED_SUCCESS));
2391 test_compare(4U, count);
2392 }
2393 delete [] insert_data;
2394
2395 return TEST_SUCCESS;
2396 }
2397
2398 static test_return_t user_supplied_bug6(memcached_st *memc)
2399 {
2400 const char *keys[]= {"036790384900", "036790384902", "036790384904", "036790384906"};
2401 size_t key_length[]= {strlen("036790384900"), strlen("036790384902"), strlen("036790384904"), strlen("036790384906")};
2402 char return_key[MEMCACHED_MAX_KEY];
2403 size_t return_key_length;
2404 char *value;
2405 size_t value_length;
2406 uint32_t flags;
2407 char *insert_data= new (std::nothrow) char[VALUE_SIZE_BUG5];
2408
2409 for (uint32_t x= 0; x < VALUE_SIZE_BUG5; x++)
2410 {
2411 insert_data[x]= (signed char)rand();
2412 }
2413
2414 test_compare(MEMCACHED_SUCCESS, memcached_flush(memc, 0));
2415
2416 test_compare(TEST_SUCCESS, confirm_keys_dont_exist(memc, keys, test_array_length(keys)));
2417
2418 // We will now confirm that memcached_mget() returns success, but we will
2419 // then check to make sure that no actual keys are returned.
2420 test_compare(MEMCACHED_SUCCESS,
2421 memcached_mget(memc, keys, key_length, 4));
2422
2423 memcached_return_t rc;
2424 uint32_t count= 0;
2425 while ((value= memcached_fetch(memc, return_key, &return_key_length,
2426 &value_length, &flags, &rc)))
2427 {
2428 count++;
2429 }
2430 test_zero(count);
2431 test_compare_got(MEMCACHED_NOTFOUND, rc, memcached_strerror(NULL, rc));
2432
2433 for (uint32_t x= 0; x < test_array_length(keys); x++)
2434 {
2435 test_compare(MEMCACHED_SUCCESS,
2436 memcached_set(memc, keys[x], key_length[x],
2437 insert_data, VALUE_SIZE_BUG5,
2438 (time_t)0, (uint32_t)0));
2439 }
2440 test_compare(TEST_SUCCESS, confirm_keys_exist(memc, keys, test_array_length(keys)));
2441
2442 for (uint32_t x= 0; x < 2; x++)
2443 {
2444 value= memcached_get(memc, keys[0], key_length[0],
2445 &value_length, &flags, &rc);
2446 test_true(value);
2447 free(value);
2448
2449 test_compare(MEMCACHED_SUCCESS,
2450 memcached_mget(memc, keys, key_length, 4));
2451 /* We test for purge of partial complete fetches */
2452 for (count= 3; count; count--)
2453 {
2454 value= memcached_fetch(memc, return_key, &return_key_length,
2455 &value_length, &flags, &rc);
2456 test_compare(MEMCACHED_SUCCESS, rc);
2457 test_memcmp(value, insert_data, value_length);
2458 test_true(value_length);
2459 free(value);
2460 }
2461 }
2462 delete [] insert_data;
2463
2464 return TEST_SUCCESS;
2465 }
2466
2467 static test_return_t user_supplied_bug8(memcached_st *)
2468 {
2469 memcached_return_t rc;
2470 memcached_st *mine;
2471 memcached_st *memc_clone;
2472
2473 memcached_server_st *servers;
2474 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";
2475
2476 servers= memcached_servers_parse(server_list);
2477 test_true(servers);
2478
2479 mine= memcached_create(NULL);
2480 rc= memcached_server_push(mine, servers);
2481 test_compare(MEMCACHED_SUCCESS, rc);
2482 memcached_server_list_free(servers);
2483
2484 test_true(mine);
2485 memc_clone= memcached_clone(NULL, mine);
2486
2487 memcached_quit(mine);
2488 memcached_quit(memc_clone);
2489
2490
2491 memcached_free(mine);
2492 memcached_free(memc_clone);
2493
2494 return TEST_SUCCESS;
2495 }
2496
2497 /* Test flag store/retrieve */
2498 static test_return_t user_supplied_bug7(memcached_st *memc)
2499 {
2500 const char *keys= "036790384900";
2501 size_t key_length= strlen(keys);
2502 char return_key[MEMCACHED_MAX_KEY];
2503 size_t return_key_length;
2504 char *value;
2505 size_t value_length;
2506 uint32_t flags;
2507 char *insert_data= new (std::nothrow) char[VALUE_SIZE_BUG5];
2508
2509 for (unsigned int x= 0; x < VALUE_SIZE_BUG5; x++)
2510 insert_data[x]= (signed char)rand();
2511
2512 memcached_flush(memc, 0);
2513
2514 flags= 245;
2515 memcached_return_t rc= memcached_set(memc, keys, key_length,
2516 insert_data, VALUE_SIZE_BUG5,
2517 (time_t)0, flags);
2518 test_compare(MEMCACHED_SUCCESS, rc);
2519
2520 flags= 0;
2521 value= memcached_get(memc, keys, key_length,
2522 &value_length, &flags, &rc);
2523 test_true(flags == 245);
2524 test_true(value);
2525 free(value);
2526
2527 rc= memcached_mget(memc, &keys, &key_length, 1);
2528
2529 flags= 0;
2530 value= memcached_fetch(memc, return_key, &return_key_length,
2531 &value_length, &flags, &rc);
2532 test_compare(uint32_t(245), flags);
2533 test_true(value);
2534 free(value);
2535 delete [] insert_data;
2536
2537
2538 return TEST_SUCCESS;
2539 }
2540
2541 static test_return_t user_supplied_bug9(memcached_st *memc)
2542 {
2543 const char *keys[]= {"UDATA:edevil@sapo.pt", "fudge&*@#", "for^#@&$not"};
2544 size_t key_length[3];
2545 uint32_t flags;
2546 unsigned count= 0;
2547
2548 char return_key[MEMCACHED_MAX_KEY];
2549 size_t return_key_length;
2550 char *return_value;
2551 size_t return_value_length;
2552
2553
2554 key_length[0]= strlen("UDATA:edevil@sapo.pt");
2555 key_length[1]= strlen("fudge&*@#");
2556 key_length[2]= strlen("for^#@&$not");
2557
2558
2559 for (unsigned int x= 0; x < 3; x++)
2560 {
2561 memcached_return_t rc= memcached_set(memc, keys[x], key_length[x],
2562 keys[x], key_length[x],
2563 (time_t)50, (uint32_t)9);
2564 test_compare(MEMCACHED_SUCCESS, rc);
2565 }
2566
2567 memcached_return_t rc= memcached_mget(memc, keys, key_length, 3);
2568 test_compare(MEMCACHED_SUCCESS, rc);
2569
2570 /* We need to empty the server before continueing test */
2571 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
2572 &return_value_length, &flags, &rc)) != NULL)
2573 {
2574 test_true(return_value);
2575 free(return_value);
2576 count++;
2577 }
2578 test_compare(3U, count);
2579
2580 return TEST_SUCCESS;
2581 }
2582
2583 /* We are testing with aggressive timeout to get failures */
2584 static test_return_t user_supplied_bug10(memcached_st *memc)
2585 {
2586 const char *key= "foo";
2587 size_t value_length= 512;
2588 size_t key_len= 3;
2589 unsigned int set= 1;
2590 memcached_st *mclone= memcached_clone(NULL, memc);
2591
2592 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_NO_BLOCK, set);
2593 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_TCP_NODELAY, set);
2594 int32_t timeout= 0;
2595 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, (uint64_t)timeout);
2596
2597 char *value= (char*)malloc(value_length * sizeof(char));
2598
2599 for (unsigned int x= 0; x < value_length; x++)
2600 {
2601 value[x]= (char) (x % 127);
2602 }
2603
2604 for (unsigned int x= 1; x <= 100000; ++x)
2605 {
2606 memcached_return_t rc= memcached_set(mclone, key, key_len,value, value_length, 0, 0);
2607
2608 test_true_got(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_WRITE_FAILURE or rc == MEMCACHED_BUFFERED or rc == MEMCACHED_TIMEOUT or rc == MEMCACHED_CONNECTION_FAILURE,
2609 memcached_strerror(NULL, rc));
2610
2611 if (rc == MEMCACHED_WRITE_FAILURE or rc == MEMCACHED_TIMEOUT)
2612 {
2613 x--;
2614 }
2615 }
2616
2617 free(value);
2618 memcached_free(mclone);
2619
2620 return TEST_SUCCESS;
2621 }
2622
2623 /*
2624 We are looking failures in the async protocol
2625 */
2626 static test_return_t user_supplied_bug11(memcached_st *memc)
2627 {
2628 const char *key= "foo";
2629 size_t value_length= 512;
2630 size_t key_len= 3;
2631 unsigned int set= 1;
2632 memcached_st *mclone= memcached_clone(NULL, memc);
2633
2634 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_NO_BLOCK, set);
2635 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_TCP_NODELAY, set);
2636 int32_t timeout= -1;
2637 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, (size_t)timeout);
2638
2639 timeout= (int32_t)memcached_behavior_get(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT);
2640
2641 test_true(timeout == -1);
2642
2643 char *value= (char*)malloc(value_length * sizeof(char));
2644
2645 for (unsigned int x= 0; x < value_length; x++)
2646 {
2647 value[x]= (char) (x % 127);
2648 }
2649
2650 for (unsigned int x= 1; x <= 100000; ++x)
2651 {
2652 memcached_return_t rc= memcached_set(mclone, key, key_len,value, value_length, 0, 0);
2653 (void)rc;
2654 }
2655
2656 free(value);
2657 memcached_free(mclone);
2658
2659 return TEST_SUCCESS;
2660 }
2661
2662 /*
2663 Bug found where incr was not returning MEMCACHED_NOTFOUND when object did not exist.
2664 */
2665 static test_return_t user_supplied_bug12(memcached_st *memc)
2666 {
2667 memcached_return_t rc;
2668 uint32_t flags;
2669 size_t value_length;
2670 char *value;
2671 uint64_t number_value;
2672
2673 value= memcached_get(memc, "autoincrement", strlen("autoincrement"),
2674 &value_length, &flags, &rc);
2675 test_true(value == NULL);
2676 test_compare(MEMCACHED_NOTFOUND, rc);
2677
2678 rc= memcached_increment(memc, "autoincrement", strlen("autoincrement"),
2679 1, &number_value);
2680
2681 test_true(value == NULL);
2682 /* The binary protocol will set the key if it doesn't exist */
2683 if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 1)
2684 {
2685 test_compare(MEMCACHED_SUCCESS, rc);
2686 }
2687 else
2688 {
2689 test_compare(MEMCACHED_NOTFOUND, rc);
2690 }
2691
2692 rc= memcached_set(memc, "autoincrement", strlen("autoincrement"), "1", 1, 0, 0);
2693
2694 value= memcached_get(memc, "autoincrement", strlen("autoincrement"),
2695 &value_length, &flags, &rc);
2696 test_true(value);
2697 test_compare(MEMCACHED_SUCCESS, rc);
2698 free(value);
2699
2700 rc= memcached_increment(memc, "autoincrement", strlen("autoincrement"),
2701 1, &number_value);
2702 test_true(number_value == 2);
2703 test_compare(MEMCACHED_SUCCESS, rc);
2704
2705 return TEST_SUCCESS;
2706 }
2707
2708 /*
2709 Bug found where command total one more than MEMCACHED_MAX_BUFFER
2710 set key34567890 0 0 8169 \r\n is sent followed by buffer of size 8169, followed by 8169
2711 */
2712 static test_return_t user_supplied_bug13(memcached_st *memc)
2713 {
2714 char key[] = "key34567890";
2715 memcached_return_t rc;
2716 size_t overflowSize;
2717
2718 char commandFirst[]= "set key34567890 0 0 ";
2719 char commandLast[] = " \r\n"; /* first line of command sent to server */
2720 size_t commandLength;
2721 size_t testSize;
2722
2723 commandLength = strlen(commandFirst) + strlen(commandLast) + 4; /* 4 is number of characters in size, probably 8196 */
2724
2725 overflowSize = MEMCACHED_MAX_BUFFER - commandLength;
2726
2727 for (testSize= overflowSize - 1; testSize < overflowSize + 1; testSize++)
2728 {
2729 char *overflow= new (std::nothrow) char[testSize];
2730 test_true(overflow);
2731
2732 memset(overflow, 'x', testSize);
2733 rc= memcached_set(memc, key, strlen(key),
2734 overflow, testSize, 0, 0);
2735 test_compare(MEMCACHED_SUCCESS, rc);
2736 delete [] overflow;
2737 }
2738
2739 return TEST_SUCCESS;
2740 }
2741
2742
2743 /*
2744 Test values of many different sizes
2745 Bug found where command total one more than MEMCACHED_MAX_BUFFER
2746 set key34567890 0 0 8169 \r\n
2747 is sent followed by buffer of size 8169, followed by 8169
2748 */
2749 static test_return_t user_supplied_bug14(memcached_st *memc)
2750 {
2751 size_t setter= 1;
2752 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, setter);
2753 memcached_return_t rc;
2754 const char *key= "foo";
2755 char *value;
2756 size_t value_length= 18000;
2757 char *string;
2758 size_t string_length;
2759 uint32_t flags;
2760 unsigned int x;
2761 size_t current_length;
2762
2763 value = (char*)malloc(value_length);
2764 test_true(value);
2765
2766 for (x= 0; x < value_length; x++)
2767 value[x] = (char) (x % 127);
2768
2769 for (current_length= 0; current_length < value_length; current_length++)
2770 {
2771 rc= memcached_set(memc, key, strlen(key),
2772 value, current_length,
2773 (time_t)0, (uint32_t)0);
2774 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
2775
2776 string= memcached_get(memc, key, strlen(key),
2777 &string_length, &flags, &rc);
2778
2779 test_compare(MEMCACHED_SUCCESS, rc);
2780 test_true(string_length == current_length);
2781 test_memcmp(string, value, string_length);
2782
2783 free(string);
2784 }
2785
2786 free(value);
2787
2788 return TEST_SUCCESS;
2789 }
2790
2791 /*
2792 Look for zero length value problems
2793 */
2794 static test_return_t user_supplied_bug15(memcached_st *memc)
2795 {
2796 uint32_t x;
2797 memcached_return_t rc;
2798 const char *key= "mykey";
2799 size_t length;
2800 uint32_t flags;
2801
2802 for (x= 0; x < 2; x++)
2803 {
2804 rc= memcached_set(memc, key, strlen(key),
2805 NULL, 0,
2806 (time_t)0, (uint32_t)0);
2807
2808 test_compare(MEMCACHED_SUCCESS, rc);
2809
2810 char *value= memcached_get(memc, key, strlen(key),
2811 &length, &flags, &rc);
2812
2813 test_compare(MEMCACHED_SUCCESS, rc);
2814 test_false(value);
2815 test_false(length);
2816 test_false(flags);
2817
2818 value= memcached_get(memc, key, strlen(key),
2819 &length, &flags, &rc);
2820
2821 test_compare(MEMCACHED_SUCCESS, rc);
2822 test_true(value == NULL);
2823 test_true(length == 0);
2824 test_true(flags == 0);
2825 }
2826
2827 return TEST_SUCCESS;
2828 }
2829
2830 /* Check the return sizes on FLAGS to make sure it stores 32bit unsigned values correctly */
2831 static test_return_t user_supplied_bug16(memcached_st *memc)
2832 {
2833 memcached_return_t rc;
2834 const char *key= "mykey";
2835 char *value;
2836 size_t length;
2837 uint32_t flags;
2838
2839 rc= memcached_set(memc, key, strlen(key),
2840 NULL, 0,
2841 (time_t)0, UINT32_MAX);
2842
2843 test_compare(MEMCACHED_SUCCESS, rc);
2844
2845 value= memcached_get(memc, key, strlen(key),
2846 &length, &flags, &rc);
2847
2848 test_compare(MEMCACHED_SUCCESS, rc);
2849 test_true(value == NULL);
2850 test_true(length == 0);
2851 test_true(flags == UINT32_MAX);
2852
2853 return TEST_SUCCESS;
2854 }
2855
2856 #if !defined(__sun) && !defined(__OpenBSD__)
2857 /* Check the validity of chinese key*/
2858 static test_return_t user_supplied_bug17(memcached_st *memc)
2859 {
2860 memcached_return_t rc;
2861 const char *key= "豆瓣";
2862 const char *value="我们在炎热抑郁的夏天无法停止豆瓣";
2863 char *value2;
2864 size_t length;
2865 uint32_t flags;
2866
2867 rc= memcached_set(memc, key, strlen(key),
2868 value, strlen(value),
2869 (time_t)0, 0);
2870
2871 test_compare(MEMCACHED_SUCCESS, rc);
2872
2873 value2= memcached_get(memc, key, strlen(key),
2874 &length, &flags, &rc);
2875
2876 test_true(length==strlen(value));
2877 test_compare(MEMCACHED_SUCCESS, rc);
2878 test_memcmp(value, value2, length);
2879 free(value2);
2880
2881 return TEST_SUCCESS;
2882 }
2883 #endif
2884
2885 /*
2886 From Andrei on IRC
2887 */
2888
2889 static test_return_t user_supplied_bug19(memcached_st *)
2890 {
2891 memcached_return_t res;
2892
2893 memcached_st *memc= memcached(test_literal_param("--server=localhost:11311/?100 --server=localhost:11312/?100"));
2894
2895 const memcached_server_st *server= memcached_server_by_key(memc, "a", 1, &res);
2896 test_true(server);
2897
2898 memcached_free(memc);
2899
2900 return TEST_SUCCESS;
2901 }
2902
2903 /* CAS test from Andei */
2904 static test_return_t user_supplied_bug20(memcached_st *memc)
2905 {
2906 memcached_return_t status;
2907 memcached_result_st *result, result_obj;
2908 const char *key = "abc";
2909 size_t key_len = strlen("abc");
2910 const char *value = "foobar";
2911 size_t value_len = strlen(value);
2912
2913 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, 1);
2914
2915 status = memcached_set(memc, key, key_len, value, value_len, (time_t)0, (uint32_t)0);
2916 test_true(status == MEMCACHED_SUCCESS);
2917
2918 status = memcached_mget(memc, &key, &key_len, 1);
2919 test_true(status == MEMCACHED_SUCCESS);
2920
2921 result= memcached_result_create(memc, &result_obj);
2922 test_true(result);
2923
2924 memcached_result_create(memc, &result_obj);
2925 result= memcached_fetch_result(memc, &result_obj, &status);
2926
2927 test_true(result);
2928 test_true(status == MEMCACHED_SUCCESS);
2929
2930 memcached_result_free(result);
2931
2932 return TEST_SUCCESS;
2933 }
2934
2935 #include "ketama_test_cases.h"
2936 static test_return_t user_supplied_bug18(memcached_st *trash)
2937 {
2938 memcached_return_t rc;
2939 uint64_t value;
2940 int x;
2941 memcached_st *memc;
2942
2943 (void)trash;
2944
2945 memc= memcached_create(NULL);
2946 test_true(memc);
2947
2948 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
2949 test_compare(MEMCACHED_SUCCESS, rc);
2950
2951 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
2952 test_true(value == 1);
2953
2954 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
2955 test_compare(MEMCACHED_SUCCESS, rc);
2956
2957 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
2958 test_true(value == MEMCACHED_HASH_MD5);
2959
2960 memcached_server_st *server_pool= memcached_servers_parse("10.0.1.1:11211 600,10.0.1.2:11211 300,10.0.1.3:11211 200,10.0.1.4:11211 350,10.0.1.5:11211 1000,10.0.1.6:11211 800,10.0.1.7:11211 950,10.0.1.8:11211 100");
2961 memcached_server_push(memc, server_pool);
2962
2963 /* verify that the server list was parsed okay. */
2964 test_true(memcached_server_count(memc) == 8);
2965 test_strcmp(server_pool[0].hostname, "10.0.1.1");
2966 test_true(server_pool[0].port == 11211);
2967 test_true(server_pool[0].weight == 600);
2968 test_strcmp(server_pool[2].hostname, "10.0.1.3");
2969 test_true(server_pool[2].port == 11211);
2970 test_true(server_pool[2].weight == 200);
2971 test_strcmp(server_pool[7].hostname, "10.0.1.8");
2972 test_true(server_pool[7].port == 11211);
2973 test_true(server_pool[7].weight == 100);
2974
2975 /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets
2976 * us test the boundary wraparound.
2977 */
2978 test_true(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->ketama.continuum[0].index);
2979
2980 /* verify the standard ketama set. */
2981 for (x= 0; x < 99; x++)
2982 {
2983 uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
2984
2985 memcached_server_instance_st instance=
2986 memcached_server_instance_by_position(memc, server_idx);
2987
2988 const char *hostname = memcached_server_name(instance);
2989 test_strcmp(hostname, ketama_test_cases[x].server);
2990 }
2991
2992 memcached_server_list_free(server_pool);
2993 memcached_free(memc);
2994
2995 return TEST_SUCCESS;
2996 }
2997
2998 /* Large mget() of missing keys with binary proto
2999 *
3000 * If many binary quiet commands (such as getq's in an mget) fill the output
3001 * buffer and the server chooses not to respond, memcached_flush hangs. See
3002 * http://lists.tangent.org/pipermail/libmemcached/2009-August/000918.html
3003 */
3004
3005 /* sighandler_t function that always asserts false */
3006 static void fail(int)
3007 {
3008 assert(0);
3009 }
3010
3011
3012 static test_return_t _user_supplied_bug21(memcached_st* memc, size_t key_count)
3013 {
3014 #ifdef WIN32
3015 (void)memc;
3016 (void)key_count;
3017 return TEST_SKIPPED;
3018 #else
3019 void (*oldalarm)(int);
3020
3021 memcached_st *memc_clone= memcached_clone(NULL, memc);
3022 test_true(memc_clone);
3023
3024 /* only binproto uses getq for mget */
3025 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1));
3026
3027 /* empty the cache to ensure misses (hence non-responses) */
3028 test_compare(MEMCACHED_SUCCESS, memcached_flush(memc_clone, 0));
3029
3030 size_t* key_lengths= new (std::nothrow) size_t[key_count];
3031 test_true(key_lengths);
3032 char **keys= static_cast<char **>(calloc(key_count, sizeof(char *)));
3033 test_true(keys);
3034 for (unsigned int x= 0; x < key_count; x++)
3035 {
3036 char buffer[30];
3037
3038 snprintf(buffer, 30, "%u", x);
3039 keys[x]= strdup(buffer);
3040 test_true(keys[x]);
3041 key_lengths[x]= strlen(keys[x]);
3042 }
3043
3044 oldalarm= signal(SIGALRM, fail);
3045 alarm(5);
3046
3047 test_compare_got(MEMCACHED_SUCCESS,
3048 memcached_mget(memc_clone, (const char **)keys, key_lengths, key_count), memcached_last_error_message(memc_clone));
3049
3050 alarm(0);
3051 signal(SIGALRM, oldalarm);
3052
3053 memcached_return_t rc;
3054 uint32_t flags;
3055 char return_key[MEMCACHED_MAX_KEY];
3056 size_t return_key_length;
3057 char *return_value;
3058 size_t return_value_length;
3059 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
3060 &return_value_length, &flags, &rc)))
3061 {
3062 test_false(return_value); // There are no keys to fetch, so the value should never be returned
3063 }
3064 test_compare(MEMCACHED_NOTFOUND, rc);
3065 test_zero(return_value_length);
3066 test_zero(return_key_length);
3067 test_false(return_key[0]);
3068 test_false(return_value);
3069
3070 for (unsigned int x= 0; x < key_count; x++)
3071 {
3072 free(keys[x]);
3073 }
3074 free(keys);
3075 delete [] key_lengths;
3076
3077 memcached_free(memc_clone);
3078
3079 return TEST_SUCCESS;
3080 #endif
3081 }
3082
3083 static test_return_t user_supplied_bug21(memcached_st *memc)
3084 {
3085 test_return_t test_rc;
3086 test_rc= pre_binary(memc);
3087
3088 if (test_rc != TEST_SUCCESS)
3089 return test_rc;
3090
3091 /* should work as of r580 */
3092 test_compare(TEST_SUCCESS,
3093 _user_supplied_bug21(memc, 10));
3094
3095 /* should fail as of r580 */
3096 test_compare(TEST_SUCCESS,
3097 _user_supplied_bug21(memc, 1000));
3098
3099 return TEST_SUCCESS;
3100 }
3101
3102 static test_return_t auto_eject_hosts(memcached_st *trash)
3103 {
3104 (void) trash;
3105 memcached_server_instance_st instance;
3106
3107 memcached_return_t rc;
3108 memcached_st *memc= memcached_create(NULL);
3109 test_true(memc);
3110
3111 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
3112 test_compare(MEMCACHED_SUCCESS, rc);
3113
3114 uint64_t value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
3115 test_true(value == 1);
3116
3117 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
3118 test_compare(MEMCACHED_SUCCESS, rc);
3119
3120 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
3121 test_true(value == MEMCACHED_HASH_MD5);
3122
3123 /* server should be removed when in delay */
3124 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS, 1);
3125 test_compare(MEMCACHED_SUCCESS, rc);
3126
3127 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS);
3128 test_true(value == 1);
3129
3130 memcached_server_st *server_pool;
3131 server_pool = memcached_servers_parse("10.0.1.1:11211 600,10.0.1.2:11211 300,10.0.1.3:11211 200,10.0.1.4:11211 350,10.0.1.5:11211 1000,10.0.1.6:11211 800,10.0.1.7:11211 950,10.0.1.8:11211 100");
3132 memcached_server_push(memc, server_pool);
3133
3134 /* verify that the server list was parsed okay. */
3135 test_true(memcached_server_count(memc) == 8);
3136 test_strcmp(server_pool[0].hostname, "10.0.1.1");
3137 test_true(server_pool[0].port == 11211);
3138 test_true(server_pool[0].weight == 600);
3139 test_strcmp(server_pool[2].hostname, "10.0.1.3");
3140 test_true(server_pool[2].port == 11211);
3141 test_true(server_pool[2].weight == 200);
3142 test_strcmp(server_pool[7].hostname, "10.0.1.8");
3143 test_true(server_pool[7].port == 11211);
3144 test_true(server_pool[7].weight == 100);
3145
3146 instance= memcached_server_instance_by_position(memc, 2);
3147 ((memcached_server_write_instance_st)instance)->next_retry = time(NULL) + 15;
3148 memc->ketama.next_distribution_rebuild= time(NULL) - 1;
3149
3150 /*
3151 This would not work if there were only two hosts.
3152 */
3153 for (size_t x= 0; x < 99; x++)
3154 {
3155 memcached_autoeject(memc);
3156 uint32_t server_idx= memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
3157 test_true(server_idx != 2);
3158 }
3159
3160 /* and re-added when it's back. */
3161 ((memcached_server_write_instance_st)instance)->next_retry = time(NULL) - 1;
3162 memc->ketama.next_distribution_rebuild= time(NULL) - 1;
3163 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION,
3164 memc->distribution);
3165 for (size_t x= 0; x < 99; x++)
3166 {
3167 uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
3168 // We re-use instance from above.
3169 instance=
3170 memcached_server_instance_by_position(memc, server_idx);
3171 const char *hostname = memcached_server_name(instance);
3172 test_strcmp(hostname, ketama_test_cases[x].server);
3173 }
3174
3175 memcached_server_list_free(server_pool);
3176 memcached_free(memc);
3177
3178 return TEST_SUCCESS;
3179 }
3180
3181 static test_return_t output_ketama_weighted_keys(memcached_st *trash)
3182 {
3183 (void) trash;
3184
3185 memcached_return_t rc;
3186 memcached_st *memc= memcached_create(NULL);
3187 test_true(memc);
3188
3189
3190 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
3191 test_compare(MEMCACHED_SUCCESS, rc);
3192
3193 uint64_t value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
3194 test_true(value == 1);
3195
3196 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
3197 test_compare(MEMCACHED_SUCCESS, rc);
3198
3199 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
3200 test_true(value == MEMCACHED_HASH_MD5);
3201
3202
3203 test_true(memcached_behavior_set_distribution(memc, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY) == MEMCACHED_SUCCESS);
3204
3205 memcached_server_st *server_pool;
3206 server_pool = memcached_servers_parse("10.0.1.1:11211,10.0.1.2:11211,10.0.1.3:11211,10.0.1.4:11211,10.0.1.5:11211,10.0.1.6:11211,10.0.1.7:11211,10.0.1.8:11211,192.168.1.1:11211,192.168.100.1:11211");
3207 memcached_server_push(memc, server_pool);
3208
3209 // @todo this needs to be refactored to actually test something.
3210 #if 0
3211 FILE *fp;
3212 if ((fp = fopen("ketama_keys.txt", "w")))
3213 {
3214 // noop
3215 } else {
3216 printf("cannot write to file ketama_keys.txt");
3217 return TEST_FAILURE;
3218 }
3219
3220 for (int x= 0; x < 10000; x++)
3221 {
3222 char key[10];
3223 snprintf(key, sizeof(key), "%d", x);
3224
3225 uint32_t server_idx = memcached_generate_hash(memc, key, strlen(key));
3226 char *hostname = memc->hosts[server_idx].hostname;
3227 in_port_t port = memc->hosts[server_idx].port;
3228 fprintf(fp, "key %s is on host /%s:%u\n", key, hostname, port);
3229 memcached_server_instance_st instance=
3230 memcached_server_instance_by_position(memc, host_index);
3231 }
3232 fclose(fp);
3233 #endif
3234 memcached_server_list_free(server_pool);
3235 memcached_free(memc);
3236
3237 return TEST_SUCCESS;
3238 }
3239
3240
3241 static test_return_t result_static(memcached_st *memc)
3242 {
3243 memcached_result_st result;
3244 memcached_result_st *result_ptr;
3245
3246 result_ptr= memcached_result_create(memc, &result);
3247 test_true(result.options.is_allocated == false);
3248 test_true(memcached_is_initialized(&result) == true);
3249 test_true(result_ptr);
3250 test_true(result_ptr == &result);
3251
3252 memcached_result_free(&result);
3253
3254 test_true(result.options.is_allocated == false);
3255 test_true(memcached_is_initialized(&result) == false);
3256
3257 return TEST_SUCCESS;
3258 }
3259
3260 static test_return_t result_alloc(memcached_st *memc)
3261 {
3262 memcached_result_st *result_ptr;
3263
3264 result_ptr= memcached_result_create(memc, NULL);
3265 test_true(result_ptr);
3266 test_true(result_ptr->options.is_allocated == true);
3267 test_true(memcached_is_initialized(result_ptr) == true);
3268 memcached_result_free(result_ptr);
3269
3270 return TEST_SUCCESS;
3271 }
3272
3273 static test_return_t cleanup_pairs(memcached_st *memc)
3274 {
3275 (void)memc;
3276 pairs_free(global_pairs);
3277
3278 return TEST_SUCCESS;
3279 }
3280
3281 static test_return_t generate_pairs(memcached_st *memc)
3282 {
3283 (void)memc;
3284 global_pairs= pairs_generate(GLOBAL_COUNT, 400);
3285 global_count= GLOBAL_COUNT;
3286
3287 for (size_t x= 0; x < global_count; x++)
3288 {
3289 global_keys[x]= global_pairs[x].key;
3290 global_keys_length[x]= global_pairs[x].key_length;
3291 }
3292
3293 return TEST_SUCCESS;
3294 }
3295
3296 static test_return_t generate_large_pairs(memcached_st *)
3297 {
3298 global_pairs= pairs_generate(GLOBAL2_COUNT, MEMCACHED_MAX_BUFFER+10);
3299 global_count= GLOBAL2_COUNT;
3300
3301 for (size_t x= 0; x < global_count; x++)
3302 {
3303 global_keys[x]= global_pairs[x].key;
3304 global_keys_length[x]= global_pairs[x].key_length;
3305 }
3306
3307 return TEST_SUCCESS;
3308 }
3309
3310 static test_return_t generate_data(memcached_st *memc)
3311 {
3312 unsigned int check_execute= execute_set(memc, global_pairs, global_count);
3313
3314 test_compare(check_execute, global_count);
3315
3316 return TEST_SUCCESS;
3317 }
3318
3319 static test_return_t generate_data_with_stats(memcached_st *memc)
3320 {
3321 uint32_t host_index= 0;
3322 unsigned int check_execute= execute_set(memc, global_pairs, global_count);
3323
3324 test_true(check_execute == global_count);
3325
3326 // @todo hosts used size stats
3327 memcached_return_t rc;
3328 memcached_stat_st *stat_p= memcached_stat(memc, NULL, &rc);
3329 test_true(stat_p);
3330
3331 for (host_index= 0; host_index < SERVERS_TO_CREATE; host_index++)
3332 {
3333 /* This test was changes so that "make test" would work properlly */
3334 #ifdef DEBUG
3335 memcached_server_instance_st instance=
3336 memcached_server_instance_by_position(memc, host_index);
3337
3338 printf("\nserver %u|%s|%u bytes: %llu\n", host_index, instance->hostname, instance->port, (unsigned long long)(stat_p + host_index)->bytes);
3339 #endif
3340 test_true((unsigned long long)(stat_p + host_index)->bytes);
3341 }
3342
3343 memcached_stat_free(NULL, stat_p);
3344
3345 return TEST_SUCCESS;
3346 }
3347 static test_return_t generate_buffer_data(memcached_st *memc)
3348 {
3349 size_t latch= 0;
3350
3351 latch= 1;
3352 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, latch);
3353 generate_data(memc);
3354
3355 return TEST_SUCCESS;
3356 }
3357
3358 static test_return_t get_read_count(memcached_st *memc)
3359 {
3360 memcached_st *memc_clone= memcached_clone(NULL, memc);
3361 test_true(memc_clone);
3362
3363 memcached_server_add_with_weight(memc_clone, "localhost", 6666, 0);
3364
3365 {
3366 char *return_value;
3367 size_t return_value_length;
3368 uint32_t flags;
3369 uint32_t count;
3370
3371 for (size_t x= count= 0; x < global_count; x++)
3372 {
3373 memcached_return_t rc;
3374 return_value= memcached_get(memc_clone, global_keys[x], global_keys_length[x],
3375 &return_value_length, &flags, &rc);
3376 if (rc == MEMCACHED_SUCCESS)
3377 {
3378 count++;
3379 if (return_value)
3380 free(return_value);
3381 }
3382 }
3383 }
3384
3385 memcached_free(memc_clone);
3386
3387 return TEST_SUCCESS;
3388 }
3389
3390 static test_return_t get_read(memcached_st *memc)
3391 {
3392 for (size_t x= 0; x < global_count; x++)
3393 {
3394 size_t return_value_length;
3395 uint32_t flags;
3396 memcached_return_t rc;
3397 char *return_value= memcached_get(memc, global_keys[x], global_keys_length[x],
3398 &return_value_length, &flags, &rc);
3399 /*
3400 test_true(return_value);
3401 test_compare(MEMCACHED_SUCCESS, rc);
3402 */
3403 if (rc == MEMCACHED_SUCCESS && return_value)
3404 free(return_value);
3405 }
3406
3407 return TEST_SUCCESS;
3408 }
3409
3410 static test_return_t mget_read(memcached_st *memc)
3411 {
3412
3413 test_skip(true, bool(libmemcached_util_version_check(memc, 1, 4, 4)));
3414
3415 test_compare(MEMCACHED_SUCCESS,
3416 memcached_mget(memc, global_keys, global_keys_length, global_count));
3417
3418 // Go fetch the keys and test to see if all of them were returned
3419 {
3420 unsigned int keys_returned;
3421 test_compare(TEST_SUCCESS, fetch_all_results(memc, keys_returned, MEMCACHED_SUCCESS));
3422 test_true(keys_returned > 0);
3423 test_compare(global_count, keys_returned);
3424 }
3425
3426 return TEST_SUCCESS;
3427 }
3428
3429 static test_return_t mget_read_result(memcached_st *memc)
3430 {
3431
3432 test_skip(true, bool(libmemcached_util_version_check(memc, 1, 4, 4)));
3433
3434 test_compare(MEMCACHED_SUCCESS,
3435 memcached_mget(memc, global_keys, global_keys_length, global_count));
3436
3437 /* Turn this into a help function */
3438 {
3439 memcached_result_st results_obj;
3440 memcached_result_st *results= memcached_result_create(memc, &results_obj);
3441
3442 memcached_return_t rc;
3443 while ((results= memcached_fetch_result(memc, &results_obj, &rc)))
3444 {
3445 test_true(results);
3446 test_compare(MEMCACHED_SUCCESS, rc);
3447 }
3448 test_compare(MEMCACHED_END, rc);
3449
3450 memcached_result_free(&results_obj);
3451 }
3452
3453 return TEST_SUCCESS;
3454 }
3455
3456 static test_return_t mget_read_internal_result(memcached_st *memc)
3457 {
3458
3459 test_skip(true, bool(libmemcached_util_version_check(memc, 1, 4, 4)));
3460
3461 test_compare(MEMCACHED_SUCCESS,
3462 memcached_mget(memc, global_keys, global_keys_length, global_count));
3463 {
3464 memcached_result_st *results= NULL;
3465 memcached_return_t rc;
3466 while ((results= memcached_fetch_result(memc, results, &rc)))
3467 {
3468 test_true(results);
3469 test_compare(MEMCACHED_SUCCESS, rc);
3470 }
3471 test_compare(MEMCACHED_END, rc);
3472
3473 memcached_result_free(results);
3474 }
3475
3476 return TEST_SUCCESS;
3477 }
3478
3479 static test_return_t mget_read_partial_result(memcached_st *memc)
3480 {
3481
3482 test_skip(true, bool(libmemcached_util_version_check(memc, 1, 4, 4)));
3483
3484 test_compare(MEMCACHED_SUCCESS,
3485 memcached_mget(memc, global_keys, global_keys_length, global_count));
3486
3487 // We will scan for just one key
3488 {
3489 memcached_result_st results_obj;
3490 memcached_result_st *results= memcached_result_create(memc, &results_obj);
3491
3492 memcached_return_t rc;
3493 results= memcached_fetch_result(memc, results, &rc);
3494 test_true(results);
3495 test_compare(MEMCACHED_SUCCESS, rc);
3496
3497 memcached_result_free(&results_obj);
3498 }
3499
3500 // We already have a read happening, lets start up another one.
3501 test_compare(MEMCACHED_SUCCESS,
3502 memcached_mget(memc, global_keys, global_keys_length, global_count));
3503 {
3504 memcached_result_st results_obj;
3505 memcached_result_st *results= memcached_result_create(memc, &results_obj);
3506
3507 memcached_return_t rc;
3508 while ((results= memcached_fetch_result(memc, &results_obj, &rc)))
3509 {
3510 test_true(results);
3511 test_compare(MEMCACHED_SUCCESS, rc);
3512 }
3513 test_compare(MEMCACHED_END, rc);
3514
3515 memcached_result_free(&results_obj);
3516 }
3517
3518 return TEST_SUCCESS;
3519 }
3520
3521 static test_return_t mget_read_function(memcached_st *memc)
3522 {
3523 test_skip(true, bool(libmemcached_util_version_check(memc, 1, 4, 4)));
3524
3525 test_compare(MEMCACHED_SUCCESS,
3526 memcached_mget(memc, global_keys, global_keys_length, global_count));
3527
3528 memcached_execute_fn callbacks[]= { &callback_counter };
3529 size_t counter= 0;
3530 test_compare(MEMCACHED_SUCCESS,
3531 memcached_fetch_execute(memc, callbacks, (void *)&counter, 1));
3532
3533 return TEST_SUCCESS;
3534 }
3535
3536 static test_return_t delete_generate(memcached_st *memc)
3537 {
3538 for (size_t x= 0; x < global_count; x++)
3539 {
3540 (void)memcached_delete(memc, global_keys[x], global_keys_length[x], (time_t)0);
3541 }
3542
3543 return TEST_SUCCESS;
3544 }
3545
3546 static test_return_t delete_buffer_generate(memcached_st *memc)
3547 {
3548 uint64_t latch= 1;
3549 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, latch);
3550
3551 for (size_t x= 0; x < global_count; x++)
3552 {
3553 (void)memcached_delete(memc, global_keys[x], global_keys_length[x], (time_t)0);
3554 }
3555
3556 return TEST_SUCCESS;
3557 }
3558
3559 static test_return_t add_host_test1(memcached_st *memc)
3560 {
3561 memcached_return_t rc;
3562 char servername[]= "0.example.com";
3563
3564 memcached_server_st *servers= memcached_server_list_append_with_weight(NULL, servername, 400, 0, &rc);
3565 test_true(servers);
3566 test_compare(1U, memcached_server_list_count(servers));
3567
3568 for (uint32_t x= 2; x < 20; x++)
3569 {
3570 char buffer[SMALL_STRING_LEN];
3571
3572 snprintf(buffer, SMALL_STRING_LEN, "%lu.example.com", (unsigned long)(400 +x));
3573 servers= memcached_server_list_append_with_weight(servers, buffer, 401, 0,
3574 &rc);
3575 test_compare(MEMCACHED_SUCCESS, rc);
3576 test_compare(x, memcached_server_list_count(servers));
3577 }
3578
3579 test_compare(MEMCACHED_SUCCESS, memcached_server_push(memc, servers));
3580 test_compare(MEMCACHED_SUCCESS, memcached_server_push(memc, servers));
3581
3582 memcached_server_list_free(servers);
3583
3584 return TEST_SUCCESS;
3585 }
3586
3587 static test_return_t pre_nonblock(memcached_st *memc)
3588 {
3589 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
3590
3591 return TEST_SUCCESS;
3592 }
3593
3594 static test_return_t pre_cork(memcached_st *memc)
3595 {
3596 #ifdef __APPLE__
3597 return TEST_SKIPPED;
3598 #endif
3599 bool set= true;
3600 if (memcached_success(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_CORK, set)))
3601 return TEST_SUCCESS;
3602
3603 return TEST_SKIPPED;
3604 }
3605
3606 static test_return_t pre_cork_and_nonblock(memcached_st *memc)
3607 {
3608 #ifdef __APPLE__
3609 return TEST_SKIPPED;
3610 #endif
3611 test_return_t test_rc;
3612 if ((test_rc= pre_cork(memc)) != TEST_SUCCESS)
3613 return test_rc;
3614
3615 return pre_nonblock(memc);
3616 }
3617
3618 static test_return_t pre_nonblock_binary(memcached_st *memc)
3619 {
3620 memcached_return_t rc= MEMCACHED_FAILURE;
3621 memcached_st *memc_clone;
3622
3623 memc_clone= memcached_clone(NULL, memc);
3624 test_true(memc_clone);
3625 // The memcached_version needs to be done on a clone, because the server
3626 // will not toggle protocol on an connection.
3627 memcached_version(memc_clone);
3628
3629 if (libmemcached_util_version_check(memc_clone, 1, 4, 4))
3630 {
3631 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
3632 rc = memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
3633 test_compare(MEMCACHED_SUCCESS, rc);
3634 test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 1);
3635 }
3636 else
3637 {
3638 return TEST_SKIPPED;
3639 }
3640
3641 memcached_free(memc_clone);
3642
3643 return rc == MEMCACHED_SUCCESS ? TEST_SUCCESS : TEST_SKIPPED;
3644 }
3645
3646 static test_return_t pre_murmur(memcached_st *memc)
3647 {
3648 #ifdef HAVE_MURMUR_HASH
3649 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MURMUR);
3650 return TEST_SUCCESS;
3651 #else
3652 (void) memc;
3653 return TEST_SKIPPED;
3654 #endif
3655 }
3656
3657 static test_return_t pre_jenkins(memcached_st *memc)
3658 {
3659 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_JENKINS);
3660
3661 return TEST_SUCCESS;
3662 }
3663
3664
3665 static test_return_t pre_md5(memcached_st *memc)
3666 {
3667 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MD5);
3668
3669 return TEST_SUCCESS;
3670 }
3671
3672 static test_return_t pre_crc(memcached_st *memc)
3673 {
3674 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_CRC);
3675
3676 return TEST_SUCCESS;
3677 }
3678
3679 static test_return_t pre_hsieh(memcached_st *memc)
3680 {
3681 #ifdef HAVE_HSIEH_HASH
3682 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_HSIEH);
3683 return TEST_SUCCESS;
3684 #else
3685 (void) memc;
3686 return TEST_SKIPPED;
3687 #endif
3688 }
3689
3690 static test_return_t pre_hash_fnv1_64(memcached_st *memc)
3691 {
3692 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MURMUR);
3693
3694 return TEST_SUCCESS;
3695 }
3696
3697 static test_return_t pre_hash_fnv1a_64(memcached_st *memc)
3698 {
3699 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1A_64);
3700
3701 return TEST_SUCCESS;
3702 }
3703
3704 static test_return_t pre_hash_fnv1_32(memcached_st *memc)
3705 {
3706 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1_32);
3707
3708 return TEST_SUCCESS;
3709 }
3710
3711 static test_return_t pre_hash_fnv1a_32(memcached_st *memc)
3712 {
3713 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1A_32);
3714
3715 return TEST_SUCCESS;
3716 }
3717
3718 static test_return_t pre_behavior_ketama(memcached_st *memc)
3719 {
3720 memcached_return_t rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA, 1);
3721 test_compare(MEMCACHED_SUCCESS, rc);
3722
3723 uint64_t value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA);
3724 test_true(value == 1);
3725
3726 return TEST_SUCCESS;
3727 }
3728
3729 static test_return_t pre_behavior_ketama_weighted(memcached_st *memc)
3730 {
3731 memcached_return_t rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
3732 test_compare(MEMCACHED_SUCCESS, rc);
3733
3734 uint64_t value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
3735 test_true(value == 1);
3736
3737 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
3738 test_compare(MEMCACHED_SUCCESS, rc);
3739
3740 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
3741 test_true(value == MEMCACHED_HASH_MD5);
3742
3743 return TEST_SUCCESS;
3744 }
3745
3746 /**
3747 @note This should be testing to see if the server really supports the binary protocol.
3748 */
3749 static test_return_t pre_binary(memcached_st *memc)
3750 {
3751 memcached_return_t rc= MEMCACHED_FAILURE;
3752
3753 if (libmemcached_util_version_check(memc, 1, 4, 4))
3754 {
3755 rc = memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
3756 test_compare(MEMCACHED_SUCCESS, rc);
3757 test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 1);
3758 }
3759
3760 return rc == MEMCACHED_SUCCESS ? TEST_SUCCESS : TEST_SKIPPED;
3761 }
3762
3763 static test_return_t pre_sasl(memcached_st *memc)
3764 {
3765 memcached_return_t rc= MEMCACHED_FAILURE;
3766
3767 #ifdef LIBMEMCACHED_WITH_SASL_SUPPORT
3768 const char *server= getenv("LIBMEMCACHED_TEST_SASL_SERVER");
3769 const char *user= getenv("LIBMEMCACHED_TEST_SASL_USERNAME");
3770 const char *pass= getenv("LIBMEMCACHED_TEST_SASL_PASSWORD");
3771
3772 if (server and user and pass)
3773 {
3774 memcached_server_st *servers= memcached_servers_parse(server);
3775 test_true(servers);
3776 memcached_servers_reset(memc);
3777 test_true(memcached_server_push(memc, servers) == MEMCACHED_SUCCESS);
3778 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
3779 rc= memcached_set_sasl_auth_data(memc, user, pass);
3780 test_compare(MEMCACHED_SUCCESS, rc);
3781 }
3782 #else
3783 (void)memc;
3784 #endif
3785
3786 return rc == MEMCACHED_SUCCESS ? TEST_SUCCESS : TEST_SKIPPED;
3787 }
3788
3789 static test_return_t pre_replication(memcached_st *memc)
3790 {
3791 test_skip(TEST_SUCCESS, pre_binary(memc));
3792
3793 /*
3794 * Make sure that we store the item on all servers
3795 * (master + replicas == number of servers)
3796 */
3797 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, memcached_server_count(memc) - 1));
3798 test_compare(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS), uint64_t(memcached_server_count(memc) - 1));
3799
3800 return TEST_SUCCESS;
3801 }
3802
3803
3804 static test_return_t pre_replication_noblock(memcached_st *memc)
3805 {
3806 test_skip(TEST_SUCCESS, pre_replication(memc));
3807
3808 return pre_nonblock(memc);
3809 }
3810
3811
3812 static void my_free(const memcached_st *ptr, void *mem, void *context)
3813 {
3814 (void)context;
3815 (void)ptr;
3816 #ifdef HARD_MALLOC_TESTS
3817 void *real_ptr= (mem == NULL) ? mem : (void*)((caddr_t)mem - 8);
3818 free(real_ptr);
3819 #else
3820 free(mem);
3821 #endif
3822 }
3823
3824
3825 static void *my_malloc(const memcached_st *ptr, const size_t size, void *context)
3826 {
3827 (void)context;
3828 (void)ptr;
3829 #ifdef HARD_MALLOC_TESTS
3830 void *ret= malloc(size + 8);
3831 if (ret != NULL)
3832 {
3833 ret= (void*)((caddr_t)ret + 8);
3834 }
3835 #else
3836 void *ret= malloc(size);
3837 #endif
3838
3839 if (ret != NULL)
3840 {
3841 memset(ret, 0xff, size);
3842 }
3843
3844 return ret;
3845 }
3846
3847
3848 static void *my_realloc(const memcached_st *ptr, void *mem, const size_t size, void *)
3849 {
3850 #ifdef HARD_MALLOC_TESTS
3851 void *real_ptr= (mem == NULL) ? NULL : (void*)((caddr_t)mem - 8);
3852 void *nmem= realloc(real_ptr, size + 8);
3853
3854 void *ret= NULL;
3855 if (nmem != NULL)
3856 {
3857 ret= (void*)((caddr_t)nmem + 8);
3858 }
3859
3860 return ret;
3861 #else
3862 (void)ptr;
3863 return realloc(mem, size);
3864 #endif
3865 }
3866
3867
3868 static void *my_calloc(const memcached_st *ptr, size_t nelem, const size_t size, void *)
3869 {
3870 #ifdef HARD_MALLOC_TESTS
3871 void *mem= my_malloc(ptr, nelem * size);
3872 if (mem)
3873 {
3874 memset(mem, 0, nelem * size);
3875 }
3876
3877 return mem;
3878 #else
3879 (void)ptr;
3880 return calloc(nelem, size);
3881 #endif
3882 }
3883
3884 static test_return_t selection_of_namespace_tests(memcached_st *memc)
3885 {
3886 memcached_return_t rc;
3887 const char *key= "mine";
3888 char *value;
3889
3890 /* Make sure be default none exists */
3891 value= (char*)memcached_callback_get(memc, MEMCACHED_CALLBACK_NAMESPACE, &rc);
3892 test_compare_got(MEMCACHED_FAILURE, rc, memcached_strerror(NULL, rc));
3893
3894 /* Test a clean set */
3895 test_compare(MEMCACHED_SUCCESS,
3896 memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, (void *)key));
3897
3898 value= (char*)memcached_callback_get(memc, MEMCACHED_CALLBACK_NAMESPACE, &rc);
3899 test_true(value);
3900 test_memcmp(value, key, 4);
3901 test_compare_got(MEMCACHED_SUCCESS, rc, memcached_strerror(NULL, rc));
3902
3903 /* Test that we can turn it off */
3904 test_compare(MEMCACHED_SUCCESS,
3905 memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, NULL));
3906
3907 value= (char*)memcached_callback_get(memc, MEMCACHED_CALLBACK_NAMESPACE, &rc);
3908 test_false(value);
3909 test_compare_got(MEMCACHED_FAILURE, rc, memcached_strerror(NULL, rc));
3910
3911 /* Now setup for main test */
3912 test_compare(MEMCACHED_SUCCESS,
3913 memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, (void *)key));
3914
3915 value= (char *)memcached_callback_get(memc, MEMCACHED_CALLBACK_NAMESPACE, &rc);
3916 test_true(value);
3917 test_compare_got(MEMCACHED_SUCCESS, rc, memcached_strerror(NULL, rc));
3918 test_memcmp(value, key, 4);
3919
3920 /* Set to Zero, and then Set to something too large */
3921 {
3922 char long_key[255];
3923 memset(long_key, 0, 255);
3924
3925 test_compare(MEMCACHED_SUCCESS,
3926 memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, NULL));
3927
3928 value= (char*)memcached_callback_get(memc, MEMCACHED_CALLBACK_NAMESPACE, &rc);
3929 test_false(value);
3930 test_true(rc == MEMCACHED_FAILURE);
3931 test_true(value == NULL);
3932
3933 /* Test a long key for failure */
3934 /* TODO, extend test to determine based on setting, what result should be */
3935 strncpy(long_key, "Thisismorethentheallottednumberofcharacters", sizeof(long_key));
3936 test_compare(MEMCACHED_SUCCESS,
3937 memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, long_key));
3938
3939 /* Now test a key with spaces (which will fail from long key, since bad key is not set) */
3940 strncpy(long_key, "This is more then the allotted number of characters", sizeof(long_key));
3941 test_compare(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) ? MEMCACHED_SUCCESS : MEMCACHED_BAD_KEY_PROVIDED,
3942 memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, long_key));
3943
3944 /* Test for a bad prefix, but with a short key */
3945 test_compare(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) ? MEMCACHED_INVALID_ARGUMENTS : MEMCACHED_SUCCESS,
3946 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_VERIFY_KEY, 1));
3947
3948 test_compare(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) ? MEMCACHED_SUCCESS : MEMCACHED_BAD_KEY_PROVIDED,
3949 memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, "dog cat"));
3950 }
3951
3952 return TEST_SUCCESS;
3953 }
3954
3955 static test_return_t set_namespace(memcached_st *memc)
3956 {
3957 memcached_return_t rc;
3958 const char *key= "mine";
3959 char *value;
3960
3961 /* Make sure be default none exists */
3962 value= (char*)memcached_callback_get(memc, MEMCACHED_CALLBACK_NAMESPACE, &rc);
3963 test_compare_got(MEMCACHED_FAILURE, rc, memcached_strerror(NULL, rc));
3964
3965 /* Test a clean set */
3966 test_compare(MEMCACHED_SUCCESS,
3967 memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, (void *)key));
3968
3969 value= (char*)memcached_callback_get(memc, MEMCACHED_CALLBACK_NAMESPACE, &rc);
3970 test_true(value);
3971 test_memcmp(value, key, 4);
3972 test_compare_got(MEMCACHED_SUCCESS, rc, memcached_strerror(NULL, rc));
3973
3974 return TEST_SUCCESS;
3975 }
3976
3977 static test_return_t set_namespace_and_binary(memcached_st *memc)
3978 {
3979 test_return_if(pre_binary(memc));
3980 test_return_if(set_namespace(memc));
3981
3982 return TEST_SUCCESS;
3983 }
3984
3985 #ifdef MEMCACHED_ENABLE_DEPRECATED
3986 static test_return_t deprecated_set_memory_alloc(memcached_st *memc)
3987 {
3988 void *test_ptr= NULL;
3989 void *cb_ptr= NULL;
3990 {
3991 memcached_malloc_fn malloc_cb=
3992 (memcached_malloc_fn)my_malloc;
3993 cb_ptr= *(void **)&malloc_cb;
3994 memcached_return_t rc;
3995
3996 test_compare(MEMCACHED_SUCCESS,
3997 memcached_callback_set(memc, MEMCACHED_CALLBACK_MALLOC_FUNCTION, cb_ptr));
3998 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_MALLOC_FUNCTION, &rc);
3999 test_compare(MEMCACHED_SUCCESS, rc);
4000 test_true(test_ptr == cb_ptr);
4001 }
4002
4003 {
4004 memcached_realloc_fn realloc_cb=
4005 (memcached_realloc_fn)my_realloc;
4006 cb_ptr= *(void **)&realloc_cb;
4007 memcached_return_t rc;
4008
4009 test_compare(MEMCACHED_SUCCESS,
4010 memcached_callback_set(memc, MEMCACHED_CALLBACK_REALLOC_FUNCTION, cb_ptr));
4011 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_REALLOC_FUNCTION, &rc);
4012 test_compare(MEMCACHED_SUCCESS, rc);
4013 test_true(test_ptr == cb_ptr);
4014 }
4015
4016 {
4017 memcached_free_fn free_cb=
4018 (memcached_free_fn)my_free;
4019 cb_ptr= *(void **)&free_cb;
4020 memcached_return_t rc;
4021
4022 test_compare(MEMCACHED_SUCCESS,
4023 memcached_callback_set(memc, MEMCACHED_CALLBACK_FREE_FUNCTION, cb_ptr));
4024 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_FREE_FUNCTION, &rc);
4025 test_compare(MEMCACHED_SUCCESS, rc);
4026 test_true(test_ptr == cb_ptr);
4027 }
4028
4029 return TEST_SUCCESS;
4030 }
4031 #endif
4032
4033
4034 static test_return_t set_memory_alloc(memcached_st *memc)
4035 {
4036 test_compare(MEMCACHED_FAILURE,
4037 memcached_set_memory_allocators(memc, NULL, my_free,
4038 my_realloc, my_calloc, NULL));
4039
4040 test_compare(MEMCACHED_SUCCESS,
4041 memcached_set_memory_allocators(memc, my_malloc, my_free,
4042 my_realloc, my_calloc, NULL));
4043
4044 memcached_malloc_fn mem_malloc;
4045 memcached_free_fn mem_free;
4046 memcached_realloc_fn mem_realloc;
4047 memcached_calloc_fn mem_calloc;
4048 memcached_get_memory_allocators(memc, &mem_malloc, &mem_free,
4049 &mem_realloc, &mem_calloc);
4050
4051 test_true(mem_malloc == my_malloc);
4052 test_true(mem_realloc == my_realloc);
4053 test_true(mem_calloc == my_calloc);
4054 test_true(mem_free == my_free);
4055
4056 return TEST_SUCCESS;
4057 }
4058
4059 static test_return_t enable_consistent_crc(memcached_st *memc)
4060 {
4061 test_return_t rc;
4062 memcached_server_distribution_t value= MEMCACHED_DISTRIBUTION_CONSISTENT;
4063 memcached_hash_t hash;
4064 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, value);
4065 if ((rc= pre_crc(memc)) != TEST_SUCCESS)
4066 return rc;
4067
4068 value= (memcached_server_distribution_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION);
4069 test_true(value == MEMCACHED_DISTRIBUTION_CONSISTENT);
4070
4071 hash= (memcached_hash_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
4072
4073 if (hash != MEMCACHED_HASH_CRC)
4074 return TEST_SKIPPED;
4075
4076 return TEST_SUCCESS;
4077 }
4078
4079 static test_return_t enable_consistent_hsieh(memcached_st *memc)
4080 {
4081 test_return_t rc;
4082 memcached_server_distribution_t value= MEMCACHED_DISTRIBUTION_CONSISTENT;
4083 memcached_hash_t hash;
4084 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, value);
4085 if ((rc= pre_hsieh(memc)) != TEST_SUCCESS)
4086 return rc;
4087
4088 value= (memcached_server_distribution_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION);
4089 test_true(value == MEMCACHED_DISTRIBUTION_CONSISTENT);
4090
4091 hash= (memcached_hash_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
4092
4093 if (hash != MEMCACHED_HASH_HSIEH)
4094 return TEST_SKIPPED;
4095
4096
4097 return TEST_SUCCESS;
4098 }
4099
4100 static test_return_t enable_cas(memcached_st *memc)
4101 {
4102 unsigned int set= 1;
4103
4104 if (libmemcached_util_version_check(memc, 1, 2, 4))
4105 {
4106 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, set);
4107
4108 return TEST_SUCCESS;
4109 }
4110
4111 return TEST_SKIPPED;
4112 }
4113
4114 static test_return_t check_for_1_2_3(memcached_st *memc)
4115 {
4116 memcached_version(memc);
4117
4118 memcached_server_instance_st instance=
4119 memcached_server_instance_by_position(memc, 0);
4120
4121 if ((instance->major_version >= 1 && (instance->minor_version == 2 && instance->micro_version >= 4))
4122 or instance->minor_version > 2)
4123 {
4124 return TEST_SUCCESS;
4125 }
4126
4127 return TEST_SKIPPED;
4128 }
4129
4130 static test_return_t pre_unix_socket(memcached_st *memc)
4131 {
4132 struct stat buf;
4133
4134 memcached_servers_reset(memc);
4135 const char *socket_file= default_socket();
4136
4137 test_skip(0, stat(socket_file, &buf));
4138
4139 test_compare(MEMCACHED_SUCCESS,
4140 memcached_server_add_unix_socket_with_weight(memc, socket_file, 0));
4141
4142 return TEST_SUCCESS;
4143 }
4144
4145 static test_return_t pre_nodelay(memcached_st *memc)
4146 {
4147 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
4148 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 0);
4149
4150 return TEST_SUCCESS;
4151 }
4152
4153 static test_return_t pre_settimer(memcached_st *memc)
4154 {
4155 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SND_TIMEOUT, 1000);
4156 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RCV_TIMEOUT, 1000);
4157
4158 return TEST_SUCCESS;
4159 }
4160
4161 static test_return_t poll_timeout(memcached_st *memc)
4162 {
4163 const uint64_t timeout= 100; // Not using, just checking that it sets
4164
4165 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, timeout);
4166
4167
4168 test_compare(timeout, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT));
4169
4170 return TEST_SUCCESS;
4171 }
4172
4173 static test_return_t noreply_test(memcached_st *memc)
4174 {
4175 memcached_return_t ret;
4176 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1);
4177 test_true(ret == MEMCACHED_SUCCESS);
4178 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
4179 test_true(ret == MEMCACHED_SUCCESS);
4180 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, 1);
4181 test_true(ret == MEMCACHED_SUCCESS);
4182 test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NOREPLY) == 1);
4183 test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS) == 1);
4184 test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS) == 1);
4185
4186 for (int count=0; count < 5; ++count)
4187 {
4188 for (size_t x= 0; x < 100; ++x)
4189 {
4190 char key[10];
4191 int check_length= (size_t)snprintf(key, sizeof(key), "%lu", (unsigned long)x);
4192 test_false((size_t)check_length >= sizeof(key) || check_length < 0);
4193
4194 size_t len= (size_t)check_length;
4195
4196 switch (count)
4197 {
4198 case 0:
4199 ret= memcached_add(memc, key, len, key, len, 0, 0);
4200 break;
4201 case 1:
4202 ret= memcached_replace(memc, key, len, key, len, 0, 0);
4203 break;
4204 case 2:
4205 ret= memcached_set(memc, key, len, key, len, 0, 0);
4206 break;
4207 case 3:
4208 ret= memcached_append(memc, key, len, key, len, 0, 0);
4209 break;
4210 case 4:
4211 ret= memcached_prepend(memc, key, len, key, len, 0, 0);
4212 break;
4213 default:
4214 test_true(count);
4215 break;
4216 }
4217 test_true(ret == MEMCACHED_SUCCESS || ret == MEMCACHED_BUFFERED);
4218 }
4219
4220 /*
4221 ** NOTE: Don't ever do this in your code! this is not a supported use of the
4222 ** API and is _ONLY_ done this way to verify that the library works the
4223 ** way it is supposed to do!!!!
4224 */
4225 int no_msg=0;
4226 for (uint32_t x= 0; x < memcached_server_count(memc); ++x)
4227 {
4228 memcached_server_instance_st instance=
4229 memcached_server_instance_by_position(memc, x);
4230 no_msg+=(int)(instance->cursor_active);
4231 }
4232
4233 test_true(no_msg == 0);
4234 test_true(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
4235
4236 /*
4237 ** Now validate that all items was set properly!
4238 */
4239 for (size_t x= 0; x < 100; ++x)
4240 {
4241 char key[10];
4242
4243 int check_length= (size_t)snprintf(key, sizeof(key), "%lu", (unsigned long)x);
4244
4245 test_false((size_t)check_length >= sizeof(key) || check_length < 0);
4246
4247 size_t len= (size_t)check_length;
4248 size_t length;
4249 uint32_t flags;
4250 char* value=memcached_get(memc, key, strlen(key),
4251 &length, &flags, &ret);
4252 test_true(ret == MEMCACHED_SUCCESS && value != NULL);
4253 switch (count)
4254 {
4255 case 0: /* FALLTHROUGH */
4256 case 1: /* FALLTHROUGH */
4257 case 2:
4258 test_true(strncmp(value, key, len) == 0);
4259 test_true(len == length);
4260 break;
4261 case 3:
4262 test_true(length == len * 2);
4263 break;
4264 case 4:
4265 test_true(length == len * 3);
4266 break;
4267 default:
4268 test_true(count);
4269 break;
4270 }
4271 free(value);
4272 }
4273 }
4274
4275 /* Try setting an illegal cas value (should not return an error to
4276 * the caller (because we don't expect a return message from the server)
4277 */
4278 const char* keys[]= {"0"};
4279 size_t lengths[]= {1};
4280 size_t length;
4281 uint32_t flags;
4282 memcached_result_st results_obj;
4283 memcached_result_st *results;
4284 ret= memcached_mget(memc, keys, lengths, 1);
4285 test_true(ret == MEMCACHED_SUCCESS);
4286
4287 results= memcached_result_create(memc, &results_obj);
4288 test_true(results);
4289 results= memcached_fetch_result(memc, &results_obj, &ret);
4290 test_true(results);
4291 test_true(ret == MEMCACHED_SUCCESS);
4292 uint64_t cas= memcached_result_cas(results);
4293 memcached_result_free(&results_obj);
4294
4295 ret= memcached_cas(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0, cas);
4296 test_true(ret == MEMCACHED_SUCCESS);
4297
4298 /*
4299 * The item will have a new cas value, so try to set it again with the old
4300 * value. This should fail!
4301 */
4302 ret= memcached_cas(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0, cas);
4303 test_true(ret == MEMCACHED_SUCCESS);
4304 test_true(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
4305 char* value=memcached_get(memc, keys[0], lengths[0], &length, &flags, &ret);
4306 test_true(ret == MEMCACHED_SUCCESS && value != NULL);
4307 free(value);
4308
4309 return TEST_SUCCESS;
4310 }
4311
4312 static test_return_t analyzer_test(memcached_st *memc)
4313 {
4314 memcached_return_t rc;
4315 memcached_stat_st *memc_stat;
4316 memcached_analysis_st *report;
4317
4318 memc_stat= memcached_stat(memc, NULL, &rc);
4319 test_compare(MEMCACHED_SUCCESS, rc);
4320 test_true(memc_stat);
4321
4322 report= memcached_analyze(memc, memc_stat, &rc);
4323 test_compare(MEMCACHED_SUCCESS, rc);
4324 test_true(report);
4325
4326 free(report);
4327 memcached_stat_free(NULL, memc_stat);
4328
4329 return TEST_SUCCESS;
4330 }
4331
4332 /* Count the objects */
4333
4334 static test_return_t dump_test(memcached_st *memc)
4335 {
4336 /* No support for Binary protocol yet */
4337 test_skip(false, memc->flags.binary_protocol);
4338
4339 test_compare(TEST_SUCCESS, set_test3(memc));
4340
4341 // confirm_key_count() call dump
4342 size_t counter= confirm_key_count(memc);
4343
4344 /* We may have more then 32 if our previous flush has not completed */
4345 test_true(counter >= 32);
4346
4347 return TEST_SUCCESS;
4348 }
4349
4350 struct test_pool_context_st {
4351 memcached_pool_st* pool;
4352 memcached_st* mmc;
4353 };
4354
4355 static void* connection_release(void *arg)
4356 {
4357 test_pool_context_st *resource= static_cast<test_pool_context_st *>(arg);
4358
4359 usleep(250);
4360 // Release all of the memc we are holding
4361 assert(memcached_success(memcached_pool_push(resource->pool, resource->mmc)));
4362 return arg;
4363 }
4364
4365 #define POOL_SIZE 10
4366 static test_return_t connection_pool_test(memcached_st *memc)
4367 {
4368 memcached_pool_st* pool= memcached_pool_create(memc, 5, POOL_SIZE);
4369 test_true(pool != NULL);
4370 memcached_st *mmc[POOL_SIZE];
4371 memcached_return_t rc;
4372
4373 // Fill up our array that we will store the memc that are in the pool
4374 for (size_t x= 0; x < POOL_SIZE; ++x)
4375 {
4376 mmc[x]= memcached_pool_pop(pool, false, &rc);
4377 test_true(mmc[x] != NULL);
4378 test_compare(MEMCACHED_SUCCESS, rc);
4379 }
4380
4381 // All memc should be gone
4382 test_true(memcached_pool_pop(pool, false, &rc) == NULL);
4383 test_compare(MEMCACHED_SUCCESS, rc);
4384
4385 pthread_t tid;
4386 test_pool_context_st item= { pool, mmc[9] };
4387
4388 pthread_create(&tid, NULL, connection_release, &item);
4389 mmc[9]= memcached_pool_pop(pool, true, &rc);
4390 test_compare(MEMCACHED_SUCCESS, rc);
4391 pthread_join(tid, NULL);
4392 test_true(mmc[9]);
4393 const char *key= "key";
4394 size_t keylen= strlen(key);
4395
4396 // verify that I can do ops with all connections
4397 test_compare(MEMCACHED_SUCCESS,
4398 memcached_set(mmc[0], key, keylen, "0", 1, 0, 0));
4399
4400 for (size_t x= 0; x < POOL_SIZE; ++x)
4401 {
4402 uint64_t number_value;
4403 test_compare(MEMCACHED_SUCCESS,
4404 memcached_increment(mmc[x], key, keylen, 1, &number_value));
4405 test_compare(number_value, (x+1));
4406 }
4407
4408 // Release them..
4409 for (size_t x= 0; x < POOL_SIZE; ++x)
4410 {
4411 test_compare(MEMCACHED_SUCCESS, memcached_pool_push(pool, mmc[x]));
4412 }
4413
4414
4415 /* verify that I can set behaviors on the pool when I don't have all
4416 * of the connections in the pool. It should however be enabled
4417 * when I push the item into the pool
4418 */
4419 mmc[0]= memcached_pool_pop(pool, false, &rc);
4420 test_true(mmc[0]);
4421
4422 rc= memcached_pool_behavior_set(pool, MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK, 9999);
4423 test_compare(MEMCACHED_SUCCESS, rc);
4424
4425 mmc[1]= memcached_pool_pop(pool, false, &rc);
4426 test_true(mmc[1]);
4427
4428 test_compare(UINT64_C(9999), memcached_behavior_get(mmc[1], MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK));
4429 test_compare(MEMCACHED_SUCCESS, memcached_pool_push(pool, mmc[1]));
4430 test_compare(MEMCACHED_SUCCESS, memcached_pool_push(pool, mmc[0]));
4431
4432 mmc[0]= memcached_pool_pop(pool, false, &rc);
4433 test_compare(UINT64_C(9999), memcached_behavior_get(mmc[0], MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK));
4434 test_compare(MEMCACHED_SUCCESS, memcached_pool_push(pool, mmc[0]));
4435
4436 test_true(memcached_pool_destroy(pool) == memc);
4437
4438 return TEST_SUCCESS;
4439 }
4440
4441 static test_return_t util_version_test(memcached_st *memc)
4442 {
4443 bool if_successful= libmemcached_util_version_check(memc, 0, 0, 0);
4444 test_true(if_successful);
4445
4446 if_successful= libmemcached_util_version_check(memc, 9, 9, 9);
4447
4448 // We expect failure
4449 if (if_successful)
4450 {
4451 fprintf(stderr, "\n----------------------------------------------------------------------\n");
4452 fprintf(stderr, "\nDumping Server Information\n\n");
4453 memcached_server_fn callbacks[1];
4454
4455 callbacks[0]= dump_server_information;
4456 memcached_server_cursor(memc, callbacks, (void *)stderr, 1);
4457 fprintf(stderr, "\n----------------------------------------------------------------------\n");
4458 }
4459 test_true(if_successful == false);
4460
4461 memcached_server_instance_st instance=
4462 memcached_server_instance_by_position(memc, 0);
4463
4464 memcached_version(memc);
4465
4466 // We only use one binary when we test, so this should be just fine.
4467 if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->minor_version, instance->micro_version);
4468 test_true(if_successful == true);
4469
4470 if (instance->micro_version > 0)
4471 if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->minor_version, (uint8_t)(instance->micro_version -1));
4472 else if (instance->minor_version > 0)
4473 if_successful= libmemcached_util_version_check(memc, instance->major_version, (uint8_t)(instance->minor_version - 1), instance->micro_version);
4474 else if (instance->major_version > 0)
4475 if_successful= libmemcached_util_version_check(memc, (uint8_t)(instance->major_version -1), instance->minor_version, instance->micro_version);
4476
4477 test_true(if_successful == true);
4478
4479 if (instance->micro_version > 0)
4480 if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->minor_version, (uint8_t)(instance->micro_version +1));
4481 else if (instance->minor_version > 0)
4482 if_successful= libmemcached_util_version_check(memc, instance->major_version, (uint8_t)(instance->minor_version +1), instance->micro_version);
4483 else if (instance->major_version > 0)
4484 if_successful= libmemcached_util_version_check(memc, (uint8_t)(instance->major_version +1), instance->minor_version, instance->micro_version);
4485
4486 test_true(if_successful == false);
4487
4488 return TEST_SUCCESS;
4489 }
4490
4491 static test_return_t getpid_connection_failure_test(memcached_st *memc)
4492 {
4493 memcached_return_t rc;
4494 memcached_server_instance_st instance=
4495 memcached_server_instance_by_position(memc, 0);
4496
4497 // Test both the version that returns a code, and the one that does not.
4498 test_true(libmemcached_util_getpid(memcached_server_name(instance),
4499 memcached_server_port(instance) -1, NULL) == -1);
4500
4501 test_true(libmemcached_util_getpid(memcached_server_name(instance),
4502 memcached_server_port(instance) -1, &rc) == -1);
4503 test_compare_got(MEMCACHED_CONNECTION_FAILURE, rc, memcached_strerror(memc, rc));
4504
4505 return TEST_SUCCESS;
4506 }
4507
4508
4509 static test_return_t getpid_test(memcached_st *memc)
4510 {
4511 memcached_return_t rc;
4512 memcached_server_instance_st instance=
4513 memcached_server_instance_by_position(memc, 0);
4514
4515 // Test both the version that returns a code, and the one that does not.
4516 test_true(libmemcached_util_getpid(memcached_server_name(instance),
4517 memcached_server_port(instance), NULL) > -1);
4518
4519 test_true(libmemcached_util_getpid(memcached_server_name(instance),
4520 memcached_server_port(instance), &rc) > -1);
4521 test_compare(MEMCACHED_SUCCESS, rc);
4522
4523 return TEST_SUCCESS;
4524 }
4525
4526 static test_return_t ping_test(memcached_st *memc)
4527 {
4528 memcached_return_t rc;
4529 memcached_server_instance_st instance=
4530 memcached_server_instance_by_position(memc, 0);
4531
4532 // Test both the version that returns a code, and the one that does not.
4533 test_true(libmemcached_util_ping(memcached_server_name(instance),
4534 memcached_server_port(instance), NULL));
4535
4536 test_true(libmemcached_util_ping(memcached_server_name(instance),
4537 memcached_server_port(instance), &rc));
4538
4539 test_compare(MEMCACHED_SUCCESS, rc);
4540
4541 return TEST_SUCCESS;
4542 }
4543
4544
4545 #if 0
4546 static test_return_t hash_sanity_test (memcached_st *memc)
4547 {
4548 (void)memc;
4549
4550 assert(MEMCACHED_HASH_DEFAULT == MEMCACHED_HASH_DEFAULT);
4551 assert(MEMCACHED_HASH_MD5 == MEMCACHED_HASH_MD5);
4552 assert(MEMCACHED_HASH_CRC == MEMCACHED_HASH_CRC);
4553 assert(MEMCACHED_HASH_FNV1_64 == MEMCACHED_HASH_FNV1_64);
4554 assert(MEMCACHED_HASH_FNV1A_64 == MEMCACHED_HASH_FNV1A_64);
4555 assert(MEMCACHED_HASH_FNV1_32 == MEMCACHED_HASH_FNV1_32);
4556 assert(MEMCACHED_HASH_FNV1A_32 == MEMCACHED_HASH_FNV1A_32);
4557 #ifdef HAVE_HSIEH_HASH
4558 assert(MEMCACHED_HASH_HSIEH == MEMCACHED_HASH_HSIEH);
4559 #endif
4560 assert(MEMCACHED_HASH_MURMUR == MEMCACHED_HASH_MURMUR);
4561 assert(MEMCACHED_HASH_JENKINS == MEMCACHED_HASH_JENKINS);
4562 assert(MEMCACHED_HASH_MAX == MEMCACHED_HASH_MAX);
4563
4564 return TEST_SUCCESS;
4565 }
4566 #endif
4567
4568 static test_return_t hsieh_avaibility_test (memcached_st *memc)
4569 {
4570 memcached_return_t expected_rc= MEMCACHED_INVALID_ARGUMENTS;
4571 #ifdef HAVE_HSIEH_HASH
4572 expected_rc= MEMCACHED_SUCCESS;
4573 #endif
4574 memcached_return_t rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH,
4575 (uint64_t)MEMCACHED_HASH_HSIEH);
4576 test_true(rc == expected_rc);
4577
4578 return TEST_SUCCESS;
4579 }
4580
4581 static test_return_t murmur_avaibility_test (memcached_st *memc)
4582 {
4583 memcached_return_t expected_rc= MEMCACHED_INVALID_ARGUMENTS;
4584 #ifdef HAVE_MURMUR_HASH
4585 expected_rc= MEMCACHED_SUCCESS;
4586 #endif
4587 memcached_return_t rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH,
4588 (uint64_t)MEMCACHED_HASH_MURMUR);
4589 test_true(rc == expected_rc);
4590
4591 return TEST_SUCCESS;
4592 }
4593
4594 static test_return_t one_at_a_time_run (memcached_st *)
4595 {
4596 uint32_t x;
4597 const char **ptr;
4598
4599 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4600 {
4601 uint32_t hash_val;
4602
4603 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_DEFAULT);
4604 test_true(one_at_a_time_values[x] == hash_val);
4605 }
4606
4607 return TEST_SUCCESS;
4608 }
4609
4610 static test_return_t md5_run (memcached_st *)
4611 {
4612 uint32_t x;
4613 const char **ptr;
4614
4615 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4616 {
4617 uint32_t hash_val;
4618
4619 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_MD5);
4620 test_true(md5_values[x] == hash_val);
4621 }
4622
4623 return TEST_SUCCESS;
4624 }
4625
4626 static test_return_t crc_run (memcached_st *)
4627 {
4628 uint32_t x;
4629 const char **ptr;
4630
4631 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4632 {
4633 uint32_t hash_val;
4634
4635 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_CRC);
4636 test_true(crc_values[x] == hash_val);
4637 }
4638
4639 return TEST_SUCCESS;
4640 }
4641
4642 static test_return_t fnv1_64_run (memcached_st *)
4643 {
4644 uint32_t x;
4645 const char **ptr;
4646
4647 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4648 {
4649 uint32_t hash_val;
4650
4651 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1_64);
4652 test_true(fnv1_64_values[x] == hash_val);
4653 }
4654
4655 return TEST_SUCCESS;
4656 }
4657
4658 static test_return_t fnv1a_64_run (memcached_st *)
4659 {
4660 uint32_t x;
4661 const char **ptr;
4662
4663 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4664 {
4665 uint32_t hash_val;
4666
4667 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1A_64);
4668 test_true(fnv1a_64_values[x] == hash_val);
4669 }
4670
4671 return TEST_SUCCESS;
4672 }
4673
4674 static test_return_t fnv1_32_run (memcached_st *)
4675 {
4676 uint32_t x;
4677 const char **ptr;
4678
4679 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4680 {
4681 uint32_t hash_val;
4682
4683 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1_32);
4684 test_true(fnv1_32_values[x] == hash_val);
4685 }
4686
4687 return TEST_SUCCESS;
4688 }
4689
4690 static test_return_t fnv1a_32_run (memcached_st *)
4691 {
4692 uint32_t x;
4693 const char **ptr;
4694
4695 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4696 {
4697 uint32_t hash_val;
4698
4699 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1A_32);
4700 test_true(fnv1a_32_values[x] == hash_val);
4701 }
4702
4703 return TEST_SUCCESS;
4704 }
4705
4706 static test_return_t hsieh_run (memcached_st *)
4707 {
4708 uint32_t x;
4709 const char **ptr;
4710
4711 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4712 {
4713 uint32_t hash_val;
4714
4715 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_HSIEH);
4716 test_true(hsieh_values[x] == hash_val);
4717 }
4718
4719 return TEST_SUCCESS;
4720 }
4721
4722 static test_return_t murmur_run (memcached_st *)
4723 {
4724 #ifdef WORDS_BIGENDIAN
4725 (void)murmur_values;
4726 return TEST_SKIPPED;
4727 #else
4728 uint32_t x;
4729 const char **ptr;
4730
4731 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4732 {
4733 uint32_t hash_val;
4734
4735 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_MURMUR);
4736 test_true(murmur_values[x] == hash_val);
4737 }
4738
4739 return TEST_SUCCESS;
4740 #endif
4741 }
4742
4743 static test_return_t jenkins_run (memcached_st *)
4744 {
4745 uint32_t x;
4746 const char **ptr;
4747
4748 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4749 {
4750 uint32_t hash_val;
4751
4752 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_JENKINS);
4753 test_true(jenkins_values[x] == hash_val);
4754 }
4755
4756 return TEST_SUCCESS;
4757 }
4758
4759 static uint32_t hash_md5_test_function(const char *string, size_t string_length, void *context)
4760 {
4761 (void)context;
4762 return libhashkit_md5(string, string_length);
4763 }
4764
4765 static uint32_t hash_crc_test_function(const char *string, size_t string_length, void *context)
4766 {
4767 (void)context;
4768 return libhashkit_crc32(string, string_length);
4769 }
4770
4771 static test_return_t memcached_get_hashkit_test (memcached_st *)
4772 {
4773 uint32_t x;
4774 const char **ptr;
4775 hashkit_st new_kit;
4776
4777 memcached_st *memc= memcached(test_literal_param("--server=localhost:1 --server=localhost:2 --server=localhost:3 --server=localhost:4 --server=localhost5"));
4778
4779 uint32_t md5_hosts[]= {4U, 1U, 0U, 1U, 4U, 2U, 0U, 3U, 0U, 0U, 3U, 1U, 0U, 0U, 1U, 3U, 0U, 0U, 0U, 3U, 1U, 0U, 4U, 4U, 3U};
4780 uint32_t crc_hosts[]= {2U, 4U, 1U, 0U, 2U, 4U, 4U, 4U, 1U, 2U, 3U, 4U, 3U, 4U, 1U, 3U, 3U, 2U, 0U, 0U, 0U, 1U, 2U, 4U, 0U};
4781
4782 const hashkit_st *kit= memcached_get_hashkit(memc);
4783
4784 hashkit_clone(&new_kit, kit);
4785 test_compare(HASHKIT_SUCCESS, hashkit_set_custom_function(&new_kit, hash_md5_test_function, NULL));
4786
4787 memcached_set_hashkit(memc, &new_kit);
4788
4789 /*
4790 Verify Setting the hash.
4791 */
4792 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4793 {
4794 uint32_t hash_val;
4795
4796 hash_val= hashkit_digest(kit, *ptr, strlen(*ptr));
4797 test_compare_got(md5_values[x], hash_val, *ptr);
4798 }
4799
4800
4801 /*
4802 Now check memcached_st.
4803 */
4804 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4805 {
4806 uint32_t hash_val;
4807
4808 hash_val= memcached_generate_hash(memc, *ptr, strlen(*ptr));
4809 test_compare_got(md5_hosts[x], hash_val, *ptr);
4810 }
4811
4812 test_compare(HASHKIT_SUCCESS, hashkit_set_custom_function(&new_kit, hash_crc_test_function, NULL));
4813
4814 memcached_set_hashkit(memc, &new_kit);
4815
4816 /*
4817 Verify Setting the hash.
4818 */
4819 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4820 {
4821 uint32_t hash_val;
4822
4823 hash_val= hashkit_digest(kit, *ptr, strlen(*ptr));
4824 test_true(crc_values[x] == hash_val);
4825 }
4826
4827 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4828 {
4829 uint32_t hash_val;
4830
4831 hash_val= memcached_generate_hash(memc, *ptr, strlen(*ptr));
4832 test_compare(crc_hosts[x], hash_val);
4833 }
4834
4835 memcached_free(memc);
4836
4837 return TEST_SUCCESS;
4838 }
4839
4840 /*
4841 Test case adapted from John Gorman <johngorman2@gmail.com>
4842
4843 We are testing the error condition when we connect to a server via memcached_get()
4844 but find that the server is not available.
4845 */
4846 static test_return_t memcached_get_MEMCACHED_ERRNO(memcached_st *)
4847 {
4848 const char *key= "MemcachedLives";
4849 size_t len;
4850 uint32_t flags;
4851 memcached_return rc;
4852
4853 // Create a handle.
4854 memcached_st *tl_memc_h= memcached(test_literal_param("--server=localhost:9898 --server=localhost:9899")); // This server should not exist
4855
4856 // See if memcached is reachable.
4857 char *value= memcached_get(tl_memc_h, key, strlen(key), &len, &flags, &rc);
4858
4859 test_false(value);
4860 test_zero(len);
4861 test_true(memcached_failed(rc));
4862
4863 memcached_free(tl_memc_h);
4864
4865 return TEST_SUCCESS;
4866 }
4867
4868 /*
4869 We connect to a server which exists, but search for a key that does not exist.
4870 */
4871 static test_return_t memcached_get_MEMCACHED_NOTFOUND(memcached_st *memc)
4872 {
4873 const char *key= "MemcachedKeyNotEXIST";
4874 size_t len;
4875 uint32_t flags;
4876 memcached_return rc;
4877 char *value;
4878
4879 // See if memcached is reachable.
4880 value= memcached_get(memc, key, strlen(key), &len, &flags, &rc);
4881
4882 test_false(value);
4883 test_zero(len);
4884 test_compare(MEMCACHED_NOTFOUND, rc);
4885
4886 return TEST_SUCCESS;
4887 }
4888
4889 /*
4890 Test case adapted from John Gorman <johngorman2@gmail.com>
4891
4892 We are testing the error condition when we connect to a server via memcached_get_by_key()
4893 but find that the server is not available.
4894 */
4895 static test_return_t memcached_get_by_key_MEMCACHED_ERRNO(memcached_st *memc)
4896 {
4897 (void)memc;
4898 memcached_st *tl_memc_h;
4899 memcached_server_st *servers;
4900
4901 const char *key= "MemcachedLives";
4902 size_t len;
4903 uint32_t flags;
4904 memcached_return rc;
4905 char *value;
4906
4907 // Create a handle.
4908 tl_memc_h= memcached_create(NULL);
4909 servers= memcached_servers_parse("localhost:9898,localhost:9899"); // This server should not exist
4910 memcached_server_push(tl_memc_h, servers);
4911 memcached_server_list_free(servers);
4912
4913 // See if memcached is reachable.
4914 value= memcached_get_by_key(tl_memc_h, key, strlen(key), key, strlen(key), &len, &flags, &rc);
4915
4916 test_false(value);
4917 test_zero(len);
4918 test_true(memcached_failed(rc));
4919
4920 memcached_free(tl_memc_h);
4921
4922 return TEST_SUCCESS;
4923 }
4924
4925 /*
4926 We connect to a server which exists, but search for a key that does not exist.
4927 */
4928 static test_return_t memcached_get_by_key_MEMCACHED_NOTFOUND(memcached_st *memc)
4929 {
4930 const char *key= "MemcachedKeyNotEXIST";
4931 size_t len;
4932 uint32_t flags;
4933 memcached_return rc;
4934 char *value;
4935
4936 // See if memcached is reachable.
4937 value= memcached_get_by_key(memc, key, strlen(key), key, strlen(key), &len, &flags, &rc);
4938
4939 test_false(value);
4940 test_zero(len);
4941 test_compare(MEMCACHED_NOTFOUND, rc);
4942
4943 return TEST_SUCCESS;
4944 }
4945
4946
4947 static test_return_t ketama_compatibility_libmemcached(memcached_st *)
4948 {
4949 memcached_st *memc= memcached_create(NULL);
4950 test_true(memc);
4951
4952 test_compare(MEMCACHED_SUCCESS,
4953 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1));
4954
4955 test_compare(1UL, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED));
4956
4957 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set_distribution(memc, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA));
4958 test_compare(MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA, memcached_behavior_get_distribution(memc));
4959
4960 memcached_server_st *server_pool= memcached_servers_parse("10.0.1.1:11211 600,10.0.1.2:11211 300,10.0.1.3:11211 200,10.0.1.4:11211 350,10.0.1.5:11211 1000,10.0.1.6:11211 800,10.0.1.7:11211 950,10.0.1.8:11211 100");
4961 memcached_server_push(memc, server_pool);
4962
4963 /* verify that the server list was parsed okay. */
4964 test_compare(8U, memcached_server_count(memc));
4965 test_strcmp(server_pool[0].hostname, "10.0.1.1");
4966 test_compare(in_port_t(11211), server_pool[0].port);
4967 test_compare(600U, server_pool[0].weight);
4968 test_strcmp(server_pool[2].hostname, "10.0.1.3");
4969 test_compare(in_port_t(11211), server_pool[2].port);
4970 test_compare(200U, server_pool[2].weight);
4971 test_strcmp(server_pool[7].hostname, "10.0.1.8");
4972 test_compare(in_port_t(11211), server_pool[7].port);
4973 test_compare(100U, server_pool[7].weight);
4974
4975 /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets
4976 * us test the boundary wraparound.
4977 */
4978 test_true(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->ketama.continuum[0].index);
4979
4980 /* verify the standard ketama set. */
4981 for (uint32_t x= 0; x < 99; x++)
4982 {
4983 uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
4984 memcached_server_instance_st instance=
4985 memcached_server_instance_by_position(memc, server_idx);
4986 const char *hostname = memcached_server_name(instance);
4987
4988 test_strcmp(hostname, ketama_test_cases[x].server);
4989 }
4990
4991 memcached_server_list_free(server_pool);
4992 memcached_free(memc);
4993
4994 return TEST_SUCCESS;
4995 }
4996
4997 static test_return_t ketama_compatibility_spymemcached(memcached_st *)
4998 {
4999 memcached_st *memc= memcached_create(NULL);
5000 test_true(memc);
5001
5002 test_compare(MEMCACHED_SUCCESS,
5003 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1));
5004
5005 test_compare(UINT64_C(1), memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED));
5006
5007 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set_distribution(memc, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY));
5008 test_compare(MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY, memcached_behavior_get_distribution(memc));
5009
5010 memcached_server_st *server_pool= memcached_servers_parse("10.0.1.1:11211 600,10.0.1.2:11211 300,10.0.1.3:11211 200,10.0.1.4:11211 350,10.0.1.5:11211 1000,10.0.1.6:11211 800,10.0.1.7:11211 950,10.0.1.8:11211 100");
5011 test_true(server_pool);
5012 memcached_server_push(memc, server_pool);
5013
5014 /* verify that the server list was parsed okay. */
5015 test_compare(8U, memcached_server_count(memc));
5016 test_strcmp(server_pool[0].hostname, "10.0.1.1");
5017 test_compare(in_port_t(11211), server_pool[0].port);
5018 test_compare(600U, server_pool[0].weight);
5019 test_strcmp(server_pool[2].hostname, "10.0.1.3");
5020 test_compare(in_port_t(11211), server_pool[2].port);
5021 test_compare(200U, server_pool[2].weight);
5022 test_strcmp(server_pool[7].hostname, "10.0.1.8");
5023 test_compare(in_port_t(11211), server_pool[7].port);
5024 test_compare(100U, server_pool[7].weight);
5025
5026 /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets
5027 * us test the boundary wraparound.
5028 */
5029 test_true(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->ketama.continuum[0].index);
5030
5031 /* verify the standard ketama set. */
5032 for (uint32_t x= 0; x < 99; x++)
5033 {
5034 uint32_t server_idx= memcached_generate_hash(memc, ketama_test_cases_spy[x].key, strlen(ketama_test_cases_spy[x].key));
5035
5036 memcached_server_instance_st instance=
5037 memcached_server_instance_by_position(memc, server_idx);
5038
5039 const char *hostname= memcached_server_name(instance);
5040
5041 test_strcmp(hostname, ketama_test_cases_spy[x].server);
5042 }
5043
5044 memcached_server_list_free(server_pool);
5045 memcached_free(memc);
5046
5047 return TEST_SUCCESS;
5048 }
5049
5050 static test_return_t regression_bug_434484(memcached_st *memc)
5051 {
5052 test_return_t test_rc;
5053 test_rc= pre_binary(memc);
5054
5055 if (test_rc != TEST_SUCCESS)
5056 return test_rc;
5057
5058 const char *key= "regression_bug_434484";
5059 size_t keylen= strlen(key);
5060
5061 memcached_return_t ret= memcached_append(memc, key, keylen, key, keylen, 0, 0);
5062 test_compare(MEMCACHED_NOTSTORED, ret);
5063
5064 size_t size= 2048 * 1024;
5065 char *data= (char*)calloc(1, size);
5066 test_true(data);
5067 test_compare(MEMCACHED_E2BIG,
5068 memcached_set(memc, key, keylen, data, size, 0, 0));
5069 free(data);
5070
5071 return TEST_SUCCESS;
5072 }
5073
5074 static test_return_t regression_bug_434843(memcached_st *memc)
5075 {
5076 test_return_t test_rc;
5077 test_rc= pre_binary(memc);
5078
5079 if (test_rc != TEST_SUCCESS)
5080 return test_rc;
5081
5082 memcached_return_t rc;
5083 size_t counter= 0;
5084 memcached_execute_fn callbacks[]= { &callback_counter };
5085
5086 /*
5087 * I only want to hit only _one_ server so I know the number of requests I'm
5088 * sending in the pipleine to the server. Let's try to do a multiget of
5089 * 1024 (that should satisfy most users don't you think?). Future versions
5090 * will include a mget_execute function call if you need a higher number.
5091 */
5092 uint32_t number_of_hosts= memcached_server_count(memc);
5093 memc->number_of_hosts= 1;
5094 const size_t max_keys= 1024;
5095 char **keys= (char**)calloc(max_keys, sizeof(char*));
5096 size_t *key_length= (size_t *)calloc(max_keys, sizeof(size_t));
5097
5098 for (size_t x= 0; x < max_keys; ++x)
5099 {
5100 char k[251];
5101
5102 key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%lu", (unsigned long)x);
5103 keys[x]= strdup(k);
5104 test_true(keys[x]);
5105 }
5106
5107 /*
5108 * Run two times.. the first time we should have 100% cache miss,
5109 * and the second time we should have 100% cache hits
5110 */
5111 for (size_t y= 0; y < 2; y++)
5112 {
5113 test_compare(MEMCACHED_SUCCESS,
5114 memcached_mget(memc, (const char**)keys, key_length, max_keys));
5115
5116 test_compare(y ? MEMCACHED_SUCCESS : MEMCACHED_NOTFOUND,
5117 memcached_fetch_execute(memc, callbacks, (void *)&counter, 1));
5118
5119 if (y == 0)
5120 {
5121 /* The first iteration should give me a 100% cache miss. verify that*/
5122 char blob[1024]= { 0 };
5123
5124 test_false(counter);
5125
5126 for (size_t x= 0; x < max_keys; ++x)
5127 {
5128 rc= memcached_add(memc, keys[x], key_length[x],
5129 blob, sizeof(blob), 0, 0);
5130 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5131 }
5132 }
5133 else
5134 {
5135 /* Verify that we received all of the key/value pairs */
5136 test_compare(counter, max_keys);
5137 }
5138 }
5139
5140 /* Release allocated resources */
5141 for (size_t x= 0; x < max_keys; ++x)
5142 {
5143 free(keys[x]);
5144 }
5145 free(keys);
5146 free(key_length);
5147
5148 memc->number_of_hosts= number_of_hosts;
5149
5150 return TEST_SUCCESS;
5151 }
5152
5153 static test_return_t regression_bug_434843_buffered(memcached_st *memc)
5154 {
5155 memcached_return_t rc;
5156 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
5157 test_compare(MEMCACHED_SUCCESS, rc);
5158
5159 return regression_bug_434843(memc);
5160 }
5161
5162 static test_return_t regression_bug_421108(memcached_st *memc)
5163 {
5164 memcached_return_t rc;
5165 memcached_stat_st *memc_stat= memcached_stat(memc, NULL, &rc);
5166 test_compare(MEMCACHED_SUCCESS, rc);
5167
5168 char *bytes_str= memcached_stat_get_value(memc, memc_stat, "bytes", &rc);
5169 test_compare(MEMCACHED_SUCCESS, rc);
5170 test_true(bytes_str);
5171 char *bytes_read_str= memcached_stat_get_value(memc, memc_stat,
5172 "bytes_read", &rc);
5173 test_compare(MEMCACHED_SUCCESS, rc);
5174 test_true(bytes_read_str);
5175
5176 char *bytes_written_str= memcached_stat_get_value(memc, memc_stat,
5177 "bytes_written", &rc);
5178 test_compare(MEMCACHED_SUCCESS, rc);
5179 test_true(bytes_written_str);
5180
5181 unsigned long long bytes= strtoull(bytes_str, 0, 10);
5182 unsigned long long bytes_read= strtoull(bytes_read_str, 0, 10);
5183 unsigned long long bytes_written= strtoull(bytes_written_str, 0, 10);
5184
5185 test_true(bytes != bytes_read);
5186 test_true(bytes != bytes_written);
5187
5188 /* Release allocated resources */
5189 free(bytes_str);
5190 free(bytes_read_str);
5191 free(bytes_written_str);
5192 memcached_stat_free(NULL, memc_stat);
5193
5194 return TEST_SUCCESS;
5195 }
5196
5197 /*
5198 * The test case isn't obvious so I should probably document why
5199 * it works the way it does. Bug 442914 was caused by a bug
5200 * in the logic in memcached_purge (it did not handle the case
5201 * where the number of bytes sent was equal to the watermark).
5202 * In this test case, create messages so that we hit that case
5203 * and then disable noreply mode and issue a new command to
5204 * verify that it isn't stuck. If we change the format for the
5205 * delete command or the watermarks, we need to update this
5206 * test....
5207 */
5208 static test_return_t regression_bug_442914(memcached_st *memc)
5209 {
5210 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1));
5211 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 1);
5212
5213 uint32_t number_of_hosts= memcached_server_count(memc);
5214 memc->number_of_hosts= 1;
5215
5216 char k[250];
5217 size_t len;
5218
5219 for (uint32_t x= 0; x < 250; ++x)
5220 {
5221 len= (size_t)snprintf(k, sizeof(k), "%0250u", x);
5222 memcached_return_t rc= memcached_delete(memc, k, len, 0);
5223 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5224 }
5225
5226 (void)snprintf(k, sizeof(k), "%037u", 251U);
5227 len= strlen(k);
5228
5229 memcached_return_t rc= memcached_delete(memc, k, len, 0);
5230 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5231
5232 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 0));
5233 test_compare(MEMCACHED_NOTFOUND, memcached_delete(memc, k, len, 0));
5234
5235 memc->number_of_hosts= number_of_hosts;
5236
5237 return TEST_SUCCESS;
5238 }
5239
5240 static test_return_t regression_bug_447342(memcached_st *memc)
5241 {
5242 memcached_server_instance_st instance_one;
5243 memcached_server_instance_st instance_two;
5244
5245 if (memcached_server_count(memc) < 3 or pre_replication(memc) != TEST_SUCCESS)
5246 return TEST_SKIPPED;
5247
5248 test_compare(MEMCACHED_SUCCESS,
5249 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 2));
5250
5251 const unsigned int max_keys= 100;
5252 char **keys= (char**)calloc(max_keys, sizeof(char*));
5253 size_t *key_length= (size_t *)calloc(max_keys, sizeof(size_t));
5254
5255 for (unsigned int x= 0; x < max_keys; ++x)
5256 {
5257 char k[251];
5258
5259 key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%lu", (unsigned long)x);
5260 keys[x]= strdup(k);
5261 test_true(keys[x]);
5262 test_compare(MEMCACHED_SUCCESS,
5263 memcached_set(memc, k, key_length[x], k, key_length[x], 0, 0));
5264 }
5265
5266 /*
5267 ** We are using the quiet commands to store the replicas, so we need
5268 ** to ensure that all of them are processed before we can continue.
5269 ** In the test we go directly from storing the object to trying to
5270 ** receive the object from all of the different servers, so we
5271 ** could end up in a race condition (the memcached server hasn't yet
5272 ** processed the quiet command from the replication set when it process
5273 ** the request from the other client (created by the clone)). As a
5274 ** workaround for that we call memcached_quit to send the quit command
5275 ** to the server and wait for the response ;-) If you use the test code
5276 ** as an example for your own code, please note that you shouldn't need
5277 ** to do this ;-)
5278 */
5279 memcached_quit(memc);
5280
5281 /* Verify that all messages are stored, and we didn't stuff too much
5282 * into the servers
5283 */
5284 test_compare(MEMCACHED_SUCCESS,
5285 memcached_mget(memc, (const char* const *)keys, key_length, max_keys));
5286
5287 unsigned int counter= 0;
5288 memcached_execute_fn callbacks[]= { &callback_counter };
5289 test_compare(MEMCACHED_SUCCESS,
5290 memcached_fetch_execute(memc, callbacks, (void *)&counter, 1));
5291
5292 /* Verify that we received all of the key/value pairs */
5293 test_compare(counter, max_keys);
5294
5295 memcached_quit(memc);
5296 /*
5297 * Don't do the following in your code. I am abusing the internal details
5298 * within the library, and this is not a supported interface.
5299 * This is to verify correct behavior in the library. Fake that two servers
5300 * are dead..
5301 */
5302 instance_one= memcached_server_instance_by_position(memc, 0);
5303 instance_two= memcached_server_instance_by_position(memc, 2);
5304 in_port_t port0= instance_one->port;
5305 in_port_t port2= instance_two->port;
5306
5307 ((memcached_server_write_instance_st)instance_one)->port= 0;
5308 ((memcached_server_write_instance_st)instance_two)->port= 0;
5309
5310 test_compare(MEMCACHED_SUCCESS,
5311 memcached_mget(memc, (const char* const *)keys, key_length, max_keys));
5312
5313 counter= 0;
5314 test_compare(MEMCACHED_SUCCESS,
5315 memcached_fetch_execute(memc, callbacks, (void *)&counter, 1));
5316 test_compare(counter, (unsigned int)max_keys);
5317
5318 /* restore the memc handle */
5319 ((memcached_server_write_instance_st)instance_one)->port= port0;
5320 ((memcached_server_write_instance_st)instance_two)->port= port2;
5321
5322 memcached_quit(memc);
5323
5324 /* Remove half of the objects */
5325 for (size_t x= 0; x < max_keys; ++x)
5326 {
5327 if (x & 1)
5328 {
5329 test_compare(MEMCACHED_SUCCESS,
5330 memcached_delete(memc, keys[x], key_length[x], 0));
5331 }
5332 }
5333
5334 memcached_quit(memc);
5335 ((memcached_server_write_instance_st)instance_one)->port= 0;
5336 ((memcached_server_write_instance_st)instance_two)->port= 0;
5337
5338 /* now retry the command, this time we should have cache misses */
5339 test_compare(MEMCACHED_SUCCESS,
5340 memcached_mget(memc, (const char* const *)keys, key_length, max_keys));
5341
5342 counter= 0;
5343 test_compare(MEMCACHED_SUCCESS,
5344 memcached_fetch_execute(memc, callbacks, (void *)&counter, 1));
5345 test_compare(counter, (unsigned int)(max_keys >> 1));
5346
5347 /* Release allocated resources */
5348 for (size_t x= 0; x < max_keys; ++x)
5349 {
5350 free(keys[x]);
5351 }
5352 free(keys);
5353 free(key_length);
5354
5355 /* restore the memc handle */
5356 ((memcached_server_write_instance_st)instance_one)->port= port0;
5357 ((memcached_server_write_instance_st)instance_two)->port= port2;
5358
5359 return TEST_SUCCESS;
5360 }
5361
5362 static test_return_t regression_bug_463297(memcached_st *memc)
5363 {
5364 memcached_st *memc_clone= memcached_clone(NULL, memc);
5365 test_true(memc_clone);
5366 test_true(memcached_version(memc_clone) == MEMCACHED_SUCCESS);
5367
5368 memcached_server_instance_st instance=
5369 memcached_server_instance_by_position(memc_clone, 0);
5370
5371 if (instance->major_version > 1 ||
5372 (instance->major_version == 1 &&
5373 instance->minor_version > 2))
5374 {
5375 /* Binary protocol doesn't support deferred delete */
5376 memcached_st *bin_clone= memcached_clone(NULL, memc);
5377 test_true(bin_clone);
5378 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(bin_clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1));
5379 test_compare(MEMCACHED_INVALID_ARGUMENTS, memcached_delete(bin_clone, "foo", 3, 1));
5380 memcached_free(bin_clone);
5381
5382 memcached_quit(memc_clone);
5383
5384 /* If we know the server version, deferred delete should fail
5385 * with invalid arguments */
5386 test_compare(MEMCACHED_INVALID_ARGUMENTS, memcached_delete(memc_clone, "foo", 3, 1));
5387
5388 /* If we don't know the server version, we should get a protocol error */
5389 memcached_return_t rc= memcached_delete(memc, "foo", 3, 1);
5390
5391 /* but there is a bug in some of the memcached servers (1.4) that treats
5392 * the counter as noreply so it doesn't send the proper error message
5393 */
5394 test_true_got(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR || rc == MEMCACHED_INVALID_ARGUMENTS, memcached_strerror(NULL, rc));
5395
5396 /* And buffered mode should be disabled and we should get protocol error */
5397 test_true(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1) == MEMCACHED_SUCCESS);
5398 rc= memcached_delete(memc, "foo", 3, 1);
5399 test_true_got(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR || rc == MEMCACHED_INVALID_ARGUMENTS, memcached_strerror(NULL, rc));
5400
5401 /* Same goes for noreply... */
5402 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1));
5403 rc= memcached_delete(memc, "foo", 3, 1);
5404 test_true_got(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR || rc == MEMCACHED_INVALID_ARGUMENTS, memcached_strerror(NULL, rc));
5405
5406 /* but a normal request should go through (and be buffered) */
5407 test_compare(MEMCACHED_BUFFERED, (rc= memcached_delete(memc, "foo", 3, 0)));
5408 test_compare(MEMCACHED_SUCCESS, memcached_flush_buffers(memc));
5409
5410 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 0));
5411 /* unbuffered noreply should be success */
5412 test_compare(MEMCACHED_SUCCESS, memcached_delete(memc, "foo", 3, 0));
5413 /* unbuffered with reply should be not found... */
5414 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 0));
5415 test_compare(MEMCACHED_NOTFOUND, memcached_delete(memc, "foo", 3, 0));
5416 }
5417
5418 memcached_free(memc_clone);
5419 return TEST_SUCCESS;
5420 }
5421
5422
5423 /* Test memcached_server_get_last_disconnect
5424 * For a working server set, shall be NULL
5425 * For a set of non existing server, shall not be NULL
5426 */
5427 static test_return_t test_get_last_disconnect(memcached_st *memc)
5428 {
5429 memcached_return_t rc;
5430 memcached_server_instance_st disconnected_server;
5431
5432 /* With the working set of server */
5433 const char *key= "marmotte";
5434 const char *value= "milka";
5435
5436 memcached_reset_last_disconnected_server(memc);
5437 test_false(memc->last_disconnected_server);
5438 rc= memcached_set(memc, key, strlen(key),
5439 value, strlen(value),
5440 (time_t)0, (uint32_t)0);
5441 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5442
5443 disconnected_server = memcached_server_get_last_disconnect(memc);
5444 test_false(disconnected_server);
5445
5446 /* With a non existing server */
5447 memcached_st *mine;
5448 memcached_server_st *servers;
5449
5450 const char *server_list= "localhost:9";
5451
5452 servers= memcached_servers_parse(server_list);
5453 test_true(servers);
5454 mine= memcached_create(NULL);
5455 rc= memcached_server_push(mine, servers);
5456 test_compare(MEMCACHED_SUCCESS, rc);
5457 memcached_server_list_free(servers);
5458 test_true(mine);
5459
5460 rc= memcached_set(mine, key, strlen(key),
5461 value, strlen(value),
5462 (time_t)0, (uint32_t)0);
5463 test_true(memcached_failed(rc));
5464
5465 disconnected_server= memcached_server_get_last_disconnect(mine);
5466 test_true_got(disconnected_server, memcached_strerror(mine, rc));
5467 test_compare(in_port_t(9), memcached_server_port(disconnected_server));
5468 test_false(strncmp(memcached_server_name(disconnected_server),"localhost",9));
5469
5470 memcached_quit(mine);
5471 memcached_free(mine);
5472
5473 return TEST_SUCCESS;
5474 }
5475
5476 static test_return_t test_multiple_get_last_disconnect(memcached_st *)
5477 {
5478 const char *server_string= "--server=localhost:8888 --server=localhost:8889 --server=localhost:8890 --server=localhost:8891 --server=localhost:8892";
5479 char buffer[BUFSIZ];
5480
5481 test_compare(MEMCACHED_SUCCESS,
5482 libmemcached_check_configuration(server_string, strlen(server_string), buffer, sizeof(buffer)));
5483
5484 memcached_st *memc= memcached(server_string, strlen(server_string));
5485 test_true(memc);
5486
5487 // We will just use the error strings as our keys
5488 uint32_t counter= 100;
5489 while (--counter)
5490 {
5491 for (int x= int(MEMCACHED_SUCCESS); x < int(MEMCACHED_MAXIMUM_RETURN); ++x)
5492 {
5493 const char *msg= memcached_strerror(memc, memcached_return_t(x));
5494 memcached_return_t ret= memcached_set(memc, msg, strlen(msg), NULL, 0, (time_t)0, (uint32_t)0);
5495 test_compare_got(MEMCACHED_CONNECTION_FAILURE, ret, memcached_last_error_message(memc));
5496
5497 memcached_server_instance_st disconnected_server= memcached_server_get_last_disconnect(memc);
5498 test_true(disconnected_server);
5499 test_strcmp("localhost", memcached_server_name(disconnected_server));
5500 test_true(memcached_server_port(disconnected_server) >= 8888 and memcached_server_port(disconnected_server) <= 8892);
5501
5502 if (random() % 2)
5503 {
5504 memcached_reset_last_disconnected_server(memc);
5505 }
5506 }
5507 }
5508
5509 memcached_free(memc);
5510
5511 return TEST_SUCCESS;
5512 }
5513
5514 static test_return_t test_verbosity(memcached_st *memc)
5515 {
5516 memcached_verbosity(memc, 3);
5517
5518 return TEST_SUCCESS;
5519 }
5520
5521 static test_return_t test_server_failure(memcached_st *memc)
5522 {
5523 if (memcached_server_count(memc) < 2)
5524 return TEST_SKIPPED;
5525
5526 memcached_server_instance_st instance= memcached_server_instance_by_position(memc, 0);
5527
5528 memcached_st *local_memc= memcached_create(NULL);
5529
5530 memcached_server_add(local_memc, memcached_server_name(instance), memcached_server_port(instance));
5531 memcached_behavior_set(local_memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, 2);
5532
5533 uint32_t server_count= memcached_server_count(local_memc);
5534 test_compare(1U, server_count);
5535
5536 // Disable the server
5537 instance= memcached_server_instance_by_position(local_memc, 0);
5538 ((memcached_server_write_instance_st)instance)->server_failure_counter= 2;
5539
5540 memcached_return_t rc;
5541 test_compare_got(MEMCACHED_SERVER_MARKED_DEAD,
5542 rc= memcached_set(local_memc, "foo", strlen("foo"), NULL, 0, (time_t)0, (uint32_t)0),
5543 memcached_last_error_message(local_memc));
5544
5545 ((memcached_server_write_instance_st)instance)->server_failure_counter= 0;
5546 test_compare(MEMCACHED_SUCCESS,
5547 memcached_set(local_memc, "foo", strlen("foo"), NULL, 0, (time_t)0, (uint32_t)0));
5548 #if 0
5549 memcached_last_error_message(local_memc));
5550 #endif
5551
5552
5553 memcached_free(local_memc);
5554
5555 return TEST_SUCCESS;
5556 }
5557
5558 static test_return_t test_cull_servers(memcached_st *memc)
5559 {
5560 uint32_t count= memcached_server_count(memc);
5561
5562 if (count < 2)
5563 {
5564 return TEST_SKIPPED;
5565 }
5566
5567 // Do not do this in your code, it is not supported.
5568 memc->servers[1].options.is_dead= true;
5569 memc->state.is_time_for_rebuild= true;
5570
5571 uint32_t new_count= memcached_server_count(memc);
5572 test_compare(count, new_count);
5573
5574 #if 0
5575 test_true(count == new_count + 1 );
5576 #endif
5577
5578 return TEST_SUCCESS;
5579 }
5580
5581
5582 static memcached_return_t stat_printer(memcached_server_instance_st server,
5583 const char *key, size_t key_length,
5584 const char *value, size_t value_length,
5585 void *context)
5586 {
5587 (void)server;
5588 (void)context;
5589 (void)key;
5590 (void)key_length;
5591 (void)value;
5592 (void)value_length;
5593
5594 return MEMCACHED_SUCCESS;
5595 }
5596
5597 static test_return_t memcached_stat_execute_test(memcached_st *memc)
5598 {
5599 memcached_return_t rc= memcached_stat_execute(memc, NULL, stat_printer, NULL);
5600 test_compare(MEMCACHED_SUCCESS, rc);
5601
5602 rc= memcached_stat_execute(memc, "slabs", stat_printer, NULL);
5603 test_compare(MEMCACHED_SUCCESS, rc);
5604
5605 rc= memcached_stat_execute(memc, "items", stat_printer, NULL);
5606 test_compare(MEMCACHED_SUCCESS, rc);
5607
5608 rc= memcached_stat_execute(memc, "sizes", stat_printer, NULL);
5609 test_compare(MEMCACHED_SUCCESS, rc);
5610
5611 return TEST_SUCCESS;
5612 }
5613
5614 /*
5615 * This test ensures that the failure counter isn't incremented during
5616 * normal termination of the memcached instance.
5617 */
5618 static test_return_t wrong_failure_counter_test(memcached_st *memc)
5619 {
5620 memcached_return_t rc;
5621 memcached_server_instance_st instance;
5622
5623 /* Set value to force connection to the server */
5624 const char *key= "marmotte";
5625 const char *value= "milka";
5626
5627 /*
5628 * Please note that I'm abusing the internal structures in libmemcached
5629 * in a non-portable way and you shouldn't be doing this. I'm only
5630 * doing this in order to verify that the library works the way it should
5631 */
5632 uint32_t number_of_hosts= memcached_server_count(memc);
5633 memc->number_of_hosts= 1;
5634
5635 /* Ensure that we are connected to the server by setting a value */
5636 rc= memcached_set(memc, key, strlen(key),
5637 value, strlen(value),
5638 (time_t)0, (uint32_t)0);
5639 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5640
5641
5642 instance= memcached_server_instance_by_position(memc, 0);
5643 /* The test is to see that the memcached_quit doesn't increase the
5644 * the server failure conter, so let's ensure that it is zero
5645 * before sending quit
5646 */
5647 ((memcached_server_write_instance_st)instance)->server_failure_counter= 0;
5648
5649 memcached_quit(memc);
5650
5651 /* Verify that it memcached_quit didn't increment the failure counter
5652 * Please note that this isn't bullet proof, because an error could
5653 * occur...
5654 */
5655 test_zero(instance->server_failure_counter);
5656
5657 /* restore the instance */
5658 memc->number_of_hosts= number_of_hosts;
5659
5660 return TEST_SUCCESS;
5661 }
5662
5663 /*
5664 * This tests ensures expected disconnections (for some behavior changes
5665 * for instance) do not wrongly increase failure counter
5666 */
5667 static test_return_t wrong_failure_counter_two_test(memcached_st *memc)
5668 {
5669 memcached_return rc;
5670
5671 memcached_st *memc_clone;
5672 memc_clone= memcached_clone(NULL, memc);
5673 test_true(memc_clone);
5674
5675 /* Set value to force connection to the server */
5676 const char *key= "marmotte";
5677 const char *value= "milka";
5678 char *string = NULL;
5679 size_t string_length;
5680 uint32_t flags;
5681
5682 rc= memcached_set(memc_clone, key, strlen(key),
5683 value, strlen(value),
5684 (time_t)0, (uint32_t)0);
5685 test_true_got(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED, memcached_strerror(NULL, rc));
5686
5687
5688 /* put failure limit to 1 */
5689 test_compare(MEMCACHED_SUCCESS,
5690 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, 1));
5691
5692 /* Put a retry timeout to effectively activate failure_limit effect */
5693 test_compare(MEMCACHED_SUCCESS,
5694 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 1));
5695
5696 /* change behavior that triggers memcached_quit()*/
5697 test_compare(MEMCACHED_SUCCESS,
5698 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_TCP_NODELAY, 1));
5699
5700
5701 /* Check if we still are connected */
5702 string= memcached_get(memc_clone, key, strlen(key),
5703 &string_length, &flags, &rc);
5704
5705 test_compare_got(MEMCACHED_SUCCESS, rc, memcached_strerror(NULL, rc));
5706 test_true(string);
5707 free(string);
5708 memcached_free(memc_clone);
5709
5710 return TEST_SUCCESS;
5711 }
5712
5713
5714
5715
5716 /*
5717 * Test that ensures mget_execute does not end into recursive calls that finally fails
5718 */
5719 static test_return_t regression_bug_490486(memcached_st *memc)
5720 {
5721 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
5722 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 1);
5723 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, 1000);
5724 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, 1);
5725 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 3600);
5726
5727 #ifdef __APPLE__
5728 return TEST_SKIPPED; // My MAC can't handle this test
5729 #endif
5730
5731 /*
5732 * I only want to hit _one_ server so I know the number of requests I'm
5733 * sending in the pipeline.
5734 */
5735 uint32_t number_of_hosts= memc->number_of_hosts;
5736 memc->number_of_hosts= 1;
5737 size_t max_keys= 20480;
5738
5739
5740 char **keys= (char **)calloc(max_keys, sizeof(char*));
5741 size_t *key_length= (size_t *)calloc(max_keys, sizeof(size_t));
5742
5743 /* First add all of the items.. */
5744 char blob[1024]= { 0 };
5745 for (size_t x= 0; x < max_keys; ++x)
5746 {
5747 char k[251];
5748 key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%lu", (unsigned long)x);
5749 keys[x]= strdup(k);
5750 test_true(keys[x]);
5751 memcached_return rc= memcached_set(memc, keys[x], key_length[x], blob, sizeof(blob), 0, 0);
5752 test_true(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED); // MEMCACHED_TIMEOUT <-- hash been observed on OSX
5753 }
5754
5755 {
5756
5757 /* Try to get all of them with a large multiget */
5758 size_t counter= 0;
5759 memcached_execute_function callbacks[]= { &callback_counter };
5760 memcached_return_t rc= memcached_mget_execute(memc, (const char**)keys, key_length,
5761 (size_t)max_keys, callbacks, &counter, 1);
5762 test_compare(MEMCACHED_SUCCESS, rc);
5763
5764 char* the_value= NULL;
5765 char the_key[MEMCACHED_MAX_KEY];
5766 size_t the_key_length;
5767 size_t the_value_length;
5768 uint32_t the_flags;
5769
5770 do {
5771 the_value= memcached_fetch(memc, the_key, &the_key_length, &the_value_length, &the_flags, &rc);
5772
5773 if ((the_value!= NULL) && (rc == MEMCACHED_SUCCESS))
5774 {
5775 ++counter;
5776 free(the_value);
5777 }
5778
5779 } while ( (the_value!= NULL) && (rc == MEMCACHED_SUCCESS));
5780
5781
5782 test_compare(MEMCACHED_END, rc);
5783
5784 /* Verify that we got all of the items */
5785 test_compare(counter, max_keys);
5786 }
5787
5788 /* Release all allocated resources */
5789 for (size_t x= 0; x < max_keys; ++x)
5790 {
5791 free(keys[x]);
5792 }
5793 free(keys);
5794 free(key_length);
5795
5796 memc->number_of_hosts= number_of_hosts;
5797
5798 return TEST_SUCCESS;
5799 }
5800
5801 static test_return_t regression_bug_583031(memcached_st *)
5802 {
5803 memcached_st *memc= memcached_create(NULL);
5804 test_true(memc);
5805 test_compare(MEMCACHED_SUCCESS, memcached_server_add(memc, "10.2.3.4", 11211));
5806
5807 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT, 1000);
5808 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 1000);
5809 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SND_TIMEOUT, 1000);
5810 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RCV_TIMEOUT, 1000);
5811 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, 1000);
5812 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, 3);
5813
5814 memcached_return_t rc;
5815 size_t length;
5816 uint32_t flags;
5817
5818 const char *value= memcached_get(memc, "dsf", 3, &length, &flags, &rc);
5819 test_false(value);
5820 test_zero(length);
5821
5822 test_compare_got(MEMCACHED_TIMEOUT, rc, memcached_strerror(memc, rc));
5823
5824 memcached_free(memc);
5825
5826 return TEST_SUCCESS;
5827 }
5828
5829 static test_return_t regression_bug_581030(memcached_st *)
5830 {
5831 #ifndef DEBUG
5832 memcached_stat_st *local_stat= memcached_stat(NULL, NULL, NULL);
5833 test_false(local_stat);
5834
5835 memcached_stat_free(NULL, NULL);
5836 #endif
5837
5838 return TEST_SUCCESS;
5839 }
5840
5841 #define regression_bug_655423_COUNT 6000
5842 static test_return_t regression_bug_655423(memcached_st *memc)
5843 {
5844 memcached_st *clone= memcached_clone(NULL, memc);
5845 memc= NULL; // Just to make sure it is not used
5846 test_true(clone);
5847 char payload[100];
5848
5849 #ifdef __APPLE__
5850 return TEST_SKIPPED;
5851 #endif
5852
5853 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1));
5854 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(clone, MEMCACHED_BEHAVIOR_SUPPORT_CAS, 1));
5855 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(clone, MEMCACHED_BEHAVIOR_TCP_NODELAY, 1));
5856 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(clone, MEMCACHED_BEHAVIOR_IO_KEY_PREFETCH, 1));
5857
5858 memset(payload, int('x'), sizeof(payload));
5859
5860 for (uint32_t x= 0; x < regression_bug_655423_COUNT; x++)
5861 {
5862 char key[MEMCACHED_MAXIMUM_INTEGER_DISPLAY_LENGTH +1];
5863 snprintf(key, sizeof(key), "%u", x);
5864
5865 test_compare(MEMCACHED_SUCCESS, memcached_set(clone, key, strlen(key), payload, sizeof(payload), 0, 0));
5866 }
5867
5868 for (uint32_t x= 0; x < regression_bug_655423_COUNT; x++)
5869 {
5870 char key[MEMCACHED_MAXIMUM_INTEGER_DISPLAY_LENGTH +1];
5871 snprintf(key, sizeof(key), "%u", x);
5872
5873 size_t value_length;
5874 memcached_return_t rc;
5875 char *value= memcached_get(clone, key, strlen(key), &value_length, NULL, &rc);
5876
5877 if (rc == MEMCACHED_NOTFOUND)
5878 {
5879 test_false(value);
5880 test_zero(value_length);
5881 continue;
5882 }
5883
5884 test_compare(MEMCACHED_SUCCESS, rc);
5885 test_true(value);
5886 test_compare(100UL, value_length);
5887 free(value);
5888 }
5889
5890 char **keys= (char**)calloc(regression_bug_655423_COUNT, sizeof(char*));
5891 size_t *key_length= (size_t *)calloc(regression_bug_655423_COUNT, sizeof(size_t));
5892 for (uint32_t x= 0; x < regression_bug_655423_COUNT; x++)
5893 {
5894 char key[MEMCACHED_MAXIMUM_INTEGER_DISPLAY_LENGTH +1];
5895 snprintf(key, sizeof(key), "%u", x);
5896
5897 keys[x]= strdup(key);
5898 test_true(keys[x]);
5899 key_length[x]= strlen(key);
5900 test_true(key_length[x]);
5901 }
5902
5903 test_compare(MEMCACHED_SUCCESS,
5904 memcached_mget(clone, (const char* const *)keys, key_length, regression_bug_655423_COUNT));
5905
5906 uint32_t count= 0;
5907 memcached_result_st *result= NULL;
5908 while ((result= memcached_fetch_result(clone, result, NULL)))
5909 {
5910 test_compare(size_t(100), memcached_result_length(result));
5911 count++;
5912 }
5913
5914 test_true(count > 100); // If we don't get back atleast this, something is up
5915
5916 /* Release all allocated resources */
5917 for (size_t x= 0; x < regression_bug_655423_COUNT; ++x)
5918 {
5919 free(keys[x]);
5920 }
5921 free(keys);
5922 free(key_length);
5923
5924
5925 memcached_free(clone);
5926
5927 return TEST_SUCCESS;
5928 }
5929
5930 /*
5931 * Test that ensures that buffered set to not trigger problems during io_flush
5932 */
5933 #define regression_bug_490520_COUNT 200480
5934 static test_return_t regression_bug_490520(memcached_st *memc)
5935 {
5936 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK,1);
5937 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS,1);
5938 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, 1000);
5939 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT,1);
5940 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 3600);
5941
5942 memc->number_of_hosts= 1;
5943
5944 char **keys= (char **)calloc(regression_bug_490520_COUNT, sizeof(char*));
5945 size_t *key_length= (size_t *)calloc(regression_bug_490520_COUNT, sizeof(size_t));
5946
5947 /* First add all of the items.. */
5948 char blob[3333] = {0};
5949 for (uint32_t x= 0; x < regression_bug_490520_COUNT; ++x)
5950 {
5951 char k[251];
5952 key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%u", x);
5953 keys[x]= strdup(k);
5954 test_true(keys[x]);
5955
5956 memcached_return rc= memcached_set(memc, keys[x], key_length[x], blob, sizeof(blob), 0, 0);
5957 test_true(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED);
5958 }
5959
5960 for (uint32_t x= 0; x < regression_bug_490520_COUNT; ++x)
5961 {
5962 free(keys[x]);
5963 }
5964 free(keys);
5965 free(key_length);
5966
5967 return TEST_SUCCESS;
5968 }
5969
5970 static void memcached_die(memcached_st* mc, memcached_return error, const char* what, uint32_t it)
5971 {
5972 fprintf(stderr, "Iteration #%u: ", it);
5973
5974 if(error == MEMCACHED_ERRNO)
5975 {
5976 fprintf(stderr, "system error %d from %s: %s\n",
5977 errno, what, strerror(errno));
5978 }
5979 else
5980 {
5981 fprintf(stderr, "error %d from %s: %s\n", error, what,
5982 memcached_strerror(mc, error));
5983 }
5984 }
5985
5986 #define TEST_CONSTANT_CREATION 200
5987
5988 static test_return_t regression_bug_(memcached_st *memc)
5989 {
5990 const char *remote_server;
5991 (void)memc;
5992
5993 if (! (remote_server= getenv("LIBMEMCACHED_REMOTE_SERVER")))
5994 {
5995 return TEST_SKIPPED;
5996 }
5997
5998 for (uint32_t x= 0; x < TEST_CONSTANT_CREATION; x++)
5999 {
6000 memcached_st* mc= memcached_create(NULL);
6001 memcached_return rc;
6002
6003 rc= memcached_behavior_set(mc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
6004 if (rc != MEMCACHED_SUCCESS)
6005 {
6006 memcached_die(mc, rc, "memcached_behavior_set", x);
6007 }
6008
6009 rc= memcached_behavior_set(mc, MEMCACHED_BEHAVIOR_CACHE_LOOKUPS, 1);
6010 if (rc != MEMCACHED_SUCCESS)
6011 {
6012 memcached_die(mc, rc, "memcached_behavior_set", x);
6013 }
6014
6015 rc= memcached_server_add(mc, remote_server, 0);
6016 if (rc != MEMCACHED_SUCCESS)
6017 {
6018 memcached_die(mc, rc, "memcached_server_add", x);
6019 }
6020
6021 const char *set_key= "akey";
6022 const size_t set_key_len= strlen(set_key);
6023 const char *set_value= "a value";
6024 const size_t set_value_len= strlen(set_value);
6025
6026 if (rc == MEMCACHED_SUCCESS)
6027 {
6028 if (x > 0)
6029 {
6030 size_t get_value_len;
6031 char *get_value;
6032 uint32_t get_value_flags;
6033
6034 get_value= memcached_get(mc, set_key, set_key_len, &get_value_len,
6035 &get_value_flags, &rc);
6036 if (rc != MEMCACHED_SUCCESS)
6037 {
6038 memcached_die(mc, rc, "memcached_get", x);
6039 }
6040 else
6041 {
6042
6043 if (x != 0 &&
6044 (get_value_len != set_value_len
6045 || 0!=strncmp(get_value, set_value, get_value_len)))
6046 {
6047 fprintf(stderr, "Values don't match?\n");
6048 rc= MEMCACHED_FAILURE;
6049 }
6050 free(get_value);
6051 }
6052 }
6053
6054 rc= memcached_set(mc,
6055 set_key, set_key_len,
6056 set_value, set_value_len,
6057 0, /* time */
6058 0 /* flags */
6059 );
6060 if (rc != MEMCACHED_SUCCESS)
6061 {
6062 memcached_die(mc, rc, "memcached_set", x);
6063 }
6064 }
6065
6066 memcached_quit(mc);
6067 memcached_free(mc);
6068
6069 if (rc != MEMCACHED_SUCCESS)
6070 {
6071 break;
6072 }
6073 }
6074
6075 return TEST_SUCCESS;
6076 }
6077
6078 /*
6079 * Test that the sasl authentication works. We cannot use the default
6080 * pool of servers, because that would require that all servers we want
6081 * to test supports SASL authentication, and that they use the default
6082 * creds.
6083 */
6084 static test_return_t sasl_auth_test(memcached_st *memc)
6085 {
6086 #ifdef LIBMEMCACHED_WITH_SASL_SUPPORT
6087 test_compare(MEMCACHED_SUCCESS, memcached_set(memc, "foo", 3, "bar", 3, (time_t)0, (uint32_t)0));
6088 test_compare(MEMCACHED_SUCCESS, memcached_delete(memc, "foo", 3, 0));
6089 test_compare(MEMCACHED_SUCCESS, memcached_destroy_sasl_auth_data(memc));
6090 test_compare(MEMCACHED_FAILURE, memcached_destroy_sasl_auth_data(memc));
6091 test_compare(MEMCACHED_FAILURE, memcached_destroy_sasl_auth_data(NULL));
6092 memcached_quit(memc);
6093
6094 test_compare(MEMCACHED_SUCCESS,
6095 memcached_set_sasl_auth_data(memc,
6096 getenv("LIBMEMCACHED_TEST_SASL_USERNAME"),
6097 getenv("LIBMEMCACHED_TEST_SASL_SERVER")));
6098
6099 test_compare(MEMCACHED_AUTH_FAILURE,
6100 memcached_set(memc, "foo", 3, "bar", 3, (time_t)0, (uint32_t)0));
6101 test_compare(MEMCACHED_SUCCESS, memcached_destroy_sasl_auth_data(memc));
6102
6103 memcached_quit(memc);
6104 return TEST_SUCCESS;
6105 #else
6106 (void)memc;
6107 return TEST_FAILURE;
6108 #endif
6109 }
6110
6111 /* Clean the server before beginning testing */
6112 test_st tests[] ={
6113 {"util_version", 1, (test_callback_fn*)util_version_test },
6114 {"flush", 0, (test_callback_fn*)flush_test },
6115 {"init", 0, (test_callback_fn*)init_test },
6116 {"allocation", 0, (test_callback_fn*)allocation_test },
6117 {"server_list_null_test", 0, (test_callback_fn*)server_list_null_test},
6118 {"server_unsort", 0, (test_callback_fn*)server_unsort_test},
6119 {"server_sort", 0, (test_callback_fn*)server_sort_test},
6120 {"server_sort2", 0, (test_callback_fn*)server_sort2_test},
6121 {"memcached_server_remove", 0, (test_callback_fn*)memcached_server_remove_test},
6122 {"clone_test", 0, (test_callback_fn*)clone_test },
6123 {"connection_test", 0, (test_callback_fn*)connection_test},
6124 {"callback_test", 0, (test_callback_fn*)callback_test},
6125 {"userdata_test", 0, (test_callback_fn*)userdata_test},
6126 {"error", 0, (test_callback_fn*)error_test },
6127 {"set", 0, (test_callback_fn*)set_test },
6128 {"set2", 0, (test_callback_fn*)set_test2 },
6129 {"set3", 0, (test_callback_fn*)set_test3 },
6130 {"dump", 1, (test_callback_fn*)dump_test},
6131 {"add", 1, (test_callback_fn*)add_test },
6132 {"memcached_fetch_result(MEMCACHED_NOTFOUND)", 1, (test_callback_fn*)memcached_fetch_result_NOT_FOUND },
6133 {"replace", 1, (test_callback_fn*)replace_test },
6134 {"delete", 1, (test_callback_fn*)delete_test },
6135 {"get", 1, (test_callback_fn*)get_test },
6136 {"get2", 0, (test_callback_fn*)get_test2 },
6137 {"get3", 0, (test_callback_fn*)get_test3 },
6138 {"get4", 0, (test_callback_fn*)get_test4 },
6139 {"partial mget", 0, (test_callback_fn*)get_test5 },
6140 {"stats_servername", 0, (test_callback_fn*)stats_servername_test },
6141 {"increment", 0, (test_callback_fn*)increment_test },
6142 {"increment_with_initial", 1, (test_callback_fn*)increment_with_initial_test },
6143 {"decrement", 0, (test_callback_fn*)decrement_test },
6144 {"decrement_with_initial", 1, (test_callback_fn*)decrement_with_initial_test },
6145 {"increment_by_key", 0, (test_callback_fn*)increment_by_key_test },
6146 {"increment_with_initial_by_key", 1, (test_callback_fn*)increment_with_initial_by_key_test },
6147 {"decrement_by_key", 0, (test_callback_fn*)decrement_by_key_test },
6148 {"decrement_with_initial_by_key", 1, (test_callback_fn*)decrement_with_initial_by_key_test },
6149 {"quit", 0, (test_callback_fn*)quit_test },
6150 {"mget", 1, (test_callback_fn*)mget_test },
6151 {"mget_result", 1, (test_callback_fn*)mget_result_test },
6152 {"mget_result_alloc", 1, (test_callback_fn*)mget_result_alloc_test },
6153 {"mget_result_function", 1, (test_callback_fn*)mget_result_function },
6154 {"mget_execute", 1, (test_callback_fn*)mget_execute },
6155 {"mget_end", 0, (test_callback_fn*)mget_end },
6156 {"get_stats", 0, (test_callback_fn*)get_stats },
6157 {"add_host_test", 0, (test_callback_fn*)add_host_test },
6158 {"add_host_test_1", 0, (test_callback_fn*)add_host_test1 },
6159 {"get_stats_keys", 0, (test_callback_fn*)get_stats_keys },
6160 {"version_string_test", 0, (test_callback_fn*)version_string_test},
6161 {"bad_key", 1, (test_callback_fn*)bad_key_test },
6162 {"memcached_server_cursor", 1, (test_callback_fn*)memcached_server_cursor_test },
6163 {"read_through", 1, (test_callback_fn*)read_through },
6164 {"delete_through", 1, (test_callback_fn*)delete_through },
6165 {"noreply", 1, (test_callback_fn*)noreply_test},
6166 {"analyzer", 1, (test_callback_fn*)analyzer_test},
6167 {"connectionpool", 1, (test_callback_fn*)connection_pool_test },
6168 {"memcached_pool_test", 1, (test_callback_fn*)memcached_pool_test },
6169 {"test_get_last_disconnect", 1, (test_callback_fn*)test_get_last_disconnect},
6170 {"verbosity", 1, (test_callback_fn*)test_verbosity},
6171 {"test_server_failure", 1, (test_callback_fn*)test_server_failure},
6172 {"cull_servers", 1, (test_callback_fn*)test_cull_servers},
6173 {"memcached_stat_execute", 1, (test_callback_fn*)memcached_stat_execute_test},
6174 {0, 0, 0}
6175 };
6176
6177 test_st behavior_tests[] ={
6178 {"libmemcached_string_behavior()", 0, (test_callback_fn*)libmemcached_string_behavior_test},
6179 {"libmemcached_string_distribution()", 0, (test_callback_fn*)libmemcached_string_distribution_test},
6180 {"behavior_test", 0, (test_callback_fn*)behavior_test},
6181 {"MEMCACHED_BEHAVIOR_CORK", 0, (test_callback_fn*)MEMCACHED_BEHAVIOR_CORK_test},
6182 {"MEMCACHED_BEHAVIOR_TCP_KEEPALIVE", 0, (test_callback_fn*)MEMCACHED_BEHAVIOR_TCP_KEEPALIVE_test},
6183 {"MEMCACHED_BEHAVIOR_TCP_KEEPIDLE", 0, (test_callback_fn*)MEMCACHED_BEHAVIOR_TCP_KEEPIDLE_test},
6184 {0, 0, 0}
6185 };
6186
6187 test_st libmemcachedutil_tests[] ={
6188 {"libmemcached_util_ping()", 1, (test_callback_fn*)ping_test },
6189 {"libmemcached_util_getpid()", 1, (test_callback_fn*)getpid_test },
6190 {"libmemcached_util_getpid(MEMCACHED_CONNECTION_FAILURE)", 1, (test_callback_fn*)getpid_connection_failure_test },
6191 {0, 0, 0}
6192 };
6193
6194 test_st basic_tests[] ={
6195 {"init", 1, (test_callback_fn*)basic_init_test},
6196 {"clone", 1, (test_callback_fn*)basic_clone_test},
6197 {"reset", 1, (test_callback_fn*)basic_reset_stack_test},
6198 {"reset heap", 1, (test_callback_fn*)basic_reset_heap_test},
6199 {"reset stack clone", 1, (test_callback_fn*)basic_reset_stack_clone_test},
6200 {"reset heap clone", 1, (test_callback_fn*)basic_reset_heap_clone_test},
6201 {0, 0, 0}
6202 };
6203
6204 test_st regression_binary_vs_block[] ={
6205 {"block add", 1, (test_callback_fn*)block_add_regression},
6206 {"binary add", 1, (test_callback_fn*)binary_add_regression},
6207 {0, 0, 0}
6208 };
6209
6210 test_st async_tests[] ={
6211 {"add", 1, (test_callback_fn*)add_wrapper },
6212 {0, 0, 0}
6213 };
6214
6215 test_st string_tests[] ={
6216 {"string static with null", 0, (test_callback_fn*)string_static_null },
6217 {"string alloc with null", 0, (test_callback_fn*)string_alloc_null },
6218 {"string alloc with 1K", 0, (test_callback_fn*)string_alloc_with_size },
6219 {"string alloc with malloc failure", 0, (test_callback_fn*)string_alloc_with_size_toobig },
6220 {"string append", 0, (test_callback_fn*)string_alloc_append },
6221 {"string append failure (too big)", 0, (test_callback_fn*)string_alloc_append_toobig },
6222 {"string_alloc_append_multiple", 0, (test_callback_fn*)string_alloc_append_multiple },
6223 {0, 0, (test_callback_fn*)0}
6224 };
6225
6226 test_st memcached_server_get_last_disconnect_tests[] ={
6227 {"memcached_server_get_last_disconnect()", 0, (test_callback_fn*)test_multiple_get_last_disconnect},
6228 {0, 0, (test_callback_fn*)0}
6229 };
6230
6231
6232 test_st result_tests[] ={
6233 {"result static", 0, (test_callback_fn*)result_static},
6234 {"result alloc", 0, (test_callback_fn*)result_alloc},
6235 {0, 0, (test_callback_fn*)0}
6236 };
6237
6238 test_st version_1_2_3[] ={
6239 {"append", 0, (test_callback_fn*)append_test },
6240 {"prepend", 0, (test_callback_fn*)prepend_test },
6241 {"cas", 0, (test_callback_fn*)cas_test },
6242 {"cas2", 0, (test_callback_fn*)cas2_test },
6243 {"append_binary", 0, (test_callback_fn*)append_binary_test },
6244 {0, 0, (test_callback_fn*)0}
6245 };
6246
6247 test_st haldenbrand_tests[] ={
6248 {"memcached_set", 0, (test_callback_fn*)user_supplied_bug1 },
6249 {"memcached_get()", 0, (test_callback_fn*)user_supplied_bug2 },
6250 {"memcached_mget()", 0, (test_callback_fn*)user_supplied_bug3 },
6251 {0, 0, (test_callback_fn*)0}
6252 };
6253
6254 test_st user_tests[] ={
6255 {"user_supplied_bug4", true, (test_callback_fn*)user_supplied_bug4 },
6256 {"user_supplied_bug5", 1, (test_callback_fn*)user_supplied_bug5 },
6257 {"user_supplied_bug6", 1, (test_callback_fn*)user_supplied_bug6 },
6258 {"user_supplied_bug7", 1, (test_callback_fn*)user_supplied_bug7 },
6259 {"user_supplied_bug8", 1, (test_callback_fn*)user_supplied_bug8 },
6260 {"user_supplied_bug9", 1, (test_callback_fn*)user_supplied_bug9 },
6261 {"user_supplied_bug10", 1, (test_callback_fn*)user_supplied_bug10 },
6262 {"user_supplied_bug11", 1, (test_callback_fn*)user_supplied_bug11 },
6263 {"user_supplied_bug12", 1, (test_callback_fn*)user_supplied_bug12 },
6264 {"user_supplied_bug13", 1, (test_callback_fn*)user_supplied_bug13 },
6265 {"user_supplied_bug14", 1, (test_callback_fn*)user_supplied_bug14 },
6266 {"user_supplied_bug15", 1, (test_callback_fn*)user_supplied_bug15 },
6267 {"user_supplied_bug16", 1, (test_callback_fn*)user_supplied_bug16 },
6268 #if !defined(__sun) && !defined(__OpenBSD__)
6269 /*
6270 ** It seems to be something weird with the character sets..
6271 ** value_fetch is unable to parse the value line (iscntrl "fails"), so I
6272 ** guess I need to find out how this is supposed to work.. Perhaps I need
6273 ** to run the test in a specific locale (I tried zh_CN.UTF-8 without success,
6274 ** so just disable the code for now...).
6275 */
6276 {"user_supplied_bug17", 1, (test_callback_fn*)user_supplied_bug17 },
6277 #endif
6278 {"user_supplied_bug18", 1, (test_callback_fn*)user_supplied_bug18 },
6279 {"user_supplied_bug19", 1, (test_callback_fn*)user_supplied_bug19 },
6280 {"user_supplied_bug20", 1, (test_callback_fn*)user_supplied_bug20 },
6281 {"user_supplied_bug21", 1, (test_callback_fn*)user_supplied_bug21 },
6282 {"wrong_failure_counter_test", 1, (test_callback_fn*)wrong_failure_counter_test},
6283 {"wrong_failure_counter_two_test", 1, (test_callback_fn*)wrong_failure_counter_two_test},
6284 {0, 0, (test_callback_fn*)0}
6285 };
6286
6287 test_st replication_tests[]= {
6288 {"set", 1, (test_callback_fn*)replication_set_test },
6289 {"get", 0, (test_callback_fn*)replication_get_test },
6290 {"mget", 0, (test_callback_fn*)replication_mget_test },
6291 {"delete", true, (test_callback_fn*)replication_delete_test },
6292 {"rand_mget", 0, (test_callback_fn*)replication_randomize_mget_test },
6293 {"fail", 0, (test_callback_fn*)replication_randomize_mget_fail_test },
6294 {0, 0, (test_callback_fn*)0}
6295 };
6296
6297 /*
6298 * The following test suite is used to verify that we don't introduce
6299 * regression bugs. If you want more information about the bug / test,
6300 * you should look in the bug report at
6301 * http://bugs.launchpad.net/libmemcached
6302 */
6303 test_st regression_tests[]= {
6304 {"lp:434484", 1, (test_callback_fn*)regression_bug_434484 },
6305 {"lp:434843", 1, (test_callback_fn*)regression_bug_434843 },
6306 {"lp:434843-buffered", 1, (test_callback_fn*)regression_bug_434843_buffered },
6307 {"lp:421108", 1, (test_callback_fn*)regression_bug_421108 },
6308 {"lp:442914", 1, (test_callback_fn*)regression_bug_442914 },
6309 {"lp:447342", 1, (test_callback_fn*)regression_bug_447342 },
6310 {"lp:463297", 1, (test_callback_fn*)regression_bug_463297 },
6311 {"lp:490486", 1, (test_callback_fn*)regression_bug_490486 },
6312 {"lp:583031", 1, (test_callback_fn*)regression_bug_583031 },
6313 {"lp:?", 1, (test_callback_fn*)regression_bug_ },
6314 {"lp:728286", 1, (test_callback_fn*)regression_bug_728286 },
6315 {"lp:581030", 1, (test_callback_fn*)regression_bug_581030 },
6316 {"lp:71231153 connect()", 1, (test_callback_fn*)regression_bug_71231153_connect },
6317 {"lp:71231153 poll()", 1, (test_callback_fn*)regression_bug_71231153_poll },
6318 {"lp:655423", 1, (test_callback_fn*)regression_bug_655423 },
6319 {"lp:490520", 1, (test_callback_fn*)regression_bug_490520 },
6320 {0, 0, (test_callback_fn*)0}
6321 };
6322
6323 test_st sasl_auth_tests[]= {
6324 {"sasl_auth", 1, (test_callback_fn*)sasl_auth_test },
6325 {0, 0, (test_callback_fn*)0}
6326 };
6327
6328 test_st ketama_compatibility[]= {
6329 {"libmemcached", 1, (test_callback_fn*)ketama_compatibility_libmemcached },
6330 {"spymemcached", 1, (test_callback_fn*)ketama_compatibility_spymemcached },
6331 {0, 0, (test_callback_fn*)0}
6332 };
6333
6334 test_st generate_tests[] ={
6335 {"generate_pairs", 1, (test_callback_fn*)generate_pairs },
6336 {"generate_data", 1, (test_callback_fn*)generate_data },
6337 {"get_read", 0, (test_callback_fn*)get_read },
6338 {"delete_generate", 0, (test_callback_fn*)delete_generate },
6339 {"generate_buffer_data", 1, (test_callback_fn*)generate_buffer_data },
6340 {"delete_buffer", 0, (test_callback_fn*)delete_buffer_generate},
6341 {"generate_data", 1, (test_callback_fn*)generate_data },
6342 {"mget_read", 0, (test_callback_fn*)mget_read },
6343 {"mget_read_result", 0, (test_callback_fn*)mget_read_result },
6344 {"memcached_fetch_result() use internal result", 0, (test_callback_fn*)mget_read_internal_result },
6345 {"memcached_fetch_result() partial read", 0, (test_callback_fn*)mget_read_partial_result },
6346 {"mget_read_function", 0, (test_callback_fn*)mget_read_function },
6347 {"cleanup", 1, (test_callback_fn*)cleanup_pairs },
6348 {"generate_large_pairs", 1, (test_callback_fn*)generate_large_pairs },
6349 {"generate_data", 1, (test_callback_fn*)generate_data },
6350 {"generate_buffer_data", 1, (test_callback_fn*)generate_buffer_data },
6351 {"cleanup", 1, (test_callback_fn*)cleanup_pairs },
6352 {0, 0, (test_callback_fn*)0}
6353 };
6354
6355 test_st consistent_tests[] ={
6356 {"generate_pairs", 1, (test_callback_fn*)generate_pairs },
6357 {"generate_data", 1, (test_callback_fn*)generate_data },
6358 {"get_read", 0, (test_callback_fn*)get_read_count },
6359 {"cleanup", 1, (test_callback_fn*)cleanup_pairs },
6360 {0, 0, (test_callback_fn*)0}
6361 };
6362
6363 test_st consistent_weighted_tests[] ={
6364 {"generate_pairs", 1, (test_callback_fn*)generate_pairs },
6365 {"generate_data", 1, (test_callback_fn*)generate_data_with_stats },
6366 {"get_read", 0, (test_callback_fn*)get_read_count },
6367 {"cleanup", 1, (test_callback_fn*)cleanup_pairs },
6368 {0, 0, (test_callback_fn*)0}
6369 };
6370
6371 test_st hsieh_availability[] ={
6372 {"hsieh_avaibility_test", 0, (test_callback_fn*)hsieh_avaibility_test},
6373 {0, 0, (test_callback_fn*)0}
6374 };
6375
6376 test_st murmur_availability[] ={
6377 {"murmur_avaibility_test", 0, (test_callback_fn*)murmur_avaibility_test},
6378 {0, 0, (test_callback_fn*)0}
6379 };
6380
6381 #if 0
6382 test_st hash_sanity[] ={
6383 {"hash sanity", 0, (test_callback_fn*)hash_sanity_test},
6384 {0, 0, (test_callback_fn*)0}
6385 };
6386 #endif
6387
6388 test_st ketama_auto_eject_hosts[] ={
6389 {"auto_eject_hosts", 1, (test_callback_fn*)auto_eject_hosts },
6390 {"output_ketama_weighted_keys", 1, (test_callback_fn*)output_ketama_weighted_keys },
6391 {0, 0, (test_callback_fn*)0}
6392 };
6393
6394 test_st hash_tests[] ={
6395 {"one_at_a_time_run", 0, (test_callback_fn*)one_at_a_time_run },
6396 {"md5", 0, (test_callback_fn*)md5_run },
6397 {"crc", 0, (test_callback_fn*)crc_run },
6398 {"fnv1_64", 0, (test_callback_fn*)fnv1_64_run },
6399 {"fnv1a_64", 0, (test_callback_fn*)fnv1a_64_run },
6400 {"fnv1_32", 0, (test_callback_fn*)fnv1_32_run },
6401 {"fnv1a_32", 0, (test_callback_fn*)fnv1a_32_run },
6402 {"hsieh", 0, (test_callback_fn*)hsieh_run },
6403 {"murmur", 0, (test_callback_fn*)murmur_run },
6404 {"jenkis", 0, (test_callback_fn*)jenkins_run },
6405 {"memcached_get_hashkit", 0, (test_callback_fn*)memcached_get_hashkit_test },
6406 {0, 0, (test_callback_fn*)0}
6407 };
6408
6409 test_st error_conditions[] ={
6410 {"memcached_get(MEMCACHED_ERRNO)", 0, (test_callback_fn*)memcached_get_MEMCACHED_ERRNO },
6411 {"memcached_get(MEMCACHED_NOTFOUND)", 0, (test_callback_fn*)memcached_get_MEMCACHED_NOTFOUND },
6412 {"memcached_get_by_key(MEMCACHED_ERRNO)", 0, (test_callback_fn*)memcached_get_by_key_MEMCACHED_ERRNO },
6413 {"memcached_get_by_key(MEMCACHED_NOTFOUND)", 0, (test_callback_fn*)memcached_get_by_key_MEMCACHED_NOTFOUND },
6414 {"memcached_get_by_key(MEMCACHED_NOTFOUND)", 0, (test_callback_fn*)memcached_get_by_key_MEMCACHED_NOTFOUND },
6415 {"memcached_increment(MEMCACHED_NO_SERVERS)", 0, (test_callback_fn*)memcached_increment_MEMCACHED_NO_SERVERS },
6416 {0, 0, (test_callback_fn*)0}
6417 };
6418
6419
6420 test_st parser_tests[] ={
6421 {"behavior", 0, (test_callback_fn*)behavior_parser_test },
6422 {"boolean_options", 0, (test_callback_fn*)parser_boolean_options_test },
6423 {"configure_file", 0, (test_callback_fn*)memcached_create_with_options_with_filename },
6424 {"distribtions", 0, (test_callback_fn*)parser_distribution_test },
6425 {"hash", 0, (test_callback_fn*)parser_hash_test },
6426 {"libmemcached_check_configuration", 0, (test_callback_fn*)libmemcached_check_configuration_test },
6427 {"libmemcached_check_configuration_with_filename", 0, (test_callback_fn*)libmemcached_check_configuration_with_filename_test },
6428 {"number_options", 0, (test_callback_fn*)parser_number_options_test },
6429 {"randomly generated options", 0, (test_callback_fn*)random_statement_build_test },
6430 {"namespace", 0, (test_callback_fn*)parser_key_prefix_test },
6431 {"server", 0, (test_callback_fn*)server_test },
6432 {"bad server strings", 0, (test_callback_fn*)servers_bad_test },
6433 {"server with weights", 0, (test_callback_fn*)server_with_weight_test },
6434 {"parsing servername, port, and weight", 0, (test_callback_fn*)test_hostname_port_weight },
6435 {"--socket=", 0, (test_callback_fn*)test_parse_socket },
6436 {"--namespace=", 0, (test_callback_fn*)test_namespace_keyword },
6437 {0, 0, (test_callback_fn*)0}
6438 };
6439
6440 test_st virtual_bucket_tests[] ={
6441 {"basic", 0, (test_callback_fn*)virtual_back_map },
6442 {0, 0, (test_callback_fn*)0}
6443 };
6444
6445 test_st namespace_tests[] ={
6446 {"basic tests", true, (test_callback_fn*)selection_of_namespace_tests },
6447 {"increment", true, (test_callback_fn*)memcached_increment_namespace },
6448 {0, 0, (test_callback_fn*)0}
6449 };
6450
6451 collection_st collection[] ={
6452 #if 0
6453 {"hash_sanity", 0, 0, hash_sanity},
6454 #endif
6455 {"libmemcachedutil", 0, 0, libmemcachedutil_tests},
6456 {"basic", 0, 0, basic_tests},
6457 {"hsieh_availability", 0, 0, hsieh_availability},
6458 {"murmur_availability", 0, 0, murmur_availability},
6459 {"block", 0, 0, tests},
6460 {"binary", (test_callback_fn*)pre_binary, 0, tests},
6461 {"nonblock", (test_callback_fn*)pre_nonblock, 0, tests},
6462 {"nodelay", (test_callback_fn*)pre_nodelay, 0, tests},
6463 {"settimer", (test_callback_fn*)pre_settimer, 0, tests},
6464 {"md5", (test_callback_fn*)pre_md5, 0, tests},
6465 {"crc", (test_callback_fn*)pre_crc, 0, tests},
6466 {"hsieh", (test_callback_fn*)pre_hsieh, 0, tests},
6467 {"jenkins", (test_callback_fn*)pre_jenkins, 0, tests},
6468 {"fnv1_64", (test_callback_fn*)pre_hash_fnv1_64, 0, tests},
6469 {"fnv1a_64", (test_callback_fn*)pre_hash_fnv1a_64, 0, tests},
6470 {"fnv1_32", (test_callback_fn*)pre_hash_fnv1_32, 0, tests},
6471 {"fnv1a_32", (test_callback_fn*)pre_hash_fnv1a_32, 0, tests},
6472 {"ketama", (test_callback_fn*)pre_behavior_ketama, 0, tests},
6473 {"ketama_auto_eject_hosts", (test_callback_fn*)pre_behavior_ketama, 0, ketama_auto_eject_hosts},
6474 {"unix_socket", (test_callback_fn*)pre_unix_socket, 0, tests},
6475 {"unix_socket_nodelay", (test_callback_fn*)pre_nodelay, 0, tests},
6476 {"poll_timeout", (test_callback_fn*)poll_timeout, 0, tests},
6477 {"gets", (test_callback_fn*)enable_cas, 0, tests},
6478 {"consistent_crc", (test_callback_fn*)enable_consistent_crc, 0, tests},
6479 {"consistent_hsieh", (test_callback_fn*)enable_consistent_hsieh, 0, tests},
6480 #ifdef MEMCACHED_ENABLE_DEPRECATED
6481 {"deprecated_memory_allocators", (test_callback_fn*)deprecated_set_memory_alloc, 0, tests},
6482 #endif
6483 {"memory_allocators", (test_callback_fn*)set_memory_alloc, 0, tests},
6484 {"namespace", (test_callback_fn*)set_namespace, 0, tests},
6485 {"namespace(BINARY)", (test_callback_fn*)set_namespace_and_binary, 0, tests},
6486 {"specific namespace", 0, 0, namespace_tests},
6487 {"specific namespace(BINARY)", (test_callback_fn*)pre_binary, 0, namespace_tests},
6488 {"sasl_auth", (test_callback_fn*)pre_sasl, 0, sasl_auth_tests },
6489 {"sasl", (test_callback_fn*)pre_sasl, 0, tests },
6490 {"version_1_2_3", (test_callback_fn*)check_for_1_2_3, 0, version_1_2_3},
6491 {"string", 0, 0, string_tests},
6492 {"result", 0, 0, result_tests},
6493 {"async", (test_callback_fn*)pre_nonblock, 0, async_tests},
6494 {"async(BINARY)", (test_callback_fn*)pre_nonblock_binary, 0, async_tests},
6495 {"Cal Haldenbrand's tests", 0, 0, haldenbrand_tests},
6496 {"user", 0, 0, user_tests},
6497 {"generate", 0, 0, generate_tests},
6498 {"generate_hsieh", (test_callback_fn*)pre_hsieh, 0, generate_tests},
6499 {"generate_ketama", (test_callback_fn*)pre_behavior_ketama, 0, generate_tests},
6500 {"generate_hsieh_consistent", (test_callback_fn*)enable_consistent_hsieh, 0, generate_tests},
6501 {"generate_md5", (test_callback_fn*)pre_md5, 0, generate_tests},
6502 {"generate_murmur", (test_callback_fn*)pre_murmur, 0, generate_tests},
6503 {"generate_jenkins", (test_callback_fn*)pre_jenkins, 0, generate_tests},
6504 {"generate_nonblock", (test_callback_fn*)pre_nonblock, 0, generate_tests},
6505 // Too slow
6506 {"generate_corked", (test_callback_fn*)pre_cork, 0, generate_tests},
6507 {"generate_corked_and_nonblock", (test_callback_fn*)pre_cork_and_nonblock, 0, generate_tests},
6508 {"consistent_not", 0, 0, consistent_tests},
6509 {"consistent_ketama", (test_callback_fn*)pre_behavior_ketama, 0, consistent_tests},
6510 {"consistent_ketama_weighted", (test_callback_fn*)pre_behavior_ketama_weighted, 0, consistent_weighted_tests},
6511 {"ketama_compat", 0, 0, ketama_compatibility},
6512 {"test_hashes", 0, 0, hash_tests},
6513 {"replication", (test_callback_fn*)pre_replication, 0, replication_tests},
6514 {"replication_noblock", (test_callback_fn*)pre_replication_noblock, 0, replication_tests},
6515 {"regression", 0, 0, regression_tests},
6516 {"behaviors", 0, 0, behavior_tests},
6517 {"regression_binary_vs_block", (test_callback_fn*)key_setup, (test_callback_fn*)key_teardown, regression_binary_vs_block},
6518 {"error_conditions", 0, 0, error_conditions},
6519 {"parser", 0, 0, parser_tests},
6520 {"virtual buckets", 0, 0, virtual_bucket_tests},
6521 {"memcached_server_get_last_disconnect", 0, 0, memcached_server_get_last_disconnect_tests},
6522 {0, 0, 0, 0}
6523 };
6524
6525 #include "tests/libmemcached_world.h"
6526
6527 void get_world(Framework *world)
6528 {
6529 world->collections= collection;
6530
6531 world->_create= (test_callback_create_fn*)world_create;
6532 world->_destroy= (test_callback_destroy_fn*)world_destroy;
6533
6534 world->item._startup= (test_callback_fn*)world_test_startup;
6535 world->item.set_pre((test_callback_fn*)world_pre_run);
6536 world->item.set_flush((test_callback_fn*)world_flush);
6537 world->item.set_post((test_callback_fn*)world_post_run);
6538 world->_on_error= (test_callback_error_fn*)world_on_error;
6539
6540 world->collection_startup= (test_callback_fn*)world_container_startup;
6541 world->collection_shutdown= (test_callback_fn*)world_container_shutdown;
6542
6543 world->set_runner(&defualt_libmemcached_runner);
6544 }