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