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