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