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