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