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