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