Merge in additional test for increment with namespace key.
[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_SUCCESS,
3983 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_VERIFY_KEY, 1),
3984 memcached_strerror(NULL, rc));
3985
3986 if (not memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL))
3987 {
3988 strncpy(long_key, "dog cat", sizeof(long_key));
3989 test_compare(MEMCACHED_BAD_KEY_PROVIDED,
3990 memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, long_key));
3991 }
3992 }
3993
3994 return TEST_SUCCESS;
3995 }
3996
3997 static test_return_t set_namespace(memcached_st *memc)
3998 {
3999 memcached_return_t rc;
4000 const char *key= "mine";
4001 char *value;
4002
4003 /* Make sure be default none exists */
4004 value= (char*)memcached_callback_get(memc, MEMCACHED_CALLBACK_NAMESPACE, &rc);
4005 test_compare_got(MEMCACHED_FAILURE, rc, memcached_strerror(NULL, rc));
4006
4007 /* Test a clean set */
4008 test_compare(MEMCACHED_SUCCESS,
4009 memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, (void *)key));
4010
4011 value= (char*)memcached_callback_get(memc, MEMCACHED_CALLBACK_NAMESPACE, &rc);
4012 test_true(value);
4013 test_memcmp(value, key, 4);
4014 test_compare_got(MEMCACHED_SUCCESS, rc, memcached_strerror(NULL, rc));
4015
4016 return TEST_SUCCESS;
4017 }
4018
4019 static test_return_t set_namespace_and_binary(memcached_st *memc)
4020 {
4021 test_return_if(pre_binary(memc));
4022 test_return_if(set_namespace(memc));
4023
4024 return TEST_SUCCESS;
4025 }
4026
4027 #ifdef MEMCACHED_ENABLE_DEPRECATED
4028 static test_return_t deprecated_set_memory_alloc(memcached_st *memc)
4029 {
4030 void *test_ptr= NULL;
4031 void *cb_ptr= NULL;
4032 {
4033 memcached_malloc_fn malloc_cb=
4034 (memcached_malloc_fn)my_malloc;
4035 cb_ptr= *(void **)&malloc_cb;
4036 memcached_return_t rc;
4037
4038 test_compare(MEMCACHED_SUCCESS,
4039 memcached_callback_set(memc, MEMCACHED_CALLBACK_MALLOC_FUNCTION, cb_ptr));
4040 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_MALLOC_FUNCTION, &rc);
4041 test_compare(MEMCACHED_SUCCESS, rc);
4042 test_true(test_ptr == cb_ptr);
4043 }
4044
4045 {
4046 memcached_realloc_fn realloc_cb=
4047 (memcached_realloc_fn)my_realloc;
4048 cb_ptr= *(void **)&realloc_cb;
4049 memcached_return_t rc;
4050
4051 test_compare(MEMCACHED_SUCCESS,
4052 memcached_callback_set(memc, MEMCACHED_CALLBACK_REALLOC_FUNCTION, cb_ptr));
4053 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_REALLOC_FUNCTION, &rc);
4054 test_compare(MEMCACHED_SUCCESS, rc);
4055 test_true(test_ptr == cb_ptr);
4056 }
4057
4058 {
4059 memcached_free_fn free_cb=
4060 (memcached_free_fn)my_free;
4061 cb_ptr= *(void **)&free_cb;
4062 memcached_return_t rc;
4063
4064 test_compare(MEMCACHED_SUCCESS,
4065 memcached_callback_set(memc, MEMCACHED_CALLBACK_FREE_FUNCTION, cb_ptr));
4066 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_FREE_FUNCTION, &rc);
4067 test_compare(MEMCACHED_SUCCESS, rc);
4068 test_true(test_ptr == cb_ptr);
4069 }
4070
4071 return TEST_SUCCESS;
4072 }
4073 #endif
4074
4075
4076 static test_return_t set_memory_alloc(memcached_st *memc)
4077 {
4078 test_compare(MEMCACHED_FAILURE,
4079 memcached_set_memory_allocators(memc, NULL, my_free,
4080 my_realloc, my_calloc, NULL));
4081
4082 test_compare(MEMCACHED_SUCCESS,
4083 memcached_set_memory_allocators(memc, my_malloc, my_free,
4084 my_realloc, my_calloc, NULL));
4085
4086 memcached_malloc_fn mem_malloc;
4087 memcached_free_fn mem_free;
4088 memcached_realloc_fn mem_realloc;
4089 memcached_calloc_fn mem_calloc;
4090 memcached_get_memory_allocators(memc, &mem_malloc, &mem_free,
4091 &mem_realloc, &mem_calloc);
4092
4093 test_true(mem_malloc == my_malloc);
4094 test_true(mem_realloc == my_realloc);
4095 test_true(mem_calloc == my_calloc);
4096 test_true(mem_free == my_free);
4097
4098 return TEST_SUCCESS;
4099 }
4100
4101 static test_return_t enable_consistent_crc(memcached_st *memc)
4102 {
4103 test_return_t rc;
4104 memcached_server_distribution_t value= MEMCACHED_DISTRIBUTION_CONSISTENT;
4105 memcached_hash_t hash;
4106 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, value);
4107 if ((rc= pre_crc(memc)) != TEST_SUCCESS)
4108 return rc;
4109
4110 value= (memcached_server_distribution_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION);
4111 test_true(value == MEMCACHED_DISTRIBUTION_CONSISTENT);
4112
4113 hash= (memcached_hash_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
4114
4115 if (hash != MEMCACHED_HASH_CRC)
4116 return TEST_SKIPPED;
4117
4118 return TEST_SUCCESS;
4119 }
4120
4121 static test_return_t enable_consistent_hsieh(memcached_st *memc)
4122 {
4123 test_return_t rc;
4124 memcached_server_distribution_t value= MEMCACHED_DISTRIBUTION_CONSISTENT;
4125 memcached_hash_t hash;
4126 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, value);
4127 if ((rc= pre_hsieh(memc)) != TEST_SUCCESS)
4128 return rc;
4129
4130 value= (memcached_server_distribution_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION);
4131 test_true(value == MEMCACHED_DISTRIBUTION_CONSISTENT);
4132
4133 hash= (memcached_hash_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
4134
4135 if (hash != MEMCACHED_HASH_HSIEH)
4136 return TEST_SKIPPED;
4137
4138
4139 return TEST_SUCCESS;
4140 }
4141
4142 static test_return_t enable_cas(memcached_st *memc)
4143 {
4144 unsigned int set= 1;
4145
4146 if (libmemcached_util_version_check(memc, 1, 2, 4))
4147 {
4148 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, set);
4149
4150 return TEST_SUCCESS;
4151 }
4152
4153 return TEST_SKIPPED;
4154 }
4155
4156 static test_return_t check_for_1_2_3(memcached_st *memc)
4157 {
4158 memcached_version(memc);
4159
4160 memcached_server_instance_st instance=
4161 memcached_server_instance_by_position(memc, 0);
4162
4163 if ((instance->major_version >= 1 && (instance->minor_version == 2 && instance->micro_version >= 4))
4164 || instance->minor_version > 2)
4165 {
4166 return TEST_SUCCESS;
4167 }
4168
4169 return TEST_SKIPPED;
4170 }
4171
4172 static test_return_t pre_unix_socket(memcached_st *memc)
4173 {
4174 memcached_return_t rc;
4175 struct stat buf;
4176
4177 memcached_servers_reset(memc);
4178
4179 if (stat("/tmp/memcached.socket", &buf))
4180 return TEST_SKIPPED;
4181
4182 rc= memcached_server_add_unix_socket_with_weight(memc, "/tmp/memcached.socket", 0);
4183
4184 return ( rc == MEMCACHED_SUCCESS ? TEST_SUCCESS : TEST_FAILURE );
4185 }
4186
4187 static test_return_t pre_nodelay(memcached_st *memc)
4188 {
4189 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
4190 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 0);
4191
4192 return TEST_SUCCESS;
4193 }
4194
4195 static test_return_t pre_settimer(memcached_st *memc)
4196 {
4197 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SND_TIMEOUT, 1000);
4198 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RCV_TIMEOUT, 1000);
4199
4200 return TEST_SUCCESS;
4201 }
4202
4203 static test_return_t poll_timeout(memcached_st *memc)
4204 {
4205 size_t timeout= 100; // Not using, just checking that it sets
4206
4207 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, timeout);
4208
4209 timeout= (size_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT);
4210
4211 test_compare(100, timeout);
4212
4213 return TEST_SUCCESS;
4214 }
4215
4216 static test_return_t noreply_test(memcached_st *memc)
4217 {
4218 memcached_return_t ret;
4219 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1);
4220 test_true(ret == MEMCACHED_SUCCESS);
4221 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
4222 test_true(ret == MEMCACHED_SUCCESS);
4223 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, 1);
4224 test_true(ret == MEMCACHED_SUCCESS);
4225 test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NOREPLY) == 1);
4226 test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS) == 1);
4227 test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS) == 1);
4228
4229 for (int count=0; count < 5; ++count)
4230 {
4231 for (size_t x= 0; x < 100; ++x)
4232 {
4233 char key[10];
4234 int check_length= (size_t)snprintf(key, sizeof(key), "%lu", (unsigned long)x);
4235 test_false((size_t)check_length >= sizeof(key) || check_length < 0);
4236
4237 size_t len= (size_t)check_length;
4238
4239 switch (count)
4240 {
4241 case 0:
4242 ret= memcached_add(memc, key, len, key, len, 0, 0);
4243 break;
4244 case 1:
4245 ret= memcached_replace(memc, key, len, key, len, 0, 0);
4246 break;
4247 case 2:
4248 ret= memcached_set(memc, key, len, key, len, 0, 0);
4249 break;
4250 case 3:
4251 ret= memcached_append(memc, key, len, key, len, 0, 0);
4252 break;
4253 case 4:
4254 ret= memcached_prepend(memc, key, len, key, len, 0, 0);
4255 break;
4256 default:
4257 test_true(count);
4258 break;
4259 }
4260 test_true(ret == MEMCACHED_SUCCESS || ret == MEMCACHED_BUFFERED);
4261 }
4262
4263 /*
4264 ** NOTE: Don't ever do this in your code! this is not a supported use of the
4265 ** API and is _ONLY_ done this way to verify that the library works the
4266 ** way it is supposed to do!!!!
4267 */
4268 int no_msg=0;
4269 for (uint32_t x= 0; x < memcached_server_count(memc); ++x)
4270 {
4271 memcached_server_instance_st instance=
4272 memcached_server_instance_by_position(memc, x);
4273 no_msg+=(int)(instance->cursor_active);
4274 }
4275
4276 test_true(no_msg == 0);
4277 test_true(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
4278
4279 /*
4280 ** Now validate that all items was set properly!
4281 */
4282 for (size_t x= 0; x < 100; ++x)
4283 {
4284 char key[10];
4285
4286 int check_length= (size_t)snprintf(key, sizeof(key), "%lu", (unsigned long)x);
4287
4288 test_false((size_t)check_length >= sizeof(key) || check_length < 0);
4289
4290 size_t len= (size_t)check_length;
4291 size_t length;
4292 uint32_t flags;
4293 char* value=memcached_get(memc, key, strlen(key),
4294 &length, &flags, &ret);
4295 test_true(ret == MEMCACHED_SUCCESS && value != NULL);
4296 switch (count)
4297 {
4298 case 0: /* FALLTHROUGH */
4299 case 1: /* FALLTHROUGH */
4300 case 2:
4301 test_true(strncmp(value, key, len) == 0);
4302 test_true(len == length);
4303 break;
4304 case 3:
4305 test_true(length == len * 2);
4306 break;
4307 case 4:
4308 test_true(length == len * 3);
4309 break;
4310 default:
4311 test_true(count);
4312 break;
4313 }
4314 free(value);
4315 }
4316 }
4317
4318 /* Try setting an illegal cas value (should not return an error to
4319 * the caller (because we don't expect a return message from the server)
4320 */
4321 const char* keys[]= {"0"};
4322 size_t lengths[]= {1};
4323 size_t length;
4324 uint32_t flags;
4325 memcached_result_st results_obj;
4326 memcached_result_st *results;
4327 ret= memcached_mget(memc, keys, lengths, 1);
4328 test_true(ret == MEMCACHED_SUCCESS);
4329
4330 results= memcached_result_create(memc, &results_obj);
4331 test_true(results);
4332 results= memcached_fetch_result(memc, &results_obj, &ret);
4333 test_true(results);
4334 test_true(ret == MEMCACHED_SUCCESS);
4335 uint64_t cas= memcached_result_cas(results);
4336 memcached_result_free(&results_obj);
4337
4338 ret= memcached_cas(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0, cas);
4339 test_true(ret == MEMCACHED_SUCCESS);
4340
4341 /*
4342 * The item will have a new cas value, so try to set it again with the old
4343 * value. This should fail!
4344 */
4345 ret= memcached_cas(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0, cas);
4346 test_true(ret == MEMCACHED_SUCCESS);
4347 test_true(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
4348 char* value=memcached_get(memc, keys[0], lengths[0], &length, &flags, &ret);
4349 test_true(ret == MEMCACHED_SUCCESS && value != NULL);
4350 free(value);
4351
4352 return TEST_SUCCESS;
4353 }
4354
4355 static test_return_t analyzer_test(memcached_st *memc)
4356 {
4357 memcached_return_t rc;
4358 memcached_stat_st *memc_stat;
4359 memcached_analysis_st *report;
4360
4361 memc_stat= memcached_stat(memc, NULL, &rc);
4362 test_compare(MEMCACHED_SUCCESS, rc);
4363 test_true(memc_stat);
4364
4365 report= memcached_analyze(memc, memc_stat, &rc);
4366 test_compare(MEMCACHED_SUCCESS, rc);
4367 test_true(report);
4368
4369 free(report);
4370 memcached_stat_free(NULL, memc_stat);
4371
4372 return TEST_SUCCESS;
4373 }
4374
4375 /* Count the objects */
4376 static memcached_return_t callback_dump_counter(const memcached_st *ptr,
4377 const char *key,
4378 size_t key_length,
4379 void *context)
4380 {
4381 (void)ptr; (void)key; (void)key_length;
4382 size_t *counter= (size_t *)context;
4383
4384 *counter= *counter + 1;
4385
4386 return MEMCACHED_SUCCESS;
4387 }
4388
4389 static test_return_t dump_test(memcached_st *memc)
4390 {
4391 size_t counter= 0;
4392 memcached_dump_fn callbacks[1];
4393
4394 callbacks[0]= &callback_dump_counter;
4395
4396 /* No support for Binary protocol yet */
4397 test_skip(false, memc->flags.binary_protocol);
4398
4399 test_compare(TEST_SUCCESS, set_test3(memc));
4400
4401 test_compare(MEMCACHED_SUCCESS,
4402 memcached_dump(memc, callbacks, (void *)&counter, 1));
4403
4404 /* We may have more then 32 if our previous flush has not completed */
4405 test_true(counter >= 32);
4406
4407 return TEST_SUCCESS;
4408 }
4409
4410 #ifdef HAVE_LIBMEMCACHEDUTIL
4411
4412 struct test_pool_context_st {
4413 memcached_pool_st* pool;
4414 memcached_st* mmc;
4415 };
4416
4417 static void* connection_release(void *arg)
4418 {
4419 test_pool_context_st *resource= static_cast<test_pool_context_st *>(arg);
4420
4421 usleep(250);
4422 // Release all of the memc we are holding
4423 assert(memcached_success(memcached_pool_push(resource->pool, resource->mmc)));
4424 return arg;
4425 }
4426
4427 #define POOL_SIZE 10
4428 static test_return_t connection_pool_test(memcached_st *memc)
4429 {
4430 memcached_pool_st* pool= memcached_pool_create(memc, 5, POOL_SIZE);
4431 test_true(pool != NULL);
4432 memcached_st *mmc[POOL_SIZE];
4433 memcached_return_t rc;
4434
4435 // Fill up our array that we will store the memc that are in the pool
4436 for (size_t x= 0; x < POOL_SIZE; ++x)
4437 {
4438 mmc[x]= memcached_pool_pop(pool, false, &rc);
4439 test_true(mmc[x] != NULL);
4440 test_compare(MEMCACHED_SUCCESS, rc);
4441 }
4442
4443 // All memc should be gone
4444 test_true(memcached_pool_pop(pool, false, &rc) == NULL);
4445 test_compare(MEMCACHED_SUCCESS, rc);
4446
4447 pthread_t tid;
4448 test_pool_context_st item= { pool, mmc[9] };
4449
4450 pthread_create(&tid, NULL, connection_release, &item);
4451 mmc[9]= memcached_pool_pop(pool, true, &rc);
4452 test_compare(MEMCACHED_SUCCESS, rc);
4453 pthread_join(tid, NULL);
4454 test_true(mmc[9]);
4455 const char *key= "key";
4456 size_t keylen= strlen(key);
4457
4458 // verify that I can do ops with all connections
4459 test_compare(MEMCACHED_SUCCESS,
4460 memcached_set(mmc[0], key, keylen, "0", 1, 0, 0));
4461
4462 for (size_t x= 0; x < POOL_SIZE; ++x)
4463 {
4464 uint64_t number_value;
4465 test_compare(MEMCACHED_SUCCESS,
4466 memcached_increment(mmc[x], key, keylen, 1, &number_value));
4467 test_compare(number_value, (x+1));
4468 }
4469
4470 // Release them..
4471 for (size_t x= 0; x < POOL_SIZE; ++x)
4472 {
4473 test_compare(MEMCACHED_SUCCESS, memcached_pool_push(pool, mmc[x]));
4474 }
4475
4476
4477 /* verify that I can set behaviors on the pool when I don't have all
4478 * of the connections in the pool. It should however be enabled
4479 * when I push the item into the pool
4480 */
4481 mmc[0]= memcached_pool_pop(pool, false, &rc);
4482 test_true(mmc[0]);
4483
4484 rc= memcached_pool_behavior_set(pool, MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK, 9999);
4485 test_compare(MEMCACHED_SUCCESS, rc);
4486
4487 mmc[1]= memcached_pool_pop(pool, false, &rc);
4488 test_true(mmc[1]);
4489
4490 test_compare(9999, memcached_behavior_get(mmc[1], MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK));
4491 test_compare(MEMCACHED_SUCCESS, memcached_pool_push(pool, mmc[1]));
4492 test_compare(MEMCACHED_SUCCESS, memcached_pool_push(pool, mmc[0]));
4493
4494 mmc[0]= memcached_pool_pop(pool, false, &rc);
4495 test_compare(9999, memcached_behavior_get(mmc[0], MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK));
4496 test_compare(MEMCACHED_SUCCESS, memcached_pool_push(pool, mmc[0]));
4497
4498 test_true(memcached_pool_destroy(pool) == memc);
4499
4500 return TEST_SUCCESS;
4501 }
4502
4503 static test_return_t util_version_test(memcached_st *memc)
4504 {
4505 bool if_successful= libmemcached_util_version_check(memc, 0, 0, 0);
4506 test_true(if_successful);
4507
4508 if_successful= libmemcached_util_version_check(memc, 9, 9, 9);
4509
4510 // We expect failure
4511 if (if_successful)
4512 {
4513 fprintf(stderr, "\n----------------------------------------------------------------------\n");
4514 fprintf(stderr, "\nDumping Server Information\n\n");
4515 memcached_server_fn callbacks[1];
4516
4517 callbacks[0]= dump_server_information;
4518 memcached_server_cursor(memc, callbacks, (void *)stderr, 1);
4519 fprintf(stderr, "\n----------------------------------------------------------------------\n");
4520 }
4521 test_true(if_successful == false);
4522
4523 memcached_server_instance_st instance=
4524 memcached_server_instance_by_position(memc, 0);
4525
4526 memcached_version(memc);
4527
4528 // We only use one binary when we test, so this should be just fine.
4529 if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->minor_version, instance->micro_version);
4530 test_true(if_successful == true);
4531
4532 if (instance->micro_version > 0)
4533 if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->minor_version, (uint8_t)(instance->micro_version -1));
4534 else if (instance->minor_version > 0)
4535 if_successful= libmemcached_util_version_check(memc, instance->major_version, (uint8_t)(instance->minor_version - 1), instance->micro_version);
4536 else if (instance->major_version > 0)
4537 if_successful= libmemcached_util_version_check(memc, (uint8_t)(instance->major_version -1), instance->minor_version, instance->micro_version);
4538
4539 test_true(if_successful == true);
4540
4541 if (instance->micro_version > 0)
4542 if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->minor_version, (uint8_t)(instance->micro_version +1));
4543 else if (instance->minor_version > 0)
4544 if_successful= libmemcached_util_version_check(memc, instance->major_version, (uint8_t)(instance->minor_version +1), instance->micro_version);
4545 else if (instance->major_version > 0)
4546 if_successful= libmemcached_util_version_check(memc, (uint8_t)(instance->major_version +1), instance->minor_version, instance->micro_version);
4547
4548 test_true(if_successful == false);
4549
4550 return TEST_SUCCESS;
4551 }
4552
4553 static test_return_t ping_test(memcached_st *memc)
4554 {
4555 memcached_return_t rc;
4556 memcached_server_instance_st instance=
4557 memcached_server_instance_by_position(memc, 0);
4558
4559 // Test both the version that returns a code, and the one that does not.
4560 test_true(libmemcached_util_ping(memcached_server_name(instance),
4561 memcached_server_port(instance), NULL));
4562
4563 test_true(libmemcached_util_ping(memcached_server_name(instance),
4564 memcached_server_port(instance), &rc));
4565
4566 test_compare(MEMCACHED_SUCCESS, rc);
4567
4568 return TEST_SUCCESS;
4569 }
4570 #endif
4571
4572
4573 #if 0
4574 static test_return_t hash_sanity_test (memcached_st *memc)
4575 {
4576 (void)memc;
4577
4578 assert(MEMCACHED_HASH_DEFAULT == MEMCACHED_HASH_DEFAULT);
4579 assert(MEMCACHED_HASH_MD5 == MEMCACHED_HASH_MD5);
4580 assert(MEMCACHED_HASH_CRC == MEMCACHED_HASH_CRC);
4581 assert(MEMCACHED_HASH_FNV1_64 == MEMCACHED_HASH_FNV1_64);
4582 assert(MEMCACHED_HASH_FNV1A_64 == MEMCACHED_HASH_FNV1A_64);
4583 assert(MEMCACHED_HASH_FNV1_32 == MEMCACHED_HASH_FNV1_32);
4584 assert(MEMCACHED_HASH_FNV1A_32 == MEMCACHED_HASH_FNV1A_32);
4585 #ifdef HAVE_HSIEH_HASH
4586 assert(MEMCACHED_HASH_HSIEH == MEMCACHED_HASH_HSIEH);
4587 #endif
4588 assert(MEMCACHED_HASH_MURMUR == MEMCACHED_HASH_MURMUR);
4589 assert(MEMCACHED_HASH_JENKINS == MEMCACHED_HASH_JENKINS);
4590 assert(MEMCACHED_HASH_MAX == MEMCACHED_HASH_MAX);
4591
4592 return TEST_SUCCESS;
4593 }
4594 #endif
4595
4596 static test_return_t hsieh_avaibility_test (memcached_st *memc)
4597 {
4598 memcached_return_t expected_rc= MEMCACHED_INVALID_ARGUMENTS;
4599 #ifdef HAVE_HSIEH_HASH
4600 expected_rc= MEMCACHED_SUCCESS;
4601 #endif
4602 memcached_return_t rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH,
4603 (uint64_t)MEMCACHED_HASH_HSIEH);
4604 test_true(rc == expected_rc);
4605
4606 return TEST_SUCCESS;
4607 }
4608
4609 static test_return_t murmur_avaibility_test (memcached_st *memc)
4610 {
4611 memcached_return_t expected_rc= MEMCACHED_INVALID_ARGUMENTS;
4612 #ifdef HAVE_MURMUR_HASH
4613 expected_rc= MEMCACHED_SUCCESS;
4614 #endif
4615 memcached_return_t rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH,
4616 (uint64_t)MEMCACHED_HASH_MURMUR);
4617 test_true(rc == expected_rc);
4618
4619 return TEST_SUCCESS;
4620 }
4621
4622 static test_return_t one_at_a_time_run (memcached_st *memc)
4623 {
4624 uint32_t x;
4625 const char **ptr;
4626 (void)memc;
4627
4628 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4629 {
4630 uint32_t hash_val;
4631
4632 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_DEFAULT);
4633 test_true(one_at_a_time_values[x] == hash_val);
4634 }
4635
4636 return TEST_SUCCESS;
4637 }
4638
4639 static test_return_t md5_run (memcached_st *memc)
4640 {
4641 uint32_t x;
4642 const char **ptr;
4643 (void)memc;
4644
4645 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4646 {
4647 uint32_t hash_val;
4648
4649 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_MD5);
4650 test_true(md5_values[x] == hash_val);
4651 }
4652
4653 return TEST_SUCCESS;
4654 }
4655
4656 static test_return_t crc_run (memcached_st *memc)
4657 {
4658 uint32_t x;
4659 const char **ptr;
4660 (void)memc;
4661
4662 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4663 {
4664 uint32_t hash_val;
4665
4666 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_CRC);
4667 test_true(crc_values[x] == hash_val);
4668 }
4669
4670 return TEST_SUCCESS;
4671 }
4672
4673 static test_return_t fnv1_64_run (memcached_st *memc)
4674 {
4675 uint32_t x;
4676 const char **ptr;
4677 (void)memc;
4678
4679 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4680 {
4681 uint32_t hash_val;
4682
4683 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1_64);
4684 test_true(fnv1_64_values[x] == hash_val);
4685 }
4686
4687 return TEST_SUCCESS;
4688 }
4689
4690 static test_return_t fnv1a_64_run (memcached_st *memc)
4691 {
4692 uint32_t x;
4693 const char **ptr;
4694 (void)memc;
4695
4696 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4697 {
4698 uint32_t hash_val;
4699
4700 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1A_64);
4701 test_true(fnv1a_64_values[x] == hash_val);
4702 }
4703
4704 return TEST_SUCCESS;
4705 }
4706
4707 static test_return_t fnv1_32_run (memcached_st *memc)
4708 {
4709 uint32_t x;
4710 const char **ptr;
4711 (void)memc;
4712
4713 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4714 {
4715 uint32_t hash_val;
4716
4717 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1_32);
4718 test_true(fnv1_32_values[x] == hash_val);
4719 }
4720
4721 return TEST_SUCCESS;
4722 }
4723
4724 static test_return_t fnv1a_32_run (memcached_st *memc)
4725 {
4726 uint32_t x;
4727 const char **ptr;
4728 (void)memc;
4729
4730 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4731 {
4732 uint32_t hash_val;
4733
4734 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1A_32);
4735 test_true(fnv1a_32_values[x] == hash_val);
4736 }
4737
4738 return TEST_SUCCESS;
4739 }
4740
4741 static test_return_t hsieh_run (memcached_st *memc)
4742 {
4743 uint32_t x;
4744 const char **ptr;
4745 (void)memc;
4746
4747 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4748 {
4749 uint32_t hash_val;
4750
4751 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_HSIEH);
4752 test_true(hsieh_values[x] == hash_val);
4753 }
4754
4755 return TEST_SUCCESS;
4756 }
4757
4758 static test_return_t murmur_run (memcached_st *memc)
4759 {
4760 #ifdef WORDS_BIGENDIAN
4761 (void)murmur_values;
4762 return TEST_SKIPPED;
4763 #else
4764 uint32_t x;
4765 const char **ptr;
4766 (void)memc;
4767
4768 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4769 {
4770 uint32_t hash_val;
4771
4772 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_MURMUR);
4773 test_true(murmur_values[x] == hash_val);
4774 }
4775
4776 return TEST_SUCCESS;
4777 #endif
4778 }
4779
4780 static test_return_t jenkins_run (memcached_st *memc)
4781 {
4782 uint32_t x;
4783 const char **ptr;
4784 (void)memc;
4785
4786 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4787 {
4788 uint32_t hash_val;
4789
4790 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_JENKINS);
4791 test_true(jenkins_values[x] == hash_val);
4792 }
4793
4794 return TEST_SUCCESS;
4795 }
4796
4797 static uint32_t hash_md5_test_function(const char *string, size_t string_length, void *context)
4798 {
4799 (void)context;
4800 return libhashkit_md5(string, string_length);
4801 }
4802
4803 static uint32_t hash_crc_test_function(const char *string, size_t string_length, void *context)
4804 {
4805 (void)context;
4806 return libhashkit_crc32(string, string_length);
4807 }
4808
4809 static test_return_t memcached_get_hashkit_test (memcached_st *memc)
4810 {
4811 uint32_t x;
4812 const char **ptr;
4813 const hashkit_st *kit;
4814 hashkit_st new_kit;
4815 hashkit_return_t hash_rc;
4816
4817 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};
4818 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};
4819
4820 kit= memcached_get_hashkit(memc);
4821
4822 hashkit_clone(&new_kit, kit);
4823 hash_rc= hashkit_set_custom_function(&new_kit, hash_md5_test_function, NULL);
4824 test_true(hash_rc == HASHKIT_SUCCESS);
4825
4826 memcached_set_hashkit(memc, &new_kit);
4827
4828 /*
4829 Verify Setting the hash.
4830 */
4831 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4832 {
4833 uint32_t hash_val;
4834
4835 hash_val= hashkit_digest(kit, *ptr, strlen(*ptr));
4836 test_true(md5_values[x] == hash_val);
4837 }
4838
4839
4840 /*
4841 Now check memcached_st.
4842 */
4843 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4844 {
4845 uint32_t hash_val;
4846
4847 hash_val= memcached_generate_hash(memc, *ptr, strlen(*ptr));
4848 test_true(md5_hosts[x] == hash_val);
4849 }
4850
4851 hash_rc= hashkit_set_custom_function(&new_kit, hash_crc_test_function, NULL);
4852 test_true(hash_rc == HASHKIT_SUCCESS);
4853
4854 memcached_set_hashkit(memc, &new_kit);
4855
4856 /*
4857 Verify Setting the hash.
4858 */
4859 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4860 {
4861 uint32_t hash_val;
4862
4863 hash_val= hashkit_digest(kit, *ptr, strlen(*ptr));
4864 test_true(crc_values[x] == hash_val);
4865 }
4866
4867 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4868 {
4869 uint32_t hash_val;
4870
4871 hash_val= memcached_generate_hash(memc, *ptr, strlen(*ptr));
4872 test_true(crc_hosts[x] == hash_val);
4873 }
4874
4875 return TEST_SUCCESS;
4876 }
4877
4878 /*
4879 Test case adapted from John Gorman <johngorman2@gmail.com>
4880
4881 We are testing the error condition when we connect to a server via memcached_get()
4882 but find that the server is not available.
4883 */
4884 static test_return_t memcached_get_MEMCACHED_ERRNO(memcached_st *memc)
4885 {
4886 (void)memc;
4887 memcached_st *tl_memc_h;
4888
4889 const char *key= "MemcachedLives";
4890 size_t len;
4891 uint32_t flags;
4892 memcached_return rc;
4893 char *value;
4894
4895 // Create a handle.
4896 tl_memc_h= memcached_create(NULL);
4897 memcached_server_st *servers= memcached_servers_parse("localhost:9898,localhost:9899"); // This server should not exist
4898 test_true(servers);
4899 memcached_server_push(tl_memc_h, servers);
4900 memcached_server_list_free(servers);
4901
4902 // See if memcached is reachable.
4903 value= memcached_get(tl_memc_h, key, strlen(key), &len, &flags, &rc);
4904
4905 test_false(value);
4906 test_compare(0, len);
4907 test_true(memcached_failed(rc));
4908
4909 memcached_free(tl_memc_h);
4910
4911 return TEST_SUCCESS;
4912 }
4913
4914 /*
4915 We connect to a server which exists, but search for a key that does not exist.
4916 */
4917 static test_return_t memcached_get_MEMCACHED_NOTFOUND(memcached_st *memc)
4918 {
4919 const char *key= "MemcachedKeyNotEXIST";
4920 size_t len;
4921 uint32_t flags;
4922 memcached_return rc;
4923 char *value;
4924
4925 // See if memcached is reachable.
4926 value= memcached_get(memc, key, strlen(key), &len, &flags, &rc);
4927
4928 test_false(value);
4929 test_compare(0, len);
4930 test_compare(MEMCACHED_NOTFOUND, rc);
4931
4932 return TEST_SUCCESS;
4933 }
4934
4935 /*
4936 Test case adapted from John Gorman <johngorman2@gmail.com>
4937
4938 We are testing the error condition when we connect to a server via memcached_get_by_key()
4939 but find that the server is not available.
4940 */
4941 static test_return_t memcached_get_by_key_MEMCACHED_ERRNO(memcached_st *memc)
4942 {
4943 (void)memc;
4944 memcached_st *tl_memc_h;
4945 memcached_server_st *servers;
4946
4947 const char *key= "MemcachedLives";
4948 size_t len;
4949 uint32_t flags;
4950 memcached_return rc;
4951 char *value;
4952
4953 // Create a handle.
4954 tl_memc_h= memcached_create(NULL);
4955 servers= memcached_servers_parse("localhost:9898,localhost:9899"); // This server should not exist
4956 memcached_server_push(tl_memc_h, servers);
4957 memcached_server_list_free(servers);
4958
4959 // See if memcached is reachable.
4960 value= memcached_get_by_key(tl_memc_h, key, strlen(key), key, strlen(key), &len, &flags, &rc);
4961
4962 test_false(value);
4963 test_compare(0, len);
4964 test_true(memcached_failed(rc));
4965
4966 memcached_free(tl_memc_h);
4967
4968 return TEST_SUCCESS;
4969 }
4970
4971 /*
4972 We connect to a server which exists, but search for a key that does not exist.
4973 */
4974 static test_return_t memcached_get_by_key_MEMCACHED_NOTFOUND(memcached_st *memc)
4975 {
4976 const char *key= "MemcachedKeyNotEXIST";
4977 size_t len;
4978 uint32_t flags;
4979 memcached_return rc;
4980 char *value;
4981
4982 // See if memcached is reachable.
4983 value= memcached_get_by_key(memc, key, strlen(key), key, strlen(key), &len, &flags, &rc);
4984
4985 test_false(value);
4986 test_compare(0, len);
4987 test_compare(MEMCACHED_NOTFOUND, rc);
4988
4989 return TEST_SUCCESS;
4990 }
4991
4992
4993 static test_return_t ketama_compatibility_libmemcached(memcached_st *)
4994 {
4995 memcached_st *memc= memcached_create(NULL);
4996 test_true(memc);
4997
4998 test_compare(MEMCACHED_SUCCESS,
4999 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1));
5000
5001 uint64_t value;
5002 test_compare(1, value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED));
5003
5004 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set_distribution(memc, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA));
5005 test_compare(MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA, memcached_behavior_get_distribution(memc));
5006
5007
5008 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");
5009 memcached_server_push(memc, server_pool);
5010
5011 /* verify that the server list was parsed okay. */
5012 test_compare(8, memcached_server_count(memc));
5013 test_strcmp(server_pool[0].hostname, "10.0.1.1");
5014 test_compare(11211, server_pool[0].port);
5015 test_compare(600, server_pool[0].weight);
5016 test_strcmp(server_pool[2].hostname, "10.0.1.3");
5017 test_compare(11211, server_pool[2].port);
5018 test_compare(200, server_pool[2].weight);
5019 test_strcmp(server_pool[7].hostname, "10.0.1.8");
5020 test_compare(11211, server_pool[7].port);
5021 test_compare(100, server_pool[7].weight);
5022
5023 /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets
5024 * us test the boundary wraparound.
5025 */
5026 test_true(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->ketama.continuum[0].index);
5027
5028 /* verify the standard ketama set. */
5029 for (uint32_t x= 0; x < 99; x++)
5030 {
5031 uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
5032 memcached_server_instance_st instance=
5033 memcached_server_instance_by_position(memc, server_idx);
5034 const char *hostname = memcached_server_name(instance);
5035
5036 test_strcmp(hostname, ketama_test_cases[x].server);
5037 }
5038
5039 memcached_server_list_free(server_pool);
5040 memcached_free(memc);
5041
5042 return TEST_SUCCESS;
5043 }
5044
5045 static test_return_t ketama_compatibility_spymemcached(memcached_st *)
5046 {
5047 uint64_t value;
5048
5049 memcached_st *memc= memcached_create(NULL);
5050 test_true(memc);
5051
5052 test_compare(MEMCACHED_SUCCESS,
5053 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1));
5054
5055 test_compare(1, value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED));
5056
5057 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set_distribution(memc, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY));
5058 test_compare(MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY, memcached_behavior_get_distribution(memc));
5059
5060 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");
5061 test_true(server_pool);
5062 memcached_server_push(memc, server_pool);
5063
5064 /* verify that the server list was parsed okay. */
5065 test_compare(8, memcached_server_count(memc));
5066 test_strcmp(server_pool[0].hostname, "10.0.1.1");
5067 test_compare(11211, server_pool[0].port);
5068 test_compare(600, server_pool[0].weight);
5069 test_strcmp(server_pool[2].hostname, "10.0.1.3");
5070 test_compare(11211, server_pool[2].port);
5071 test_compare(200, server_pool[2].weight);
5072 test_strcmp(server_pool[7].hostname, "10.0.1.8");
5073 test_compare(11211, server_pool[7].port);
5074 test_compare(100, server_pool[7].weight);
5075
5076 /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets
5077 * us test the boundary wraparound.
5078 */
5079 test_true(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->ketama.continuum[0].index);
5080
5081 /* verify the standard ketama set. */
5082 for (uint32_t x= 0; x < 99; x++)
5083 {
5084 uint32_t server_idx= memcached_generate_hash(memc, ketama_test_cases_spy[x].key, strlen(ketama_test_cases_spy[x].key));
5085
5086 memcached_server_instance_st instance=
5087 memcached_server_instance_by_position(memc, server_idx);
5088
5089 const char *hostname= memcached_server_name(instance);
5090
5091 test_strcmp(hostname, ketama_test_cases_spy[x].server);
5092 }
5093
5094 memcached_server_list_free(server_pool);
5095 memcached_free(memc);
5096
5097 return TEST_SUCCESS;
5098 }
5099
5100 static test_return_t regression_bug_434484(memcached_st *memc)
5101 {
5102 test_return_t test_rc;
5103 test_rc= pre_binary(memc);
5104
5105 if (test_rc != TEST_SUCCESS)
5106 return test_rc;
5107
5108 const char *key= "regression_bug_434484";
5109 size_t keylen= strlen(key);
5110
5111 memcached_return_t ret= memcached_append(memc, key, keylen, key, keylen, 0, 0);
5112 test_compare(MEMCACHED_NOTSTORED, ret);
5113
5114 size_t size= 2048 * 1024;
5115 char *data= (char*)calloc(1, size);
5116 test_true(data);
5117 test_compare(MEMCACHED_E2BIG,
5118 memcached_set(memc, key, keylen, data, size, 0, 0));
5119 free(data);
5120
5121 return TEST_SUCCESS;
5122 }
5123
5124 static test_return_t regression_bug_434843(memcached_st *memc)
5125 {
5126 test_return_t test_rc;
5127 test_rc= pre_binary(memc);
5128
5129 if (test_rc != TEST_SUCCESS)
5130 return test_rc;
5131
5132 memcached_return_t rc;
5133 size_t counter= 0;
5134 memcached_execute_fn callbacks[]= { &callback_counter };
5135
5136 /*
5137 * I only want to hit only _one_ server so I know the number of requests I'm
5138 * sending in the pipleine to the server. Let's try to do a multiget of
5139 * 1024 (that should satisfy most users don't you think?). Future versions
5140 * will include a mget_execute function call if you need a higher number.
5141 */
5142 uint32_t number_of_hosts= memcached_server_count(memc);
5143 memc->number_of_hosts= 1;
5144 const size_t max_keys= 1024;
5145 char **keys= (char**)calloc(max_keys, sizeof(char*));
5146 size_t *key_length= (size_t *)calloc(max_keys, sizeof(size_t));
5147
5148 for (size_t x= 0; x < max_keys; ++x)
5149 {
5150 char k[251];
5151
5152 key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%lu", (unsigned long)x);
5153 keys[x]= strdup(k);
5154 test_true(keys[x]);
5155 }
5156
5157 /*
5158 * Run two times.. the first time we should have 100% cache miss,
5159 * and the second time we should have 100% cache hits
5160 */
5161 for (size_t y= 0; y < 2; y++)
5162 {
5163 test_compare(MEMCACHED_SUCCESS,
5164 memcached_mget(memc, (const char**)keys, key_length, max_keys));
5165
5166 test_compare(y ? MEMCACHED_SUCCESS : MEMCACHED_NOTFOUND,
5167 memcached_fetch_execute(memc, callbacks, (void *)&counter, 1));
5168
5169 if (y == 0)
5170 {
5171 /* The first iteration should give me a 100% cache miss. verify that*/
5172 char blob[1024]= { 0 };
5173
5174 test_false(counter);
5175
5176 for (size_t x= 0; x < max_keys; ++x)
5177 {
5178 rc= memcached_add(memc, keys[x], key_length[x],
5179 blob, sizeof(blob), 0, 0);
5180 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5181 }
5182 }
5183 else
5184 {
5185 /* Verify that we received all of the key/value pairs */
5186 test_compare(counter, max_keys);
5187 }
5188 }
5189
5190 /* Release allocated resources */
5191 for (size_t x= 0; x < max_keys; ++x)
5192 {
5193 free(keys[x]);
5194 }
5195 free(keys);
5196 free(key_length);
5197
5198 memc->number_of_hosts= number_of_hosts;
5199
5200 return TEST_SUCCESS;
5201 }
5202
5203 static test_return_t regression_bug_434843_buffered(memcached_st *memc)
5204 {
5205 memcached_return_t rc;
5206 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
5207 test_compare(MEMCACHED_SUCCESS, rc);
5208
5209 return regression_bug_434843(memc);
5210 }
5211
5212 static test_return_t regression_bug_421108(memcached_st *memc)
5213 {
5214 memcached_return_t rc;
5215 memcached_stat_st *memc_stat= memcached_stat(memc, NULL, &rc);
5216 test_compare(MEMCACHED_SUCCESS, rc);
5217
5218 char *bytes_str= memcached_stat_get_value(memc, memc_stat, "bytes", &rc);
5219 test_compare(MEMCACHED_SUCCESS, rc);
5220 test_true(bytes_str);
5221 char *bytes_read_str= memcached_stat_get_value(memc, memc_stat,
5222 "bytes_read", &rc);
5223 test_compare(MEMCACHED_SUCCESS, rc);
5224 test_true(bytes_read_str);
5225
5226 char *bytes_written_str= memcached_stat_get_value(memc, memc_stat,
5227 "bytes_written", &rc);
5228 test_compare(MEMCACHED_SUCCESS, rc);
5229 test_true(bytes_written_str);
5230
5231 unsigned long long bytes= strtoull(bytes_str, 0, 10);
5232 unsigned long long bytes_read= strtoull(bytes_read_str, 0, 10);
5233 unsigned long long bytes_written= strtoull(bytes_written_str, 0, 10);
5234
5235 test_true(bytes != bytes_read);
5236 test_true(bytes != bytes_written);
5237
5238 /* Release allocated resources */
5239 free(bytes_str);
5240 free(bytes_read_str);
5241 free(bytes_written_str);
5242 memcached_stat_free(NULL, memc_stat);
5243
5244 return TEST_SUCCESS;
5245 }
5246
5247 /*
5248 * The test case isn't obvious so I should probably document why
5249 * it works the way it does. Bug 442914 was caused by a bug
5250 * in the logic in memcached_purge (it did not handle the case
5251 * where the number of bytes sent was equal to the watermark).
5252 * In this test case, create messages so that we hit that case
5253 * and then disable noreply mode and issue a new command to
5254 * verify that it isn't stuck. If we change the format for the
5255 * delete command or the watermarks, we need to update this
5256 * test....
5257 */
5258 static test_return_t regression_bug_442914(memcached_st *memc)
5259 {
5260 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1));
5261 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 1);
5262
5263 uint32_t number_of_hosts= memcached_server_count(memc);
5264 memc->number_of_hosts= 1;
5265
5266 char k[250];
5267 size_t len;
5268
5269 for (uint32_t x= 0; x < 250; ++x)
5270 {
5271 len= (size_t)snprintf(k, sizeof(k), "%0250u", x);
5272 memcached_return_t rc= memcached_delete(memc, k, len, 0);
5273 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5274 }
5275
5276 (void)snprintf(k, sizeof(k), "%037u", 251U);
5277 len= strlen(k);
5278
5279 memcached_return_t rc= memcached_delete(memc, k, len, 0);
5280 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5281
5282 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 0));
5283 test_compare(MEMCACHED_NOTFOUND, memcached_delete(memc, k, len, 0));
5284
5285 memc->number_of_hosts= number_of_hosts;
5286
5287 return TEST_SUCCESS;
5288 }
5289
5290 static test_return_t regression_bug_447342(memcached_st *memc)
5291 {
5292 memcached_server_instance_st instance_one;
5293 memcached_server_instance_st instance_two;
5294
5295 if (memcached_server_count(memc) < 3 or pre_replication(memc) != TEST_SUCCESS)
5296 return TEST_SKIPPED;
5297
5298 test_compare(MEMCACHED_SUCCESS,
5299 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 2));
5300
5301 const size_t max_keys= 100;
5302 char **keys= (char**)calloc(max_keys, sizeof(char*));
5303 size_t *key_length= (size_t *)calloc(max_keys, sizeof(size_t));
5304
5305 for (size_t x= 0; x < max_keys; ++x)
5306 {
5307 char k[251];
5308
5309 key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%lu", (unsigned long)x);
5310 keys[x]= strdup(k);
5311 test_true(keys[x]);
5312 test_compare(MEMCACHED_SUCCESS,
5313 memcached_set(memc, k, key_length[x], k, key_length[x], 0, 0));
5314 }
5315
5316 /*
5317 ** We are using the quiet commands to store the replicas, so we need
5318 ** to ensure that all of them are processed before we can continue.
5319 ** In the test we go directly from storing the object to trying to
5320 ** receive the object from all of the different servers, so we
5321 ** could end up in a race condition (the memcached server hasn't yet
5322 ** processed the quiet command from the replication set when it process
5323 ** the request from the other client (created by the clone)). As a
5324 ** workaround for that we call memcached_quit to send the quit command
5325 ** to the server and wait for the response ;-) If you use the test code
5326 ** as an example for your own code, please note that you shouldn't need
5327 ** to do this ;-)
5328 */
5329 memcached_quit(memc);
5330
5331 /* Verify that all messages are stored, and we didn't stuff too much
5332 * into the servers
5333 */
5334 test_compare(MEMCACHED_SUCCESS,
5335 memcached_mget(memc, (const char* const *)keys, key_length, max_keys));
5336
5337 size_t counter= 0;
5338 memcached_execute_fn callbacks[]= { &callback_counter };
5339 memcached_return_t rc;
5340 test_compare_got(MEMCACHED_SUCCESS,
5341 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1),
5342 memcached_strerror(NULL, rc));
5343
5344 /* Verify that we received all of the key/value pairs */
5345 test_compare(counter, max_keys);
5346
5347 memcached_quit(memc);
5348 /*
5349 * Don't do the following in your code. I am abusing the internal details
5350 * within the library, and this is not a supported interface.
5351 * This is to verify correct behavior in the library. Fake that two servers
5352 * are dead..
5353 */
5354 instance_one= memcached_server_instance_by_position(memc, 0);
5355 instance_two= memcached_server_instance_by_position(memc, 2);
5356 in_port_t port0= instance_one->port;
5357 in_port_t port2= instance_two->port;
5358
5359 ((memcached_server_write_instance_st)instance_one)->port= 0;
5360 ((memcached_server_write_instance_st)instance_two)->port= 0;
5361
5362 test_compare(MEMCACHED_SUCCESS,
5363 memcached_mget(memc, (const char* const *)keys, key_length, max_keys));
5364
5365 counter= 0;
5366 test_compare(MEMCACHED_SUCCESS,
5367 memcached_fetch_execute(memc, callbacks, (void *)&counter, 1));
5368 test_compare(counter, (unsigned int)max_keys);
5369
5370 /* restore the memc handle */
5371 ((memcached_server_write_instance_st)instance_one)->port= port0;
5372 ((memcached_server_write_instance_st)instance_two)->port= port2;
5373
5374 memcached_quit(memc);
5375
5376 /* Remove half of the objects */
5377 for (size_t x= 0; x < max_keys; ++x)
5378 {
5379 if (x & 1)
5380 {
5381 test_compare(MEMCACHED_SUCCESS,
5382 memcached_delete(memc, keys[x], key_length[x], 0));
5383 }
5384 }
5385
5386 memcached_quit(memc);
5387 ((memcached_server_write_instance_st)instance_one)->port= 0;
5388 ((memcached_server_write_instance_st)instance_two)->port= 0;
5389
5390 /* now retry the command, this time we should have cache misses */
5391 test_compare(MEMCACHED_SUCCESS,
5392 memcached_mget(memc, (const char* const *)keys, key_length, max_keys));
5393
5394 counter= 0;
5395 test_compare_got(MEMCACHED_SUCCESS,
5396 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1),
5397 memcached_strerror(NULL, rc));
5398 test_compare(counter, (unsigned int)(max_keys >> 1));
5399
5400 /* Release allocated resources */
5401 for (size_t x= 0; x < max_keys; ++x)
5402 {
5403 free(keys[x]);
5404 }
5405 free(keys);
5406 free(key_length);
5407
5408 /* restore the memc handle */
5409 ((memcached_server_write_instance_st)instance_one)->port= port0;
5410 ((memcached_server_write_instance_st)instance_two)->port= port2;
5411
5412 return TEST_SUCCESS;
5413 }
5414
5415 static test_return_t regression_bug_463297(memcached_st *memc)
5416 {
5417 memcached_st *memc_clone= memcached_clone(NULL, memc);
5418 test_true(memc_clone);
5419 test_true(memcached_version(memc_clone) == MEMCACHED_SUCCESS);
5420
5421 memcached_server_instance_st instance=
5422 memcached_server_instance_by_position(memc_clone, 0);
5423
5424 if (instance->major_version > 1 ||
5425 (instance->major_version == 1 &&
5426 instance->minor_version > 2))
5427 {
5428 /* Binary protocol doesn't support deferred delete */
5429 memcached_st *bin_clone= memcached_clone(NULL, memc);
5430 test_true(bin_clone);
5431 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(bin_clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1));
5432 test_compare(MEMCACHED_INVALID_ARGUMENTS, memcached_delete(bin_clone, "foo", 3, 1));
5433 memcached_free(bin_clone);
5434
5435 memcached_quit(memc_clone);
5436
5437 /* If we know the server version, deferred delete should fail
5438 * with invalid arguments */
5439 test_compare(MEMCACHED_INVALID_ARGUMENTS, memcached_delete(memc_clone, "foo", 3, 1));
5440
5441 /* If we don't know the server version, we should get a protocol error */
5442 memcached_return_t rc= memcached_delete(memc, "foo", 3, 1);
5443
5444 /* but there is a bug in some of the memcached servers (1.4) that treats
5445 * the counter as noreply so it doesn't send the proper error message
5446 */
5447 test_true_got(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR || rc == MEMCACHED_INVALID_ARGUMENTS, memcached_strerror(NULL, rc));
5448
5449 /* And buffered mode should be disabled and we should get protocol error */
5450 test_true(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1) == MEMCACHED_SUCCESS);
5451 rc= memcached_delete(memc, "foo", 3, 1);
5452 test_true_got(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR || rc == MEMCACHED_INVALID_ARGUMENTS, memcached_strerror(NULL, rc));
5453
5454 /* Same goes for noreply... */
5455 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1));
5456 rc= memcached_delete(memc, "foo", 3, 1);
5457 test_true_got(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR || rc == MEMCACHED_INVALID_ARGUMENTS, memcached_strerror(NULL, rc));
5458
5459 /* but a normal request should go through (and be buffered) */
5460 test_compare(MEMCACHED_BUFFERED, (rc= memcached_delete(memc, "foo", 3, 0)));
5461 test_compare(MEMCACHED_SUCCESS, memcached_flush_buffers(memc));
5462
5463 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 0));
5464 /* unbuffered noreply should be success */
5465 test_compare(MEMCACHED_SUCCESS, memcached_delete(memc, "foo", 3, 0));
5466 /* unbuffered with reply should be not found... */
5467 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 0));
5468 test_compare(MEMCACHED_NOTFOUND, memcached_delete(memc, "foo", 3, 0));
5469 }
5470
5471 memcached_free(memc_clone);
5472 return TEST_SUCCESS;
5473 }
5474
5475
5476 /* Test memcached_server_get_last_disconnect
5477 * For a working server set, shall be NULL
5478 * For a set of non existing server, shall not be NULL
5479 */
5480 static test_return_t test_get_last_disconnect(memcached_st *memc)
5481 {
5482 memcached_return_t rc;
5483 memcached_server_instance_st disconnected_server;
5484
5485 /* With the working set of server */
5486 const char *key= "marmotte";
5487 const char *value= "milka";
5488
5489 memcached_reset_last_disconnected_server(memc);
5490 test_false(memc->last_disconnected_server);
5491 rc= memcached_set(memc, key, strlen(key),
5492 value, strlen(value),
5493 (time_t)0, (uint32_t)0);
5494 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5495
5496 disconnected_server = memcached_server_get_last_disconnect(memc);
5497 test_false(disconnected_server);
5498
5499 /* With a non existing server */
5500 memcached_st *mine;
5501 memcached_server_st *servers;
5502
5503 const char *server_list= "localhost:9";
5504
5505 servers= memcached_servers_parse(server_list);
5506 test_true(servers);
5507 mine= memcached_create(NULL);
5508 rc= memcached_server_push(mine, servers);
5509 test_compare(MEMCACHED_SUCCESS, rc);
5510 memcached_server_list_free(servers);
5511 test_true(mine);
5512
5513 rc= memcached_set(mine, key, strlen(key),
5514 value, strlen(value),
5515 (time_t)0, (uint32_t)0);
5516 test_true(memcached_failed(rc));
5517
5518 disconnected_server= memcached_server_get_last_disconnect(mine);
5519 test_true_got(disconnected_server, memcached_strerror(mine, rc));
5520 test_compare(9, memcached_server_port(disconnected_server));
5521 test_false(strncmp(memcached_server_name(disconnected_server),"localhost",9));
5522
5523 memcached_quit(mine);
5524 memcached_free(mine);
5525
5526 return TEST_SUCCESS;
5527 }
5528
5529 static test_return_t test_multiple_get_last_disconnect(memcached_st *)
5530 {
5531 const char *server_string= "--server=localhost:8888 --server=localhost:8889 --server=localhost:8890 --server=localhost:8891 --server=localhost:8892";
5532 char buffer[BUFSIZ];
5533
5534 memcached_return_t rc;
5535 test_compare_got(MEMCACHED_SUCCESS,
5536 rc= libmemcached_check_configuration(server_string, strlen(server_string), buffer, sizeof(buffer)),
5537 memcached_strerror(NULL, rc));
5538
5539 memcached_st *memc= memcached(server_string, strlen(server_string));
5540 test_true(memc);
5541
5542 // We will just use the error strings as our keys
5543 uint32_t counter= 100;
5544 while (--counter)
5545 {
5546 for (int x= int(MEMCACHED_SUCCESS); x < int(MEMCACHED_MAXIMUM_RETURN); ++x)
5547 {
5548 const char *msg= memcached_strerror(memc, memcached_return_t(x));
5549 memcached_return_t ret= memcached_set(memc, msg, strlen(msg), NULL, 0, (time_t)0, (uint32_t)0);
5550 test_compare_got(MEMCACHED_CONNECTION_FAILURE, ret, memcached_last_error_message(memc));
5551
5552 memcached_server_instance_st disconnected_server= memcached_server_get_last_disconnect(memc);
5553 test_true(disconnected_server);
5554 test_strcmp("localhost", memcached_server_name(disconnected_server));
5555 test_true(memcached_server_port(disconnected_server) >= 8888 and memcached_server_port(disconnected_server) <= 8892);
5556
5557 if (random() % 2)
5558 {
5559 memcached_reset_last_disconnected_server(memc);
5560 }
5561 }
5562 }
5563
5564 memcached_free(memc);
5565
5566 return TEST_SUCCESS;
5567 }
5568
5569 static test_return_t test_verbosity(memcached_st *memc)
5570 {
5571 memcached_verbosity(memc, 3);
5572
5573 return TEST_SUCCESS;
5574 }
5575
5576 static test_return_t test_server_failure(memcached_st *memc)
5577 {
5578 memcached_server_instance_st instance= memcached_server_instance_by_position(memc, 0);
5579
5580 memcached_st *local_memc= memcached_create(NULL);
5581
5582 memcached_server_add(local_memc, memcached_server_name(instance), memcached_server_port(instance));
5583 memcached_behavior_set(local_memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, 2);
5584
5585 uint32_t server_count= memcached_server_count(local_memc);
5586 test_compare(1, server_count);
5587
5588 // Disable the server
5589 instance= memcached_server_instance_by_position(local_memc, 0);
5590 ((memcached_server_write_instance_st)instance)->server_failure_counter= 2;
5591
5592 memcached_return_t rc;
5593 test_compare_got(MEMCACHED_SERVER_MARKED_DEAD,
5594 rc= memcached_set(local_memc, "foo", strlen("foo"), NULL, 0, (time_t)0, (uint32_t)0),
5595 memcached_last_error_message(local_memc));
5596
5597 ((memcached_server_write_instance_st)instance)->server_failure_counter= 0;
5598 test_compare_got(MEMCACHED_SUCCESS,
5599 rc= memcached_set(local_memc, "foo", strlen("foo"), NULL, 0, (time_t)0, (uint32_t)0),
5600 memcached_strerror(NULL, rc));
5601 #if 0
5602 memcached_last_error_message(local_memc));
5603 #endif
5604
5605
5606 memcached_free(local_memc);
5607
5608 return TEST_SUCCESS;
5609 }
5610
5611 static test_return_t test_cull_servers(memcached_st *memc)
5612 {
5613 uint32_t count = memcached_server_count(memc);
5614
5615 // Do not do this in your code, it is not supported.
5616 memc->servers[1].options.is_dead= true;
5617 memc->state.is_time_for_rebuild= true;
5618
5619 uint32_t new_count= memcached_server_count(memc);
5620 test_compare(count, new_count);
5621
5622 #if 0
5623 test_true(count == new_count + 1 );
5624 #endif
5625
5626 return TEST_SUCCESS;
5627 }
5628
5629
5630 static memcached_return_t stat_printer(memcached_server_instance_st server,
5631 const char *key, size_t key_length,
5632 const char *value, size_t value_length,
5633 void *context)
5634 {
5635 (void)server;
5636 (void)context;
5637 (void)key;
5638 (void)key_length;
5639 (void)value;
5640 (void)value_length;
5641
5642 return MEMCACHED_SUCCESS;
5643 }
5644
5645 static test_return_t memcached_stat_execute_test(memcached_st *memc)
5646 {
5647 memcached_return_t rc= memcached_stat_execute(memc, NULL, stat_printer, NULL);
5648 test_compare(MEMCACHED_SUCCESS, rc);
5649
5650 rc= memcached_stat_execute(memc, "slabs", stat_printer, NULL);
5651 test_compare(MEMCACHED_SUCCESS, rc);
5652
5653 rc= memcached_stat_execute(memc, "items", stat_printer, NULL);
5654 test_compare(MEMCACHED_SUCCESS, rc);
5655
5656 rc= memcached_stat_execute(memc, "sizes", stat_printer, NULL);
5657 test_compare(MEMCACHED_SUCCESS, rc);
5658
5659 return TEST_SUCCESS;
5660 }
5661
5662 /*
5663 * This test ensures that the failure counter isn't incremented during
5664 * normal termination of the memcached instance.
5665 */
5666 static test_return_t wrong_failure_counter_test(memcached_st *memc)
5667 {
5668 memcached_return_t rc;
5669 memcached_server_instance_st instance;
5670
5671 /* Set value to force connection to the server */
5672 const char *key= "marmotte";
5673 const char *value= "milka";
5674
5675 /*
5676 * Please note that I'm abusing the internal structures in libmemcached
5677 * in a non-portable way and you shouldn't be doing this. I'm only
5678 * doing this in order to verify that the library works the way it should
5679 */
5680 uint32_t number_of_hosts= memcached_server_count(memc);
5681 memc->number_of_hosts= 1;
5682
5683 /* Ensure that we are connected to the server by setting a value */
5684 rc= memcached_set(memc, key, strlen(key),
5685 value, strlen(value),
5686 (time_t)0, (uint32_t)0);
5687 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5688
5689
5690 instance= memcached_server_instance_by_position(memc, 0);
5691 /* The test is to see that the memcached_quit doesn't increase the
5692 * the server failure conter, so let's ensure that it is zero
5693 * before sending quit
5694 */
5695 ((memcached_server_write_instance_st)instance)->server_failure_counter= 0;
5696
5697 memcached_quit(memc);
5698
5699 /* Verify that it memcached_quit didn't increment the failure counter
5700 * Please note that this isn't bullet proof, because an error could
5701 * occur...
5702 */
5703 test_compare(0, instance->server_failure_counter);
5704
5705 /* restore the instance */
5706 memc->number_of_hosts= number_of_hosts;
5707
5708 return TEST_SUCCESS;
5709 }
5710
5711 /*
5712 * This tests ensures expected disconnections (for some behavior changes
5713 * for instance) do not wrongly increase failure counter
5714 */
5715 static test_return_t wrong_failure_counter_two_test(memcached_st *memc)
5716 {
5717 memcached_return rc;
5718
5719 memcached_st *memc_clone;
5720 memc_clone= memcached_clone(NULL, memc);
5721 test_true(memc_clone);
5722
5723 /* Set value to force connection to the server */
5724 const char *key= "marmotte";
5725 const char *value= "milka";
5726 char *string = NULL;
5727 size_t string_length;
5728 uint32_t flags;
5729
5730 rc= memcached_set(memc_clone, key, strlen(key),
5731 value, strlen(value),
5732 (time_t)0, (uint32_t)0);
5733 test_true_got(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED, memcached_strerror(NULL, rc));
5734
5735
5736 /* put failure limit to 1 */
5737 test_compare(MEMCACHED_SUCCESS,
5738 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, 1));
5739
5740 /* Put a retry timeout to effectively activate failure_limit effect */
5741 test_compare(MEMCACHED_SUCCESS,
5742 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 1));
5743
5744 /* change behavior that triggers memcached_quit()*/
5745 test_compare(MEMCACHED_SUCCESS,
5746 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_TCP_NODELAY, 1));
5747
5748
5749 /* Check if we still are connected */
5750 string= memcached_get(memc_clone, key, strlen(key),
5751 &string_length, &flags, &rc);
5752
5753 test_compare_got(MEMCACHED_SUCCESS, rc, memcached_strerror(NULL, rc));
5754 test_true(string);
5755 free(string);
5756 memcached_free(memc_clone);
5757
5758 return TEST_SUCCESS;
5759 }
5760
5761
5762
5763
5764 /*
5765 * Test that ensures mget_execute does not end into recursive calls that finally fails
5766 */
5767 static test_return_t regression_bug_490486(memcached_st *memc)
5768 {
5769 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
5770 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 1);
5771 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, 1000);
5772 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, 1);
5773 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 3600);
5774
5775 #ifdef __APPLE__
5776 return TEST_SKIPPED; // My MAC can't handle this test
5777 #endif
5778
5779 /*
5780 * I only want to hit _one_ server so I know the number of requests I'm
5781 * sending in the pipeline.
5782 */
5783 uint32_t number_of_hosts= memc->number_of_hosts;
5784 memc->number_of_hosts= 1;
5785 size_t max_keys= 20480;
5786
5787
5788 char **keys= (char **)calloc(max_keys, sizeof(char*));
5789 size_t *key_length= (size_t *)calloc(max_keys, sizeof(size_t));
5790
5791 /* First add all of the items.. */
5792 char blob[1024]= { 0 };
5793 for (size_t x= 0; x < max_keys; ++x)
5794 {
5795 char k[251];
5796 key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%lu", (unsigned long)x);
5797 keys[x]= strdup(k);
5798 test_true(keys[x]);
5799 memcached_return rc= memcached_set(memc, keys[x], key_length[x], blob, sizeof(blob), 0, 0);
5800 test_true(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED); // MEMCACHED_TIMEOUT <-- hash been observed on OSX
5801 }
5802
5803 {
5804
5805 /* Try to get all of them with a large multiget */
5806 size_t counter= 0;
5807 memcached_execute_function callbacks[]= { &callback_counter };
5808 memcached_return_t rc= memcached_mget_execute(memc, (const char**)keys, key_length,
5809 (size_t)max_keys, callbacks, &counter, 1);
5810 test_compare(MEMCACHED_SUCCESS, rc);
5811
5812 char* the_value= NULL;
5813 char the_key[MEMCACHED_MAX_KEY];
5814 size_t the_key_length;
5815 size_t the_value_length;
5816 uint32_t the_flags;
5817
5818 do {
5819 the_value= memcached_fetch(memc, the_key, &the_key_length, &the_value_length, &the_flags, &rc);
5820
5821 if ((the_value!= NULL) && (rc == MEMCACHED_SUCCESS))
5822 {
5823 ++counter;
5824 free(the_value);
5825 }
5826
5827 } while ( (the_value!= NULL) && (rc == MEMCACHED_SUCCESS));
5828
5829
5830 test_compare(MEMCACHED_END, rc);
5831
5832 /* Verify that we got all of the items */
5833 test_compare(counter, max_keys);
5834 }
5835
5836 /* Release all allocated resources */
5837 for (size_t x= 0; x < max_keys; ++x)
5838 {
5839 free(keys[x]);
5840 }
5841 free(keys);
5842 free(key_length);
5843
5844 memc->number_of_hosts= number_of_hosts;
5845
5846 return TEST_SUCCESS;
5847 }
5848
5849 static test_return_t regression_bug_583031(memcached_st *)
5850 {
5851 memcached_st *memc= memcached_create(NULL);
5852 test_true(memc);
5853 test_compare(MEMCACHED_SUCCESS, memcached_server_add(memc, "10.2.3.4", 11211));
5854
5855 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT, 1000);
5856 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 1000);
5857 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SND_TIMEOUT, 1000);
5858 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RCV_TIMEOUT, 1000);
5859 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, 1000);
5860 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, 3);
5861
5862 memcached_return_t rc;
5863 size_t length;
5864 uint32_t flags;
5865
5866 const char *value= memcached_get(memc, "dsf", 3, &length, &flags, &rc);
5867 test_false(value);
5868 test_compare(0, length);
5869
5870 test_compare_got(MEMCACHED_TIMEOUT, rc, memcached_strerror(memc, rc));
5871
5872 memcached_free(memc);
5873
5874 return TEST_SUCCESS;
5875 }
5876
5877 static test_return_t regression_bug_581030(memcached_st *)
5878 {
5879 #ifndef DEBUG
5880 memcached_stat_st *local_stat= memcached_stat(NULL, NULL, NULL);
5881 test_false(local_stat);
5882
5883 memcached_stat_free(NULL, NULL);
5884 #endif
5885
5886 return TEST_SUCCESS;
5887 }
5888
5889 #define regression_bug_655423_COUNT 6000
5890 static test_return_t regression_bug_655423(memcached_st *memc)
5891 {
5892 memcached_st *clone= memcached_clone(NULL, memc);
5893 memc= NULL; // Just to make sure it is not used
5894 test_true(clone);
5895 char payload[100];
5896
5897 #ifdef __APPLE__
5898 return TEST_SKIPPED;
5899 #endif
5900
5901 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1));
5902 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(clone, MEMCACHED_BEHAVIOR_SUPPORT_CAS, 1));
5903 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(clone, MEMCACHED_BEHAVIOR_TCP_NODELAY, 1));
5904 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(clone, MEMCACHED_BEHAVIOR_IO_KEY_PREFETCH, 1));
5905
5906 memset(payload, int('x'), sizeof(payload));
5907
5908 for (uint32_t x= 0; x < regression_bug_655423_COUNT; x++)
5909 {
5910 char key[MEMCACHED_MAXIMUM_INTEGER_DISPLAY_LENGTH +1];
5911 snprintf(key, sizeof(key), "%u", x);
5912
5913 test_compare(MEMCACHED_SUCCESS, memcached_set(clone, key, strlen(key), payload, sizeof(payload), 0, 0));
5914 }
5915
5916 for (uint32_t x= 0; x < regression_bug_655423_COUNT; x++)
5917 {
5918 char key[MEMCACHED_MAXIMUM_INTEGER_DISPLAY_LENGTH +1];
5919 snprintf(key, sizeof(key), "%u", x);
5920
5921 size_t value_length;
5922 memcached_return_t rc;
5923 char *value= memcached_get(clone, key, strlen(key), &value_length, NULL, &rc);
5924
5925 if (rc == MEMCACHED_NOTFOUND)
5926 {
5927 test_false(value);
5928 test_compare(0, value_length);
5929 continue;
5930 }
5931
5932 test_compare(MEMCACHED_SUCCESS, rc);
5933 test_true(value);
5934 test_compare(100, value_length);
5935 free(value);
5936 }
5937
5938 char **keys= (char**)calloc(regression_bug_655423_COUNT, sizeof(char*));
5939 size_t *key_length= (size_t *)calloc(regression_bug_655423_COUNT, sizeof(size_t));
5940 for (uint32_t x= 0; x < regression_bug_655423_COUNT; x++)
5941 {
5942 char key[MEMCACHED_MAXIMUM_INTEGER_DISPLAY_LENGTH +1];
5943 snprintf(key, sizeof(key), "%u", x);
5944
5945 keys[x]= strdup(key);
5946 test_true(keys[x]);
5947 key_length[x]= strlen(key);
5948 test_true(key_length[x]);
5949 }
5950
5951 memcached_return_t rc;
5952 test_compare_got(MEMCACHED_SUCCESS,
5953 rc= memcached_mget(clone, (const char* const *)keys, key_length, regression_bug_655423_COUNT),
5954 memcached_strerror(NULL, rc));
5955
5956 uint32_t count= 0;
5957 memcached_result_st *result= NULL;
5958 while ((result= memcached_fetch_result(clone, result, NULL)))
5959 {
5960 test_compare(100, memcached_result_length(result));
5961 count++;
5962 }
5963
5964 test_true(count > 100); // If we don't get back atleast this, something is up
5965
5966 /* Release all allocated resources */
5967 for (size_t x= 0; x < regression_bug_655423_COUNT; ++x)
5968 {
5969 free(keys[x]);
5970 }
5971 free(keys);
5972 free(key_length);
5973
5974
5975 memcached_free(clone);
5976
5977 return TEST_SUCCESS;
5978 }
5979
5980 /*
5981 * Test that ensures that buffered set to not trigger problems during io_flush
5982 */
5983 #define regression_bug_490520_COUNT 200480
5984 static test_return_t regression_bug_490520(memcached_st *memc)
5985 {
5986 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK,1);
5987 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS,1);
5988 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, 1000);
5989 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT,1);
5990 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 3600);
5991
5992 memc->number_of_hosts= 1;
5993
5994 char **keys= (char **)calloc(regression_bug_490520_COUNT, sizeof(char*));
5995 size_t *key_length= (size_t *)calloc(regression_bug_490520_COUNT, sizeof(size_t));
5996
5997 /* First add all of the items.. */
5998 char blob[3333] = {0};
5999 for (uint32_t x= 0; x < regression_bug_490520_COUNT; ++x)
6000 {
6001 char k[251];
6002 key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%u", x);
6003 keys[x]= strdup(k);
6004 test_true(keys[x]);
6005
6006 memcached_return rc= memcached_set(memc, keys[x], key_length[x], blob, sizeof(blob), 0, 0);
6007 test_true(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED);
6008 }
6009
6010 for (uint32_t x= 0; x < regression_bug_490520_COUNT; ++x)
6011 {
6012 free(keys[x]);
6013 }
6014 free(keys);
6015 free(key_length);
6016
6017 return TEST_SUCCESS;
6018 }
6019
6020 static void memcached_die(memcached_st* mc, memcached_return error, const char* what, uint32_t it)
6021 {
6022 fprintf(stderr, "Iteration #%u: ", it);
6023
6024 if(error == MEMCACHED_ERRNO)
6025 {
6026 fprintf(stderr, "system error %d from %s: %s\n",
6027 errno, what, strerror(errno));
6028 }
6029 else
6030 {
6031 fprintf(stderr, "error %d from %s: %s\n", error, what,
6032 memcached_strerror(mc, error));
6033 }
6034 }
6035
6036 #define TEST_CONSTANT_CREATION 200
6037
6038 static test_return_t regression_bug_(memcached_st *memc)
6039 {
6040 const char *remote_server;
6041 (void)memc;
6042
6043 if (! (remote_server= getenv("LIBMEMCACHED_REMOTE_SERVER")))
6044 {
6045 return TEST_SKIPPED;
6046 }
6047
6048 for (uint32_t x= 0; x < TEST_CONSTANT_CREATION; x++)
6049 {
6050 memcached_st* mc= memcached_create(NULL);
6051 memcached_return rc;
6052
6053 rc= memcached_behavior_set(mc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
6054 if (rc != MEMCACHED_SUCCESS)
6055 {
6056 memcached_die(mc, rc, "memcached_behavior_set", x);
6057 }
6058
6059 rc= memcached_behavior_set(mc, MEMCACHED_BEHAVIOR_CACHE_LOOKUPS, 1);
6060 if (rc != MEMCACHED_SUCCESS)
6061 {
6062 memcached_die(mc, rc, "memcached_behavior_set", x);
6063 }
6064
6065 rc= memcached_server_add(mc, remote_server, 0);
6066 if (rc != MEMCACHED_SUCCESS)
6067 {
6068 memcached_die(mc, rc, "memcached_server_add", x);
6069 }
6070
6071 const char *set_key= "akey";
6072 const size_t set_key_len= strlen(set_key);
6073 const char *set_value= "a value";
6074 const size_t set_value_len= strlen(set_value);
6075
6076 if (rc == MEMCACHED_SUCCESS)
6077 {
6078 if (x > 0)
6079 {
6080 size_t get_value_len;
6081 char *get_value;
6082 uint32_t get_value_flags;
6083
6084 get_value= memcached_get(mc, set_key, set_key_len, &get_value_len,
6085 &get_value_flags, &rc);
6086 if (rc != MEMCACHED_SUCCESS)
6087 {
6088 memcached_die(mc, rc, "memcached_get", x);
6089 }
6090 else
6091 {
6092
6093 if (x != 0 &&
6094 (get_value_len != set_value_len
6095 || 0!=strncmp(get_value, set_value, get_value_len)))
6096 {
6097 fprintf(stderr, "Values don't match?\n");
6098 rc= MEMCACHED_FAILURE;
6099 }
6100 free(get_value);
6101 }
6102 }
6103
6104 rc= memcached_set(mc,
6105 set_key, set_key_len,
6106 set_value, set_value_len,
6107 0, /* time */
6108 0 /* flags */
6109 );
6110 if (rc != MEMCACHED_SUCCESS)
6111 {
6112 memcached_die(mc, rc, "memcached_set", x);
6113 }
6114 }
6115
6116 memcached_quit(mc);
6117 memcached_free(mc);
6118
6119 if (rc != MEMCACHED_SUCCESS)
6120 {
6121 break;
6122 }
6123 }
6124
6125 return TEST_SUCCESS;
6126 }
6127
6128 /*
6129 * Test that the sasl authentication works. We cannot use the default
6130 * pool of servers, because that would require that all servers we want
6131 * to test supports SASL authentication, and that they use the default
6132 * creds.
6133 */
6134 static test_return_t sasl_auth_test(memcached_st *memc)
6135 {
6136 #ifdef LIBMEMCACHED_WITH_SASL_SUPPORT
6137 test_compare(MEMCACHED_SUCCESS, memcached_set(memc, "foo", 3, "bar", 3, (time_t)0, (uint32_t)0));
6138 test_compare(MEMCACHED_SUCCESS, memcached_delete(memc, "foo", 3, 0));
6139 test_compare(MEMCACHED_SUCCESS, memcached_destroy_sasl_auth_data(memc));
6140 test_compare(MEMCACHED_FAILURE, memcached_destroy_sasl_auth_data(memc));
6141 test_compare(MEMCACHED_FAILURE, memcached_destroy_sasl_auth_data(NULL));
6142 memcached_quit(memc);
6143
6144 test_compare(MEMCACHED_SUCCESS,
6145 memcached_set_sasl_auth_data(memc,
6146 getenv("LIBMEMCACHED_TEST_SASL_USERNAME"),
6147 getenv("LIBMEMCACHED_TEST_SASL_SERVER")));
6148
6149 test_compare(MEMCACHED_AUTH_FAILURE,
6150 memcached_set(memc, "foo", 3, "bar", 3, (time_t)0, (uint32_t)0));
6151 test_compare(MEMCACHED_SUCCESS, memcached_destroy_sasl_auth_data(memc));
6152
6153 memcached_quit(memc);
6154 return TEST_SUCCESS;
6155 #else
6156 (void)memc;
6157 return TEST_FAILURE;
6158 #endif
6159 }
6160
6161 /* Clean the server before beginning testing */
6162 test_st tests[] ={
6163 {"util_version", 1, (test_callback_fn*)util_version_test },
6164 {"flush", 0, (test_callback_fn*)flush_test },
6165 {"init", 0, (test_callback_fn*)init_test },
6166 {"allocation", 0, (test_callback_fn*)allocation_test },
6167 {"server_list_null_test", 0, (test_callback_fn*)server_list_null_test},
6168 {"server_unsort", 0, (test_callback_fn*)server_unsort_test},
6169 {"server_sort", 0, (test_callback_fn*)server_sort_test},
6170 {"server_sort2", 0, (test_callback_fn*)server_sort2_test},
6171 {"memcached_server_remove", 0, (test_callback_fn*)memcached_server_remove_test},
6172 {"clone_test", 0, (test_callback_fn*)clone_test },
6173 {"connection_test", 0, (test_callback_fn*)connection_test},
6174 {"callback_test", 0, (test_callback_fn*)callback_test},
6175 {"userdata_test", 0, (test_callback_fn*)userdata_test},
6176 {"error", 0, (test_callback_fn*)error_test },
6177 {"set", 0, (test_callback_fn*)set_test },
6178 {"set2", 0, (test_callback_fn*)set_test2 },
6179 {"set3", 0, (test_callback_fn*)set_test3 },
6180 {"dump", 1, (test_callback_fn*)dump_test},
6181 {"add", 1, (test_callback_fn*)add_test },
6182 {"memcached_fetch_result(MEMCACHED_NOTFOUND)", 1, (test_callback_fn*)memcached_fetch_result_NOT_FOUND },
6183 {"replace", 1, (test_callback_fn*)replace_test },
6184 {"delete", 1, (test_callback_fn*)delete_test },
6185 {"get", 1, (test_callback_fn*)get_test },
6186 {"get2", 0, (test_callback_fn*)get_test2 },
6187 {"get3", 0, (test_callback_fn*)get_test3 },
6188 {"get4", 0, (test_callback_fn*)get_test4 },
6189 {"partial mget", 0, (test_callback_fn*)get_test5 },
6190 {"stats_servername", 0, (test_callback_fn*)stats_servername_test },
6191 {"increment", 0, (test_callback_fn*)increment_test },
6192 {"increment_with_initial", 1, (test_callback_fn*)increment_with_initial_test },
6193 {"decrement", 0, (test_callback_fn*)decrement_test },
6194 {"decrement_with_initial", 1, (test_callback_fn*)decrement_with_initial_test },
6195 {"increment_by_key", 0, (test_callback_fn*)increment_by_key_test },
6196 {"increment_with_initial_by_key", 1, (test_callback_fn*)increment_with_initial_by_key_test },
6197 {"decrement_by_key", 0, (test_callback_fn*)decrement_by_key_test },
6198 {"decrement_with_initial_by_key", 1, (test_callback_fn*)decrement_with_initial_by_key_test },
6199 {"quit", 0, (test_callback_fn*)quit_test },
6200 {"mget", 1, (test_callback_fn*)mget_test },
6201 {"mget_result", 1, (test_callback_fn*)mget_result_test },
6202 {"mget_result_alloc", 1, (test_callback_fn*)mget_result_alloc_test },
6203 {"mget_result_function", 1, (test_callback_fn*)mget_result_function },
6204 {"mget_execute", 1, (test_callback_fn*)mget_execute },
6205 {"mget_end", 0, (test_callback_fn*)mget_end },
6206 {"get_stats", 0, (test_callback_fn*)get_stats },
6207 {"add_host_test", 0, (test_callback_fn*)add_host_test },
6208 {"add_host_test_1", 0, (test_callback_fn*)add_host_test1 },
6209 {"get_stats_keys", 0, (test_callback_fn*)get_stats_keys },
6210 {"version_string_test", 0, (test_callback_fn*)version_string_test},
6211 {"bad_key", 1, (test_callback_fn*)bad_key_test },
6212 {"memcached_server_cursor", 1, (test_callback_fn*)memcached_server_cursor_test },
6213 {"read_through", 1, (test_callback_fn*)read_through },
6214 {"delete_through", 1, (test_callback_fn*)delete_through },
6215 {"noreply", 1, (test_callback_fn*)noreply_test},
6216 {"analyzer", 1, (test_callback_fn*)analyzer_test},
6217 {"connectionpool", 1, (test_callback_fn*)connection_pool_test },
6218 {"memcached_pool_test", 1, (test_callback_fn*)memcached_pool_test },
6219 {"ping", 1, (test_callback_fn*)ping_test },
6220 {"test_get_last_disconnect", 1, (test_callback_fn*)test_get_last_disconnect},
6221 {"verbosity", 1, (test_callback_fn*)test_verbosity},
6222 {"test_server_failure", 1, (test_callback_fn*)test_server_failure},
6223 {"cull_servers", 1, (test_callback_fn*)test_cull_servers},
6224 {"memcached_stat_execute", 1, (test_callback_fn*)memcached_stat_execute_test},
6225 {0, 0, 0}
6226 };
6227
6228 test_st behavior_tests[] ={
6229 {"libmemcached_string_behavior()", 0, (test_callback_fn*)libmemcached_string_behavior_test},
6230 {"libmemcached_string_distribution()", 0, (test_callback_fn*)libmemcached_string_distribution_test},
6231 {"behavior_test", 0, (test_callback_fn*)behavior_test},
6232 {"MEMCACHED_BEHAVIOR_CORK", 0, (test_callback_fn*)MEMCACHED_BEHAVIOR_CORK_test},
6233 {"MEMCACHED_BEHAVIOR_TCP_KEEPALIVE", 0, (test_callback_fn*)MEMCACHED_BEHAVIOR_TCP_KEEPALIVE_test},
6234 {"MEMCACHED_BEHAVIOR_TCP_KEEPIDLE", 0, (test_callback_fn*)MEMCACHED_BEHAVIOR_TCP_KEEPIDLE_test},
6235 {0, 0, 0}
6236 };
6237
6238 test_st basic_tests[] ={
6239 {"init", 1, (test_callback_fn*)basic_init_test},
6240 {"clone", 1, (test_callback_fn*)basic_clone_test},
6241 {"reset", 1, (test_callback_fn*)basic_reset_stack_test},
6242 {"reset heap", 1, (test_callback_fn*)basic_reset_heap_test},
6243 {"reset stack clone", 1, (test_callback_fn*)basic_reset_stack_clone_test},
6244 {"reset heap clone", 1, (test_callback_fn*)basic_reset_heap_clone_test},
6245 {0, 0, 0}
6246 };
6247
6248 test_st regression_binary_vs_block[] ={
6249 {"block add", 1, (test_callback_fn*)block_add_regression},
6250 {"binary add", 1, (test_callback_fn*)binary_add_regression},
6251 {0, 0, 0}
6252 };
6253
6254 test_st async_tests[] ={
6255 {"add", 1, (test_callback_fn*)add_wrapper },
6256 {0, 0, 0}
6257 };
6258
6259 test_st string_tests[] ={
6260 {"string static with null", 0, (test_callback_fn*)string_static_null },
6261 {"string alloc with null", 0, (test_callback_fn*)string_alloc_null },
6262 {"string alloc with 1K", 0, (test_callback_fn*)string_alloc_with_size },
6263 {"string alloc with malloc failure", 0, (test_callback_fn*)string_alloc_with_size_toobig },
6264 {"string append", 0, (test_callback_fn*)string_alloc_append },
6265 {"string append failure (too big)", 0, (test_callback_fn*)string_alloc_append_toobig },
6266 {"string_alloc_append_multiple", 0, (test_callback_fn*)string_alloc_append_multiple },
6267 {0, 0, (test_callback_fn*)0}
6268 };
6269
6270 test_st memcached_server_get_last_disconnect_tests[] ={
6271 {"memcached_server_get_last_disconnect()", 0, (test_callback_fn*)test_multiple_get_last_disconnect},
6272 {0, 0, (test_callback_fn*)0}
6273 };
6274
6275
6276 test_st result_tests[] ={
6277 {"result static", 0, (test_callback_fn*)result_static},
6278 {"result alloc", 0, (test_callback_fn*)result_alloc},
6279 {0, 0, (test_callback_fn*)0}
6280 };
6281
6282 test_st version_1_2_3[] ={
6283 {"append", 0, (test_callback_fn*)append_test },
6284 {"prepend", 0, (test_callback_fn*)prepend_test },
6285 {"cas", 0, (test_callback_fn*)cas_test },
6286 {"cas2", 0, (test_callback_fn*)cas2_test },
6287 {"append_binary", 0, (test_callback_fn*)append_binary_test },
6288 {0, 0, (test_callback_fn*)0}
6289 };
6290
6291 test_st haldenbrand_tests[] ={
6292 {"memcached_set", 0, (test_callback_fn*)user_supplied_bug1 },
6293 {"memcached_get()", 0, (test_callback_fn*)user_supplied_bug2 },
6294 {"memcached_mget()", 0, (test_callback_fn*)user_supplied_bug3 },
6295 {0, 0, (test_callback_fn*)0}
6296 };
6297
6298 test_st user_tests[] ={
6299 {"user_supplied_bug4", true, (test_callback_fn*)user_supplied_bug4 },
6300 {"user_supplied_bug5", 1, (test_callback_fn*)user_supplied_bug5 },
6301 {"user_supplied_bug6", 1, (test_callback_fn*)user_supplied_bug6 },
6302 {"user_supplied_bug7", 1, (test_callback_fn*)user_supplied_bug7 },
6303 {"user_supplied_bug8", 1, (test_callback_fn*)user_supplied_bug8 },
6304 {"user_supplied_bug9", 1, (test_callback_fn*)user_supplied_bug9 },
6305 {"user_supplied_bug10", 1, (test_callback_fn*)user_supplied_bug10 },
6306 {"user_supplied_bug11", 1, (test_callback_fn*)user_supplied_bug11 },
6307 {"user_supplied_bug12", 1, (test_callback_fn*)user_supplied_bug12 },
6308 {"user_supplied_bug13", 1, (test_callback_fn*)user_supplied_bug13 },
6309 {"user_supplied_bug14", 1, (test_callback_fn*)user_supplied_bug14 },
6310 {"user_supplied_bug15", 1, (test_callback_fn*)user_supplied_bug15 },
6311 {"user_supplied_bug16", 1, (test_callback_fn*)user_supplied_bug16 },
6312 #if !defined(__sun) && !defined(__OpenBSD__)
6313 /*
6314 ** It seems to be something weird with the character sets..
6315 ** value_fetch is unable to parse the value line (iscntrl "fails"), so I
6316 ** guess I need to find out how this is supposed to work.. Perhaps I need
6317 ** to run the test in a specific locale (I tried zh_CN.UTF-8 without success,
6318 ** so just disable the code for now...).
6319 */
6320 {"user_supplied_bug17", 1, (test_callback_fn*)user_supplied_bug17 },
6321 #endif
6322 {"user_supplied_bug18", 1, (test_callback_fn*)user_supplied_bug18 },
6323 {"user_supplied_bug19", 1, (test_callback_fn*)user_supplied_bug19 },
6324 {"user_supplied_bug20", 1, (test_callback_fn*)user_supplied_bug20 },
6325 {"user_supplied_bug21", 1, (test_callback_fn*)user_supplied_bug21 },
6326 {"wrong_failure_counter_test", 1, (test_callback_fn*)wrong_failure_counter_test},
6327 {"wrong_failure_counter_two_test", 1, (test_callback_fn*)wrong_failure_counter_two_test},
6328 {0, 0, (test_callback_fn*)0}
6329 };
6330
6331 test_st replication_tests[]= {
6332 {"set", 1, (test_callback_fn*)replication_set_test },
6333 {"get", 0, (test_callback_fn*)replication_get_test },
6334 {"mget", 0, (test_callback_fn*)replication_mget_test },
6335 {"delete", 0, (test_callback_fn*)replication_delete_test },
6336 {"rand_mget", 0, (test_callback_fn*)replication_randomize_mget_test },
6337 {"fail", 0, (test_callback_fn*)replication_randomize_mget_fail_test },
6338 {0, 0, (test_callback_fn*)0}
6339 };
6340
6341 /*
6342 * The following test suite is used to verify that we don't introduce
6343 * regression bugs. If you want more information about the bug / test,
6344 * you should look in the bug report at
6345 * http://bugs.launchpad.net/libmemcached
6346 */
6347 test_st regression_tests[]= {
6348 {"lp:434484", 1, (test_callback_fn*)regression_bug_434484 },
6349 {"lp:434843", 1, (test_callback_fn*)regression_bug_434843 },
6350 {"lp:434843-buffered", 1, (test_callback_fn*)regression_bug_434843_buffered },
6351 {"lp:421108", 1, (test_callback_fn*)regression_bug_421108 },
6352 {"lp:442914", 1, (test_callback_fn*)regression_bug_442914 },
6353 {"lp:447342", 1, (test_callback_fn*)regression_bug_447342 },
6354 {"lp:463297", 1, (test_callback_fn*)regression_bug_463297 },
6355 {"lp:490486", 1, (test_callback_fn*)regression_bug_490486 },
6356 {"lp:583031", 1, (test_callback_fn*)regression_bug_583031 },
6357 {"lp:?", 1, (test_callback_fn*)regression_bug_ },
6358 {"lp:728286", 1, (test_callback_fn*)regression_bug_728286 },
6359 {"lp:581030", 1, (test_callback_fn*)regression_bug_581030 },
6360 {"lp:71231153 connect()", 1, (test_callback_fn*)regression_bug_71231153_connect },
6361 {"lp:71231153 poll()", 1, (test_callback_fn*)regression_bug_71231153_poll },
6362 {"lp:655423", 1, (test_callback_fn*)regression_bug_655423 },
6363 {"lp:490520", 1, (test_callback_fn*)regression_bug_490520 },
6364 {0, 0, (test_callback_fn*)0}
6365 };
6366
6367 test_st sasl_auth_tests[]= {
6368 {"sasl_auth", 1, (test_callback_fn*)sasl_auth_test },
6369 {0, 0, (test_callback_fn*)0}
6370 };
6371
6372 test_st ketama_compatibility[]= {
6373 {"libmemcached", 1, (test_callback_fn*)ketama_compatibility_libmemcached },
6374 {"spymemcached", 1, (test_callback_fn*)ketama_compatibility_spymemcached },
6375 {0, 0, (test_callback_fn*)0}
6376 };
6377
6378 test_st generate_tests[] ={
6379 {"generate_pairs", 1, (test_callback_fn*)generate_pairs },
6380 {"generate_data", 1, (test_callback_fn*)generate_data },
6381 {"get_read", 0, (test_callback_fn*)get_read },
6382 {"delete_generate", 0, (test_callback_fn*)delete_generate },
6383 {"generate_buffer_data", 1, (test_callback_fn*)generate_buffer_data },
6384 {"delete_buffer", 0, (test_callback_fn*)delete_buffer_generate},
6385 {"generate_data", 1, (test_callback_fn*)generate_data },
6386 {"mget_read", 0, (test_callback_fn*)mget_read },
6387 {"mget_read_result", 0, (test_callback_fn*)mget_read_result },
6388 {"memcached_fetch_result() use internal result", 0, (test_callback_fn*)mget_read_internal_result },
6389 {"memcached_fetch_result() partial read", 0, (test_callback_fn*)mget_read_partial_result },
6390 {"mget_read_function", 0, (test_callback_fn*)mget_read_function },
6391 {"cleanup", 1, (test_callback_fn*)cleanup_pairs },
6392 {"generate_large_pairs", 1, (test_callback_fn*)generate_large_pairs },
6393 {"generate_data", 1, (test_callback_fn*)generate_data },
6394 {"generate_buffer_data", 1, (test_callback_fn*)generate_buffer_data },
6395 {"cleanup", 1, (test_callback_fn*)cleanup_pairs },
6396 {0, 0, (test_callback_fn*)0}
6397 };
6398
6399 test_st consistent_tests[] ={
6400 {"generate_pairs", 1, (test_callback_fn*)generate_pairs },
6401 {"generate_data", 1, (test_callback_fn*)generate_data },
6402 {"get_read", 0, (test_callback_fn*)get_read_count },
6403 {"cleanup", 1, (test_callback_fn*)cleanup_pairs },
6404 {0, 0, (test_callback_fn*)0}
6405 };
6406
6407 test_st consistent_weighted_tests[] ={
6408 {"generate_pairs", 1, (test_callback_fn*)generate_pairs },
6409 {"generate_data", 1, (test_callback_fn*)generate_data_with_stats },
6410 {"get_read", 0, (test_callback_fn*)get_read_count },
6411 {"cleanup", 1, (test_callback_fn*)cleanup_pairs },
6412 {0, 0, (test_callback_fn*)0}
6413 };
6414
6415 test_st hsieh_availability[] ={
6416 {"hsieh_avaibility_test", 0, (test_callback_fn*)hsieh_avaibility_test},
6417 {0, 0, (test_callback_fn*)0}
6418 };
6419
6420 test_st murmur_availability[] ={
6421 {"murmur_avaibility_test", 0, (test_callback_fn*)murmur_avaibility_test},
6422 {0, 0, (test_callback_fn*)0}
6423 };
6424
6425 #if 0
6426 test_st hash_sanity[] ={
6427 {"hash sanity", 0, (test_callback_fn*)hash_sanity_test},
6428 {0, 0, (test_callback_fn*)0}
6429 };
6430 #endif
6431
6432 test_st ketama_auto_eject_hosts[] ={
6433 {"auto_eject_hosts", 1, (test_callback_fn*)auto_eject_hosts },
6434 {"output_ketama_weighted_keys", 1, (test_callback_fn*)output_ketama_weighted_keys },
6435 {0, 0, (test_callback_fn*)0}
6436 };
6437
6438 test_st hash_tests[] ={
6439 {"one_at_a_time_run", 0, (test_callback_fn*)one_at_a_time_run },
6440 {"md5", 0, (test_callback_fn*)md5_run },
6441 {"crc", 0, (test_callback_fn*)crc_run },
6442 {"fnv1_64", 0, (test_callback_fn*)fnv1_64_run },
6443 {"fnv1a_64", 0, (test_callback_fn*)fnv1a_64_run },
6444 {"fnv1_32", 0, (test_callback_fn*)fnv1_32_run },
6445 {"fnv1a_32", 0, (test_callback_fn*)fnv1a_32_run },
6446 {"hsieh", 0, (test_callback_fn*)hsieh_run },
6447 {"murmur", 0, (test_callback_fn*)murmur_run },
6448 {"jenkis", 0, (test_callback_fn*)jenkins_run },
6449 {"memcached_get_hashkit", 0, (test_callback_fn*)memcached_get_hashkit_test },
6450 {0, 0, (test_callback_fn*)0}
6451 };
6452
6453 test_st error_conditions[] ={
6454 {"memcached_get(MEMCACHED_ERRNO)", 0, (test_callback_fn*)memcached_get_MEMCACHED_ERRNO },
6455 {"memcached_get(MEMCACHED_NOTFOUND)", 0, (test_callback_fn*)memcached_get_MEMCACHED_NOTFOUND },
6456 {"memcached_get_by_key(MEMCACHED_ERRNO)", 0, (test_callback_fn*)memcached_get_by_key_MEMCACHED_ERRNO },
6457 {"memcached_get_by_key(MEMCACHED_NOTFOUND)", 0, (test_callback_fn*)memcached_get_by_key_MEMCACHED_NOTFOUND },
6458 {"memcached_get_by_key(MEMCACHED_NOTFOUND)", 0, (test_callback_fn*)memcached_get_by_key_MEMCACHED_NOTFOUND },
6459 {"memcached_increment(MEMCACHED_NO_SERVERS)", 0, (test_callback_fn*)memcached_increment_MEMCACHED_NO_SERVERS },
6460 {0, 0, (test_callback_fn*)0}
6461 };
6462
6463
6464 test_st parser_tests[] ={
6465 {"behavior", 0, (test_callback_fn*)behavior_parser_test },
6466 {"boolean_options", 0, (test_callback_fn*)parser_boolean_options_test },
6467 {"configure_file", 0, (test_callback_fn*)memcached_create_with_options_with_filename },
6468 {"distribtions", 0, (test_callback_fn*)parser_distribution_test },
6469 {"hash", 0, (test_callback_fn*)parser_hash_test },
6470 {"libmemcached_check_configuration", 0, (test_callback_fn*)libmemcached_check_configuration_test },
6471 {"libmemcached_check_configuration_with_filename", 0, (test_callback_fn*)libmemcached_check_configuration_with_filename_test },
6472 {"number_options", 0, (test_callback_fn*)parser_number_options_test },
6473 {"randomly generated options", 0, (test_callback_fn*)random_statement_build_test },
6474 {"prefix_key", 0, (test_callback_fn*)parser_key_prefix_test },
6475 {"server", 0, (test_callback_fn*)server_test },
6476 {"bad server strings", 0, (test_callback_fn*)servers_bad_test },
6477 {"server with weights", 0, (test_callback_fn*)server_with_weight_test },
6478 {"parsing servername, port, and weight", 0, (test_callback_fn*)test_hostname_port_weight },
6479 {0, 0, (test_callback_fn*)0}
6480 };
6481
6482 test_st virtual_bucket_tests[] ={
6483 {"basic", 0, (test_callback_fn*)virtual_back_map },
6484 {0, 0, (test_callback_fn*)0}
6485 };
6486
6487 test_st namespace_tests[] ={
6488 {"basic tests", 0, (test_callback_fn*)selection_of_namespace_tests },
6489 {"increment", 0, (test_callback_fn*)memcached_increment_namespace },
6490 {0, 0, (test_callback_fn*)0}
6491 };
6492
6493 collection_st collection[] ={
6494 #if 0
6495 {"hash_sanity", 0, 0, hash_sanity},
6496 #endif
6497 {"basic", 0, 0, basic_tests},
6498 {"hsieh_availability", 0, 0, hsieh_availability},
6499 {"murmur_availability", 0, 0, murmur_availability},
6500 {"block", 0, 0, tests},
6501 {"binary", (test_callback_fn*)pre_binary, 0, tests},
6502 {"nonblock", (test_callback_fn*)pre_nonblock, 0, tests},
6503 {"nodelay", (test_callback_fn*)pre_nodelay, 0, tests},
6504 {"settimer", (test_callback_fn*)pre_settimer, 0, tests},
6505 {"md5", (test_callback_fn*)pre_md5, 0, tests},
6506 {"crc", (test_callback_fn*)pre_crc, 0, tests},
6507 {"hsieh", (test_callback_fn*)pre_hsieh, 0, tests},
6508 {"jenkins", (test_callback_fn*)pre_jenkins, 0, tests},
6509 {"fnv1_64", (test_callback_fn*)pre_hash_fnv1_64, 0, tests},
6510 {"fnv1a_64", (test_callback_fn*)pre_hash_fnv1a_64, 0, tests},
6511 {"fnv1_32", (test_callback_fn*)pre_hash_fnv1_32, 0, tests},
6512 {"fnv1a_32", (test_callback_fn*)pre_hash_fnv1a_32, 0, tests},
6513 {"ketama", (test_callback_fn*)pre_behavior_ketama, 0, tests},
6514 {"ketama_auto_eject_hosts", (test_callback_fn*)pre_behavior_ketama, 0, ketama_auto_eject_hosts},
6515 {"unix_socket", (test_callback_fn*)pre_unix_socket, 0, tests},
6516 {"unix_socket_nodelay", (test_callback_fn*)pre_nodelay, 0, tests},
6517 {"poll_timeout", (test_callback_fn*)poll_timeout, 0, tests},
6518 {"gets", (test_callback_fn*)enable_cas, 0, tests},
6519 {"consistent_crc", (test_callback_fn*)enable_consistent_crc, 0, tests},
6520 {"consistent_hsieh", (test_callback_fn*)enable_consistent_hsieh, 0, tests},
6521 #ifdef MEMCACHED_ENABLE_DEPRECATED
6522 {"deprecated_memory_allocators", (test_callback_fn*)deprecated_set_memory_alloc, 0, tests},
6523 #endif
6524 {"memory_allocators", (test_callback_fn*)set_memory_alloc, 0, tests},
6525 {"namespace", (test_callback_fn*)set_namespace, 0, tests},
6526 {"namespace(BINARY)", (test_callback_fn*)set_namespace_and_binary, 0, tests},
6527 {"specific namespace", 0, 0, namespace_tests},
6528 {"sasl_auth", (test_callback_fn*)pre_sasl, 0, sasl_auth_tests },
6529 {"sasl", (test_callback_fn*)pre_sasl, 0, tests },
6530 {"version_1_2_3", (test_callback_fn*)check_for_1_2_3, 0, version_1_2_3},
6531 {"string", 0, 0, string_tests},
6532 {"result", 0, 0, result_tests},
6533 {"async", (test_callback_fn*)pre_nonblock, 0, async_tests},
6534 {"async_binary", (test_callback_fn*)pre_nonblock_binary, 0, async_tests},
6535 {"Cal Haldenbrand's tests", 0, 0, haldenbrand_tests},
6536 {"user", 0, 0, user_tests},
6537 {"generate", 0, 0, generate_tests},
6538 {"generate_hsieh", (test_callback_fn*)pre_hsieh, 0, generate_tests},
6539 {"generate_ketama", (test_callback_fn*)pre_behavior_ketama, 0, generate_tests},
6540 {"generate_hsieh_consistent", (test_callback_fn*)enable_consistent_hsieh, 0, generate_tests},
6541 {"generate_md5", (test_callback_fn*)pre_md5, 0, generate_tests},
6542 {"generate_murmur", (test_callback_fn*)pre_murmur, 0, generate_tests},
6543 {"generate_jenkins", (test_callback_fn*)pre_jenkins, 0, generate_tests},
6544 {"generate_nonblock", (test_callback_fn*)pre_nonblock, 0, generate_tests},
6545 // Too slow
6546 {"generate_corked", (test_callback_fn*)pre_cork, 0, generate_tests},
6547 {"generate_corked_and_nonblock", (test_callback_fn*)pre_cork_and_nonblock, 0, generate_tests},
6548 {"consistent_not", 0, 0, consistent_tests},
6549 {"consistent_ketama", (test_callback_fn*)pre_behavior_ketama, 0, consistent_tests},
6550 {"consistent_ketama_weighted", (test_callback_fn*)pre_behavior_ketama_weighted, 0, consistent_weighted_tests},
6551 {"ketama_compat", 0, 0, ketama_compatibility},
6552 {"test_hashes", 0, 0, hash_tests},
6553 {"replication", (test_callback_fn*)pre_replication, 0, replication_tests},
6554 {"replication_noblock", (test_callback_fn*)pre_replication_noblock, 0, replication_tests},
6555 {"regression", 0, 0, regression_tests},
6556 {"behaviors", 0, 0, behavior_tests},
6557 {"regression_binary_vs_block", (test_callback_fn*)key_setup, (test_callback_fn*)key_teardown, regression_binary_vs_block},
6558 {"error_conditions", 0, 0, error_conditions},
6559 {"parser", 0, 0, parser_tests},
6560 {"virtual buckets", 0, 0, virtual_bucket_tests},
6561 {"memcached_server_get_last_disconnect", 0, 0, memcached_server_get_last_disconnect_tests},
6562 {0, 0, 0, 0}
6563 };
6564
6565 #include "tests/libmemcached_world.h"
6566
6567 void get_world(Framework *world)
6568 {
6569 world->collections= collection;
6570
6571 world->_create= (test_callback_create_fn*)world_create;
6572 world->_destroy= (test_callback_fn*)world_destroy;
6573
6574 world->item._startup= (test_callback_fn*)world_test_startup;
6575 world->item._flush= (test_callback_fn*)world_flush;
6576 world->item.set_pre((test_callback_fn*)world_pre_run);
6577 world->item.set_post((test_callback_fn*)world_post_run);
6578 world->_on_error= (test_callback_error_fn*)world_on_error;
6579
6580 world->collection_startup= (test_callback_fn*)world_container_startup;
6581 world->collection_shutdown= (test_callback_fn*)world_container_shutdown;
6582
6583 world->runner= &defualt_libmemcached_runner;
6584 }