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