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