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