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