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