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