e787070b6df78bcbc91d2555082810521fdb8339
[awesomized/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 memcached_return_t rc;
2490 const char *keys= "036790384900";
2491 size_t key_length= strlen(keys);
2492 char return_key[MEMCACHED_MAX_KEY];
2493 size_t return_key_length;
2494 char *value;
2495 size_t value_length;
2496 uint32_t flags;
2497 unsigned int x;
2498 char *insert_data= new (std::nothrow) char[VALUE_SIZE_BUG5];
2499
2500 for (x= 0; x < VALUE_SIZE_BUG5; x++)
2501 insert_data[x]= (signed char)rand();
2502
2503 memcached_flush(memc, 0);
2504
2505 flags= 245;
2506 rc= memcached_set(memc, keys, key_length,
2507 insert_data, VALUE_SIZE_BUG5,
2508 (time_t)0, flags);
2509 test_true(rc == MEMCACHED_SUCCESS);
2510
2511 flags= 0;
2512 value= memcached_get(memc, keys, key_length,
2513 &value_length, &flags, &rc);
2514 test_true(flags == 245);
2515 test_true(value);
2516 free(value);
2517
2518 rc= memcached_mget(memc, &keys, &key_length, 1);
2519
2520 flags= 0;
2521 value= memcached_fetch(memc, return_key, &return_key_length,
2522 &value_length, &flags, &rc);
2523 test_compare(245, flags);
2524 test_true(value);
2525 free(value);
2526 delete [] insert_data;
2527
2528
2529 return TEST_SUCCESS;
2530 }
2531
2532 static test_return_t user_supplied_bug9(memcached_st *memc)
2533 {
2534 memcached_return_t rc;
2535 const char *keys[]= {"UDATA:edevil@sapo.pt", "fudge&*@#", "for^#@&$not"};
2536 size_t key_length[3];
2537 uint32_t flags;
2538 unsigned count= 0;
2539
2540 char return_key[MEMCACHED_MAX_KEY];
2541 size_t return_key_length;
2542 char *return_value;
2543 size_t return_value_length;
2544
2545
2546 key_length[0]= strlen("UDATA:edevil@sapo.pt");
2547 key_length[1]= strlen("fudge&*@#");
2548 key_length[2]= strlen("for^#@&$not");
2549
2550
2551 for (unsigned int x= 0; x < 3; x++)
2552 {
2553 rc= memcached_set(memc, keys[x], key_length[x],
2554 keys[x], key_length[x],
2555 (time_t)50, (uint32_t)9);
2556 test_true(rc == MEMCACHED_SUCCESS);
2557 }
2558
2559 rc= memcached_mget(memc, keys, key_length, 3);
2560 test_true(rc == MEMCACHED_SUCCESS);
2561
2562 /* We need to empty the server before continueing test */
2563 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
2564 &return_value_length, &flags, &rc)) != NULL)
2565 {
2566 test_true(return_value);
2567 free(return_value);
2568 count++;
2569 }
2570 test_true(count == 3);
2571
2572 return TEST_SUCCESS;
2573 }
2574
2575 /* We are testing with aggressive timeout to get failures */
2576 static test_return_t user_supplied_bug10(memcached_st *memc)
2577 {
2578 const char *key= "foo";
2579 char *value;
2580 size_t value_length= 512;
2581 unsigned int x;
2582 size_t key_len= 3;
2583 memcached_return_t rc;
2584 unsigned int set= 1;
2585 memcached_st *mclone= memcached_clone(NULL, memc);
2586 int32_t timeout;
2587
2588 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_NO_BLOCK, set);
2589 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_TCP_NODELAY, set);
2590 timeout= 2;
2591 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT,
2592 (uint64_t)timeout);
2593
2594 value = (char*)malloc(value_length * sizeof(char));
2595
2596 for (x= 0; x < value_length; x++)
2597 value[x]= (char) (x % 127);
2598
2599 for (x= 1; x <= 100000; ++x)
2600 {
2601 rc= memcached_set(mclone, key, key_len,value, value_length, 0, 0);
2602
2603 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_WRITE_FAILURE ||
2604 rc == MEMCACHED_BUFFERED || rc == MEMCACHED_TIMEOUT);
2605
2606 if (rc == MEMCACHED_WRITE_FAILURE || rc == MEMCACHED_TIMEOUT)
2607 x--;
2608 }
2609
2610 free(value);
2611 memcached_free(mclone);
2612
2613 return TEST_SUCCESS;
2614 }
2615
2616 /*
2617 We are looking failures in the async protocol
2618 */
2619 static test_return_t user_supplied_bug11(memcached_st *memc)
2620 {
2621 const char *key= "foo";
2622 char *value;
2623 size_t value_length= 512;
2624 unsigned int x;
2625 size_t key_len= 3;
2626 memcached_return_t rc;
2627 unsigned int set= 1;
2628 int32_t timeout;
2629 memcached_st *mclone= memcached_clone(NULL, memc);
2630
2631 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_NO_BLOCK, set);
2632 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_TCP_NODELAY, set);
2633 timeout= -1;
2634 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT,
2635 (size_t)timeout);
2636
2637 timeout= (int32_t)memcached_behavior_get(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT);
2638
2639 test_true(timeout == -1);
2640
2641 value = (char*)malloc(value_length * sizeof(char));
2642
2643 for (x= 0; x < value_length; x++)
2644 value[x]= (char) (x % 127);
2645
2646 for (x= 1; x <= 100000; ++x)
2647 {
2648 rc= memcached_set(mclone, key, key_len,value, value_length, 0, 0);
2649 }
2650
2651 free(value);
2652 memcached_free(mclone);
2653
2654 return TEST_SUCCESS;
2655 }
2656
2657 /*
2658 Bug found where incr was not returning MEMCACHED_NOTFOUND when object did not exist.
2659 */
2660 static test_return_t user_supplied_bug12(memcached_st *memc)
2661 {
2662 memcached_return_t rc;
2663 uint32_t flags;
2664 size_t value_length;
2665 char *value;
2666 uint64_t number_value;
2667
2668 value= memcached_get(memc, "autoincrement", strlen("autoincrement"),
2669 &value_length, &flags, &rc);
2670 test_true(value == NULL);
2671 test_true(rc == MEMCACHED_NOTFOUND);
2672
2673 rc= memcached_increment(memc, "autoincrement", strlen("autoincrement"),
2674 1, &number_value);
2675
2676 test_true(value == NULL);
2677 /* The binary protocol will set the key if it doesn't exist */
2678 if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 1)
2679 {
2680 test_true(rc == MEMCACHED_SUCCESS);
2681 }
2682 else
2683 {
2684 test_true(rc == MEMCACHED_NOTFOUND);
2685 }
2686
2687 rc= memcached_set(memc, "autoincrement", strlen("autoincrement"), "1", 1, 0, 0);
2688
2689 value= memcached_get(memc, "autoincrement", strlen("autoincrement"),
2690 &value_length, &flags, &rc);
2691 test_true(value);
2692 test_true(rc == MEMCACHED_SUCCESS);
2693 free(value);
2694
2695 rc= memcached_increment(memc, "autoincrement", strlen("autoincrement"),
2696 1, &number_value);
2697 test_true(number_value == 2);
2698 test_true(rc == MEMCACHED_SUCCESS);
2699
2700 return TEST_SUCCESS;
2701 }
2702
2703 /*
2704 Bug found where command total one more than MEMCACHED_MAX_BUFFER
2705 set key34567890 0 0 8169 \r\n is sent followed by buffer of size 8169, followed by 8169
2706 */
2707 static test_return_t user_supplied_bug13(memcached_st *memc)
2708 {
2709 char key[] = "key34567890";
2710 memcached_return_t rc;
2711 size_t overflowSize;
2712
2713 char commandFirst[]= "set key34567890 0 0 ";
2714 char commandLast[] = " \r\n"; /* first line of command sent to server */
2715 size_t commandLength;
2716 size_t testSize;
2717
2718 commandLength = strlen(commandFirst) + strlen(commandLast) + 4; /* 4 is number of characters in size, probably 8196 */
2719
2720 overflowSize = MEMCACHED_MAX_BUFFER - commandLength;
2721
2722 for (testSize= overflowSize - 1; testSize < overflowSize + 1; testSize++)
2723 {
2724 char *overflow= new (std::nothrow) char[testSize];
2725 test_true(overflow);
2726
2727 memset(overflow, 'x', testSize);
2728 rc= memcached_set(memc, key, strlen(key),
2729 overflow, testSize, 0, 0);
2730 test_true(rc == MEMCACHED_SUCCESS);
2731 delete overflow;
2732 }
2733
2734 return TEST_SUCCESS;
2735 }
2736
2737
2738 /*
2739 Test values of many different sizes
2740 Bug found where command total one more than MEMCACHED_MAX_BUFFER
2741 set key34567890 0 0 8169 \r\n
2742 is sent followed by buffer of size 8169, followed by 8169
2743 */
2744 static test_return_t user_supplied_bug14(memcached_st *memc)
2745 {
2746 size_t setter= 1;
2747 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, setter);
2748 memcached_return_t rc;
2749 const char *key= "foo";
2750 char *value;
2751 size_t value_length= 18000;
2752 char *string;
2753 size_t string_length;
2754 uint32_t flags;
2755 unsigned int x;
2756 size_t current_length;
2757
2758 value = (char*)malloc(value_length);
2759 test_true(value);
2760
2761 for (x= 0; x < value_length; x++)
2762 value[x] = (char) (x % 127);
2763
2764 for (current_length= 0; current_length < value_length; current_length++)
2765 {
2766 rc= memcached_set(memc, key, strlen(key),
2767 value, current_length,
2768 (time_t)0, (uint32_t)0);
2769 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
2770
2771 string= memcached_get(memc, key, strlen(key),
2772 &string_length, &flags, &rc);
2773
2774 test_true(rc == MEMCACHED_SUCCESS);
2775 test_true(string_length == current_length);
2776 test_true(!memcmp(string, value, string_length));
2777
2778 free(string);
2779 }
2780
2781 free(value);
2782
2783 return TEST_SUCCESS;
2784 }
2785
2786 /*
2787 Look for zero length value problems
2788 */
2789 static test_return_t user_supplied_bug15(memcached_st *memc)
2790 {
2791 uint32_t x;
2792 memcached_return_t rc;
2793 const char *key= "mykey";
2794 char *value;
2795 size_t length;
2796 uint32_t flags;
2797
2798 for (x= 0; x < 2; x++)
2799 {
2800 rc= memcached_set(memc, key, strlen(key),
2801 NULL, 0,
2802 (time_t)0, (uint32_t)0);
2803
2804 test_true(rc == MEMCACHED_SUCCESS);
2805
2806 value= memcached_get(memc, key, strlen(key),
2807 &length, &flags, &rc);
2808
2809 test_true(rc == MEMCACHED_SUCCESS);
2810 test_true(value == NULL);
2811 test_true(length == 0);
2812 test_true(flags == 0);
2813
2814 value= memcached_get(memc, key, strlen(key),
2815 &length, &flags, &rc);
2816
2817 test_true(rc == MEMCACHED_SUCCESS);
2818 test_true(value == NULL);
2819 test_true(length == 0);
2820 test_true(flags == 0);
2821 }
2822
2823 return TEST_SUCCESS;
2824 }
2825
2826 /* Check the return sizes on FLAGS to make sure it stores 32bit unsigned values correctly */
2827 static test_return_t user_supplied_bug16(memcached_st *memc)
2828 {
2829 memcached_return_t rc;
2830 const char *key= "mykey";
2831 char *value;
2832 size_t length;
2833 uint32_t flags;
2834
2835 rc= memcached_set(memc, key, strlen(key),
2836 NULL, 0,
2837 (time_t)0, UINT32_MAX);
2838
2839 test_true(rc == MEMCACHED_SUCCESS);
2840
2841 value= memcached_get(memc, key, strlen(key),
2842 &length, &flags, &rc);
2843
2844 test_true(rc == MEMCACHED_SUCCESS);
2845 test_true(value == NULL);
2846 test_true(length == 0);
2847 test_true(flags == UINT32_MAX);
2848
2849 return TEST_SUCCESS;
2850 }
2851
2852 #if !defined(__sun) && !defined(__OpenBSD__)
2853 /* Check the validity of chinese key*/
2854 static test_return_t user_supplied_bug17(memcached_st *memc)
2855 {
2856 memcached_return_t rc;
2857 const char *key= "豆瓣";
2858 const char *value="我们在炎热抑郁的夏天无法停止豆瓣";
2859 char *value2;
2860 size_t length;
2861 uint32_t flags;
2862
2863 rc= memcached_set(memc, key, strlen(key),
2864 value, strlen(value),
2865 (time_t)0, 0);
2866
2867 test_true(rc == MEMCACHED_SUCCESS);
2868
2869 value2= memcached_get(memc, key, strlen(key),
2870 &length, &flags, &rc);
2871
2872 test_true(length==strlen(value));
2873 test_true(rc == MEMCACHED_SUCCESS);
2874 test_true(memcmp(value, value2, length)==0);
2875 free(value2);
2876
2877 return TEST_SUCCESS;
2878 }
2879 #endif
2880
2881 /*
2882 From Andrei on IRC
2883 */
2884
2885 static test_return_t user_supplied_bug19(memcached_st *not_used)
2886 {
2887 memcached_st *memc;
2888 const memcached_server_st *server;
2889 memcached_return_t res;
2890
2891 (void)not_used;
2892
2893 memc= memcached_create(NULL);
2894 memcached_server_add_with_weight(memc, "localhost", 11311, 100);
2895 memcached_server_add_with_weight(memc, "localhost", 11312, 100);
2896
2897 server= memcached_server_by_key(memc, "a", 1, &res);
2898
2899 memcached_free(memc);
2900
2901 return TEST_SUCCESS;
2902 }
2903
2904 /* CAS test from Andei */
2905 static test_return_t user_supplied_bug20(memcached_st *memc)
2906 {
2907 memcached_return_t status;
2908 memcached_result_st *result, result_obj;
2909 const char *key = "abc";
2910 size_t key_len = strlen("abc");
2911 const char *value = "foobar";
2912 size_t value_len = strlen(value);
2913
2914 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, 1);
2915
2916 status = memcached_set(memc, key, key_len, value, value_len, (time_t)0, (uint32_t)0);
2917 test_true(status == MEMCACHED_SUCCESS);
2918
2919 status = memcached_mget(memc, &key, &key_len, 1);
2920 test_true(status == MEMCACHED_SUCCESS);
2921
2922 result= memcached_result_create(memc, &result_obj);
2923 test_true(result);
2924
2925 memcached_result_create(memc, &result_obj);
2926 result= memcached_fetch_result(memc, &result_obj, &status);
2927
2928 test_true(result);
2929 test_true(status == MEMCACHED_SUCCESS);
2930
2931 memcached_result_free(result);
2932
2933 return TEST_SUCCESS;
2934 }
2935
2936 #include "ketama_test_cases.h"
2937 static test_return_t user_supplied_bug18(memcached_st *trash)
2938 {
2939 memcached_return_t rc;
2940 uint64_t value;
2941 int x;
2942 memcached_server_st *server_pool;
2943 memcached_st *memc;
2944
2945 (void)trash;
2946
2947 memc= memcached_create(NULL);
2948 test_true(memc);
2949
2950 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
2951 test_true(rc == MEMCACHED_SUCCESS);
2952
2953 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
2954 test_true(value == 1);
2955
2956 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
2957 test_true(rc == MEMCACHED_SUCCESS);
2958
2959 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
2960 test_true(value == MEMCACHED_HASH_MD5);
2961
2962 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");
2963 memcached_server_push(memc, server_pool);
2964
2965 /* verify that the server list was parsed okay. */
2966 test_true(memcached_server_count(memc) == 8);
2967 test_true(strcmp(server_pool[0].hostname, "10.0.1.1") == 0);
2968 test_true(server_pool[0].port == 11211);
2969 test_true(server_pool[0].weight == 600);
2970 test_true(strcmp(server_pool[2].hostname, "10.0.1.3") == 0);
2971 test_true(server_pool[2].port == 11211);
2972 test_true(server_pool[2].weight == 200);
2973 test_true(strcmp(server_pool[7].hostname, "10.0.1.8") == 0);
2974 test_true(server_pool[7].port == 11211);
2975 test_true(server_pool[7].weight == 100);
2976
2977 /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets
2978 * us test the boundary wraparound.
2979 */
2980 test_true(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->ketama.continuum[0].index);
2981
2982 /* verify the standard ketama set. */
2983 for (x= 0; x < 99; x++)
2984 {
2985 uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
2986
2987 memcached_server_instance_st instance=
2988 memcached_server_instance_by_position(memc, server_idx);
2989
2990 const char *hostname = memcached_server_name(instance);
2991 test_strcmp(hostname, ketama_test_cases[x].server);
2992 }
2993
2994 memcached_server_list_free(server_pool);
2995 memcached_free(memc);
2996
2997 return TEST_SUCCESS;
2998 }
2999
3000 /* Large mget() of missing keys with binary proto
3001 *
3002 * If many binary quiet commands (such as getq's in an mget) fill the output
3003 * buffer and the server chooses not to respond, memcached_flush hangs. See
3004 * http://lists.tangent.org/pipermail/libmemcached/2009-August/000918.html
3005 */
3006
3007 /* sighandler_t function that always asserts false */
3008 static void fail(int unused)
3009 {
3010 (void)unused;
3011 assert(0);
3012 }
3013
3014
3015 static test_return_t _user_supplied_bug21(memcached_st* memc, size_t key_count)
3016 {
3017 #ifdef WIN32
3018 (void)memc;
3019 (void)key_count;
3020 return TEST_SKIPPED;
3021 #else
3022 memcached_return_t rc;
3023 unsigned int x;
3024 char **keys;
3025 size_t* key_lengths;
3026 void (*oldalarm)(int);
3027 memcached_st *memc_clone;
3028
3029 memc_clone= memcached_clone(NULL, memc);
3030 test_true(memc_clone);
3031
3032 /* only binproto uses getq for mget */
3033 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
3034
3035 /* empty the cache to ensure misses (hence non-responses) */
3036 rc= memcached_flush(memc_clone, 0);
3037 test_true(rc == MEMCACHED_SUCCESS);
3038
3039 key_lengths= new (std::nothrow) size_t[key_count];
3040 test_true(key_lengths);
3041 keys= static_cast<char **>(calloc(key_count, sizeof(char *)));
3042 test_true(keys);
3043 for (x= 0; x < key_count; x++)
3044 {
3045 char buffer[30];
3046
3047 snprintf(buffer, 30, "%u", x);
3048 keys[x]= strdup(buffer);
3049 key_lengths[x]= strlen(keys[x]);
3050 }
3051
3052 oldalarm= signal(SIGALRM, fail);
3053 alarm(5);
3054
3055 rc= memcached_mget(memc_clone, (const char **)keys, key_lengths, key_count);
3056 test_true(rc == MEMCACHED_SUCCESS);
3057
3058 alarm(0);
3059 signal(SIGALRM, oldalarm);
3060
3061 size_t keys_returned;
3062 test_true(fetch_all_results(memc, &keys_returned) == TEST_SUCCESS);
3063
3064 for (x= 0; x < key_count; x++)
3065 free(keys[x]);
3066 free(keys);
3067 delete key_lengths;
3068
3069 memcached_free(memc_clone);
3070
3071 return TEST_SUCCESS;
3072 #endif
3073 }
3074
3075 static test_return_t user_supplied_bug21(memcached_st *memc)
3076 {
3077 test_return_t test_rc;
3078 test_rc= pre_binary(memc);
3079
3080 if (test_rc != TEST_SUCCESS)
3081 return test_rc;
3082
3083 test_return_t rc;
3084
3085 /* should work as of r580 */
3086 rc= _user_supplied_bug21(memc, 10);
3087 test_true(rc == TEST_SUCCESS);
3088
3089 /* should fail as of r580 */
3090 rc= _user_supplied_bug21(memc, 1000);
3091 test_true(rc == TEST_SUCCESS);
3092
3093 return TEST_SUCCESS;
3094 }
3095
3096 static test_return_t auto_eject_hosts(memcached_st *trash)
3097 {
3098 (void) trash;
3099 memcached_server_instance_st instance;
3100
3101 memcached_return_t rc;
3102 memcached_st *memc= memcached_create(NULL);
3103 test_true(memc);
3104
3105 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
3106 test_true(rc == MEMCACHED_SUCCESS);
3107
3108 uint64_t value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
3109 test_true(value == 1);
3110
3111 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
3112 test_true(rc == MEMCACHED_SUCCESS);
3113
3114 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
3115 test_true(value == MEMCACHED_HASH_MD5);
3116
3117 /* server should be removed when in delay */
3118 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS, 1);
3119 test_true(rc == MEMCACHED_SUCCESS);
3120
3121 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS);
3122 test_true(value == 1);
3123
3124 memcached_server_st *server_pool;
3125 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");
3126 memcached_server_push(memc, server_pool);
3127
3128 /* verify that the server list was parsed okay. */
3129 test_true(memcached_server_count(memc) == 8);
3130 test_true(strcmp(server_pool[0].hostname, "10.0.1.1") == 0);
3131 test_true(server_pool[0].port == 11211);
3132 test_true(server_pool[0].weight == 600);
3133 test_true(strcmp(server_pool[2].hostname, "10.0.1.3") == 0);
3134 test_true(server_pool[2].port == 11211);
3135 test_true(server_pool[2].weight == 200);
3136 test_true(strcmp(server_pool[7].hostname, "10.0.1.8") == 0);
3137 test_true(server_pool[7].port == 11211);
3138 test_true(server_pool[7].weight == 100);
3139
3140 instance= memcached_server_instance_by_position(memc, 2);
3141 ((memcached_server_write_instance_st)instance)->next_retry = time(NULL) + 15;
3142 memc->ketama.next_distribution_rebuild= time(NULL) - 1;
3143
3144 /*
3145 This would not work if there were only two hosts.
3146 */
3147 for (size_t x= 0; x < 99; x++)
3148 {
3149 memcached_autoeject(memc);
3150 uint32_t server_idx= memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
3151 test_true(server_idx != 2);
3152 }
3153
3154 /* and re-added when it's back. */
3155 ((memcached_server_write_instance_st)instance)->next_retry = time(NULL) - 1;
3156 memc->ketama.next_distribution_rebuild= time(NULL) - 1;
3157 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION,
3158 memc->distribution);
3159 for (size_t x= 0; x < 99; x++)
3160 {
3161 uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
3162 // We re-use instance from above.
3163 instance=
3164 memcached_server_instance_by_position(memc, server_idx);
3165 const char *hostname = memcached_server_name(instance);
3166 test_true(strcmp(hostname, ketama_test_cases[x].server) == 0);
3167 }
3168
3169 memcached_server_list_free(server_pool);
3170 memcached_free(memc);
3171
3172 return TEST_SUCCESS;
3173 }
3174
3175 static test_return_t output_ketama_weighted_keys(memcached_st *trash)
3176 {
3177 (void) trash;
3178
3179 memcached_return_t rc;
3180 memcached_st *memc= memcached_create(NULL);
3181 test_true(memc);
3182
3183
3184 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
3185 test_true(rc == MEMCACHED_SUCCESS);
3186
3187 uint64_t value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
3188 test_true(value == 1);
3189
3190 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
3191 test_true(rc == MEMCACHED_SUCCESS);
3192
3193 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
3194 test_true(value == MEMCACHED_HASH_MD5);
3195
3196
3197 test_true(memcached_behavior_set_distribution(memc, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY) == MEMCACHED_SUCCESS);
3198
3199 memcached_server_st *server_pool;
3200 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");
3201 memcached_server_push(memc, server_pool);
3202
3203 // @todo this needs to be refactored to actually test something.
3204 #if 0
3205 FILE *fp;
3206 if ((fp = fopen("ketama_keys.txt", "w")))
3207 {
3208 // noop
3209 } else {
3210 printf("cannot write to file ketama_keys.txt");
3211 return TEST_FAILURE;
3212 }
3213
3214 for (int x= 0; x < 10000; x++)
3215 {
3216 char key[10];
3217 snprintf(key, sizeof(key), "%d", x);
3218
3219 uint32_t server_idx = memcached_generate_hash(memc, key, strlen(key));
3220 char *hostname = memc->hosts[server_idx].hostname;
3221 in_port_t port = memc->hosts[server_idx].port;
3222 fprintf(fp, "key %s is on host /%s:%u\n", key, hostname, port);
3223 memcached_server_instance_st instance=
3224 memcached_server_instance_by_position(memc, host_index);
3225 }
3226 fclose(fp);
3227 #endif
3228 memcached_server_list_free(server_pool);
3229 memcached_free(memc);
3230
3231 return TEST_SUCCESS;
3232 }
3233
3234
3235 static test_return_t result_static(memcached_st *memc)
3236 {
3237 memcached_result_st result;
3238 memcached_result_st *result_ptr;
3239
3240 result_ptr= memcached_result_create(memc, &result);
3241 test_true(result.options.is_allocated == false);
3242 test_true(memcached_is_initialized(&result) == true);
3243 test_true(result_ptr);
3244 test_true(result_ptr == &result);
3245
3246 memcached_result_free(&result);
3247
3248 test_true(result.options.is_allocated == false);
3249 test_true(memcached_is_initialized(&result) == false);
3250
3251 return TEST_SUCCESS;
3252 }
3253
3254 static test_return_t result_alloc(memcached_st *memc)
3255 {
3256 memcached_result_st *result_ptr;
3257
3258 result_ptr= memcached_result_create(memc, NULL);
3259 test_true(result_ptr);
3260 test_true(result_ptr->options.is_allocated == true);
3261 test_true(memcached_is_initialized(result_ptr) == true);
3262 memcached_result_free(result_ptr);
3263
3264 return TEST_SUCCESS;
3265 }
3266
3267 static test_return_t cleanup_pairs(memcached_st *memc)
3268 {
3269 (void)memc;
3270 pairs_free(global_pairs);
3271
3272 return TEST_SUCCESS;
3273 }
3274
3275 static test_return_t generate_pairs(memcached_st *memc)
3276 {
3277 (void)memc;
3278 global_pairs= pairs_generate(GLOBAL_COUNT, 400);
3279 global_count= GLOBAL_COUNT;
3280
3281 for (size_t x= 0; x < global_count; x++)
3282 {
3283 global_keys[x]= global_pairs[x].key;
3284 global_keys_length[x]= global_pairs[x].key_length;
3285 }
3286
3287 return TEST_SUCCESS;
3288 }
3289
3290 static test_return_t generate_large_pairs(memcached_st *memc)
3291 {
3292 (void)memc;
3293 global_pairs= pairs_generate(GLOBAL2_COUNT, MEMCACHED_MAX_BUFFER+10);
3294 global_count= GLOBAL2_COUNT;
3295
3296 for (size_t x= 0; x < global_count; x++)
3297 {
3298 global_keys[x]= global_pairs[x].key;
3299 global_keys_length[x]= global_pairs[x].key_length;
3300 }
3301
3302 return TEST_SUCCESS;
3303 }
3304
3305 static test_return_t generate_data(memcached_st *memc)
3306 {
3307 unsigned int check_execute= execute_set(memc, global_pairs, global_count);
3308
3309 test_true(check_execute == global_count);
3310
3311 return TEST_SUCCESS;
3312 }
3313
3314 static test_return_t generate_data_with_stats(memcached_st *memc)
3315 {
3316 memcached_stat_st *stat_p;
3317 memcached_return_t rc;
3318 uint32_t host_index= 0;
3319 unsigned int check_execute= execute_set(memc, global_pairs, global_count);
3320
3321 test_true(check_execute == global_count);
3322
3323 //TODO: hosts used size stats
3324 stat_p= memcached_stat(memc, NULL, &rc);
3325 test_true(stat_p);
3326
3327 for (host_index= 0; host_index < SERVERS_TO_CREATE; host_index++)
3328 {
3329 /* This test was changes so that "make test" would work properlly */
3330 #ifdef DEBUG
3331 memcached_server_instance_st instance=
3332 memcached_server_instance_by_position(memc, host_index);
3333
3334 printf("\nserver %u|%s|%u bytes: %llu\n", host_index, instance->hostname, instance->port, (unsigned long long)(stat_p + host_index)->bytes);
3335 #endif
3336 test_true((unsigned long long)(stat_p + host_index)->bytes);
3337 }
3338
3339 memcached_stat_free(NULL, stat_p);
3340
3341 return TEST_SUCCESS;
3342 }
3343 static test_return_t generate_buffer_data(memcached_st *memc)
3344 {
3345 size_t latch= 0;
3346
3347 latch= 1;
3348 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, latch);
3349 generate_data(memc);
3350
3351 return TEST_SUCCESS;
3352 }
3353
3354 static test_return_t get_read_count(memcached_st *memc)
3355 {
3356 memcached_return_t rc;
3357 memcached_st *memc_clone;
3358
3359 memc_clone= memcached_clone(NULL, memc);
3360 test_true(memc_clone);
3361
3362 memcached_server_add_with_weight(memc_clone, "localhost", 6666, 0);
3363
3364 {
3365 char *return_value;
3366 size_t return_value_length;
3367 uint32_t flags;
3368 uint32_t count;
3369
3370 for (size_t x= count= 0; x < global_count; x++)
3371 {
3372 return_value= memcached_get(memc_clone, global_keys[x], global_keys_length[x],
3373 &return_value_length, &flags, &rc);
3374 if (rc == MEMCACHED_SUCCESS)
3375 {
3376 count++;
3377 if (return_value)
3378 free(return_value);
3379 }
3380 }
3381 }
3382
3383 memcached_free(memc_clone);
3384
3385 return TEST_SUCCESS;
3386 }
3387
3388 static test_return_t get_read(memcached_st *memc)
3389 {
3390 memcached_return_t rc;
3391
3392 {
3393 char *return_value;
3394 size_t return_value_length;
3395 uint32_t flags;
3396
3397 for (size_t x= 0; x < global_count; x++)
3398 {
3399 return_value= memcached_get(memc, global_keys[x], global_keys_length[x],
3400 &return_value_length, &flags, &rc);
3401 /*
3402 test_true(return_value);
3403 test_true(rc == MEMCACHED_SUCCESS);
3404 */
3405 if (rc == MEMCACHED_SUCCESS && return_value)
3406 free(return_value);
3407 }
3408 }
3409
3410 return TEST_SUCCESS;
3411 }
3412
3413 static test_return_t mget_read(memcached_st *memc)
3414 {
3415 memcached_return_t rc;
3416
3417 if (! libmemcached_util_version_check(memc, 1, 4, 4))
3418 return TEST_SKIPPED;
3419
3420 rc= memcached_mget(memc, global_keys, global_keys_length, global_count);
3421
3422 test_true_got(rc == MEMCACHED_SUCCESS, memcached_strerror(NULL, rc));
3423
3424 // Go fetch the keys and test to see if all of them were returned
3425 {
3426 size_t keys_returned;
3427 test_true(fetch_all_results(memc, &keys_returned) == TEST_SUCCESS);
3428 char buffer[30];
3429 snprintf(buffer, sizeof(buffer), "%lu", (unsigned long)keys_returned);
3430 test_true_got(global_count == keys_returned, buffer);
3431 }
3432
3433
3434 return TEST_SUCCESS;
3435 }
3436
3437 static test_return_t mget_read_result(memcached_st *memc)
3438 {
3439 memcached_return_t rc;
3440
3441 if (! libmemcached_util_version_check(memc, 1, 4, 4))
3442 return TEST_SKIPPED;
3443
3444 rc= memcached_mget(memc, global_keys, global_keys_length, global_count);
3445
3446 test_true_got(rc == MEMCACHED_SUCCESS, memcached_strerror(NULL, rc));
3447
3448 /* Turn this into a help function */
3449 {
3450 memcached_result_st results_obj;
3451 memcached_result_st *results;
3452
3453 results= memcached_result_create(memc, &results_obj);
3454
3455 while ((results= memcached_fetch_result(memc, &results_obj, &rc)))
3456 {
3457 test_true(results);
3458 test_true(rc == MEMCACHED_SUCCESS);
3459 }
3460
3461 memcached_result_free(&results_obj);
3462 }
3463
3464 return TEST_SUCCESS;
3465 }
3466
3467 static test_return_t mget_read_function(memcached_st *memc)
3468 {
3469 memcached_return_t rc;
3470 size_t counter;
3471 memcached_execute_fn callbacks[1];
3472
3473 if (! libmemcached_util_version_check(memc, 1, 4, 4))
3474 return TEST_SKIPPED;
3475
3476 rc= memcached_mget(memc, global_keys, global_keys_length, global_count);
3477
3478 test_true_got(rc == MEMCACHED_SUCCESS, memcached_strerror(NULL, rc));
3479
3480 callbacks[0]= &callback_counter;
3481 counter= 0;
3482 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
3483
3484 return TEST_SUCCESS;
3485 }
3486
3487 static test_return_t delete_generate(memcached_st *memc)
3488 {
3489 for (size_t x= 0; x < global_count; x++)
3490 {
3491 (void)memcached_delete(memc, global_keys[x], global_keys_length[x], (time_t)0);
3492 }
3493
3494 return TEST_SUCCESS;
3495 }
3496
3497 static test_return_t delete_buffer_generate(memcached_st *memc)
3498 {
3499 uint64_t latch= 0;
3500
3501 latch= 1;
3502 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, latch);
3503
3504 for (size_t x= 0; x < global_count; x++)
3505 {
3506 (void)memcached_delete(memc, global_keys[x], global_keys_length[x], (time_t)0);
3507 }
3508
3509 return TEST_SUCCESS;
3510 }
3511
3512 static test_return_t add_host_test1(memcached_st *memc)
3513 {
3514 memcached_return_t rc;
3515 char servername[]= "0.example.com";
3516 memcached_server_st *servers;
3517
3518 servers= memcached_server_list_append_with_weight(NULL, servername, 400, 0, &rc);
3519 test_true(servers);
3520 test_true(1 == memcached_server_list_count(servers));
3521
3522 for (size_t x= 2; x < 20; x++)
3523 {
3524 char buffer[SMALL_STRING_LEN];
3525
3526 snprintf(buffer, SMALL_STRING_LEN, "%lu.example.com", (unsigned long)(400 +x));
3527 servers= memcached_server_list_append_with_weight(servers, buffer, 401, 0,
3528 &rc);
3529 test_true(rc == MEMCACHED_SUCCESS);
3530 test_true(x == memcached_server_list_count(servers));
3531 }
3532
3533 rc= memcached_server_push(memc, servers);
3534 test_true(rc == MEMCACHED_SUCCESS);
3535 rc= memcached_server_push(memc, servers);
3536 test_true(rc == MEMCACHED_SUCCESS);
3537
3538 memcached_server_list_free(servers);
3539
3540 return TEST_SUCCESS;
3541 }
3542
3543 static test_return_t pre_nonblock(memcached_st *memc)
3544 {
3545 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
3546
3547 return TEST_SUCCESS;
3548 }
3549
3550 static test_return_t pre_cork(memcached_st *memc)
3551 {
3552 memcached_return_t rc;
3553 bool set= true;
3554
3555 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_CORK, set);
3556
3557 #ifdef __APPLE__
3558 return TEST_SKIPPED;
3559 #endif
3560
3561 if (rc == MEMCACHED_SUCCESS)
3562 return TEST_SUCCESS;
3563
3564 return TEST_SKIPPED;
3565 }
3566
3567 static test_return_t pre_cork_and_nonblock(memcached_st *memc)
3568 {
3569 test_return_t rc;
3570
3571 rc= pre_cork(memc);
3572
3573 #ifdef __APPLE__
3574 return TEST_SKIPPED;
3575 #endif
3576
3577 if (rc != TEST_SUCCESS)
3578 return rc;
3579
3580 return pre_nonblock(memc);
3581 }
3582
3583 static test_return_t pre_nonblock_binary(memcached_st *memc)
3584 {
3585 memcached_return_t rc= MEMCACHED_FAILURE;
3586 memcached_st *memc_clone;
3587
3588 memc_clone= memcached_clone(NULL, memc);
3589 test_true(memc_clone);
3590 // The memcached_version needs to be done on a clone, because the server
3591 // will not toggle protocol on an connection.
3592 memcached_version(memc_clone);
3593
3594 if (libmemcached_util_version_check(memc_clone, 1, 4, 4))
3595 {
3596 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
3597 rc = memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
3598 test_true(rc == MEMCACHED_SUCCESS);
3599 test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 1);
3600 }
3601 else
3602 {
3603 return TEST_SKIPPED;
3604 }
3605
3606 memcached_free(memc_clone);
3607
3608 return rc == MEMCACHED_SUCCESS ? TEST_SUCCESS : TEST_SKIPPED;
3609 }
3610
3611 static test_return_t pre_murmur(memcached_st *memc)
3612 {
3613 #ifdef HAVE_MURMUR_HASH
3614 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MURMUR);
3615 return TEST_SUCCESS;
3616 #else
3617 (void) memc;
3618 return TEST_SKIPPED;
3619 #endif
3620 }
3621
3622 static test_return_t pre_jenkins(memcached_st *memc)
3623 {
3624 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_JENKINS);
3625
3626 return TEST_SUCCESS;
3627 }
3628
3629
3630 static test_return_t pre_md5(memcached_st *memc)
3631 {
3632 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MD5);
3633
3634 return TEST_SUCCESS;
3635 }
3636
3637 static test_return_t pre_crc(memcached_st *memc)
3638 {
3639 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_CRC);
3640
3641 return TEST_SUCCESS;
3642 }
3643
3644 static test_return_t pre_hsieh(memcached_st *memc)
3645 {
3646 #ifdef HAVE_HSIEH_HASH
3647 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_HSIEH);
3648 return TEST_SUCCESS;
3649 #else
3650 (void) memc;
3651 return TEST_SKIPPED;
3652 #endif
3653 }
3654
3655 static test_return_t pre_hash_fnv1_64(memcached_st *memc)
3656 {
3657 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MURMUR);
3658
3659 return TEST_SUCCESS;
3660 }
3661
3662 static test_return_t pre_hash_fnv1a_64(memcached_st *memc)
3663 {
3664 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1A_64);
3665
3666 return TEST_SUCCESS;
3667 }
3668
3669 static test_return_t pre_hash_fnv1_32(memcached_st *memc)
3670 {
3671 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1_32);
3672
3673 return TEST_SUCCESS;
3674 }
3675
3676 static test_return_t pre_hash_fnv1a_32(memcached_st *memc)
3677 {
3678 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1A_32);
3679
3680 return TEST_SUCCESS;
3681 }
3682
3683 static test_return_t pre_behavior_ketama(memcached_st *memc)
3684 {
3685 memcached_return_t rc;
3686 uint64_t value;
3687
3688 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA, 1);
3689 test_true(rc == MEMCACHED_SUCCESS);
3690
3691 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA);
3692 test_true(value == 1);
3693
3694 return TEST_SUCCESS;
3695 }
3696
3697 static test_return_t pre_behavior_ketama_weighted(memcached_st *memc)
3698 {
3699 memcached_return_t rc;
3700 uint64_t value;
3701
3702 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
3703 test_true(rc == MEMCACHED_SUCCESS);
3704
3705 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
3706 test_true(value == 1);
3707
3708 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
3709 test_true(rc == MEMCACHED_SUCCESS);
3710
3711 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
3712 test_true(value == MEMCACHED_HASH_MD5);
3713
3714 return TEST_SUCCESS;
3715 }
3716
3717 /**
3718 @note This should be testing to see if the server really supports the binary protocol.
3719 */
3720 static test_return_t pre_binary(memcached_st *memc)
3721 {
3722 memcached_return_t rc= MEMCACHED_FAILURE;
3723
3724 if (libmemcached_util_version_check(memc, 1, 4, 4))
3725 {
3726 rc = memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
3727 test_true(rc == MEMCACHED_SUCCESS);
3728 test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 1);
3729 }
3730
3731 return rc == MEMCACHED_SUCCESS ? TEST_SUCCESS : TEST_SKIPPED;
3732 }
3733
3734 static test_return_t pre_sasl(memcached_st *memc)
3735 {
3736 memcached_return_t rc= MEMCACHED_FAILURE;
3737
3738 #ifdef LIBMEMCACHED_WITH_SASL_SUPPORT
3739 const char *server= getenv("LIBMEMCACHED_TEST_SASL_SERVER");
3740 const char *user= getenv("LIBMEMCACHED_TEST_SASL_USERNAME");
3741 const char *pass= getenv("LIBMEMCACHED_TEST_SASL_PASSWORD");
3742
3743 if (server != NULL && user != NULL && pass != NULL)
3744 {
3745 memcached_server_st *servers= memcached_servers_parse(server);
3746 test_true(servers != NULL);
3747 memcached_servers_reset(memc);
3748 test_true(memcached_server_push(memc, servers) == MEMCACHED_SUCCESS);
3749 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
3750 rc= memcached_set_sasl_auth_data(memc, user, pass);
3751 test_true(rc == MEMCACHED_SUCCESS);
3752 }
3753 #else
3754 (void)memc;
3755 #endif
3756
3757 return rc == MEMCACHED_SUCCESS ? TEST_SUCCESS : TEST_SKIPPED;
3758 }
3759
3760 static test_return_t pre_replication(memcached_st *memc)
3761 {
3762 test_return_t test_rc;
3763 test_rc= pre_binary(memc);
3764
3765 if (test_rc != TEST_SUCCESS)
3766 return test_rc;
3767
3768 /*
3769 * Make sure that we store the item on all servers
3770 * (master + replicas == number of servers)
3771 */
3772 memcached_return_t rc;
3773 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS,
3774 memcached_server_count(memc) - 1);
3775 test_true(rc == MEMCACHED_SUCCESS);
3776 test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS) == memcached_server_count(memc) - 1);
3777
3778 return rc == MEMCACHED_SUCCESS ? TEST_SUCCESS : TEST_SKIPPED;
3779 }
3780
3781
3782 static test_return_t pre_replication_noblock(memcached_st *memc)
3783 {
3784 test_return_t rc;
3785
3786 rc= pre_replication(memc);
3787 if (rc != TEST_SUCCESS)
3788 return rc;
3789
3790 rc= pre_nonblock(memc);
3791
3792 return rc;
3793 }
3794
3795
3796 static void my_free(const memcached_st *ptr, void *mem, void *context)
3797 {
3798 (void)context;
3799 (void)ptr;
3800 #ifdef HARD_MALLOC_TESTS
3801 void *real_ptr= (mem == NULL) ? mem : (void*)((caddr_t)mem - 8);
3802 free(real_ptr);
3803 #else
3804 free(mem);
3805 #endif
3806 }
3807
3808
3809 static void *my_malloc(const memcached_st *ptr, const size_t size, void *context)
3810 {
3811 (void)context;
3812 (void)ptr;
3813 #ifdef HARD_MALLOC_TESTS
3814 void *ret= malloc(size + 8);
3815 if (ret != NULL)
3816 {
3817 ret= (void*)((caddr_t)ret + 8);
3818 }
3819 #else
3820 void *ret= malloc(size);
3821 #endif
3822
3823 if (ret != NULL)
3824 {
3825 memset(ret, 0xff, size);
3826 }
3827
3828 return ret;
3829 }
3830
3831
3832 static void *my_realloc(const memcached_st *ptr, void *mem, const size_t size, void *context)
3833 {
3834 (void)context;
3835 #ifdef HARD_MALLOC_TESTS
3836 void *real_ptr= (mem == NULL) ? NULL : (void*)((caddr_t)mem - 8);
3837 void *nmem= realloc(real_ptr, size + 8);
3838
3839 void *ret= NULL;
3840 if (nmem != NULL)
3841 {
3842 ret= (void*)((caddr_t)nmem + 8);
3843 }
3844
3845 return ret;
3846 #else
3847 (void)ptr;
3848 return realloc(mem, size);
3849 #endif
3850 }
3851
3852
3853 static void *my_calloc(const memcached_st *ptr, size_t nelem, const size_t size, void *context)
3854 {
3855 (void)context;
3856 #ifdef HARD_MALLOC_TESTS
3857 void *mem= my_malloc(ptr, nelem * size);
3858 if (mem)
3859 {
3860 memset(mem, 0, nelem * size);
3861 }
3862
3863 return mem;
3864 #else
3865 (void)ptr;
3866 return calloc(nelem, size);
3867 #endif
3868 }
3869
3870 static test_return_t set_prefix(memcached_st *memc)
3871 {
3872 memcached_return_t rc;
3873 const char *key= "mine";
3874 char *value;
3875
3876 /* Make sure be default none exists */
3877 value= (char*)memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3878 test_true(rc == MEMCACHED_FAILURE);
3879
3880 /* Test a clean set */
3881 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, (void *)key);
3882 test_true_got(rc == MEMCACHED_SUCCESS, memcached_last_error_message(memc));
3883
3884 value= (char*)memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3885 test_true(value);
3886 test_true(memcmp(value, key, 4) == 0);
3887 test_true(rc == MEMCACHED_SUCCESS);
3888
3889 /* Test that we can turn it off */
3890 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, NULL);
3891 test_true(rc == MEMCACHED_SUCCESS);
3892
3893 value= (char*)memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3894 test_false(value);
3895 test_true(rc == MEMCACHED_FAILURE);
3896
3897 /* Now setup for main test */
3898 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, (void *)key);
3899 test_true(rc == MEMCACHED_SUCCESS);
3900
3901 value= (char *)memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3902 test_true(value);
3903 test_true(rc == MEMCACHED_SUCCESS);
3904 test_true(memcmp(value, key, 4) == 0);
3905
3906 /* Set to Zero, and then Set to something too large */
3907 {
3908 char long_key[255];
3909 memset(long_key, 0, 255);
3910
3911 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, NULL);
3912 test_true(rc == MEMCACHED_SUCCESS);
3913
3914 value= (char*)memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3915 test_false(value);
3916 test_true(rc == MEMCACHED_FAILURE);
3917 test_true(value == NULL);
3918
3919 /* Test a long key for failure */
3920 /* TODO, extend test to determine based on setting, what result should be */
3921 strncpy(long_key, "Thisismorethentheallottednumberofcharacters", sizeof(long_key));
3922 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, long_key);
3923 //test_true(rc == MEMCACHED_BAD_KEY_PROVIDED);
3924 test_true(rc == MEMCACHED_SUCCESS);
3925
3926 /* Now test a key with spaces (which will fail from long key, since bad key is not set) */
3927 strncpy(long_key, "This is more then the allotted number of characters", sizeof(long_key));
3928 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, long_key);
3929 test_true(rc == MEMCACHED_BAD_KEY_PROVIDED);
3930
3931 /* Test for a bad prefix, but with a short key */
3932 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_VERIFY_KEY, 1);
3933 test_true(rc == MEMCACHED_SUCCESS);
3934
3935 strncpy(long_key, "dog cat", sizeof(long_key));
3936 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, long_key);
3937 test_true(rc == MEMCACHED_BAD_KEY_PROVIDED);
3938 }
3939
3940 return TEST_SUCCESS;
3941 }
3942
3943
3944 #ifdef MEMCACHED_ENABLE_DEPRECATED
3945 static test_return_t deprecated_set_memory_alloc(memcached_st *memc)
3946 {
3947 void *test_ptr= NULL;
3948 void *cb_ptr= NULL;
3949 {
3950 memcached_malloc_fn malloc_cb=
3951 (memcached_malloc_fn)my_malloc;
3952 cb_ptr= *(void **)&malloc_cb;
3953 memcached_return_t rc;
3954
3955 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_MALLOC_FUNCTION, cb_ptr);
3956 test_true(rc == MEMCACHED_SUCCESS);
3957 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_MALLOC_FUNCTION, &rc);
3958 test_true(rc == MEMCACHED_SUCCESS);
3959 test_true(test_ptr == cb_ptr);
3960 }
3961
3962 {
3963 memcached_realloc_fn realloc_cb=
3964 (memcached_realloc_fn)my_realloc;
3965 cb_ptr= *(void **)&realloc_cb;
3966 memcached_return_t rc;
3967
3968 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_REALLOC_FUNCTION, cb_ptr);
3969 test_true(rc == MEMCACHED_SUCCESS);
3970 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_REALLOC_FUNCTION, &rc);
3971 test_true(rc == MEMCACHED_SUCCESS);
3972 test_true(test_ptr == cb_ptr);
3973 }
3974
3975 {
3976 memcached_free_fn free_cb=
3977 (memcached_free_fn)my_free;
3978 cb_ptr= *(void **)&free_cb;
3979 memcached_return_t rc;
3980
3981 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_FREE_FUNCTION, cb_ptr);
3982 test_true(rc == MEMCACHED_SUCCESS);
3983 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_FREE_FUNCTION, &rc);
3984 test_true(rc == MEMCACHED_SUCCESS);
3985 test_true(test_ptr == cb_ptr);
3986 }
3987
3988 return TEST_SUCCESS;
3989 }
3990 #endif
3991
3992
3993 static test_return_t set_memory_alloc(memcached_st *memc)
3994 {
3995 memcached_return_t rc;
3996 rc= memcached_set_memory_allocators(memc, NULL, my_free,
3997 my_realloc, my_calloc, NULL);
3998 test_true(rc == MEMCACHED_FAILURE);
3999
4000 rc= memcached_set_memory_allocators(memc, my_malloc, my_free,
4001 my_realloc, my_calloc, NULL);
4002
4003 memcached_malloc_fn mem_malloc;
4004 memcached_free_fn mem_free;
4005 memcached_realloc_fn mem_realloc;
4006 memcached_calloc_fn mem_calloc;
4007 memcached_get_memory_allocators(memc, &mem_malloc, &mem_free,
4008 &mem_realloc, &mem_calloc);
4009
4010 test_true(mem_malloc == my_malloc);
4011 test_true(mem_realloc == my_realloc);
4012 test_true(mem_calloc == my_calloc);
4013 test_true(mem_free == my_free);
4014
4015 return TEST_SUCCESS;
4016 }
4017
4018 static test_return_t enable_consistent_crc(memcached_st *memc)
4019 {
4020 test_return_t rc;
4021 memcached_server_distribution_t value= MEMCACHED_DISTRIBUTION_CONSISTENT;
4022 memcached_hash_t hash;
4023 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, value);
4024 if ((rc= pre_crc(memc)) != TEST_SUCCESS)
4025 return rc;
4026
4027 value= (memcached_server_distribution_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION);
4028 test_true(value == MEMCACHED_DISTRIBUTION_CONSISTENT);
4029
4030 hash= (memcached_hash_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
4031
4032 if (hash != MEMCACHED_HASH_CRC)
4033 return TEST_SKIPPED;
4034
4035 return TEST_SUCCESS;
4036 }
4037
4038 static test_return_t enable_consistent_hsieh(memcached_st *memc)
4039 {
4040 test_return_t rc;
4041 memcached_server_distribution_t value= MEMCACHED_DISTRIBUTION_CONSISTENT;
4042 memcached_hash_t hash;
4043 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, value);
4044 if ((rc= pre_hsieh(memc)) != TEST_SUCCESS)
4045 return rc;
4046
4047 value= (memcached_server_distribution_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION);
4048 test_true(value == MEMCACHED_DISTRIBUTION_CONSISTENT);
4049
4050 hash= (memcached_hash_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
4051
4052 if (hash != MEMCACHED_HASH_HSIEH)
4053 return TEST_SKIPPED;
4054
4055
4056 return TEST_SUCCESS;
4057 }
4058
4059 static test_return_t enable_cas(memcached_st *memc)
4060 {
4061 unsigned int set= 1;
4062
4063 if (libmemcached_util_version_check(memc, 1, 2, 4))
4064 {
4065 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, set);
4066
4067 return TEST_SUCCESS;
4068 }
4069
4070 return TEST_SKIPPED;
4071 }
4072
4073 static test_return_t check_for_1_2_3(memcached_st *memc)
4074 {
4075 memcached_version(memc);
4076
4077 memcached_server_instance_st instance=
4078 memcached_server_instance_by_position(memc, 0);
4079
4080 if ((instance->major_version >= 1 && (instance->minor_version == 2 && instance->micro_version >= 4))
4081 || instance->minor_version > 2)
4082 {
4083 return TEST_SUCCESS;
4084 }
4085
4086 return TEST_SKIPPED;
4087 }
4088
4089 static test_return_t pre_unix_socket(memcached_st *memc)
4090 {
4091 memcached_return_t rc;
4092 struct stat buf;
4093
4094 memcached_servers_reset(memc);
4095
4096 if (stat("/tmp/memcached.socket", &buf))
4097 return TEST_SKIPPED;
4098
4099 rc= memcached_server_add_unix_socket_with_weight(memc, "/tmp/memcached.socket", 0);
4100
4101 return ( rc == MEMCACHED_SUCCESS ? TEST_SUCCESS : TEST_FAILURE );
4102 }
4103
4104 static test_return_t pre_nodelay(memcached_st *memc)
4105 {
4106 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
4107 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 0);
4108
4109 return TEST_SUCCESS;
4110 }
4111
4112 static test_return_t pre_settimer(memcached_st *memc)
4113 {
4114 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SND_TIMEOUT, 1000);
4115 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RCV_TIMEOUT, 1000);
4116
4117 return TEST_SUCCESS;
4118 }
4119
4120 static test_return_t poll_timeout(memcached_st *memc)
4121 {
4122 size_t timeout;
4123
4124 timeout= 100;
4125
4126 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, timeout);
4127
4128 timeout= (size_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT);
4129
4130 test_true(timeout == 100);
4131
4132 return TEST_SUCCESS;
4133 }
4134
4135 static test_return_t noreply_test(memcached_st *memc)
4136 {
4137 memcached_return_t ret;
4138 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1);
4139 test_true(ret == MEMCACHED_SUCCESS);
4140 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
4141 test_true(ret == MEMCACHED_SUCCESS);
4142 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, 1);
4143 test_true(ret == MEMCACHED_SUCCESS);
4144 test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NOREPLY) == 1);
4145 test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS) == 1);
4146 test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS) == 1);
4147
4148 for (int count=0; count < 5; ++count)
4149 {
4150 for (size_t x= 0; x < 100; ++x)
4151 {
4152 char key[10];
4153 int check_length= (size_t)snprintf(key, sizeof(key), "%lu", (unsigned long)x);
4154 test_false((size_t)check_length >= sizeof(key) || check_length < 0);
4155
4156 size_t len= (size_t)check_length;
4157
4158 switch (count)
4159 {
4160 case 0:
4161 ret= memcached_add(memc, key, len, key, len, 0, 0);
4162 break;
4163 case 1:
4164 ret= memcached_replace(memc, key, len, key, len, 0, 0);
4165 break;
4166 case 2:
4167 ret= memcached_set(memc, key, len, key, len, 0, 0);
4168 break;
4169 case 3:
4170 ret= memcached_append(memc, key, len, key, len, 0, 0);
4171 break;
4172 case 4:
4173 ret= memcached_prepend(memc, key, len, key, len, 0, 0);
4174 break;
4175 default:
4176 test_true(count);
4177 break;
4178 }
4179 test_true(ret == MEMCACHED_SUCCESS || ret == MEMCACHED_BUFFERED);
4180 }
4181
4182 /*
4183 ** NOTE: Don't ever do this in your code! this is not a supported use of the
4184 ** API and is _ONLY_ done this way to verify that the library works the
4185 ** way it is supposed to do!!!!
4186 */
4187 int no_msg=0;
4188 for (uint32_t x= 0; x < memcached_server_count(memc); ++x)
4189 {
4190 memcached_server_instance_st instance=
4191 memcached_server_instance_by_position(memc, x);
4192 no_msg+=(int)(instance->cursor_active);
4193 }
4194
4195 test_true(no_msg == 0);
4196 test_true(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
4197
4198 /*
4199 ** Now validate that all items was set properly!
4200 */
4201 for (size_t x= 0; x < 100; ++x)
4202 {
4203 char key[10];
4204
4205 int check_length= (size_t)snprintf(key, sizeof(key), "%lu", (unsigned long)x);
4206
4207 test_false((size_t)check_length >= sizeof(key) || check_length < 0);
4208
4209 size_t len= (size_t)check_length;
4210 size_t length;
4211 uint32_t flags;
4212 char* value=memcached_get(memc, key, strlen(key),
4213 &length, &flags, &ret);
4214 test_true(ret == MEMCACHED_SUCCESS && value != NULL);
4215 switch (count)
4216 {
4217 case 0: /* FALLTHROUGH */
4218 case 1: /* FALLTHROUGH */
4219 case 2:
4220 test_true(strncmp(value, key, len) == 0);
4221 test_true(len == length);
4222 break;
4223 case 3:
4224 test_true(length == len * 2);
4225 break;
4226 case 4:
4227 test_true(length == len * 3);
4228 break;
4229 default:
4230 test_true(count);
4231 break;
4232 }
4233 free(value);
4234 }
4235 }
4236
4237 /* Try setting an illegal cas value (should not return an error to
4238 * the caller (because we don't expect a return message from the server)
4239 */
4240 const char* keys[]= {"0"};
4241 size_t lengths[]= {1};
4242 size_t length;
4243 uint32_t flags;
4244 memcached_result_st results_obj;
4245 memcached_result_st *results;
4246 ret= memcached_mget(memc, keys, lengths, 1);
4247 test_true(ret == MEMCACHED_SUCCESS);
4248
4249 results= memcached_result_create(memc, &results_obj);
4250 test_true(results);
4251 results= memcached_fetch_result(memc, &results_obj, &ret);
4252 test_true(results);
4253 test_true(ret == MEMCACHED_SUCCESS);
4254 uint64_t cas= memcached_result_cas(results);
4255 memcached_result_free(&results_obj);
4256
4257 ret= memcached_cas(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0, cas);
4258 test_true(ret == MEMCACHED_SUCCESS);
4259
4260 /*
4261 * The item will have a new cas value, so try to set it again with the old
4262 * value. This should fail!
4263 */
4264 ret= memcached_cas(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0, cas);
4265 test_true(ret == MEMCACHED_SUCCESS);
4266 test_true(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
4267 char* value=memcached_get(memc, keys[0], lengths[0], &length, &flags, &ret);
4268 test_true(ret == MEMCACHED_SUCCESS && value != NULL);
4269 free(value);
4270
4271 return TEST_SUCCESS;
4272 }
4273
4274 static test_return_t analyzer_test(memcached_st *memc)
4275 {
4276 memcached_return_t rc;
4277 memcached_stat_st *memc_stat;
4278 memcached_analysis_st *report;
4279
4280 memc_stat= memcached_stat(memc, NULL, &rc);
4281 test_true(rc == MEMCACHED_SUCCESS);
4282 test_true(memc_stat);
4283
4284 report= memcached_analyze(memc, memc_stat, &rc);
4285 test_true(rc == MEMCACHED_SUCCESS);
4286 test_true(report);
4287
4288 free(report);
4289 memcached_stat_free(NULL, memc_stat);
4290
4291 return TEST_SUCCESS;
4292 }
4293
4294 /* Count the objects */
4295 static memcached_return_t callback_dump_counter(const memcached_st *ptr,
4296 const char *key,
4297 size_t key_length,
4298 void *context)
4299 {
4300 (void)ptr; (void)key; (void)key_length;
4301 size_t *counter= (size_t *)context;
4302
4303 *counter= *counter + 1;
4304
4305 return MEMCACHED_SUCCESS;
4306 }
4307
4308 static test_return_t dump_test(memcached_st *memc)
4309 {
4310 memcached_return_t rc;
4311 size_t counter= 0;
4312 memcached_dump_fn callbacks[1];
4313 test_return_t main_rc;
4314
4315 callbacks[0]= &callback_dump_counter;
4316
4317 /* No support for Binary protocol yet */
4318 if (memc->flags.binary_protocol)
4319 return TEST_SUCCESS;
4320
4321 main_rc= set_test3(memc);
4322
4323 test_true (main_rc == TEST_SUCCESS);
4324
4325 rc= memcached_dump(memc, callbacks, (void *)&counter, 1);
4326 test_true(rc == MEMCACHED_SUCCESS);
4327
4328 /* We may have more then 32 if our previous flush has not completed */
4329 test_true(counter >= 32);
4330
4331 return TEST_SUCCESS;
4332 }
4333
4334 #ifdef HAVE_LIBMEMCACHEDUTIL
4335
4336 struct test_pool_context_st {
4337 memcached_pool_st* pool;
4338 memcached_st* mmc;
4339 };
4340
4341 static void* connection_release(void *arg)
4342 {
4343 test_pool_context_st *resource= static_cast<test_pool_context_st *>(arg);
4344
4345 usleep(250);
4346 // Release all of the memc we are holding
4347 assert(memcached_pool_push(resource->pool, resource->mmc) == MEMCACHED_SUCCESS);
4348 return arg;
4349 }
4350
4351 #define POOL_SIZE 10
4352 static test_return_t connection_pool_test(memcached_st *memc)
4353 {
4354 memcached_pool_st* pool= memcached_pool_create(memc, 5, POOL_SIZE);
4355 test_true(pool != NULL);
4356 memcached_st *mmc[POOL_SIZE];
4357 memcached_return_t rc;
4358
4359 // Fill up our array that we will store the memc that are in the pool
4360 for (size_t x= 0; x < POOL_SIZE; ++x)
4361 {
4362 mmc[x]= memcached_pool_pop(pool, false, &rc);
4363 test_true(mmc[x] != NULL);
4364 test_true(rc == MEMCACHED_SUCCESS);
4365 }
4366
4367 // All memc should be gone
4368 test_true(memcached_pool_pop(pool, false, &rc) == NULL);
4369 test_true(rc == MEMCACHED_SUCCESS);
4370
4371 pthread_t tid;
4372 test_pool_context_st item= { pool, mmc[9] };
4373
4374 pthread_create(&tid, NULL, connection_release, &item);
4375 mmc[9]= memcached_pool_pop(pool, true, &rc);
4376 test_true(rc == MEMCACHED_SUCCESS);
4377 pthread_join(tid, NULL);
4378 test_true(mmc[9]);
4379 const char *key= "key";
4380 size_t keylen= strlen(key);
4381
4382 // verify that I can do ops with all connections
4383 rc= memcached_set(mmc[0], key, keylen, "0", 1, 0, 0);
4384 test_true(rc == MEMCACHED_SUCCESS);
4385
4386 for (size_t x= 0; x < POOL_SIZE; ++x)
4387 {
4388 uint64_t number_value;
4389 rc= memcached_increment(mmc[x], key, keylen, 1, &number_value);
4390 test_true(rc == MEMCACHED_SUCCESS);
4391 test_true(number_value == (x+1));
4392 }
4393
4394 // Release them..
4395 for (size_t x= 0; x < POOL_SIZE; ++x)
4396 {
4397 test_true(memcached_pool_push(pool, mmc[x]) == MEMCACHED_SUCCESS);
4398 }
4399
4400
4401 /* verify that I can set behaviors on the pool when I don't have all
4402 * of the connections in the pool. It should however be enabled
4403 * when I push the item into the pool
4404 */
4405 mmc[0]= memcached_pool_pop(pool, false, &rc);
4406 test_true(mmc[0] != NULL);
4407
4408 rc= memcached_pool_behavior_set(pool, MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK, 9999);
4409 test_true(rc == MEMCACHED_SUCCESS);
4410
4411 mmc[1]= memcached_pool_pop(pool, false, &rc);
4412 test_true(mmc[1] != NULL);
4413
4414 test_true(memcached_behavior_get(mmc[1], MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK) == 9999);
4415 test_true(memcached_pool_push(pool, mmc[1]) == MEMCACHED_SUCCESS);
4416 test_true(memcached_pool_push(pool, mmc[0]) == MEMCACHED_SUCCESS);
4417
4418 mmc[0]= memcached_pool_pop(pool, false, &rc);
4419 test_true(memcached_behavior_get(mmc[0], MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK) == 9999);
4420 test_true(memcached_pool_push(pool, mmc[0]) == MEMCACHED_SUCCESS);
4421
4422 test_true(memcached_pool_destroy(pool) == memc);
4423
4424 return TEST_SUCCESS;
4425 }
4426
4427 static test_return_t util_version_test(memcached_st *memc)
4428 {
4429 bool if_successful;
4430
4431 if_successful= libmemcached_util_version_check(memc, 0, 0, 0);
4432 test_true(if_successful == true);
4433
4434 if_successful= libmemcached_util_version_check(memc, 9, 9, 9);
4435
4436 // We expect failure
4437 if (if_successful)
4438 {
4439 fprintf(stderr, "\n----------------------------------------------------------------------\n");
4440 fprintf(stderr, "\nDumping Server Information\n\n");
4441 memcached_server_fn callbacks[1];
4442
4443 callbacks[0]= dump_server_information;
4444 memcached_server_cursor(memc, callbacks, (void *)stderr, 1);
4445 fprintf(stderr, "\n----------------------------------------------------------------------\n");
4446 }
4447 test_true(if_successful == false);
4448
4449 memcached_server_instance_st instance=
4450 memcached_server_instance_by_position(memc, 0);
4451
4452 memcached_version(memc);
4453
4454 // We only use one binary when we test, so this should be just fine.
4455 if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->minor_version, instance->micro_version);
4456 test_true(if_successful == true);
4457
4458 if (instance->micro_version > 0)
4459 if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->minor_version, (uint8_t)(instance->micro_version -1));
4460 else if (instance->minor_version > 0)
4461 if_successful= libmemcached_util_version_check(memc, instance->major_version, (uint8_t)(instance->minor_version - 1), instance->micro_version);
4462 else if (instance->major_version > 0)
4463 if_successful= libmemcached_util_version_check(memc, (uint8_t)(instance->major_version -1), instance->minor_version, instance->micro_version);
4464
4465 test_true(if_successful == true);
4466
4467 if (instance->micro_version > 0)
4468 if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->minor_version, (uint8_t)(instance->micro_version +1));
4469 else if (instance->minor_version > 0)
4470 if_successful= libmemcached_util_version_check(memc, instance->major_version, (uint8_t)(instance->minor_version +1), instance->micro_version);
4471 else if (instance->major_version > 0)
4472 if_successful= libmemcached_util_version_check(memc, (uint8_t)(instance->major_version +1), instance->minor_version, instance->micro_version);
4473
4474 test_true(if_successful == false);
4475
4476 return TEST_SUCCESS;
4477 }
4478
4479 static test_return_t ping_test(memcached_st *memc)
4480 {
4481 memcached_return_t rc;
4482 memcached_server_instance_st instance=
4483 memcached_server_instance_by_position(memc, 0);
4484
4485 // Test both the version that returns a code, and the one that does not.
4486 test_true(libmemcached_util_ping(memcached_server_name(instance),
4487 memcached_server_port(instance), NULL));
4488
4489 test_true(libmemcached_util_ping(memcached_server_name(instance),
4490 memcached_server_port(instance), &rc));
4491
4492 test_true(rc == MEMCACHED_SUCCESS);
4493
4494 return TEST_SUCCESS;
4495 }
4496 #endif
4497
4498
4499 #if 0
4500 static test_return_t hash_sanity_test (memcached_st *memc)
4501 {
4502 (void)memc;
4503
4504 assert(MEMCACHED_HASH_DEFAULT == MEMCACHED_HASH_DEFAULT);
4505 assert(MEMCACHED_HASH_MD5 == MEMCACHED_HASH_MD5);
4506 assert(MEMCACHED_HASH_CRC == MEMCACHED_HASH_CRC);
4507 assert(MEMCACHED_HASH_FNV1_64 == MEMCACHED_HASH_FNV1_64);
4508 assert(MEMCACHED_HASH_FNV1A_64 == MEMCACHED_HASH_FNV1A_64);
4509 assert(MEMCACHED_HASH_FNV1_32 == MEMCACHED_HASH_FNV1_32);
4510 assert(MEMCACHED_HASH_FNV1A_32 == MEMCACHED_HASH_FNV1A_32);
4511 #ifdef HAVE_HSIEH_HASH
4512 assert(MEMCACHED_HASH_HSIEH == MEMCACHED_HASH_HSIEH);
4513 #endif
4514 assert(MEMCACHED_HASH_MURMUR == MEMCACHED_HASH_MURMUR);
4515 assert(MEMCACHED_HASH_JENKINS == MEMCACHED_HASH_JENKINS);
4516 assert(MEMCACHED_HASH_MAX == MEMCACHED_HASH_MAX);
4517
4518 return TEST_SUCCESS;
4519 }
4520 #endif
4521
4522 static test_return_t hsieh_avaibility_test (memcached_st *memc)
4523 {
4524 memcached_return_t expected_rc= MEMCACHED_INVALID_ARGUMENTS;
4525 #ifdef HAVE_HSIEH_HASH
4526 expected_rc= MEMCACHED_SUCCESS;
4527 #endif
4528 memcached_return_t rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH,
4529 (uint64_t)MEMCACHED_HASH_HSIEH);
4530 test_true(rc == expected_rc);
4531
4532 return TEST_SUCCESS;
4533 }
4534
4535 static test_return_t murmur_avaibility_test (memcached_st *memc)
4536 {
4537 memcached_return_t expected_rc= MEMCACHED_INVALID_ARGUMENTS;
4538 #ifdef HAVE_MURMUR_HASH
4539 expected_rc= MEMCACHED_SUCCESS;
4540 #endif
4541 memcached_return_t rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH,
4542 (uint64_t)MEMCACHED_HASH_MURMUR);
4543 test_true(rc == expected_rc);
4544
4545 return TEST_SUCCESS;
4546 }
4547
4548 static test_return_t one_at_a_time_run (memcached_st *memc)
4549 {
4550 uint32_t x;
4551 const char **ptr;
4552 (void)memc;
4553
4554 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4555 {
4556 uint32_t hash_val;
4557
4558 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_DEFAULT);
4559 test_true(one_at_a_time_values[x] == hash_val);
4560 }
4561
4562 return TEST_SUCCESS;
4563 }
4564
4565 static test_return_t md5_run (memcached_st *memc)
4566 {
4567 uint32_t x;
4568 const char **ptr;
4569 (void)memc;
4570
4571 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4572 {
4573 uint32_t hash_val;
4574
4575 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_MD5);
4576 test_true(md5_values[x] == hash_val);
4577 }
4578
4579 return TEST_SUCCESS;
4580 }
4581
4582 static test_return_t crc_run (memcached_st *memc)
4583 {
4584 uint32_t x;
4585 const char **ptr;
4586 (void)memc;
4587
4588 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4589 {
4590 uint32_t hash_val;
4591
4592 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_CRC);
4593 test_true(crc_values[x] == hash_val);
4594 }
4595
4596 return TEST_SUCCESS;
4597 }
4598
4599 static test_return_t fnv1_64_run (memcached_st *memc)
4600 {
4601 uint32_t x;
4602 const char **ptr;
4603 (void)memc;
4604
4605 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4606 {
4607 uint32_t hash_val;
4608
4609 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1_64);
4610 test_true(fnv1_64_values[x] == hash_val);
4611 }
4612
4613 return TEST_SUCCESS;
4614 }
4615
4616 static test_return_t fnv1a_64_run (memcached_st *memc)
4617 {
4618 uint32_t x;
4619 const char **ptr;
4620 (void)memc;
4621
4622 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4623 {
4624 uint32_t hash_val;
4625
4626 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1A_64);
4627 test_true(fnv1a_64_values[x] == hash_val);
4628 }
4629
4630 return TEST_SUCCESS;
4631 }
4632
4633 static test_return_t fnv1_32_run (memcached_st *memc)
4634 {
4635 uint32_t x;
4636 const char **ptr;
4637 (void)memc;
4638
4639 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4640 {
4641 uint32_t hash_val;
4642
4643 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1_32);
4644 test_true(fnv1_32_values[x] == hash_val);
4645 }
4646
4647 return TEST_SUCCESS;
4648 }
4649
4650 static test_return_t fnv1a_32_run (memcached_st *memc)
4651 {
4652 uint32_t x;
4653 const char **ptr;
4654 (void)memc;
4655
4656 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4657 {
4658 uint32_t hash_val;
4659
4660 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1A_32);
4661 test_true(fnv1a_32_values[x] == hash_val);
4662 }
4663
4664 return TEST_SUCCESS;
4665 }
4666
4667 static test_return_t hsieh_run (memcached_st *memc)
4668 {
4669 uint32_t x;
4670 const char **ptr;
4671 (void)memc;
4672
4673 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4674 {
4675 uint32_t hash_val;
4676
4677 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_HSIEH);
4678 test_true(hsieh_values[x] == hash_val);
4679 }
4680
4681 return TEST_SUCCESS;
4682 }
4683
4684 static test_return_t murmur_run (memcached_st *memc)
4685 {
4686 #ifdef WORDS_BIGENDIAN
4687 (void)murmur_values;
4688 return TEST_SKIPPED;
4689 #else
4690 uint32_t x;
4691 const char **ptr;
4692 (void)memc;
4693
4694 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4695 {
4696 uint32_t hash_val;
4697
4698 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_MURMUR);
4699 test_true(murmur_values[x] == hash_val);
4700 }
4701
4702 return TEST_SUCCESS;
4703 #endif
4704 }
4705
4706 static test_return_t jenkins_run (memcached_st *memc)
4707 {
4708 uint32_t x;
4709 const char **ptr;
4710 (void)memc;
4711
4712 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4713 {
4714 uint32_t hash_val;
4715
4716 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_JENKINS);
4717 test_true(jenkins_values[x] == hash_val);
4718 }
4719
4720 return TEST_SUCCESS;
4721 }
4722
4723 static uint32_t hash_md5_test_function(const char *string, size_t string_length, void *context)
4724 {
4725 (void)context;
4726 return libhashkit_md5(string, string_length);
4727 }
4728
4729 static uint32_t hash_crc_test_function(const char *string, size_t string_length, void *context)
4730 {
4731 (void)context;
4732 return libhashkit_crc32(string, string_length);
4733 }
4734
4735 static test_return_t memcached_get_hashkit_test (memcached_st *memc)
4736 {
4737 uint32_t x;
4738 const char **ptr;
4739 const hashkit_st *kit;
4740 hashkit_st new_kit;
4741 hashkit_return_t hash_rc;
4742
4743 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};
4744 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};
4745
4746 kit= memcached_get_hashkit(memc);
4747
4748 hashkit_clone(&new_kit, kit);
4749 hash_rc= hashkit_set_custom_function(&new_kit, hash_md5_test_function, NULL);
4750 test_true(hash_rc == HASHKIT_SUCCESS);
4751
4752 memcached_set_hashkit(memc, &new_kit);
4753
4754 /*
4755 Verify Setting the hash.
4756 */
4757 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4758 {
4759 uint32_t hash_val;
4760
4761 hash_val= hashkit_digest(kit, *ptr, strlen(*ptr));
4762 test_true(md5_values[x] == hash_val);
4763 }
4764
4765
4766 /*
4767 Now check memcached_st.
4768 */
4769 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4770 {
4771 uint32_t hash_val;
4772
4773 hash_val= memcached_generate_hash(memc, *ptr, strlen(*ptr));
4774 test_true(md5_hosts[x] == hash_val);
4775 }
4776
4777 hash_rc= hashkit_set_custom_function(&new_kit, hash_crc_test_function, NULL);
4778 test_true(hash_rc == HASHKIT_SUCCESS);
4779
4780 memcached_set_hashkit(memc, &new_kit);
4781
4782 /*
4783 Verify Setting the hash.
4784 */
4785 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4786 {
4787 uint32_t hash_val;
4788
4789 hash_val= hashkit_digest(kit, *ptr, strlen(*ptr));
4790 test_true(crc_values[x] == hash_val);
4791 }
4792
4793 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4794 {
4795 uint32_t hash_val;
4796
4797 hash_val= memcached_generate_hash(memc, *ptr, strlen(*ptr));
4798 test_true(crc_hosts[x] == hash_val);
4799 }
4800
4801 return TEST_SUCCESS;
4802 }
4803
4804 /*
4805 Test case adapted from John Gorman <johngorman2@gmail.com>
4806
4807 We are testing the error condition when we connect to a server via memcached_get()
4808 but find that the server is not available.
4809 */
4810 static test_return_t memcached_get_MEMCACHED_ERRNO(memcached_st *memc)
4811 {
4812 (void)memc;
4813 memcached_st *tl_memc_h;
4814 memcached_server_st *servers;
4815
4816 const char *key= "MemcachedLives";
4817 size_t len;
4818 uint32_t flags;
4819 memcached_return rc;
4820 char *value;
4821
4822 // Create a handle.
4823 tl_memc_h= memcached_create(NULL);
4824 servers= memcached_servers_parse("localhost:9898,localhost:9899"); // This server should not exist
4825 memcached_server_push(tl_memc_h, servers);
4826 memcached_server_list_free(servers);
4827
4828 // See if memcached is reachable.
4829 value= memcached_get(tl_memc_h, key, strlen(key), &len, &flags, &rc);
4830
4831 test_false(value);
4832 test_true(len == 0);
4833 test_false(rc == MEMCACHED_SUCCESS);
4834
4835 memcached_free(tl_memc_h);
4836
4837 return TEST_SUCCESS;
4838 }
4839
4840 /*
4841 We connect to a server which exists, but search for a key that does not exist.
4842 */
4843 static test_return_t memcached_get_MEMCACHED_NOTFOUND(memcached_st *memc)
4844 {
4845 const char *key= "MemcachedKeyNotEXIST";
4846 size_t len;
4847 uint32_t flags;
4848 memcached_return rc;
4849 char *value;
4850
4851 // See if memcached is reachable.
4852 value= memcached_get(memc, key, strlen(key), &len, &flags, &rc);
4853
4854 test_false(value);
4855 test_true(len == 0);
4856 test_true(rc == MEMCACHED_NOTFOUND);
4857
4858 return TEST_SUCCESS;
4859 }
4860
4861 /*
4862 Test case adapted from John Gorman <johngorman2@gmail.com>
4863
4864 We are testing the error condition when we connect to a server via memcached_get_by_key()
4865 but find that the server is not available.
4866 */
4867 static test_return_t memcached_get_by_key_MEMCACHED_ERRNO(memcached_st *memc)
4868 {
4869 (void)memc;
4870 memcached_st *tl_memc_h;
4871 memcached_server_st *servers;
4872
4873 const char *key= "MemcachedLives";
4874 size_t len;
4875 uint32_t flags;
4876 memcached_return rc;
4877 char *value;
4878
4879 // Create a handle.
4880 tl_memc_h= memcached_create(NULL);
4881 servers= memcached_servers_parse("localhost:9898,localhost:9899"); // This server should not exist
4882 memcached_server_push(tl_memc_h, servers);
4883 memcached_server_list_free(servers);
4884
4885 // See if memcached is reachable.
4886 value= memcached_get_by_key(tl_memc_h, key, strlen(key), key, strlen(key), &len, &flags, &rc);
4887
4888 test_false(value);
4889 test_true(len == 0);
4890 test_false(rc == MEMCACHED_SUCCESS);
4891
4892 memcached_free(tl_memc_h);
4893
4894 return TEST_SUCCESS;
4895 }
4896
4897 /*
4898 We connect to a server which exists, but search for a key that does not exist.
4899 */
4900 static test_return_t memcached_get_by_key_MEMCACHED_NOTFOUND(memcached_st *memc)
4901 {
4902 const char *key= "MemcachedKeyNotEXIST";
4903 size_t len;
4904 uint32_t flags;
4905 memcached_return rc;
4906 char *value;
4907
4908 // See if memcached is reachable.
4909 value= memcached_get_by_key(memc, key, strlen(key), key, strlen(key), &len, &flags, &rc);
4910
4911 test_false(value);
4912 test_true(len == 0);
4913 test_true(rc == MEMCACHED_NOTFOUND);
4914
4915 return TEST_SUCCESS;
4916 }
4917
4918
4919 static test_return_t ketama_compatibility_libmemcached(memcached_st *trash)
4920 {
4921 memcached_return_t rc;
4922 uint64_t value;
4923 int x;
4924 memcached_server_st *server_pool;
4925 memcached_st *memc;
4926
4927 (void)trash;
4928
4929 memc= memcached_create(NULL);
4930 test_true(memc);
4931
4932 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
4933 test_true(rc == MEMCACHED_SUCCESS);
4934
4935 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
4936 test_true(value == 1);
4937
4938 test_true(memcached_behavior_set_distribution(memc, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA) == MEMCACHED_SUCCESS);
4939 test_true(memcached_behavior_get_distribution(memc) == MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA);
4940
4941
4942 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");
4943 memcached_server_push(memc, server_pool);
4944
4945 /* verify that the server list was parsed okay. */
4946 test_true(memcached_server_count(memc) == 8);
4947 test_strcmp(server_pool[0].hostname, "10.0.1.1");
4948 test_true(server_pool[0].port == 11211);
4949 test_true(server_pool[0].weight == 600);
4950 test_strcmp(server_pool[2].hostname, "10.0.1.3");
4951 test_true(server_pool[2].port == 11211);
4952 test_true(server_pool[2].weight == 200);
4953 test_strcmp(server_pool[7].hostname, "10.0.1.8");
4954 test_true(server_pool[7].port == 11211);
4955 test_true(server_pool[7].weight == 100);
4956
4957 /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets
4958 * us test the boundary wraparound.
4959 */
4960 test_true(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->ketama.continuum[0].index);
4961
4962 /* verify the standard ketama set. */
4963 for (x= 0; x < 99; x++)
4964 {
4965 uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
4966 memcached_server_instance_st instance=
4967 memcached_server_instance_by_position(memc, server_idx);
4968 const char *hostname = memcached_server_name(instance);
4969
4970 test_strcmp(hostname, ketama_test_cases[x].server);
4971 }
4972
4973 memcached_server_list_free(server_pool);
4974 memcached_free(memc);
4975
4976 return TEST_SUCCESS;
4977 }
4978
4979 static test_return_t ketama_compatibility_spymemcached(memcached_st *trash)
4980 {
4981 memcached_return_t rc;
4982 uint64_t value;
4983 memcached_server_st *server_pool;
4984 memcached_st *memc;
4985
4986 (void)trash;
4987
4988 memc= memcached_create(NULL);
4989 test_true(memc);
4990
4991 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
4992 test_true(rc == MEMCACHED_SUCCESS);
4993
4994 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
4995 test_true(value == 1);
4996
4997 test_true(memcached_behavior_set_distribution(memc, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY) == MEMCACHED_SUCCESS);
4998 test_true(memcached_behavior_get_distribution(memc) == MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY);
4999
5000 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");
5001 assert(server_pool);
5002 memcached_server_push(memc, server_pool);
5003
5004 /* verify that the server list was parsed okay. */
5005 test_true(memcached_server_count(memc) == 8);
5006 test_strcmp(server_pool[0].hostname, "10.0.1.1");
5007 test_true(server_pool[0].port == 11211);
5008 test_true(server_pool[0].weight == 600);
5009 test_strcmp(server_pool[2].hostname, "10.0.1.3");
5010 test_true(server_pool[2].port == 11211);
5011 test_true(server_pool[2].weight == 200);
5012 test_strcmp(server_pool[7].hostname, "10.0.1.8");
5013 test_true(server_pool[7].port == 11211);
5014 test_true(server_pool[7].weight == 100);
5015
5016 /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets
5017 * us test the boundary wraparound.
5018 */
5019 test_true(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->ketama.continuum[0].index);
5020
5021 /* verify the standard ketama set. */
5022 for (uint32_t x= 0; x < 99; x++)
5023 {
5024 uint32_t server_idx= memcached_generate_hash(memc, ketama_test_cases_spy[x].key, strlen(ketama_test_cases_spy[x].key));
5025
5026 memcached_server_instance_st instance=
5027 memcached_server_instance_by_position(memc, server_idx);
5028
5029 const char *hostname= memcached_server_name(instance);
5030
5031 test_strcmp(hostname, ketama_test_cases_spy[x].server);
5032 }
5033
5034 memcached_server_list_free(server_pool);
5035 memcached_free(memc);
5036
5037 return TEST_SUCCESS;
5038 }
5039
5040 static test_return_t regression_bug_434484(memcached_st *memc)
5041 {
5042 test_return_t test_rc;
5043 test_rc= pre_binary(memc);
5044
5045 if (test_rc != TEST_SUCCESS)
5046 return test_rc;
5047
5048 const char *key= "regression_bug_434484";
5049 size_t keylen= strlen(key);
5050
5051 memcached_return_t ret= memcached_append(memc, key, keylen, key, keylen, 0, 0);
5052 test_true(ret == MEMCACHED_NOTSTORED);
5053
5054 size_t size= 2048 * 1024;
5055 char *data= (char*)calloc(1, size);
5056 test_true(data);
5057 ret= memcached_set(memc, key, keylen, data, size, 0, 0);
5058 test_true(ret == MEMCACHED_E2BIG);
5059 free(data);
5060
5061 return TEST_SUCCESS;
5062 }
5063
5064 static test_return_t regression_bug_434843(memcached_st *memc)
5065 {
5066 test_return_t test_rc;
5067 test_rc= pre_binary(memc);
5068
5069 if (test_rc != TEST_SUCCESS)
5070 return test_rc;
5071
5072 memcached_return_t rc;
5073 size_t counter= 0;
5074 memcached_execute_fn callbacks[]= { &callback_counter };
5075
5076 /*
5077 * I only want to hit only _one_ server so I know the number of requests I'm
5078 * sending in the pipleine to the server. Let's try to do a multiget of
5079 * 1024 (that should satisfy most users don't you think?). Future versions
5080 * will include a mget_execute function call if you need a higher number.
5081 */
5082 uint32_t number_of_hosts= memcached_server_count(memc);
5083 memc->number_of_hosts= 1;
5084 const size_t max_keys= 1024;
5085 char **keys= (char**)calloc(max_keys, sizeof(char*));
5086 size_t *key_length= (size_t *)calloc(max_keys, sizeof(size_t));
5087
5088 for (size_t x= 0; x < max_keys; ++x)
5089 {
5090 char k[251];
5091
5092 key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%lu", (unsigned long)x);
5093 keys[x]= strdup(k);
5094 test_true(keys[x] != NULL);
5095 }
5096
5097 /*
5098 * Run two times.. the first time we should have 100% cache miss,
5099 * and the second time we should have 100% cache hits
5100 */
5101 for (size_t y= 0; y < 2; y++)
5102 {
5103 rc= memcached_mget(memc, (const char**)keys, key_length, max_keys);
5104 test_true(rc == MEMCACHED_SUCCESS);
5105 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
5106
5107 if (y == 0)
5108 {
5109 /* The first iteration should give me a 100% cache miss. verify that*/
5110 char blob[1024]= { 0 };
5111
5112 test_true(counter == 0);
5113
5114 for (size_t x= 0; x < max_keys; ++x)
5115 {
5116 rc= memcached_add(memc, keys[x], key_length[x],
5117 blob, sizeof(blob), 0, 0);
5118 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5119 }
5120 }
5121 else
5122 {
5123 /* Verify that we received all of the key/value pairs */
5124 test_true(counter == max_keys);
5125 }
5126 }
5127
5128 /* Release allocated resources */
5129 for (size_t x= 0; x < max_keys; ++x)
5130 {
5131 free(keys[x]);
5132 }
5133 free(keys);
5134 free(key_length);
5135
5136 memc->number_of_hosts= number_of_hosts;
5137
5138 return TEST_SUCCESS;
5139 }
5140
5141 static test_return_t regression_bug_434843_buffered(memcached_st *memc)
5142 {
5143 memcached_return_t rc;
5144 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
5145 test_true(rc == MEMCACHED_SUCCESS);
5146
5147 return regression_bug_434843(memc);
5148 }
5149
5150 static test_return_t regression_bug_421108(memcached_st *memc)
5151 {
5152 memcached_return_t rc;
5153 memcached_stat_st *memc_stat= memcached_stat(memc, NULL, &rc);
5154 test_true(rc == MEMCACHED_SUCCESS);
5155
5156 char *bytes= memcached_stat_get_value(memc, memc_stat, "bytes", &rc);
5157 test_true(rc == MEMCACHED_SUCCESS);
5158 test_true(bytes != NULL);
5159 char *bytes_read= memcached_stat_get_value(memc, memc_stat,
5160 "bytes_read", &rc);
5161 test_true(rc == MEMCACHED_SUCCESS);
5162 test_true(bytes_read != NULL);
5163
5164 char *bytes_written= memcached_stat_get_value(memc, memc_stat,
5165 "bytes_written", &rc);
5166 test_true(rc == MEMCACHED_SUCCESS);
5167 test_true(bytes_written != NULL);
5168
5169 test_true(strcmp(bytes, bytes_read) != 0);
5170 test_true(strcmp(bytes, bytes_written) != 0);
5171
5172 /* Release allocated resources */
5173 free(bytes);
5174 free(bytes_read);
5175 free(bytes_written);
5176 memcached_stat_free(NULL, memc_stat);
5177
5178 return TEST_SUCCESS;
5179 }
5180
5181 /*
5182 * The test case isn't obvious so I should probably document why
5183 * it works the way it does. Bug 442914 was caused by a bug
5184 * in the logic in memcached_purge (it did not handle the case
5185 * where the number of bytes sent was equal to the watermark).
5186 * In this test case, create messages so that we hit that case
5187 * and then disable noreply mode and issue a new command to
5188 * verify that it isn't stuck. If we change the format for the
5189 * delete command or the watermarks, we need to update this
5190 * test....
5191 */
5192 static test_return_t regression_bug_442914(memcached_st *memc)
5193 {
5194 memcached_return_t rc;
5195 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1);
5196 test_true(rc == MEMCACHED_SUCCESS);
5197 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 1);
5198
5199 uint32_t number_of_hosts= memcached_server_count(memc);
5200 memc->number_of_hosts= 1;
5201
5202 char k[250];
5203 size_t len;
5204
5205 for (uint32_t x= 0; x < 250; ++x)
5206 {
5207 len= (size_t)snprintf(k, sizeof(k), "%0250u", x);
5208 rc= memcached_delete(memc, k, len, 0);
5209 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5210 }
5211
5212 (void)snprintf(k, sizeof(k), "%037u", 251U);
5213 len= strlen(k);
5214
5215 rc= memcached_delete(memc, k, len, 0);
5216 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5217
5218 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 0);
5219 test_true(rc == MEMCACHED_SUCCESS);
5220 rc= memcached_delete(memc, k, len, 0);
5221 test_true(rc == MEMCACHED_NOTFOUND);
5222
5223 memc->number_of_hosts= number_of_hosts;
5224
5225 return TEST_SUCCESS;
5226 }
5227
5228 static test_return_t regression_bug_447342(memcached_st *memc)
5229 {
5230 memcached_server_instance_st instance_one;
5231 memcached_server_instance_st instance_two;
5232
5233 if (memcached_server_count(memc) < 3 || pre_replication(memc) != TEST_SUCCESS)
5234 return TEST_SKIPPED;
5235
5236 memcached_return_t rc;
5237
5238 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 2);
5239 test_true(rc == MEMCACHED_SUCCESS);
5240
5241 const size_t max_keys= 100;
5242 char **keys= (char**)calloc(max_keys, sizeof(char*));
5243 size_t *key_length= (size_t *)calloc(max_keys, sizeof(size_t));
5244
5245 for (size_t x= 0; x < max_keys; ++x)
5246 {
5247 char k[251];
5248
5249 key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%lu", (unsigned long)x);
5250 keys[x]= strdup(k);
5251 test_true(keys[x] != NULL);
5252 rc= memcached_set(memc, k, key_length[x], k, key_length[x], 0, 0);
5253 test_true(rc == MEMCACHED_SUCCESS);
5254 }
5255
5256 /*
5257 ** We are using the quiet commands to store the replicas, so we need
5258 ** to ensure that all of them are processed before we can continue.
5259 ** In the test we go directly from storing the object to trying to
5260 ** receive the object from all of the different servers, so we
5261 ** could end up in a race condition (the memcached server hasn't yet
5262 ** processed the quiet command from the replication set when it process
5263 ** the request from the other client (created by the clone)). As a
5264 ** workaround for that we call memcached_quit to send the quit command
5265 ** to the server and wait for the response ;-) If you use the test code
5266 ** as an example for your own code, please note that you shouldn't need
5267 ** to do this ;-)
5268 */
5269 memcached_quit(memc);
5270
5271 /* Verify that all messages are stored, and we didn't stuff too much
5272 * into the servers
5273 */
5274 rc= memcached_mget(memc, (const char* const *)keys, key_length, max_keys);
5275 test_true(rc == MEMCACHED_SUCCESS);
5276
5277 size_t counter= 0;
5278 memcached_execute_fn callbacks[]= { &callback_counter };
5279 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
5280 /* Verify that we received all of the key/value pairs */
5281 test_true(counter == max_keys);
5282
5283 memcached_quit(memc);
5284 /*
5285 * Don't do the following in your code. I am abusing the internal details
5286 * within the library, and this is not a supported interface.
5287 * This is to verify correct behavior in the library. Fake that two servers
5288 * are dead..
5289 */
5290 instance_one= memcached_server_instance_by_position(memc, 0);
5291 instance_two= memcached_server_instance_by_position(memc, 2);
5292 in_port_t port0= instance_one->port;
5293 in_port_t port2= instance_two->port;
5294
5295 ((memcached_server_write_instance_st)instance_one)->port= 0;
5296 ((memcached_server_write_instance_st)instance_two)->port= 0;
5297
5298 rc= memcached_mget(memc, (const char* const *)keys, key_length, max_keys);
5299 test_true(rc == MEMCACHED_SUCCESS);
5300
5301 counter= 0;
5302 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
5303 test_true(counter == (unsigned int)max_keys);
5304
5305 /* restore the memc handle */
5306 ((memcached_server_write_instance_st)instance_one)->port= port0;
5307 ((memcached_server_write_instance_st)instance_two)->port= port2;
5308
5309 memcached_quit(memc);
5310
5311 /* Remove half of the objects */
5312 for (size_t x= 0; x < max_keys; ++x)
5313 {
5314 if (x & 1)
5315 {
5316 rc= memcached_delete(memc, keys[x], key_length[x], 0);
5317 test_true(rc == MEMCACHED_SUCCESS);
5318 }
5319 }
5320
5321 memcached_quit(memc);
5322 ((memcached_server_write_instance_st)instance_one)->port= 0;
5323 ((memcached_server_write_instance_st)instance_two)->port= 0;
5324
5325 /* now retry the command, this time we should have cache misses */
5326 rc= memcached_mget(memc, (const char* const *)keys, key_length, max_keys);
5327 test_true(rc == MEMCACHED_SUCCESS);
5328
5329 counter= 0;
5330 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
5331 test_true(counter == (unsigned int)(max_keys >> 1));
5332
5333 /* Release allocated resources */
5334 for (size_t x= 0; x < max_keys; ++x)
5335 {
5336 free(keys[x]);
5337 }
5338 free(keys);
5339 free(key_length);
5340
5341 /* restore the memc handle */
5342 ((memcached_server_write_instance_st)instance_one)->port= port0;
5343 ((memcached_server_write_instance_st)instance_two)->port= port2;
5344
5345 return TEST_SUCCESS;
5346 }
5347
5348 static test_return_t regression_bug_463297(memcached_st *memc)
5349 {
5350 memcached_st *memc_clone= memcached_clone(NULL, memc);
5351 test_true(memc_clone != NULL);
5352 test_true(memcached_version(memc_clone) == MEMCACHED_SUCCESS);
5353
5354 memcached_server_instance_st instance=
5355 memcached_server_instance_by_position(memc_clone, 0);
5356
5357 if (instance->major_version > 1 ||
5358 (instance->major_version == 1 &&
5359 instance->minor_version > 2))
5360 {
5361 /* Binary protocol doesn't support deferred delete */
5362 memcached_st *bin_clone= memcached_clone(NULL, memc);
5363 test_true(bin_clone != NULL);
5364 test_true(memcached_behavior_set(bin_clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1) == MEMCACHED_SUCCESS);
5365 test_true(memcached_delete(bin_clone, "foo", 3, 1) == MEMCACHED_INVALID_ARGUMENTS);
5366 memcached_free(bin_clone);
5367
5368 memcached_quit(memc_clone);
5369
5370 /* If we know the server version, deferred delete should fail
5371 * with invalid arguments */
5372 test_true(memcached_delete(memc_clone, "foo", 3, 1) == MEMCACHED_INVALID_ARGUMENTS);
5373
5374 /* If we don't know the server version, we should get a protocol error */
5375 memcached_return_t rc= memcached_delete(memc, "foo", 3, 1);
5376
5377 /* but there is a bug in some of the memcached servers (1.4) that treats
5378 * the counter as noreply so it doesn't send the proper error message
5379 */
5380 test_true_got(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR || rc == MEMCACHED_INVALID_ARGUMENTS, memcached_strerror(NULL, rc));
5381
5382 /* And buffered mode should be disabled and we should get protocol error */
5383 test_true(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1) == MEMCACHED_SUCCESS);
5384 rc= memcached_delete(memc, "foo", 3, 1);
5385 test_true_got(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR || rc == MEMCACHED_INVALID_ARGUMENTS, memcached_strerror(NULL, rc));
5386
5387 /* Same goes for noreply... */
5388 test_true(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1) == MEMCACHED_SUCCESS);
5389 rc= memcached_delete(memc, "foo", 3, 1);
5390 test_true_got(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR || rc == MEMCACHED_INVALID_ARGUMENTS, memcached_strerror(NULL, rc));
5391
5392 /* but a normal request should go through (and be buffered) */
5393 test_true((rc= memcached_delete(memc, "foo", 3, 0)) == MEMCACHED_BUFFERED);
5394 test_true(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
5395
5396 test_true(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 0) == MEMCACHED_SUCCESS);
5397 /* unbuffered noreply should be success */
5398 test_true(memcached_delete(memc, "foo", 3, 0) == MEMCACHED_SUCCESS);
5399 /* unbuffered with reply should be not found... */
5400 test_true(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 0) == MEMCACHED_SUCCESS);
5401 test_true(memcached_delete(memc, "foo", 3, 0) == MEMCACHED_NOTFOUND);
5402 }
5403
5404 memcached_free(memc_clone);
5405 return TEST_SUCCESS;
5406 }
5407
5408
5409 /* Test memcached_server_get_last_disconnect
5410 * For a working server set, shall be NULL
5411 * For a set of non existing server, shall not be NULL
5412 */
5413 static test_return_t test_get_last_disconnect(memcached_st *memc)
5414 {
5415 memcached_return_t rc;
5416 memcached_server_instance_st disconnected_server;
5417
5418 /* With the working set of server */
5419 const char *key= "marmotte";
5420 const char *value= "milka";
5421
5422 memcached_reset_last_disconnected_server(memc);
5423 rc= memcached_set(memc, key, strlen(key),
5424 value, strlen(value),
5425 (time_t)0, (uint32_t)0);
5426 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5427
5428 disconnected_server = memcached_server_get_last_disconnect(memc);
5429 test_true(disconnected_server == NULL);
5430
5431 /* With a non existing server */
5432 memcached_st *mine;
5433 memcached_server_st *servers;
5434
5435 const char *server_list= "localhost:9";
5436
5437 servers= memcached_servers_parse(server_list);
5438 test_true(servers);
5439 mine= memcached_create(NULL);
5440 rc= memcached_server_push(mine, servers);
5441 test_true(rc == MEMCACHED_SUCCESS);
5442 memcached_server_list_free(servers);
5443 test_true(mine);
5444
5445 rc= memcached_set(mine, key, strlen(key),
5446 value, strlen(value),
5447 (time_t)0, (uint32_t)0);
5448 test_true(rc != MEMCACHED_SUCCESS);
5449
5450 disconnected_server= memcached_server_get_last_disconnect(mine);
5451 if (disconnected_server == NULL)
5452 {
5453 fprintf(stderr, "RC %s\n", memcached_strerror(mine, rc));
5454 abort();
5455 }
5456 test_true(disconnected_server != NULL);
5457 test_true(memcached_server_port(disconnected_server)== 9);
5458 test_true(strncmp(memcached_server_name(disconnected_server),"localhost",9) == 0);
5459
5460 memcached_quit(mine);
5461 memcached_free(mine);
5462
5463 return TEST_SUCCESS;
5464 }
5465
5466 static test_return_t test_verbosity(memcached_st *memc)
5467 {
5468 memcached_verbosity(memc, 3);
5469
5470 return TEST_SUCCESS;
5471 }
5472
5473 static test_return_t test_server_failure(memcached_st *memc)
5474 {
5475 memcached_st *local_memc;
5476 memcached_server_instance_st instance= memcached_server_instance_by_position(memc, 0);
5477
5478 local_memc= memcached_create(NULL);
5479
5480 memcached_server_add(local_memc, memcached_server_name(instance), memcached_server_port(instance));
5481 memcached_behavior_set(local_memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, 2);
5482
5483 uint32_t server_count= memcached_server_count(local_memc);
5484
5485 test_true(server_count == 1);
5486
5487 // Disable the server
5488 instance= memcached_server_instance_by_position(local_memc, 0);
5489 ((memcached_server_write_instance_st)instance)->server_failure_counter= 2;
5490
5491 memcached_return_t rc;
5492 rc= memcached_set(local_memc, "foo", strlen("foo"),
5493 NULL, 0,
5494 (time_t)0, (uint32_t)0);
5495 test_true(rc == MEMCACHED_SERVER_MARKED_DEAD);
5496
5497 ((memcached_server_write_instance_st)instance)->server_failure_counter= 0;
5498 rc= memcached_set(local_memc, "foo", strlen("foo"),
5499 NULL, 0,
5500 (time_t)0, (uint32_t)0);
5501 test_true(rc == MEMCACHED_SUCCESS);
5502
5503
5504 memcached_free(local_memc);
5505
5506 return TEST_SUCCESS;
5507 }
5508
5509 static test_return_t test_cull_servers(memcached_st *memc)
5510 {
5511 uint32_t count = memcached_server_count(memc);
5512
5513 // Do not do this in your code, it is not supported.
5514 memc->servers[1].options.is_dead= true;
5515 memc->state.is_time_for_rebuild= true;
5516
5517 uint32_t new_count= memcached_server_count(memc);
5518 test_true(count == new_count);
5519
5520 #if 0
5521 test_true(count == new_count + 1 );
5522 #endif
5523
5524 return TEST_SUCCESS;
5525 }
5526
5527
5528 static memcached_return_t stat_printer(memcached_server_instance_st server,
5529 const char *key, size_t key_length,
5530 const char *value, size_t value_length,
5531 void *context)
5532 {
5533 (void)server;
5534 (void)context;
5535 (void)key;
5536 (void)key_length;
5537 (void)value;
5538 (void)value_length;
5539
5540 return MEMCACHED_SUCCESS;
5541 }
5542
5543 static test_return_t memcached_stat_execute_test(memcached_st *memc)
5544 {
5545 memcached_return_t rc= memcached_stat_execute(memc, NULL, stat_printer, NULL);
5546 test_true(rc == MEMCACHED_SUCCESS);
5547
5548 rc= memcached_stat_execute(memc, "slabs", stat_printer, NULL);
5549 test_true(rc == MEMCACHED_SUCCESS);
5550
5551 rc= memcached_stat_execute(memc, "items", stat_printer, NULL);
5552 test_true(rc == MEMCACHED_SUCCESS);
5553
5554 rc= memcached_stat_execute(memc, "sizes", stat_printer, NULL);
5555 test_true(rc == MEMCACHED_SUCCESS);
5556
5557 return TEST_SUCCESS;
5558 }
5559
5560 /*
5561 * This test ensures that the failure counter isn't incremented during
5562 * normal termination of the memcached instance.
5563 */
5564 static test_return_t wrong_failure_counter_test(memcached_st *memc)
5565 {
5566 memcached_return_t rc;
5567 memcached_server_instance_st instance;
5568
5569 /* Set value to force connection to the server */
5570 const char *key= "marmotte";
5571 const char *value= "milka";
5572
5573 /*
5574 * Please note that I'm abusing the internal structures in libmemcached
5575 * in a non-portable way and you shouldn't be doing this. I'm only
5576 * doing this in order to verify that the library works the way it should
5577 */
5578 uint32_t number_of_hosts= memcached_server_count(memc);
5579 memc->number_of_hosts= 1;
5580
5581 /* Ensure that we are connected to the server by setting a value */
5582 rc= memcached_set(memc, key, strlen(key),
5583 value, strlen(value),
5584 (time_t)0, (uint32_t)0);
5585 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5586
5587
5588 instance= memcached_server_instance_by_position(memc, 0);
5589 /* The test is to see that the memcached_quit doesn't increase the
5590 * the server failure conter, so let's ensure that it is zero
5591 * before sending quit
5592 */
5593 ((memcached_server_write_instance_st)instance)->server_failure_counter= 0;
5594
5595 memcached_quit(memc);
5596
5597 /* Verify that it memcached_quit didn't increment the failure counter
5598 * Please note that this isn't bullet proof, because an error could
5599 * occur...
5600 */
5601 test_true(instance->server_failure_counter == 0);
5602
5603 /* restore the instance */
5604 memc->number_of_hosts= number_of_hosts;
5605
5606 return TEST_SUCCESS;
5607 }
5608
5609 /*
5610 * This tests ensures expected disconnections (for some behavior changes
5611 * for instance) do not wrongly increase failure counter
5612 */
5613 static test_return_t wrong_failure_counter_two_test(memcached_st *memc)
5614 {
5615 memcached_return rc;
5616
5617 memcached_st *memc_clone;
5618 memc_clone= memcached_clone(NULL, memc);
5619 test_true(memc_clone);
5620
5621 /* Set value to force connection to the server */
5622 const char *key= "marmotte";
5623 const char *value= "milka";
5624 char *string = NULL;
5625 size_t string_length;
5626 uint32_t flags;
5627
5628 rc= memcached_set(memc_clone, key, strlen(key),
5629 value, strlen(value),
5630 (time_t)0, (uint32_t)0);
5631 test_true_got(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED, memcached_strerror(NULL, rc));
5632
5633
5634 /* put failure limit to 1 */
5635 rc= memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, 1);
5636 assert(rc == MEMCACHED_SUCCESS);
5637
5638 /* Put a retry timeout to effectively activate failure_limit effect */
5639 rc= memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 1);
5640 assert(rc == MEMCACHED_SUCCESS);
5641
5642 /* change behavior that triggers memcached_quit()*/
5643 rc= memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_TCP_NODELAY, 1);
5644 assert(rc == MEMCACHED_SUCCESS);
5645
5646
5647 /* Check if we still are connected */
5648 string= memcached_get(memc_clone, key, strlen(key),
5649 &string_length, &flags, &rc);
5650
5651 test_true_got(rc == MEMCACHED_SUCCESS, memcached_strerror(NULL, rc));
5652 test_true(string);
5653 free(string);
5654 memcached_free(memc_clone);
5655
5656 return TEST_SUCCESS;
5657 }
5658
5659
5660
5661
5662 /*
5663 * Test that ensures mget_execute does not end into recursive calls that finally fails
5664 */
5665 static test_return_t regression_bug_490486(memcached_st *memc)
5666 {
5667 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
5668 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 1);
5669 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, 1000);
5670 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, 1);
5671 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 3600);
5672
5673 #ifdef __APPLE__
5674 return TEST_SKIPPED; // My MAC can't handle this test
5675 #endif
5676
5677 /*
5678 * I only want to hit _one_ server so I know the number of requests I'm
5679 * sending in the pipeline.
5680 */
5681 uint32_t number_of_hosts= memc->number_of_hosts;
5682 memc->number_of_hosts= 1;
5683 size_t max_keys= 20480;
5684
5685
5686 char **keys= (char **)calloc(max_keys, sizeof(char*));
5687 size_t *key_length= (size_t *)calloc(max_keys, sizeof(size_t));
5688
5689 /* First add all of the items.. */
5690 bool slept= false;
5691 char blob[1024]= { 0 };
5692 memcached_return rc;
5693 for (size_t x= 0; x < max_keys; ++x)
5694 {
5695 char k[251];
5696 key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%lu", (unsigned long)x);
5697 keys[x]= strdup(k);
5698 assert(keys[x] != NULL);
5699 rc= memcached_set(memc, keys[x], key_length[x], blob, sizeof(blob), 0, 0);
5700 #ifdef __APPLE__
5701 if (rc == MEMCACHED_SERVER_MARKED_DEAD)
5702 {
5703 break; // We are out of business
5704 }
5705 #endif
5706 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED || rc == MEMCACHED_TIMEOUT); // MEMCACHED_TIMEOUT <-- only observed on OSX
5707
5708 if (rc == MEMCACHED_TIMEOUT && slept == false)
5709 {
5710 x++;
5711 sleep(1);// We will try to sleep
5712 slept= true;
5713 }
5714 else if (rc == MEMCACHED_TIMEOUT && slept == true)
5715 {
5716 // We failed to send everything.
5717 break;
5718 }
5719 }
5720
5721 if (rc != MEMCACHED_SERVER_MARKED_DEAD)
5722 {
5723
5724 /* Try to get all of them with a large multiget */
5725 size_t counter= 0;
5726 memcached_execute_function callbacks[]= { &callback_counter };
5727 rc= memcached_mget_execute(memc, (const char**)keys, key_length,
5728 (size_t)max_keys, callbacks, &counter, 1);
5729
5730 assert(rc == MEMCACHED_SUCCESS);
5731 char* the_value= NULL;
5732 char the_key[MEMCACHED_MAX_KEY];
5733 size_t the_key_length;
5734 size_t the_value_length;
5735 uint32_t the_flags;
5736
5737 do {
5738 the_value= memcached_fetch(memc, the_key, &the_key_length, &the_value_length, &the_flags, &rc);
5739
5740 if ((the_value!= NULL) && (rc == MEMCACHED_SUCCESS))
5741 {
5742 ++counter;
5743 free(the_value);
5744 }
5745
5746 } while ( (the_value!= NULL) && (rc == MEMCACHED_SUCCESS));
5747
5748
5749 assert(rc == MEMCACHED_END);
5750
5751 /* Verify that we got all of the items */
5752 assert(counter == max_keys);
5753 }
5754
5755 /* Release all allocated resources */
5756 for (size_t x= 0; x < max_keys; ++x)
5757 {
5758 free(keys[x]);
5759 }
5760 free(keys);
5761 free(key_length);
5762
5763 memc->number_of_hosts= number_of_hosts;
5764
5765 return TEST_SUCCESS;
5766 }
5767
5768 static test_return_t regression_bug_583031(memcached_st *unused)
5769 {
5770 (void)unused;
5771
5772 memcached_st *memc= memcached_create(NULL);
5773 assert(memc);
5774 memcached_server_add(memc, "10.2.3.4", 11211);
5775
5776 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT, 1000);
5777 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 1000);
5778 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SND_TIMEOUT, 1000);
5779 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RCV_TIMEOUT, 1000);
5780 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, 1000);
5781 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, 3);
5782
5783 memcached_return_t rc;
5784 size_t length;
5785 uint32_t flags;
5786
5787 (void)memcached_get(memc, "dsf", 3, &length, &flags, &rc);
5788
5789 test_true_got(rc == MEMCACHED_TIMEOUT || rc == MEMCACHED_ERRNO || rc == MEMCACHED_FAILURE, memcached_strerror(memc, rc));
5790
5791 memcached_free(memc);
5792
5793 return TEST_SUCCESS;
5794 }
5795
5796 static test_return_t regression_bug_581030(memcached_st *unused)
5797 {
5798 (void)unused;
5799
5800 #ifndef DEBUG
5801 memcached_stat_st *local_stat= memcached_stat(NULL, NULL, NULL);
5802 test_false(local_stat);
5803
5804 memcached_stat_free(NULL, NULL);
5805 #endif
5806
5807 return TEST_SUCCESS;
5808 }
5809
5810 static void memcached_die(memcached_st* mc, memcached_return error, const char* what, uint32_t it)
5811 {
5812 fprintf(stderr, "Iteration #%u: ", it);
5813
5814 if(error == MEMCACHED_ERRNO)
5815 {
5816 fprintf(stderr, "system error %d from %s: %s\n",
5817 errno, what, strerror(errno));
5818 }
5819 else
5820 {
5821 fprintf(stderr, "error %d from %s: %s\n", error, what,
5822 memcached_strerror(mc, error));
5823 }
5824 }
5825
5826 #define TEST_CONSTANT_CREATION 200
5827
5828 static test_return_t regression_bug_(memcached_st *memc)
5829 {
5830 const char *remote_server;
5831 (void)memc;
5832
5833 if (! (remote_server= getenv("LIBMEMCACHED_REMOTE_SERVER")))
5834 {
5835 return TEST_SKIPPED;
5836 }
5837
5838 for (uint32_t x= 0; x < TEST_CONSTANT_CREATION; x++)
5839 {
5840 memcached_st* mc= memcached_create(NULL);
5841 memcached_return rc;
5842
5843 rc= memcached_behavior_set(mc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
5844 if (rc != MEMCACHED_SUCCESS)
5845 {
5846 memcached_die(mc, rc, "memcached_behavior_set", x);
5847 }
5848
5849 rc= memcached_behavior_set(mc, MEMCACHED_BEHAVIOR_CACHE_LOOKUPS, 1);
5850 if (rc != MEMCACHED_SUCCESS)
5851 {
5852 memcached_die(mc, rc, "memcached_behavior_set", x);
5853 }
5854
5855 rc= memcached_server_add(mc, remote_server, 0);
5856 if (rc != MEMCACHED_SUCCESS)
5857 {
5858 memcached_die(mc, rc, "memcached_server_add", x);
5859 }
5860
5861 const char *set_key= "akey";
5862 const size_t set_key_len= strlen(set_key);
5863 const char *set_value= "a value";
5864 const size_t set_value_len= strlen(set_value);
5865
5866 if (rc == MEMCACHED_SUCCESS)
5867 {
5868 if (x > 0)
5869 {
5870 size_t get_value_len;
5871 char *get_value;
5872 uint32_t get_value_flags;
5873
5874 get_value= memcached_get(mc, set_key, set_key_len, &get_value_len,
5875 &get_value_flags, &rc);
5876 if (rc != MEMCACHED_SUCCESS)
5877 {
5878 memcached_die(mc, rc, "memcached_get", x);
5879 }
5880 else
5881 {
5882
5883 if (x != 0 &&
5884 (get_value_len != set_value_len
5885 || 0!=strncmp(get_value, set_value, get_value_len)))
5886 {
5887 fprintf(stderr, "Values don't match?\n");
5888 rc= MEMCACHED_FAILURE;
5889 }
5890 free(get_value);
5891 }
5892 }
5893
5894 rc= memcached_set(mc,
5895 set_key, set_key_len,
5896 set_value, set_value_len,
5897 0, /* time */
5898 0 /* flags */
5899 );
5900 if (rc != MEMCACHED_SUCCESS)
5901 {
5902 memcached_die(mc, rc, "memcached_set", x);
5903 }
5904 }
5905
5906 memcached_quit(mc);
5907 memcached_free(mc);
5908
5909 if (rc != MEMCACHED_SUCCESS)
5910 {
5911 break;
5912 }
5913 }
5914
5915 return TEST_SUCCESS;
5916 }
5917
5918 /*
5919 * Test that the sasl authentication works. We cannot use the default
5920 * pool of servers, because that would require that all servers we want
5921 * to test supports SASL authentication, and that they use the default
5922 * creds.
5923 */
5924 static test_return_t sasl_auth_test(memcached_st *memc)
5925 {
5926 #ifdef LIBMEMCACHED_WITH_SASL_SUPPORT
5927 memcached_return_t rc;
5928
5929 rc= memcached_set(memc, "foo", 3, "bar", 3, (time_t)0, (uint32_t)0);
5930 test_true(rc == MEMCACHED_SUCCESS);
5931 test_true((rc= memcached_delete(memc, "foo", 3, 0)) == MEMCACHED_SUCCESS);
5932 test_true((rc= memcached_destroy_sasl_auth_data(memc)) == MEMCACHED_SUCCESS);
5933 test_true((rc= memcached_destroy_sasl_auth_data(memc)) == MEMCACHED_FAILURE);
5934 test_true((rc= memcached_destroy_sasl_auth_data(NULL)) == MEMCACHED_FAILURE);
5935 memcached_quit(memc);
5936
5937 rc= memcached_set_sasl_auth_data(memc,
5938 getenv("LIBMEMCACHED_TEST_SASL_USERNAME"),
5939 getenv("LIBMEMCACHED_TEST_SASL_SERVER"));
5940 test_true(rc == MEMCACHED_SUCCESS);
5941
5942 rc= memcached_set(memc, "foo", 3, "bar", 3, (time_t)0, (uint32_t)0);
5943 test_true(rc == MEMCACHED_AUTH_FAILURE);
5944 test_true(memcached_destroy_sasl_auth_data(memc) == MEMCACHED_SUCCESS);
5945
5946 memcached_quit(memc);
5947 return TEST_SUCCESS;
5948 #else
5949 (void)memc;
5950 return TEST_FAILURE;
5951 #endif
5952 }
5953
5954 /* Clean the server before beginning testing */
5955 test_st tests[] ={
5956 {"util_version", 1, (test_callback_fn)util_version_test },
5957 {"flush", 0, (test_callback_fn)flush_test },
5958 {"init", 0, (test_callback_fn)init_test },
5959 {"allocation", 0, (test_callback_fn)allocation_test },
5960 {"server_list_null_test", 0, (test_callback_fn)server_list_null_test},
5961 {"server_unsort", 0, (test_callback_fn)server_unsort_test},
5962 {"server_sort", 0, (test_callback_fn)server_sort_test},
5963 {"server_sort2", 0, (test_callback_fn)server_sort2_test},
5964 {"memcached_server_remove", 0, (test_callback_fn)memcached_server_remove_test},
5965 {"clone_test", 0, (test_callback_fn)clone_test },
5966 {"connection_test", 0, (test_callback_fn)connection_test},
5967 {"callback_test", 0, (test_callback_fn)callback_test},
5968 {"userdata_test", 0, (test_callback_fn)userdata_test},
5969 {"error", 0, (test_callback_fn)error_test },
5970 {"set", 0, (test_callback_fn)set_test },
5971 {"set2", 0, (test_callback_fn)set_test2 },
5972 {"set3", 0, (test_callback_fn)set_test3 },
5973 {"dump", 1, (test_callback_fn)dump_test},
5974 {"add", 1, (test_callback_fn)add_test },
5975 {"replace", 1, (test_callback_fn)replace_test },
5976 {"delete", 1, (test_callback_fn)delete_test },
5977 {"get", 1, (test_callback_fn)get_test },
5978 {"get2", 0, (test_callback_fn)get_test2 },
5979 {"get3", 0, (test_callback_fn)get_test3 },
5980 {"get4", 0, (test_callback_fn)get_test4 },
5981 {"partial mget", 0, (test_callback_fn)get_test5 },
5982 {"stats_servername", 0, (test_callback_fn)stats_servername_test },
5983 {"increment", 0, (test_callback_fn)increment_test },
5984 {"increment_with_initial", 1, (test_callback_fn)increment_with_initial_test },
5985 {"decrement", 0, (test_callback_fn)decrement_test },
5986 {"decrement_with_initial", 1, (test_callback_fn)decrement_with_initial_test },
5987 {"increment_by_key", 0, (test_callback_fn)increment_by_key_test },
5988 {"increment_with_initial_by_key", 1, (test_callback_fn)increment_with_initial_by_key_test },
5989 {"decrement_by_key", 0, (test_callback_fn)decrement_by_key_test },
5990 {"decrement_with_initial_by_key", 1, (test_callback_fn)decrement_with_initial_by_key_test },
5991 {"quit", 0, (test_callback_fn)quit_test },
5992 {"mget", 1, (test_callback_fn)mget_test },
5993 {"mget_result", 1, (test_callback_fn)mget_result_test },
5994 {"mget_result_alloc", 1, (test_callback_fn)mget_result_alloc_test },
5995 {"mget_result_function", 1, (test_callback_fn)mget_result_function },
5996 {"mget_execute", 1, (test_callback_fn)mget_execute },
5997 {"mget_end", 0, (test_callback_fn)mget_end },
5998 {"get_stats", 0, (test_callback_fn)get_stats },
5999 {"add_host_test", 0, (test_callback_fn)add_host_test },
6000 {"add_host_test_1", 0, (test_callback_fn)add_host_test1 },
6001 {"get_stats_keys", 0, (test_callback_fn)get_stats_keys },
6002 {"version_string_test", 0, (test_callback_fn)version_string_test},
6003 {"bad_key", 1, (test_callback_fn)bad_key_test },
6004 {"memcached_server_cursor", 1, (test_callback_fn)memcached_server_cursor_test },
6005 {"read_through", 1, (test_callback_fn)read_through },
6006 {"delete_through", 1, (test_callback_fn)delete_through },
6007 {"noreply", 1, (test_callback_fn)noreply_test},
6008 {"analyzer", 1, (test_callback_fn)analyzer_test},
6009 {"connectionpool", 1, (test_callback_fn)connection_pool_test },
6010 {"memcached_pool_test", 1, (test_callback_fn)memcached_pool_test },
6011 {"ping", 1, (test_callback_fn)ping_test },
6012 {"test_get_last_disconnect", 1, (test_callback_fn)test_get_last_disconnect},
6013 {"verbosity", 1, (test_callback_fn)test_verbosity},
6014 {"test_server_failure", 1, (test_callback_fn)test_server_failure},
6015 {"cull_servers", 1, (test_callback_fn)test_cull_servers},
6016 {"memcached_stat_execute", 1, (test_callback_fn)memcached_stat_execute_test},
6017 {0, 0, 0}
6018 };
6019
6020 test_st behavior_tests[] ={
6021 {"behavior_test", 0, (test_callback_fn)behavior_test},
6022 {"MEMCACHED_BEHAVIOR_CORK", 0, (test_callback_fn)MEMCACHED_BEHAVIOR_CORK_test},
6023 {"MEMCACHED_BEHAVIOR_TCP_KEEPALIVE", 0, (test_callback_fn)MEMCACHED_BEHAVIOR_TCP_KEEPALIVE_test},
6024 {"MEMCACHED_BEHAVIOR_TCP_KEEPIDLE", 0, (test_callback_fn)MEMCACHED_BEHAVIOR_TCP_KEEPIDLE_test},
6025 {0, 0, 0}
6026 };
6027
6028 test_st basic_tests[] ={
6029 {"init", 1, (test_callback_fn)basic_init_test},
6030 {"clone", 1, (test_callback_fn)basic_clone_test},
6031 {"reset", 1, (test_callback_fn)basic_reset_stack_test},
6032 {"reset heap", 1, (test_callback_fn)basic_reset_heap_test},
6033 {"reset stack clone", 1, (test_callback_fn)basic_reset_stack_clone_test},
6034 {"reset heap clone", 1, (test_callback_fn)basic_reset_heap_clone_test},
6035 {0, 0, 0}
6036 };
6037
6038 test_st regression_binary_vs_block[] ={
6039 {"block add", 1, (test_callback_fn)block_add_regression},
6040 {"binary add", 1, (test_callback_fn)binary_add_regression},
6041 {0, 0, 0}
6042 };
6043
6044 test_st async_tests[] ={
6045 {"add", 1, (test_callback_fn)add_wrapper },
6046 {0, 0, 0}
6047 };
6048
6049 test_st string_tests[] ={
6050 {"string static with null", 0, (test_callback_fn)string_static_null },
6051 {"string alloc with null", 0, (test_callback_fn)string_alloc_null },
6052 {"string alloc with 1K", 0, (test_callback_fn)string_alloc_with_size },
6053 {"string alloc with malloc failure", 0, (test_callback_fn)string_alloc_with_size_toobig },
6054 {"string append", 0, (test_callback_fn)string_alloc_append },
6055 {"string append failure (too big)", 0, (test_callback_fn)string_alloc_append_toobig },
6056 {"string_alloc_append_multiple", 0, (test_callback_fn)string_alloc_append_multiple },
6057 {0, 0, (test_callback_fn)0}
6058 };
6059
6060 test_st result_tests[] ={
6061 {"result static", 0, (test_callback_fn)result_static},
6062 {"result alloc", 0, (test_callback_fn)result_alloc},
6063 {0, 0, (test_callback_fn)0}
6064 };
6065
6066 test_st version_1_2_3[] ={
6067 {"append", 0, (test_callback_fn)append_test },
6068 {"prepend", 0, (test_callback_fn)prepend_test },
6069 {"cas", 0, (test_callback_fn)cas_test },
6070 {"cas2", 0, (test_callback_fn)cas2_test },
6071 {"append_binary", 0, (test_callback_fn)append_binary_test },
6072 {0, 0, (test_callback_fn)0}
6073 };
6074
6075 test_st user_tests[] ={
6076 {"user_supplied_bug1", 0, (test_callback_fn)user_supplied_bug1 },
6077 {"user_supplied_bug2", 0, (test_callback_fn)user_supplied_bug2 },
6078 {"user_supplied_bug3", 0, (test_callback_fn)user_supplied_bug3 },
6079 {"user_supplied_bug4", 0, (test_callback_fn)user_supplied_bug4 },
6080 {"user_supplied_bug5", 1, (test_callback_fn)user_supplied_bug5 },
6081 {"user_supplied_bug6", 1, (test_callback_fn)user_supplied_bug6 },
6082 {"user_supplied_bug7", 1, (test_callback_fn)user_supplied_bug7 },
6083 {"user_supplied_bug8", 1, (test_callback_fn)user_supplied_bug8 },
6084 {"user_supplied_bug9", 1, (test_callback_fn)user_supplied_bug9 },
6085 {"user_supplied_bug10", 1, (test_callback_fn)user_supplied_bug10 },
6086 {"user_supplied_bug11", 1, (test_callback_fn)user_supplied_bug11 },
6087 {"user_supplied_bug12", 1, (test_callback_fn)user_supplied_bug12 },
6088 {"user_supplied_bug13", 1, (test_callback_fn)user_supplied_bug13 },
6089 {"user_supplied_bug14", 1, (test_callback_fn)user_supplied_bug14 },
6090 {"user_supplied_bug15", 1, (test_callback_fn)user_supplied_bug15 },
6091 {"user_supplied_bug16", 1, (test_callback_fn)user_supplied_bug16 },
6092 #if !defined(__sun) && !defined(__OpenBSD__)
6093 /*
6094 ** It seems to be something weird with the character sets..
6095 ** value_fetch is unable to parse the value line (iscntrl "fails"), so I
6096 ** guess I need to find out how this is supposed to work.. Perhaps I need
6097 ** to run the test in a specific locale (I tried zh_CN.UTF-8 without success,
6098 ** so just disable the code for now...).
6099 */
6100 {"user_supplied_bug17", 1, (test_callback_fn)user_supplied_bug17 },
6101 #endif
6102 {"user_supplied_bug18", 1, (test_callback_fn)user_supplied_bug18 },
6103 {"user_supplied_bug19", 1, (test_callback_fn)user_supplied_bug19 },
6104 {"user_supplied_bug20", 1, (test_callback_fn)user_supplied_bug20 },
6105 {"user_supplied_bug21", 1, (test_callback_fn)user_supplied_bug21 },
6106 {"wrong_failure_counter_test", 1, (test_callback_fn)wrong_failure_counter_test},
6107 {"wrong_failure_counter_two_test", 1, (test_callback_fn)wrong_failure_counter_two_test},
6108 {0, 0, (test_callback_fn)0}
6109 };
6110
6111 test_st replication_tests[]= {
6112 {"set", 1, (test_callback_fn)replication_set_test },
6113 {"get", 0, (test_callback_fn)replication_get_test },
6114 {"mget", 0, (test_callback_fn)replication_mget_test },
6115 {"delete", 0, (test_callback_fn)replication_delete_test },
6116 {"rand_mget", 0, (test_callback_fn)replication_randomize_mget_test },
6117 {0, 0, (test_callback_fn)0}
6118 };
6119
6120 /*
6121 * The following test suite is used to verify that we don't introduce
6122 * regression bugs. If you want more information about the bug / test,
6123 * you should look in the bug report at
6124 * http://bugs.launchpad.net/libmemcached
6125 */
6126 test_st regression_tests[]= {
6127 {"lp:434484", 1, (test_callback_fn)regression_bug_434484 },
6128 {"lp:434843", 1, (test_callback_fn)regression_bug_434843 },
6129 {"lp:434843-buffered", 1, (test_callback_fn)regression_bug_434843_buffered },
6130 {"lp:421108", 1, (test_callback_fn)regression_bug_421108 },
6131 {"lp:442914", 1, (test_callback_fn)regression_bug_442914 },
6132 {"lp:447342", 1, (test_callback_fn)regression_bug_447342 },
6133 {"lp:463297", 1, (test_callback_fn)regression_bug_463297 },
6134 {"lp:490486", 1, (test_callback_fn)regression_bug_490486 },
6135 {"lp:583031", 1, (test_callback_fn)regression_bug_583031 },
6136 {"lp:?", 1, (test_callback_fn)regression_bug_ },
6137 {"lp:728286", 1, (test_callback_fn)regression_bug_728286 },
6138 {"lp:581030", 1, (test_callback_fn)regression_bug_581030 },
6139 {0, 0, (test_callback_fn)0}
6140 };
6141
6142 test_st sasl_auth_tests[]= {
6143 {"sasl_auth", 1, (test_callback_fn)sasl_auth_test },
6144 {0, 0, (test_callback_fn)0}
6145 };
6146
6147 test_st ketama_compatibility[]= {
6148 {"libmemcached", 1, (test_callback_fn)ketama_compatibility_libmemcached },
6149 {"spymemcached", 1, (test_callback_fn)ketama_compatibility_spymemcached },
6150 {0, 0, (test_callback_fn)0}
6151 };
6152
6153 test_st generate_tests[] ={
6154 {"generate_pairs", 1, (test_callback_fn)generate_pairs },
6155 {"generate_data", 1, (test_callback_fn)generate_data },
6156 {"get_read", 0, (test_callback_fn)get_read },
6157 {"delete_generate", 0, (test_callback_fn)delete_generate },
6158 {"generate_buffer_data", 1, (test_callback_fn)generate_buffer_data },
6159 {"delete_buffer", 0, (test_callback_fn)delete_buffer_generate},
6160 {"generate_data", 1, (test_callback_fn)generate_data },
6161 {"mget_read", 0, (test_callback_fn)mget_read },
6162 {"mget_read_result", 0, (test_callback_fn)mget_read_result },
6163 {"mget_read_function", 0, (test_callback_fn)mget_read_function },
6164 {"cleanup", 1, (test_callback_fn)cleanup_pairs },
6165 {"generate_large_pairs", 1, (test_callback_fn)generate_large_pairs },
6166 {"generate_data", 1, (test_callback_fn)generate_data },
6167 {"generate_buffer_data", 1, (test_callback_fn)generate_buffer_data },
6168 {"cleanup", 1, (test_callback_fn)cleanup_pairs },
6169 {0, 0, (test_callback_fn)0}
6170 };
6171
6172 test_st consistent_tests[] ={
6173 {"generate_pairs", 1, (test_callback_fn)generate_pairs },
6174 {"generate_data", 1, (test_callback_fn)generate_data },
6175 {"get_read", 0, (test_callback_fn)get_read_count },
6176 {"cleanup", 1, (test_callback_fn)cleanup_pairs },
6177 {0, 0, (test_callback_fn)0}
6178 };
6179
6180 test_st consistent_weighted_tests[] ={
6181 {"generate_pairs", 1, (test_callback_fn)generate_pairs },
6182 {"generate_data", 1, (test_callback_fn)generate_data_with_stats },
6183 {"get_read", 0, (test_callback_fn)get_read_count },
6184 {"cleanup", 1, (test_callback_fn)cleanup_pairs },
6185 {0, 0, (test_callback_fn)0}
6186 };
6187
6188 test_st hsieh_availability[] ={
6189 {"hsieh_avaibility_test", 0, (test_callback_fn)hsieh_avaibility_test},
6190 {0, 0, (test_callback_fn)0}
6191 };
6192
6193 test_st murmur_availability[] ={
6194 {"murmur_avaibility_test", 0, (test_callback_fn)murmur_avaibility_test},
6195 {0, 0, (test_callback_fn)0}
6196 };
6197
6198 #if 0
6199 test_st hash_sanity[] ={
6200 {"hash sanity", 0, (test_callback_fn)hash_sanity_test},
6201 {0, 0, (test_callback_fn)0}
6202 };
6203 #endif
6204
6205 test_st ketama_auto_eject_hosts[] ={
6206 {"auto_eject_hosts", 1, (test_callback_fn)auto_eject_hosts },
6207 {"output_ketama_weighted_keys", 1, (test_callback_fn)output_ketama_weighted_keys },
6208 {0, 0, (test_callback_fn)0}
6209 };
6210
6211 test_st hash_tests[] ={
6212 {"one_at_a_time_run", 0, (test_callback_fn)one_at_a_time_run },
6213 {"md5", 0, (test_callback_fn)md5_run },
6214 {"crc", 0, (test_callback_fn)crc_run },
6215 {"fnv1_64", 0, (test_callback_fn)fnv1_64_run },
6216 {"fnv1a_64", 0, (test_callback_fn)fnv1a_64_run },
6217 {"fnv1_32", 0, (test_callback_fn)fnv1_32_run },
6218 {"fnv1a_32", 0, (test_callback_fn)fnv1a_32_run },
6219 {"hsieh", 0, (test_callback_fn)hsieh_run },
6220 {"murmur", 0, (test_callback_fn)murmur_run },
6221 {"jenkis", 0, (test_callback_fn)jenkins_run },
6222 {"memcached_get_hashkit", 0, (test_callback_fn)memcached_get_hashkit_test },
6223 {0, 0, (test_callback_fn)0}
6224 };
6225
6226 test_st error_conditions[] ={
6227 {"memcached_get(MEMCACHED_ERRNO)", 0, (test_callback_fn)memcached_get_MEMCACHED_ERRNO },
6228 {"memcached_get(MEMCACHED_NOTFOUND)", 0, (test_callback_fn)memcached_get_MEMCACHED_NOTFOUND },
6229 {"memcached_get_by_key(MEMCACHED_ERRNO)", 0, (test_callback_fn)memcached_get_by_key_MEMCACHED_ERRNO },
6230 {"memcached_get_by_key(MEMCACHED_NOTFOUND)", 0, (test_callback_fn)memcached_get_by_key_MEMCACHED_NOTFOUND },
6231 {"memcached_get_by_key(MEMCACHED_NOTFOUND)", 0, (test_callback_fn)memcached_get_by_key_MEMCACHED_NOTFOUND },
6232 {"memcached_increment(MEMCACHED_NO_SERVERS)", 0, (test_callback_fn)memcached_increment_MEMCACHED_NO_SERVERS },
6233 {0, 0, (test_callback_fn)0}
6234 };
6235
6236
6237 test_st parser_tests[] ={
6238 {"behavior", 0, (test_callback_fn)behavior_parser_test },
6239 {"boolean_options", 0, (test_callback_fn)parser_boolean_options_test },
6240 {"configure_file", 0, (test_callback_fn)memcached_create_with_options_with_filename },
6241 {"distribtions", 0, (test_callback_fn)parser_distribution_test },
6242 {"hash", 0, (test_callback_fn)parser_hash_test },
6243 {"libmemcached_check_configuration", 0, (test_callback_fn)libmemcached_check_configuration_test },
6244 {"libmemcached_check_configuration_with_filename", 0, (test_callback_fn)libmemcached_check_configuration_with_filename_test },
6245 {"number_options", 0, (test_callback_fn)parser_number_options_test },
6246 {"randomly generated options", 0, (test_callback_fn)random_statement_build_test },
6247 {"prefix_key", 0, (test_callback_fn)parser_key_prefix_test },
6248 {"server", 0, (test_callback_fn)server_test },
6249 {"bad server strings", 0, (test_callback_fn)servers_bad_test },
6250 {"server with weights", 0, (test_callback_fn)server_with_weight_test },
6251 {0, 0, (test_callback_fn)0}
6252 };
6253
6254 test_st virtual_bucket_tests[] ={
6255 {"basic", 0, (test_callback_fn)virtual_back_map },
6256 {0, 0, (test_callback_fn)0}
6257 };
6258
6259 collection_st collection[] ={
6260 #if 0
6261 {"hash_sanity", 0, 0, hash_sanity},
6262 #endif
6263 {"basic", 0, 0, basic_tests},
6264 {"hsieh_availability", 0, 0, hsieh_availability},
6265 {"murmur_availability", 0, 0, murmur_availability},
6266 {"block", 0, 0, tests},
6267 {"binary", (test_callback_fn)pre_binary, 0, tests},
6268 {"nonblock", (test_callback_fn)pre_nonblock, 0, tests},
6269 {"nodelay", (test_callback_fn)pre_nodelay, 0, tests},
6270 {"settimer", (test_callback_fn)pre_settimer, 0, tests},
6271 {"md5", (test_callback_fn)pre_md5, 0, tests},
6272 {"crc", (test_callback_fn)pre_crc, 0, tests},
6273 {"hsieh", (test_callback_fn)pre_hsieh, 0, tests},
6274 {"jenkins", (test_callback_fn)pre_jenkins, 0, tests},
6275 {"fnv1_64", (test_callback_fn)pre_hash_fnv1_64, 0, tests},
6276 {"fnv1a_64", (test_callback_fn)pre_hash_fnv1a_64, 0, tests},
6277 {"fnv1_32", (test_callback_fn)pre_hash_fnv1_32, 0, tests},
6278 {"fnv1a_32", (test_callback_fn)pre_hash_fnv1a_32, 0, tests},
6279 {"ketama", (test_callback_fn)pre_behavior_ketama, 0, tests},
6280 {"ketama_auto_eject_hosts", (test_callback_fn)pre_behavior_ketama, 0, ketama_auto_eject_hosts},
6281 {"unix_socket", (test_callback_fn)pre_unix_socket, 0, tests},
6282 {"unix_socket_nodelay", (test_callback_fn)pre_nodelay, 0, tests},
6283 {"poll_timeout", (test_callback_fn)poll_timeout, 0, tests},
6284 {"gets", (test_callback_fn)enable_cas, 0, tests},
6285 {"consistent_crc", (test_callback_fn)enable_consistent_crc, 0, tests},
6286 {"consistent_hsieh", (test_callback_fn)enable_consistent_hsieh, 0, tests},
6287 #ifdef MEMCACHED_ENABLE_DEPRECATED
6288 {"deprecated_memory_allocators", (test_callback_fn)deprecated_set_memory_alloc, 0, tests},
6289 #endif
6290 {"memory_allocators", (test_callback_fn)set_memory_alloc, 0, tests},
6291 {"prefix", (test_callback_fn)set_prefix, 0, tests},
6292 {"sasl_auth", (test_callback_fn)pre_sasl, 0, sasl_auth_tests },
6293 {"sasl", (test_callback_fn)pre_sasl, 0, tests },
6294 {"version_1_2_3", (test_callback_fn)check_for_1_2_3, 0, version_1_2_3},
6295 {"string", 0, 0, string_tests},
6296 {"result", 0, 0, result_tests},
6297 {"async", (test_callback_fn)pre_nonblock, 0, async_tests},
6298 {"async_binary", (test_callback_fn)pre_nonblock_binary, 0, async_tests},
6299 {"user", 0, 0, user_tests},
6300 {"generate", 0, 0, generate_tests},
6301 {"generate_hsieh", (test_callback_fn)pre_hsieh, 0, generate_tests},
6302 {"generate_ketama", (test_callback_fn)pre_behavior_ketama, 0, generate_tests},
6303 {"generate_hsieh_consistent", (test_callback_fn)enable_consistent_hsieh, 0, generate_tests},
6304 {"generate_md5", (test_callback_fn)pre_md5, 0, generate_tests},
6305 {"generate_murmur", (test_callback_fn)pre_murmur, 0, generate_tests},
6306 {"generate_jenkins", (test_callback_fn)pre_jenkins, 0, generate_tests},
6307 {"generate_nonblock", (test_callback_fn)pre_nonblock, 0, generate_tests},
6308 // Too slow
6309 {"generate_corked", (test_callback_fn)pre_cork, 0, generate_tests},
6310 {"generate_corked_and_nonblock", (test_callback_fn)pre_cork_and_nonblock, 0, generate_tests},
6311 {"consistent_not", 0, 0, consistent_tests},
6312 {"consistent_ketama", (test_callback_fn)pre_behavior_ketama, 0, consistent_tests},
6313 {"consistent_ketama_weighted", (test_callback_fn)pre_behavior_ketama_weighted, 0, consistent_weighted_tests},
6314 {"ketama_compat", 0, 0, ketama_compatibility},
6315 {"test_hashes", 0, 0, hash_tests},
6316 {"replication", (test_callback_fn)pre_replication, 0, replication_tests},
6317 {"replication_noblock", (test_callback_fn)pre_replication_noblock, 0, replication_tests},
6318 {"regression", 0, 0, regression_tests},
6319 {"behaviors", 0, 0, behavior_tests},
6320 {"regression_binary_vs_block", (test_callback_fn)key_setup, (test_callback_fn)key_teardown, regression_binary_vs_block},
6321 {"error_conditions", 0, 0, error_conditions},
6322 {"parser", 0, 0, parser_tests},
6323 {"virtual buckets", 0, 0, virtual_bucket_tests},
6324 {0, 0, 0, 0}
6325 };
6326
6327 #include "tests/libmemcached_world.h"
6328
6329 void get_world(world_st *world)
6330 {
6331 world->collections= collection;
6332
6333 world->create= (test_callback_create_fn)world_create;
6334 world->destroy= (test_callback_fn)world_destroy;
6335
6336 world->test.startup= (test_callback_fn)world_test_startup;
6337 world->test.flush= (test_callback_fn)world_flush;
6338 world->test.pre_run= (test_callback_fn)world_pre_run;
6339 world->test.post_run= (test_callback_fn)world_post_run;
6340 world->test.on_error= (test_callback_error_fn)world_on_error;
6341
6342 world->collection.startup= (test_callback_fn)world_container_startup;
6343 world->collection.shutdown= (test_callback_fn)world_container_shutdown;
6344
6345 world->runner= &defualt_libmemcached_runner;
6346 }