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