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