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