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