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