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