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