Concurrent memcached_verbosity().
[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 static test_return_t fetch_all_results(memcached_st *memc)
1943 {
1944 memcached_return_t rc= MEMCACHED_SUCCESS;
1945 char return_key[MEMCACHED_MAX_KEY];
1946 size_t return_key_length;
1947 char *return_value;
1948 size_t return_value_length;
1949 uint32_t flags;
1950
1951 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
1952 &return_value_length, &flags, &rc)))
1953 {
1954 test_true(return_value);
1955 test_true(rc == MEMCACHED_SUCCESS);
1956 free(return_value);
1957 }
1958
1959 return ((rc == MEMCACHED_END) || (rc == MEMCACHED_SUCCESS)) ? TEST_SUCCESS : TEST_FAILURE;
1960 }
1961
1962 /* Test case provided by Cal Haldenbrand */
1963 static test_return_t user_supplied_bug1(memcached_st *memc)
1964 {
1965 unsigned int setter= 1;
1966
1967 unsigned long long total= 0;
1968 uint32_t size= 0;
1969 char key[10];
1970 char randomstuff[6 * 1024];
1971 memcached_return_t rc;
1972
1973 memset(randomstuff, 0, 6 * 1024);
1974
1975 /* We just keep looking at the same values over and over */
1976 srandom(10);
1977
1978 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, setter);
1979 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, setter);
1980
1981
1982 /* add key */
1983 for (uint32_t x= 0 ; total < 20 * 1024576 ; x++ )
1984 {
1985 unsigned int j= 0;
1986
1987 size= (uint32_t)(rand() % ( 5 * 1024 ) ) + 400;
1988 memset(randomstuff, 0, 6 * 1024);
1989 test_true(size < 6 * 1024); /* Being safe here */
1990
1991 for (j= 0 ; j < size ;j++)
1992 randomstuff[j] = (signed char) ((rand() % 26) + 97);
1993
1994 total += size;
1995 snprintf(key, sizeof(key), "%u", x);
1996 rc = memcached_set(memc, key, strlen(key),
1997 randomstuff, strlen(randomstuff), 10, 0);
1998 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
1999 /* If we fail, lets try again */
2000 if (rc != MEMCACHED_SUCCESS && rc != MEMCACHED_BUFFERED)
2001 rc = memcached_set(memc, key, strlen(key),
2002 randomstuff, strlen(randomstuff), 10, 0);
2003 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
2004 }
2005
2006 return TEST_SUCCESS;
2007 }
2008
2009 /* Test case provided by Cal Haldenbrand */
2010 static test_return_t user_supplied_bug2(memcached_st *memc)
2011 {
2012 unsigned int setter;
2013 size_t total= 0;
2014
2015 setter= 1;
2016 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, setter);
2017 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, setter);
2018 #ifdef NOT_YET
2019 setter = 20 * 1024576;
2020 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE, setter);
2021 setter = 20 * 1024576;
2022 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE, setter);
2023 getter = memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE);
2024 getter = memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE);
2025
2026 for (x= 0, errors= 0; total < 20 * 1024576 ; x++)
2027 #endif
2028
2029 for (uint32_t x= 0, errors= 0; total < 24576 ; x++)
2030 {
2031 memcached_return_t rc= MEMCACHED_SUCCESS;
2032 char buffer[SMALL_STRING_LEN];
2033 uint32_t flags= 0;
2034 size_t val_len= 0;
2035 char *getval;
2036
2037 memset(buffer, 0, SMALL_STRING_LEN);
2038
2039 snprintf(buffer, sizeof(buffer), "%u", x);
2040 getval= memcached_get(memc, buffer, strlen(buffer),
2041 &val_len, &flags, &rc);
2042 if (rc != MEMCACHED_SUCCESS)
2043 {
2044 if (rc == MEMCACHED_NOTFOUND)
2045 errors++;
2046 else
2047 {
2048 test_true(rc);
2049 }
2050
2051 continue;
2052 }
2053 total+= val_len;
2054 errors= 0;
2055 free(getval);
2056 }
2057
2058 return TEST_SUCCESS;
2059 }
2060
2061 /* Do a large mget() over all the keys we think exist */
2062 #define KEY_COUNT 3000 // * 1024576
2063 static test_return_t user_supplied_bug3(memcached_st *memc)
2064 {
2065 memcached_return_t rc;
2066 unsigned int setter;
2067 unsigned int x;
2068 char **keys;
2069 size_t key_lengths[KEY_COUNT];
2070
2071 setter= 1;
2072 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, setter);
2073 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, setter);
2074 #ifdef NOT_YET
2075 setter = 20 * 1024576;
2076 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE, setter);
2077 setter = 20 * 1024576;
2078 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE, setter);
2079 getter = memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE);
2080 getter = memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE);
2081 #endif
2082
2083 keys= calloc(KEY_COUNT, sizeof(char *));
2084 test_true(keys);
2085 for (x= 0; x < KEY_COUNT; x++)
2086 {
2087 char buffer[30];
2088
2089 snprintf(buffer, 30, "%u", x);
2090 keys[x]= strdup(buffer);
2091 key_lengths[x]= strlen(keys[x]);
2092 }
2093
2094 rc= memcached_mget(memc, (const char **)keys, key_lengths, KEY_COUNT);
2095 test_true(rc == MEMCACHED_SUCCESS);
2096
2097 test_true(fetch_all_results(memc) == TEST_SUCCESS);
2098
2099 for (x= 0; x < KEY_COUNT; x++)
2100 free(keys[x]);
2101 free(keys);
2102
2103 return TEST_SUCCESS;
2104 }
2105
2106 /* Make sure we behave properly if server list has no values */
2107 static test_return_t user_supplied_bug4(memcached_st *memc)
2108 {
2109 memcached_return_t rc;
2110 const char *keys[]= {"fudge", "son", "food"};
2111 size_t key_length[]= {5, 3, 4};
2112 unsigned int x;
2113 uint32_t flags;
2114 char return_key[MEMCACHED_MAX_KEY];
2115 size_t return_key_length;
2116 char *return_value;
2117 size_t return_value_length;
2118
2119 /* Here we free everything before running a bunch of mget tests */
2120 memcached_servers_reset(memc);
2121
2122
2123 /* We need to empty the server before continueing test */
2124 rc= memcached_flush(memc, 0);
2125 test_true(rc == MEMCACHED_NO_SERVERS);
2126
2127 rc= memcached_mget(memc, keys, key_length, 3);
2128 test_true(rc == MEMCACHED_NO_SERVERS);
2129
2130 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
2131 &return_value_length, &flags, &rc)) != NULL)
2132 {
2133 test_true(return_value);
2134 }
2135 test_true(!return_value);
2136 test_true(return_value_length == 0);
2137 test_true(rc == MEMCACHED_NO_SERVERS);
2138
2139 for (x= 0; x < 3; x++)
2140 {
2141 rc= memcached_set(memc, keys[x], key_length[x],
2142 keys[x], key_length[x],
2143 (time_t)50, (uint32_t)9);
2144 test_true(rc == MEMCACHED_NO_SERVERS);
2145 }
2146
2147 rc= memcached_mget(memc, keys, key_length, 3);
2148 test_true(rc == MEMCACHED_NO_SERVERS);
2149
2150 x= 0;
2151 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
2152 &return_value_length, &flags, &rc)))
2153 {
2154 test_true(return_value);
2155 test_true(rc == MEMCACHED_SUCCESS);
2156 test_true(return_key_length == return_value_length);
2157 test_true(!memcmp(return_value, return_key, return_value_length));
2158 free(return_value);
2159 x++;
2160 }
2161
2162 return TEST_SUCCESS;
2163 }
2164
2165 #define VALUE_SIZE_BUG5 1048064
2166 static test_return_t user_supplied_bug5(memcached_st *memc)
2167 {
2168 memcached_return_t rc;
2169 const char *keys[]= {"036790384900", "036790384902", "036790384904", "036790384906"};
2170 size_t key_length[]= {strlen("036790384900"), strlen("036790384902"), strlen("036790384904"), strlen("036790384906")};
2171 char return_key[MEMCACHED_MAX_KEY];
2172 size_t return_key_length;
2173 char *value;
2174 size_t value_length;
2175 uint32_t flags;
2176 unsigned int count;
2177 unsigned int x;
2178 char insert_data[VALUE_SIZE_BUG5];
2179
2180 for (x= 0; x < VALUE_SIZE_BUG5; x++)
2181 insert_data[x]= (signed char)rand();
2182
2183 memcached_flush(memc, 0);
2184 value= memcached_get(memc, keys[0], key_length[0],
2185 &value_length, &flags, &rc);
2186 test_true(value == NULL);
2187 rc= memcached_mget(memc, keys, key_length, 4);
2188
2189 count= 0;
2190 while ((value= memcached_fetch(memc, return_key, &return_key_length,
2191 &value_length, &flags, &rc)))
2192 count++;
2193 test_true(count == 0);
2194
2195 for (x= 0; x < 4; x++)
2196 {
2197 rc= memcached_set(memc, keys[x], key_length[x],
2198 insert_data, VALUE_SIZE_BUG5,
2199 (time_t)0, (uint32_t)0);
2200 test_true(rc == MEMCACHED_SUCCESS);
2201 }
2202
2203 for (x= 0; x < 10; x++)
2204 {
2205 value= memcached_get(memc, keys[0], key_length[0],
2206 &value_length, &flags, &rc);
2207 test_true(value);
2208 free(value);
2209
2210 rc= memcached_mget(memc, keys, key_length, 4);
2211 count= 0;
2212 while ((value= memcached_fetch(memc, return_key, &return_key_length,
2213 &value_length, &flags, &rc)))
2214 {
2215 count++;
2216 free(value);
2217 }
2218 test_true(count == 4);
2219 }
2220
2221 return TEST_SUCCESS;
2222 }
2223
2224 static test_return_t user_supplied_bug6(memcached_st *memc)
2225 {
2226 memcached_return_t rc;
2227 const char *keys[]= {"036790384900", "036790384902", "036790384904", "036790384906"};
2228 size_t key_length[]= {strlen("036790384900"), strlen("036790384902"), strlen("036790384904"), strlen("036790384906")};
2229 char return_key[MEMCACHED_MAX_KEY];
2230 size_t return_key_length;
2231 char *value;
2232 size_t value_length;
2233 uint32_t flags;
2234 unsigned int count;
2235 unsigned int x;
2236 char insert_data[VALUE_SIZE_BUG5];
2237
2238 for (x= 0; x < VALUE_SIZE_BUG5; x++)
2239 insert_data[x]= (signed char)rand();
2240
2241 memcached_flush(memc, 0);
2242 value= memcached_get(memc, keys[0], key_length[0],
2243 &value_length, &flags, &rc);
2244 test_true(value == NULL);
2245 test_true(rc == MEMCACHED_NOTFOUND);
2246 rc= memcached_mget(memc, keys, key_length, 4);
2247 test_true(rc == MEMCACHED_SUCCESS);
2248
2249 count= 0;
2250 while ((value= memcached_fetch(memc, return_key, &return_key_length,
2251 &value_length, &flags, &rc)))
2252 count++;
2253 test_true(count == 0);
2254 test_true(rc == MEMCACHED_END);
2255
2256 for (x= 0; x < 4; x++)
2257 {
2258 rc= memcached_set(memc, keys[x], key_length[x],
2259 insert_data, VALUE_SIZE_BUG5,
2260 (time_t)0, (uint32_t)0);
2261 test_true(rc == MEMCACHED_SUCCESS);
2262 }
2263
2264 for (x= 0; x < 2; x++)
2265 {
2266 value= memcached_get(memc, keys[0], key_length[0],
2267 &value_length, &flags, &rc);
2268 test_true(value);
2269 free(value);
2270
2271 rc= memcached_mget(memc, keys, key_length, 4);
2272 test_true(rc == MEMCACHED_SUCCESS);
2273 count= 3;
2274 /* We test for purge of partial complete fetches */
2275 for (count= 3; count; count--)
2276 {
2277 value= memcached_fetch(memc, return_key, &return_key_length,
2278 &value_length, &flags, &rc);
2279 test_true(rc == MEMCACHED_SUCCESS);
2280 test_true(!(memcmp(value, insert_data, value_length)));
2281 test_true(value_length);
2282 free(value);
2283 }
2284 }
2285
2286 return TEST_SUCCESS;
2287 }
2288
2289 static test_return_t user_supplied_bug8(memcached_st *memc __attribute__((unused)))
2290 {
2291 memcached_return_t rc;
2292 memcached_st *mine;
2293 memcached_st *memc_clone;
2294
2295 memcached_server_st *servers;
2296 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";
2297
2298 servers= memcached_servers_parse(server_list);
2299 test_true(servers);
2300
2301 mine= memcached_create(NULL);
2302 rc= memcached_server_push(mine, servers);
2303 test_true(rc == MEMCACHED_SUCCESS);
2304 memcached_server_list_free(servers);
2305
2306 test_true(mine);
2307 memc_clone= memcached_clone(NULL, mine);
2308
2309 memcached_quit(mine);
2310 memcached_quit(memc_clone);
2311
2312
2313 memcached_free(mine);
2314 memcached_free(memc_clone);
2315
2316 return TEST_SUCCESS;
2317 }
2318
2319 /* Test flag store/retrieve */
2320 static test_return_t user_supplied_bug7(memcached_st *memc)
2321 {
2322 memcached_return_t rc;
2323 const char *keys= "036790384900";
2324 size_t key_length= strlen(keys);
2325 char return_key[MEMCACHED_MAX_KEY];
2326 size_t return_key_length;
2327 char *value;
2328 size_t value_length;
2329 uint32_t flags;
2330 unsigned int x;
2331 char insert_data[VALUE_SIZE_BUG5];
2332
2333 for (x= 0; x < VALUE_SIZE_BUG5; x++)
2334 insert_data[x]= (signed char)rand();
2335
2336 memcached_flush(memc, 0);
2337
2338 flags= 245;
2339 rc= memcached_set(memc, keys, key_length,
2340 insert_data, VALUE_SIZE_BUG5,
2341 (time_t)0, flags);
2342 test_true(rc == MEMCACHED_SUCCESS);
2343
2344 flags= 0;
2345 value= memcached_get(memc, keys, key_length,
2346 &value_length, &flags, &rc);
2347 test_true(flags == 245);
2348 test_true(value);
2349 free(value);
2350
2351 rc= memcached_mget(memc, &keys, &key_length, 1);
2352
2353 flags= 0;
2354 value= memcached_fetch(memc, return_key, &return_key_length,
2355 &value_length, &flags, &rc);
2356 test_true(flags == 245);
2357 test_true(value);
2358 free(value);
2359
2360
2361 return TEST_SUCCESS;
2362 }
2363
2364 static test_return_t user_supplied_bug9(memcached_st *memc)
2365 {
2366 memcached_return_t rc;
2367 const char *keys[]= {"UDATA:edevil@sapo.pt", "fudge&*@#", "for^#@&$not"};
2368 size_t key_length[3];
2369 unsigned int x;
2370 uint32_t flags;
2371 unsigned count= 0;
2372
2373 char return_key[MEMCACHED_MAX_KEY];
2374 size_t return_key_length;
2375 char *return_value;
2376 size_t return_value_length;
2377
2378
2379 key_length[0]= strlen("UDATA:edevil@sapo.pt");
2380 key_length[1]= strlen("fudge&*@#");
2381 key_length[2]= strlen("for^#@&$not");
2382
2383
2384 for (x= 0; x < 3; x++)
2385 {
2386 rc= memcached_set(memc, keys[x], key_length[x],
2387 keys[x], key_length[x],
2388 (time_t)50, (uint32_t)9);
2389 test_true(rc == MEMCACHED_SUCCESS);
2390 }
2391
2392 rc= memcached_mget(memc, keys, key_length, 3);
2393 test_true(rc == MEMCACHED_SUCCESS);
2394
2395 /* We need to empty the server before continueing test */
2396 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
2397 &return_value_length, &flags, &rc)) != NULL)
2398 {
2399 test_true(return_value);
2400 free(return_value);
2401 count++;
2402 }
2403 test_true(count == 3);
2404
2405 return TEST_SUCCESS;
2406 }
2407
2408 /* We are testing with aggressive timeout to get failures */
2409 static test_return_t user_supplied_bug10(memcached_st *memc)
2410 {
2411 const char *key= "foo";
2412 char *value;
2413 size_t value_length= 512;
2414 unsigned int x;
2415 size_t key_len= 3;
2416 memcached_return_t rc;
2417 unsigned int set= 1;
2418 memcached_st *mclone= memcached_clone(NULL, memc);
2419 int32_t timeout;
2420
2421 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_NO_BLOCK, set);
2422 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_TCP_NODELAY, set);
2423 timeout= 2;
2424 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT,
2425 (uint64_t)timeout);
2426
2427 value = (char*)malloc(value_length * sizeof(char));
2428
2429 for (x= 0; x < value_length; x++)
2430 value[x]= (char) (x % 127);
2431
2432 for (x= 1; x <= 100000; ++x)
2433 {
2434 rc= memcached_set(mclone, key, key_len,value, value_length, 0, 0);
2435
2436 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_WRITE_FAILURE ||
2437 rc == MEMCACHED_BUFFERED || rc == MEMCACHED_TIMEOUT);
2438
2439 if (rc == MEMCACHED_WRITE_FAILURE || rc == MEMCACHED_TIMEOUT)
2440 x--;
2441 }
2442
2443 free(value);
2444 memcached_free(mclone);
2445
2446 return TEST_SUCCESS;
2447 }
2448
2449 /*
2450 We are looking failures in the async protocol
2451 */
2452 static test_return_t user_supplied_bug11(memcached_st *memc)
2453 {
2454 const char *key= "foo";
2455 char *value;
2456 size_t value_length= 512;
2457 unsigned int x;
2458 size_t key_len= 3;
2459 memcached_return_t rc;
2460 unsigned int set= 1;
2461 int32_t timeout;
2462 memcached_st *mclone= memcached_clone(NULL, memc);
2463
2464 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_NO_BLOCK, set);
2465 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_TCP_NODELAY, set);
2466 timeout= -1;
2467 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT,
2468 (size_t)timeout);
2469
2470 timeout= (int32_t)memcached_behavior_get(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT);
2471
2472 test_true(timeout == -1);
2473
2474 value = (char*)malloc(value_length * sizeof(char));
2475
2476 for (x= 0; x < value_length; x++)
2477 value[x]= (char) (x % 127);
2478
2479 for (x= 1; x <= 100000; ++x)
2480 {
2481 rc= memcached_set(mclone, key, key_len,value, value_length, 0, 0);
2482 }
2483
2484 free(value);
2485 memcached_free(mclone);
2486
2487 return TEST_SUCCESS;
2488 }
2489
2490 /*
2491 Bug found where incr was not returning MEMCACHED_NOTFOUND when object did not exist.
2492 */
2493 static test_return_t user_supplied_bug12(memcached_st *memc)
2494 {
2495 memcached_return_t rc;
2496 uint32_t flags;
2497 size_t value_length;
2498 char *value;
2499 uint64_t number_value;
2500
2501 value= memcached_get(memc, "autoincrement", strlen("autoincrement"),
2502 &value_length, &flags, &rc);
2503 test_true(value == NULL);
2504 test_true(rc == MEMCACHED_NOTFOUND);
2505
2506 rc= memcached_increment(memc, "autoincrement", strlen("autoincrement"),
2507 1, &number_value);
2508
2509 test_true(value == NULL);
2510 /* The binary protocol will set the key if it doesn't exist */
2511 if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 1)
2512 {
2513 test_true(rc == MEMCACHED_SUCCESS);
2514 }
2515 else
2516 {
2517 test_true(rc == MEMCACHED_NOTFOUND);
2518 }
2519
2520 rc= memcached_set(memc, "autoincrement", strlen("autoincrement"), "1", 1, 0, 0);
2521
2522 value= memcached_get(memc, "autoincrement", strlen("autoincrement"),
2523 &value_length, &flags, &rc);
2524 test_true(value);
2525 test_true(rc == MEMCACHED_SUCCESS);
2526 free(value);
2527
2528 rc= memcached_increment(memc, "autoincrement", strlen("autoincrement"),
2529 1, &number_value);
2530 test_true(number_value == 2);
2531 test_true(rc == MEMCACHED_SUCCESS);
2532
2533 return TEST_SUCCESS;
2534 }
2535
2536 /*
2537 Bug found where command total one more than MEMCACHED_MAX_BUFFER
2538 set key34567890 0 0 8169 \r\n is sent followed by buffer of size 8169, followed by 8169
2539 */
2540 static test_return_t user_supplied_bug13(memcached_st *memc)
2541 {
2542 char key[] = "key34567890";
2543 char *overflow;
2544 memcached_return_t rc;
2545 size_t overflowSize;
2546
2547 char commandFirst[]= "set key34567890 0 0 ";
2548 char commandLast[] = " \r\n"; /* first line of command sent to server */
2549 size_t commandLength;
2550 size_t testSize;
2551
2552 commandLength = strlen(commandFirst) + strlen(commandLast) + 4; /* 4 is number of characters in size, probably 8196 */
2553
2554 overflowSize = MEMCACHED_MAX_BUFFER - commandLength;
2555
2556 for (testSize= overflowSize - 1; testSize < overflowSize + 1; testSize++)
2557 {
2558 overflow= malloc(testSize);
2559 test_true(overflow != NULL);
2560
2561 memset(overflow, 'x', testSize);
2562 rc= memcached_set(memc, key, strlen(key),
2563 overflow, testSize, 0, 0);
2564 test_true(rc == MEMCACHED_SUCCESS);
2565 free(overflow);
2566 }
2567
2568 return TEST_SUCCESS;
2569 }
2570
2571
2572 /*
2573 Test values of many different sizes
2574 Bug found where command total one more than MEMCACHED_MAX_BUFFER
2575 set key34567890 0 0 8169 \r\n
2576 is sent followed by buffer of size 8169, followed by 8169
2577 */
2578 static test_return_t user_supplied_bug14(memcached_st *memc)
2579 {
2580 size_t setter= 1;
2581 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, setter);
2582 memcached_return_t rc;
2583 const char *key= "foo";
2584 char *value;
2585 size_t value_length= 18000;
2586 char *string;
2587 size_t string_length;
2588 uint32_t flags;
2589 unsigned int x;
2590 size_t current_length;
2591
2592 value = (char*)malloc(value_length);
2593 test_true(value);
2594
2595 for (x= 0; x < value_length; x++)
2596 value[x] = (char) (x % 127);
2597
2598 for (current_length= 0; current_length < value_length; current_length++)
2599 {
2600 rc= memcached_set(memc, key, strlen(key),
2601 value, current_length,
2602 (time_t)0, (uint32_t)0);
2603 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
2604
2605 string= memcached_get(memc, key, strlen(key),
2606 &string_length, &flags, &rc);
2607
2608 test_true(rc == MEMCACHED_SUCCESS);
2609 test_true(string_length == current_length);
2610 test_true(!memcmp(string, value, string_length));
2611
2612 free(string);
2613 }
2614
2615 free(value);
2616
2617 return TEST_SUCCESS;
2618 }
2619
2620 /*
2621 Look for zero length value problems
2622 */
2623 static test_return_t user_supplied_bug15(memcached_st *memc)
2624 {
2625 uint32_t x;
2626 memcached_return_t rc;
2627 const char *key= "mykey";
2628 char *value;
2629 size_t length;
2630 uint32_t flags;
2631
2632 for (x= 0; x < 2; x++)
2633 {
2634 rc= memcached_set(memc, key, strlen(key),
2635 NULL, 0,
2636 (time_t)0, (uint32_t)0);
2637
2638 test_true(rc == MEMCACHED_SUCCESS);
2639
2640 value= memcached_get(memc, key, strlen(key),
2641 &length, &flags, &rc);
2642
2643 test_true(rc == MEMCACHED_SUCCESS);
2644 test_true(value == NULL);
2645 test_true(length == 0);
2646 test_true(flags == 0);
2647
2648 value= memcached_get(memc, key, strlen(key),
2649 &length, &flags, &rc);
2650
2651 test_true(rc == MEMCACHED_SUCCESS);
2652 test_true(value == NULL);
2653 test_true(length == 0);
2654 test_true(flags == 0);
2655 }
2656
2657 return TEST_SUCCESS;
2658 }
2659
2660 /* Check the return sizes on FLAGS to make sure it stores 32bit unsigned values correctly */
2661 static test_return_t user_supplied_bug16(memcached_st *memc)
2662 {
2663 memcached_return_t rc;
2664 const char *key= "mykey";
2665 char *value;
2666 size_t length;
2667 uint32_t flags;
2668
2669 rc= memcached_set(memc, key, strlen(key),
2670 NULL, 0,
2671 (time_t)0, UINT32_MAX);
2672
2673 test_true(rc == MEMCACHED_SUCCESS);
2674
2675 value= memcached_get(memc, key, strlen(key),
2676 &length, &flags, &rc);
2677
2678 test_true(rc == MEMCACHED_SUCCESS);
2679 test_true(value == NULL);
2680 test_true(length == 0);
2681 test_true(flags == UINT32_MAX);
2682
2683 return TEST_SUCCESS;
2684 }
2685
2686 #ifndef __sun
2687 /* Check the validity of chinese key*/
2688 static test_return_t user_supplied_bug17(memcached_st *memc)
2689 {
2690 memcached_return_t rc;
2691 const char *key= "豆瓣";
2692 const char *value="我们在炎热抑郁的夏天无法停止豆瓣";
2693 char *value2;
2694 size_t length;
2695 uint32_t flags;
2696
2697 rc= memcached_set(memc, key, strlen(key),
2698 value, strlen(value),
2699 (time_t)0, 0);
2700
2701 test_true(rc == MEMCACHED_SUCCESS);
2702
2703 value2= memcached_get(memc, key, strlen(key),
2704 &length, &flags, &rc);
2705
2706 test_true(length==strlen(value));
2707 test_true(rc == MEMCACHED_SUCCESS);
2708 test_true(memcmp(value, value2, length)==0);
2709 free(value2);
2710
2711 return TEST_SUCCESS;
2712 }
2713 #endif
2714
2715 /*
2716 From Andrei on IRC
2717 */
2718
2719 static test_return_t user_supplied_bug19(memcached_st *not_used)
2720 {
2721 memcached_st *memc;
2722 const memcached_server_st *server;
2723 memcached_return_t res;
2724
2725 (void)not_used;
2726
2727 memc= memcached_create(NULL);
2728 memcached_server_add_with_weight(memc, "localhost", 11311, 100);
2729 memcached_server_add_with_weight(memc, "localhost", 11312, 100);
2730
2731 server= memcached_server_by_key(memc, "a", 1, &res);
2732
2733 memcached_free(memc);
2734
2735 return TEST_SUCCESS;
2736 }
2737
2738 /* CAS test from Andei */
2739 static test_return_t user_supplied_bug20(memcached_st *memc)
2740 {
2741 memcached_return_t status;
2742 memcached_result_st *result, result_obj;
2743 const char *key = "abc";
2744 size_t key_len = strlen("abc");
2745 const char *value = "foobar";
2746 size_t value_len = strlen(value);
2747
2748 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, 1);
2749
2750 status = memcached_set(memc, key, key_len, value, value_len, (time_t)0, (uint32_t)0);
2751 test_true(status == MEMCACHED_SUCCESS);
2752
2753 status = memcached_mget(memc, &key, &key_len, 1);
2754 test_true(status == MEMCACHED_SUCCESS);
2755
2756 result= memcached_result_create(memc, &result_obj);
2757 test_true(result);
2758
2759 memcached_result_create(memc, &result_obj);
2760 result= memcached_fetch_result(memc, &result_obj, &status);
2761
2762 test_true(result);
2763 test_true(status == MEMCACHED_SUCCESS);
2764
2765 memcached_result_free(result);
2766
2767 return TEST_SUCCESS;
2768 }
2769
2770 #include "ketama_test_cases.h"
2771 static test_return_t user_supplied_bug18(memcached_st *trash)
2772 {
2773 memcached_return_t rc;
2774 uint64_t value;
2775 int x;
2776 memcached_server_st *server_pool;
2777 memcached_st *memc;
2778
2779 (void)trash;
2780
2781 memc= memcached_create(NULL);
2782 test_true(memc);
2783
2784 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
2785 test_true(rc == MEMCACHED_SUCCESS);
2786
2787 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
2788 test_true(value == 1);
2789
2790 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
2791 test_true(rc == MEMCACHED_SUCCESS);
2792
2793 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
2794 test_true(value == MEMCACHED_HASH_MD5);
2795
2796 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");
2797 memcached_server_push(memc, server_pool);
2798
2799 /* verify that the server list was parsed okay. */
2800 test_true(memcached_server_count(memc) == 8);
2801 test_true(strcmp(server_pool[0].hostname, "10.0.1.1") == 0);
2802 test_true(server_pool[0].port == 11211);
2803 test_true(server_pool[0].weight == 600);
2804 test_true(strcmp(server_pool[2].hostname, "10.0.1.3") == 0);
2805 test_true(server_pool[2].port == 11211);
2806 test_true(server_pool[2].weight == 200);
2807 test_true(strcmp(server_pool[7].hostname, "10.0.1.8") == 0);
2808 test_true(server_pool[7].port == 11211);
2809 test_true(server_pool[7].weight == 100);
2810
2811 /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets
2812 * us test the boundary wraparound.
2813 */
2814 test_true(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->continuum[0].index);
2815
2816 /* verify the standard ketama set. */
2817 for (x= 0; x < 99; x++)
2818 {
2819 uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
2820
2821 memcached_server_instance_st instance=
2822 memcached_server_instance_by_position(memc, server_idx);
2823
2824 const char *hostname = memcached_server_name(instance);
2825 test_strcmp(hostname, ketama_test_cases[x].server);
2826 }
2827
2828 memcached_server_list_free(server_pool);
2829 memcached_free(memc);
2830
2831 return TEST_SUCCESS;
2832 }
2833
2834 /* Large mget() of missing keys with binary proto
2835 *
2836 * If many binary quiet commands (such as getq's in an mget) fill the output
2837 * buffer and the server chooses not to respond, memcached_flush hangs. See
2838 * http://lists.tangent.org/pipermail/libmemcached/2009-August/000918.html
2839 */
2840
2841 /* sighandler_t function that always asserts false */
2842 static void fail(int unused __attribute__((unused)))
2843 {
2844 assert(0);
2845 }
2846
2847
2848 static test_return_t _user_supplied_bug21(memcached_st* memc, size_t key_count)
2849 {
2850 memcached_return_t rc;
2851 unsigned int x;
2852 char **keys;
2853 size_t* key_lengths;
2854 void (*oldalarm)(int);
2855 memcached_st *memc_clone;
2856
2857 memc_clone= memcached_clone(NULL, memc);
2858 test_true(memc_clone);
2859
2860 /* only binproto uses getq for mget */
2861 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
2862
2863 /* empty the cache to ensure misses (hence non-responses) */
2864 rc= memcached_flush(memc_clone, 0);
2865 test_true(rc == MEMCACHED_SUCCESS);
2866
2867 key_lengths= calloc(key_count, sizeof(size_t));
2868 keys= calloc(key_count, sizeof(char *));
2869 test_true(keys);
2870 for (x= 0; x < key_count; x++)
2871 {
2872 char buffer[30];
2873
2874 snprintf(buffer, 30, "%u", x);
2875 keys[x]= strdup(buffer);
2876 key_lengths[x]= strlen(keys[x]);
2877 }
2878
2879 oldalarm= signal(SIGALRM, fail);
2880 alarm(5);
2881
2882 rc= memcached_mget(memc_clone, (const char **)keys, key_lengths, key_count);
2883 test_true(rc == MEMCACHED_SUCCESS);
2884
2885 alarm(0);
2886 signal(SIGALRM, oldalarm);
2887
2888 test_true(fetch_all_results(memc) == TEST_SUCCESS);
2889
2890 for (x= 0; x < key_count; x++)
2891 free(keys[x]);
2892 free(keys);
2893 free(key_lengths);
2894
2895 memcached_free(memc_clone);
2896
2897 return TEST_SUCCESS;
2898 }
2899
2900 static test_return_t pre_binary(memcached_st *memc);
2901
2902 static test_return_t user_supplied_bug21(memcached_st *memc)
2903 {
2904 test_return_t test_rc;
2905 test_rc= pre_binary(memc);
2906
2907 if (test_rc != TEST_SUCCESS)
2908 return test_rc;
2909
2910 test_return_t rc;
2911
2912 /* should work as of r580 */
2913 rc= _user_supplied_bug21(memc, 10);
2914 test_true(rc == TEST_SUCCESS);
2915
2916 /* should fail as of r580 */
2917 rc= _user_supplied_bug21(memc, 1000);
2918 test_true(rc == TEST_SUCCESS);
2919
2920 return TEST_SUCCESS;
2921 }
2922
2923 static test_return_t auto_eject_hosts(memcached_st *trash)
2924 {
2925 (void) trash;
2926 memcached_server_instance_st instance;
2927
2928 memcached_return_t rc;
2929 memcached_st *memc= memcached_create(NULL);
2930 test_true(memc);
2931
2932 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
2933 test_true(rc == MEMCACHED_SUCCESS);
2934
2935 uint64_t value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
2936 test_true(value == 1);
2937
2938 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
2939 test_true(rc == MEMCACHED_SUCCESS);
2940
2941 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
2942 test_true(value == MEMCACHED_HASH_MD5);
2943
2944 /* server should be removed when in delay */
2945 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS, 1);
2946 test_true(rc == MEMCACHED_SUCCESS);
2947
2948 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS);
2949 test_true(value == 1);
2950
2951 memcached_server_st *server_pool;
2952 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");
2953 memcached_server_push(memc, server_pool);
2954
2955 /* verify that the server list was parsed okay. */
2956 test_true(memcached_server_count(memc) == 8);
2957 test_true(strcmp(server_pool[0].hostname, "10.0.1.1") == 0);
2958 test_true(server_pool[0].port == 11211);
2959 test_true(server_pool[0].weight == 600);
2960 test_true(strcmp(server_pool[2].hostname, "10.0.1.3") == 0);
2961 test_true(server_pool[2].port == 11211);
2962 test_true(server_pool[2].weight == 200);
2963 test_true(strcmp(server_pool[7].hostname, "10.0.1.8") == 0);
2964 test_true(server_pool[7].port == 11211);
2965 test_true(server_pool[7].weight == 100);
2966
2967 instance= memcached_server_instance_by_position(memc, 2);
2968 ((memcached_server_write_instance_st)instance)->next_retry = time(NULL) + 15;
2969 memc->next_distribution_rebuild= time(NULL) - 1;
2970
2971 /*
2972 This would not work if there were only two hosts.
2973 */
2974 for (size_t x= 0; x < 99; x++)
2975 {
2976 memcached_autoeject(memc);
2977 uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
2978 test_true(server_idx != 2);
2979 }
2980
2981 /* and re-added when it's back. */
2982 ((memcached_server_write_instance_st)instance)->next_retry = time(NULL) - 1;
2983 memc->next_distribution_rebuild= time(NULL) - 1;
2984 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION,
2985 memc->distribution);
2986 for (size_t x= 0; x < 99; x++)
2987 {
2988 uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
2989 // We re-use instance from above.
2990 instance=
2991 memcached_server_instance_by_position(memc, server_idx);
2992 const char *hostname = memcached_server_name(instance);
2993 test_true(strcmp(hostname, ketama_test_cases[x].server) == 0);
2994 }
2995
2996 memcached_server_list_free(server_pool);
2997 memcached_free(memc);
2998
2999 return TEST_SUCCESS;
3000 }
3001
3002 static test_return_t output_ketama_weighted_keys(memcached_st *trash)
3003 {
3004 (void) trash;
3005
3006 memcached_return_t rc;
3007 memcached_st *memc= memcached_create(NULL);
3008 test_true(memc);
3009
3010
3011 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
3012 test_true(rc == MEMCACHED_SUCCESS);
3013
3014 uint64_t value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
3015 test_true(value == 1);
3016
3017 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
3018 test_true(rc == MEMCACHED_SUCCESS);
3019
3020 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
3021 test_true(value == MEMCACHED_HASH_MD5);
3022
3023
3024 test_true(memcached_behavior_set_distribution(memc, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY) == MEMCACHED_SUCCESS);
3025
3026 memcached_server_st *server_pool;
3027 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");
3028 memcached_server_push(memc, server_pool);
3029
3030 // @todo this needs to be refactored to actually test something.
3031 #if 0
3032 FILE *fp;
3033 if ((fp = fopen("ketama_keys.txt", "w")))
3034 {
3035 // noop
3036 } else {
3037 printf("cannot write to file ketama_keys.txt");
3038 return TEST_FAILURE;
3039 }
3040
3041 for (int x= 0; x < 10000; x++)
3042 {
3043 char key[10];
3044 sprintf(key, "%d", x);
3045
3046 uint32_t server_idx = memcached_generate_hash(memc, key, strlen(key));
3047 char *hostname = memc->hosts[server_idx].hostname;
3048 in_port_t port = memc->hosts[server_idx].port;
3049 fprintf(fp, "key %s is on host /%s:%u\n", key, hostname, port);
3050 }
3051 fclose(fp);
3052 #endif
3053 memcached_server_list_free(server_pool);
3054 memcached_free(memc);
3055
3056 return TEST_SUCCESS;
3057 }
3058
3059
3060 static test_return_t result_static(memcached_st *memc)
3061 {
3062 memcached_result_st result;
3063 memcached_result_st *result_ptr;
3064
3065 result_ptr= memcached_result_create(memc, &result);
3066 test_true(result.options.is_allocated == false);
3067 test_true(memcached_is_initialized(&result) == true);
3068 test_true(result_ptr);
3069 test_true(result_ptr == &result);
3070
3071 memcached_result_free(&result);
3072
3073 test_true(result.options.is_allocated == false);
3074 test_true(memcached_is_initialized(&result) == false);
3075
3076 return TEST_SUCCESS;
3077 }
3078
3079 static test_return_t result_alloc(memcached_st *memc)
3080 {
3081 memcached_result_st *result_ptr;
3082
3083 result_ptr= memcached_result_create(memc, NULL);
3084 test_true(result_ptr);
3085 test_true(result_ptr->options.is_allocated == true);
3086 test_true(memcached_is_initialized(result_ptr) == true);
3087 memcached_result_free(result_ptr);
3088
3089 return TEST_SUCCESS;
3090 }
3091
3092 static test_return_t string_static_null(memcached_st *memc)
3093 {
3094 memcached_string_st string;
3095 memcached_string_st *string_ptr;
3096
3097 string_ptr= memcached_string_create(memc, &string, 0);
3098 test_true(string.options.is_initialized == true);
3099 test_true(string_ptr);
3100
3101 /* The following two better be the same! */
3102 test_true(memcached_is_allocated(string_ptr) == false);
3103 test_true(memcached_is_allocated(&string) == false);
3104 test_true(&string == string_ptr);
3105
3106 test_true(string.options.is_initialized == true);
3107 test_true(memcached_is_initialized(&string) == true);
3108 memcached_string_free(&string);
3109 test_true(memcached_is_initialized(&string) == false);
3110
3111 return TEST_SUCCESS;
3112 }
3113
3114 static test_return_t string_alloc_null(memcached_st *memc)
3115 {
3116 memcached_string_st *string;
3117
3118 string= memcached_string_create(memc, NULL, 0);
3119 test_true(string);
3120 test_true(memcached_is_allocated(string) == true);
3121 test_true(memcached_is_initialized(string) == true);
3122 memcached_string_free(string);
3123
3124 return TEST_SUCCESS;
3125 }
3126
3127 static test_return_t string_alloc_with_size(memcached_st *memc)
3128 {
3129 memcached_string_st *string;
3130
3131 string= memcached_string_create(memc, NULL, 1024);
3132 test_true(string);
3133 test_true(memcached_is_allocated(string) == true);
3134 test_true(memcached_is_initialized(string) == true);
3135 memcached_string_free(string);
3136
3137 return TEST_SUCCESS;
3138 }
3139
3140 static test_return_t string_alloc_with_size_toobig(memcached_st *memc)
3141 {
3142 memcached_string_st *string;
3143
3144 string= memcached_string_create(memc, NULL, SIZE_MAX);
3145 test_true(string == NULL);
3146
3147 return TEST_SUCCESS;
3148 }
3149
3150 static test_return_t string_alloc_append(memcached_st *memc)
3151 {
3152 unsigned int x;
3153 char buffer[SMALL_STRING_LEN];
3154 memcached_string_st *string;
3155
3156 /* Ring the bell! */
3157 memset(buffer, 6, SMALL_STRING_LEN);
3158
3159 string= memcached_string_create(memc, NULL, 100);
3160 test_true(string);
3161 test_true(memcached_is_allocated(string) == true);
3162 test_true(memcached_is_initialized(string) == true);
3163
3164 for (x= 0; x < 1024; x++)
3165 {
3166 memcached_return_t rc;
3167 rc= memcached_string_append(string, buffer, SMALL_STRING_LEN);
3168 test_true(rc == MEMCACHED_SUCCESS);
3169 }
3170 test_true(memcached_is_allocated(string) == true);
3171 memcached_string_free(string);
3172
3173 return TEST_SUCCESS;
3174 }
3175
3176 static test_return_t string_alloc_append_toobig(memcached_st *memc)
3177 {
3178 memcached_return_t rc;
3179 unsigned int x;
3180 char buffer[SMALL_STRING_LEN];
3181 memcached_string_st *string;
3182
3183 /* Ring the bell! */
3184 memset(buffer, 6, SMALL_STRING_LEN);
3185
3186 string= memcached_string_create(memc, NULL, 100);
3187 test_true(string);
3188 test_true(memcached_is_allocated(string) == true);
3189 test_true(memcached_is_initialized(string) == true);
3190
3191 for (x= 0; x < 1024; x++)
3192 {
3193 rc= memcached_string_append(string, buffer, SMALL_STRING_LEN);
3194 test_true(rc == MEMCACHED_SUCCESS);
3195 }
3196 rc= memcached_string_append(string, buffer, SIZE_MAX);
3197 test_true(rc == MEMCACHED_MEMORY_ALLOCATION_FAILURE);
3198 test_true(memcached_is_allocated(string) == true);
3199 memcached_string_free(string);
3200
3201 return TEST_SUCCESS;
3202 }
3203
3204 static test_return_t cleanup_pairs(memcached_st *memc __attribute__((unused)))
3205 {
3206 pairs_free(global_pairs);
3207
3208 return TEST_SUCCESS;
3209 }
3210
3211 static test_return_t generate_pairs(memcached_st *memc __attribute__((unused)))
3212 {
3213 global_pairs= pairs_generate(GLOBAL_COUNT, 400);
3214 global_count= GLOBAL_COUNT;
3215
3216 for (size_t x= 0; x < global_count; x++)
3217 {
3218 global_keys[x]= global_pairs[x].key;
3219 global_keys_length[x]= global_pairs[x].key_length;
3220 }
3221
3222 return TEST_SUCCESS;
3223 }
3224
3225 static test_return_t generate_large_pairs(memcached_st *memc __attribute__((unused)))
3226 {
3227 global_pairs= pairs_generate(GLOBAL2_COUNT, MEMCACHED_MAX_BUFFER+10);
3228 global_count= GLOBAL2_COUNT;
3229
3230 for (size_t x= 0; x < global_count; x++)
3231 {
3232 global_keys[x]= global_pairs[x].key;
3233 global_keys_length[x]= global_pairs[x].key_length;
3234 }
3235
3236 return TEST_SUCCESS;
3237 }
3238
3239 static test_return_t generate_data(memcached_st *memc)
3240 {
3241 execute_set(memc, global_pairs, global_count);
3242
3243 return TEST_SUCCESS;
3244 }
3245
3246 static test_return_t generate_data_with_stats(memcached_st *memc)
3247 {
3248 memcached_stat_st *stat_p;
3249 memcached_return_t rc;
3250 uint32_t host_index= 0;
3251 execute_set(memc, global_pairs, global_count);
3252
3253 //TODO: hosts used size stats
3254 stat_p= memcached_stat(memc, NULL, &rc);
3255 test_true(stat_p);
3256
3257 for (host_index= 0; host_index < SERVERS_TO_CREATE; host_index++)
3258 {
3259 /* This test was changes so that "make test" would work properlly */
3260 #ifdef DEBUG
3261 memcached_server_instance_st instance=
3262 memcached_server_instance_by_position(memc, host_index);
3263
3264 printf("\nserver %u|%s|%u bytes: %llu\n", host_index, instance->hostname, instance->port, (unsigned long long)(stat_p + host_index)->bytes);
3265 #endif
3266 test_true((unsigned long long)(stat_p + host_index)->bytes);
3267 }
3268
3269 memcached_stat_free(NULL, stat_p);
3270
3271 return TEST_SUCCESS;
3272 }
3273 static test_return_t generate_buffer_data(memcached_st *memc)
3274 {
3275 size_t latch= 0;
3276
3277 latch= 1;
3278 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, latch);
3279 generate_data(memc);
3280
3281 return TEST_SUCCESS;
3282 }
3283
3284 static test_return_t get_read_count(memcached_st *memc)
3285 {
3286 memcached_return_t rc;
3287 memcached_st *memc_clone;
3288
3289 memc_clone= memcached_clone(NULL, memc);
3290 test_true(memc_clone);
3291
3292 memcached_server_add_with_weight(memc_clone, "localhost", 6666, 0);
3293
3294 {
3295 char *return_value;
3296 size_t return_value_length;
3297 uint32_t flags;
3298 uint32_t count;
3299
3300 for (size_t x= count= 0; x < global_count; x++)
3301 {
3302 return_value= memcached_get(memc_clone, global_keys[x], global_keys_length[x],
3303 &return_value_length, &flags, &rc);
3304 if (rc == MEMCACHED_SUCCESS)
3305 {
3306 count++;
3307 if (return_value)
3308 free(return_value);
3309 }
3310 }
3311 }
3312
3313 memcached_free(memc_clone);
3314
3315 return TEST_SUCCESS;
3316 }
3317
3318 static test_return_t get_read(memcached_st *memc)
3319 {
3320 memcached_return_t rc;
3321
3322 {
3323 char *return_value;
3324 size_t return_value_length;
3325 uint32_t flags;
3326
3327 for (size_t x= 0; x < global_count; x++)
3328 {
3329 return_value= memcached_get(memc, global_keys[x], global_keys_length[x],
3330 &return_value_length, &flags, &rc);
3331 /*
3332 test_true(return_value);
3333 test_true(rc == MEMCACHED_SUCCESS);
3334 */
3335 if (rc == MEMCACHED_SUCCESS && return_value)
3336 free(return_value);
3337 }
3338 }
3339
3340 return TEST_SUCCESS;
3341 }
3342
3343 static test_return_t mget_read(memcached_st *memc)
3344 {
3345 memcached_return_t rc;
3346
3347 rc= memcached_mget(memc, global_keys, global_keys_length, global_count);
3348 test_true(rc == MEMCACHED_SUCCESS);
3349 test_true(fetch_all_results(memc) == TEST_SUCCESS);
3350
3351 return TEST_SUCCESS;
3352 }
3353
3354 static test_return_t mget_read_result(memcached_st *memc)
3355 {
3356 memcached_return_t rc;
3357
3358 rc= memcached_mget(memc, global_keys, global_keys_length, global_count);
3359 test_true(rc == MEMCACHED_SUCCESS);
3360 /* Turn this into a help function */
3361 {
3362 memcached_result_st results_obj;
3363 memcached_result_st *results;
3364
3365 results= memcached_result_create(memc, &results_obj);
3366
3367 while ((results= memcached_fetch_result(memc, &results_obj, &rc)))
3368 {
3369 test_true(results);
3370 test_true(rc == MEMCACHED_SUCCESS);
3371 }
3372
3373 memcached_result_free(&results_obj);
3374 }
3375
3376 return TEST_SUCCESS;
3377 }
3378
3379 static test_return_t mget_read_function(memcached_st *memc)
3380 {
3381 memcached_return_t rc;
3382 size_t counter;
3383 memcached_execute_fn callbacks[1];
3384
3385 rc= memcached_mget(memc, global_keys, global_keys_length, global_count);
3386 test_true(rc == MEMCACHED_SUCCESS);
3387
3388 callbacks[0]= &callback_counter;
3389 counter= 0;
3390 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
3391
3392 return TEST_SUCCESS;
3393 }
3394
3395 static test_return_t delete_generate(memcached_st *memc)
3396 {
3397 for (size_t x= 0; x < global_count; x++)
3398 {
3399 (void)memcached_delete(memc, global_keys[x], global_keys_length[x], (time_t)0);
3400 }
3401
3402 return TEST_SUCCESS;
3403 }
3404
3405 static test_return_t delete_buffer_generate(memcached_st *memc)
3406 {
3407 uint64_t latch= 0;
3408
3409 latch= 1;
3410 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, latch);
3411
3412 for (size_t x= 0; x < global_count; x++)
3413 {
3414 (void)memcached_delete(memc, global_keys[x], global_keys_length[x], (time_t)0);
3415 }
3416
3417 return TEST_SUCCESS;
3418 }
3419
3420 static test_return_t add_host_test1(memcached_st *memc)
3421 {
3422 memcached_return_t rc;
3423 char servername[]= "0.example.com";
3424 memcached_server_st *servers;
3425
3426 servers= memcached_server_list_append_with_weight(NULL, servername, 400, 0, &rc);
3427 test_true(servers);
3428 test_true(1 == memcached_server_list_count(servers));
3429
3430 for (size_t x= 2; x < 20; x++)
3431 {
3432 char buffer[SMALL_STRING_LEN];
3433
3434 snprintf(buffer, SMALL_STRING_LEN, "%zu.example.com", 400+x);
3435 servers= memcached_server_list_append_with_weight(servers, buffer, 401, 0,
3436 &rc);
3437 test_true(rc == MEMCACHED_SUCCESS);
3438 test_true(x == memcached_server_list_count(servers));
3439 }
3440
3441 rc= memcached_server_push(memc, servers);
3442 test_true(rc == MEMCACHED_SUCCESS);
3443 rc= memcached_server_push(memc, servers);
3444 test_true(rc == MEMCACHED_SUCCESS);
3445
3446 memcached_server_list_free(servers);
3447
3448 return TEST_SUCCESS;
3449 }
3450
3451 static test_return_t pre_nonblock(memcached_st *memc)
3452 {
3453 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
3454
3455 return TEST_SUCCESS;
3456 }
3457
3458 static test_return_t pre_cork(memcached_st *memc)
3459 {
3460 memcached_return_t rc;
3461 bool set= true;
3462
3463 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_CORK, set);
3464
3465 #ifdef __APPLE__
3466 return TEST_SKIPPED;
3467 #endif
3468
3469 if (rc == MEMCACHED_SUCCESS)
3470 return TEST_SUCCESS;
3471
3472 return TEST_SKIPPED;
3473 }
3474
3475 static test_return_t pre_cork_and_nonblock(memcached_st *memc)
3476 {
3477 test_return_t rc;
3478
3479 rc= pre_cork(memc);
3480
3481 #ifdef __APPLE__
3482 return TEST_SKIPPED;
3483 #endif
3484
3485 if (rc != TEST_SUCCESS)
3486 return rc;
3487
3488 return pre_nonblock(memc);
3489 }
3490
3491 static test_return_t pre_nonblock_binary(memcached_st *memc)
3492 {
3493 memcached_return_t rc= MEMCACHED_FAILURE;
3494 memcached_st *memc_clone;
3495 memcached_server_instance_st instance;
3496
3497 memc_clone= memcached_clone(NULL, memc);
3498 test_true(memc_clone);
3499 // The memcached_version needs to be done on a clone, because the server
3500 // will not toggle protocol on an connection.
3501 memcached_version(memc_clone);
3502
3503 instance= memcached_server_instance_by_position(memc_clone, 0);
3504
3505 if (instance->major_version >= 1 && instance->minor_version > 2)
3506 {
3507 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
3508 rc = memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
3509 test_true(rc == MEMCACHED_SUCCESS);
3510 test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 1);
3511 }
3512 else
3513 {
3514 return TEST_SKIPPED;
3515 }
3516
3517 memcached_free(memc_clone);
3518
3519 return rc == MEMCACHED_SUCCESS ? TEST_SUCCESS : TEST_SKIPPED;
3520 }
3521
3522 static test_return_t pre_murmur(memcached_st *memc)
3523 {
3524 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MURMUR);
3525
3526 return TEST_SUCCESS;
3527 }
3528
3529 static test_return_t pre_jenkins(memcached_st *memc)
3530 {
3531 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_JENKINS);
3532
3533 return TEST_SUCCESS;
3534 }
3535
3536
3537 static test_return_t pre_md5(memcached_st *memc)
3538 {
3539 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MD5);
3540
3541 return TEST_SUCCESS;
3542 }
3543
3544 static test_return_t pre_crc(memcached_st *memc)
3545 {
3546 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_CRC);
3547
3548 return TEST_SUCCESS;
3549 }
3550
3551 static test_return_t pre_hsieh(memcached_st *memc)
3552 {
3553 #ifdef HAVE_HSIEH_HASH
3554 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_HSIEH);
3555 return TEST_SUCCESS;
3556 #else
3557 (void) memc;
3558 return TEST_SKIPPED;
3559 #endif
3560 }
3561
3562 static test_return_t pre_hash_fnv1_64(memcached_st *memc)
3563 {
3564 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MURMUR);
3565
3566 return TEST_SUCCESS;
3567 }
3568
3569 static test_return_t pre_hash_fnv1a_64(memcached_st *memc)
3570 {
3571 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1A_64);
3572
3573 return TEST_SUCCESS;
3574 }
3575
3576 static test_return_t pre_hash_fnv1_32(memcached_st *memc)
3577 {
3578 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1_32);
3579
3580 return TEST_SUCCESS;
3581 }
3582
3583 static test_return_t pre_hash_fnv1a_32(memcached_st *memc)
3584 {
3585 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1A_32);
3586
3587 return TEST_SUCCESS;
3588 }
3589
3590 static test_return_t pre_behavior_ketama(memcached_st *memc)
3591 {
3592 memcached_return_t rc;
3593 uint64_t value;
3594
3595 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA, 1);
3596 test_true(rc == MEMCACHED_SUCCESS);
3597
3598 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA);
3599 test_true(value == 1);
3600
3601 return TEST_SUCCESS;
3602 }
3603
3604 static test_return_t pre_behavior_ketama_weighted(memcached_st *memc)
3605 {
3606 memcached_return_t rc;
3607 uint64_t value;
3608
3609 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
3610 test_true(rc == MEMCACHED_SUCCESS);
3611
3612 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
3613 test_true(value == 1);
3614
3615 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5);
3616 test_true(rc == MEMCACHED_SUCCESS);
3617
3618 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
3619 test_true(value == MEMCACHED_HASH_MD5);
3620
3621 return TEST_SUCCESS;
3622 }
3623
3624 /**
3625 @note This should be testing to see if the server really supports the binary protocol.
3626 */
3627 static test_return_t pre_binary(memcached_st *memc)
3628 {
3629 memcached_return_t rc= MEMCACHED_FAILURE;
3630 memcached_st *memc_clone;
3631 memcached_server_instance_st instance;
3632
3633 memc_clone= memcached_clone(NULL, memc);
3634 test_true(memc_clone);
3635 // The memcached_version needs to be done on a clone, because the server
3636 // will not toggle protocol on an connection.
3637 memcached_version(memc_clone);
3638
3639 instance= memcached_server_instance_by_position(memc_clone, 0);
3640
3641 if (instance->major_version >= 1 && instance->minor_version > 2)
3642 {
3643 rc = memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
3644 test_true(rc == MEMCACHED_SUCCESS);
3645 test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 1);
3646 }
3647
3648 memcached_free(memc_clone);
3649
3650 return rc == MEMCACHED_SUCCESS ? TEST_SUCCESS : TEST_SKIPPED;
3651 }
3652
3653 static test_return_t pre_sasl(memcached_st *memc)
3654 {
3655 memcached_return_t rc= MEMCACHED_FAILURE;
3656
3657 #ifdef LIBMEMCACHED_WITH_SASL_SUPPORT
3658 const char *server= getenv("LIBMEMCACHED_TEST_SASL_SERVER");
3659 const char *user= getenv("LIBMEMCACHED_TEST_SASL_USERNAME");
3660 const char *pass= getenv("LIBMEMCACHED_TEST_SASL_PASSWORD");
3661
3662 if (server != NULL && user != NULL && pass != NULL)
3663 {
3664 memcached_server_st *servers= memcached_servers_parse(server);
3665 test_true(servers != NULL);
3666 memcached_servers_reset(memc);
3667 test_true(memcached_server_push(memc, servers) == MEMCACHED_SUCCESS);
3668 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
3669 rc= memcached_set_sasl_auth_data(memc, user, pass);
3670 test_true(rc == MEMCACHED_SUCCESS);
3671 }
3672 #else
3673 (void)memc;
3674 #endif
3675
3676 return rc == MEMCACHED_SUCCESS ? TEST_SUCCESS : TEST_SKIPPED;
3677 }
3678
3679 static test_return_t pre_replication(memcached_st *memc)
3680 {
3681 test_return_t test_rc;
3682 test_rc= pre_binary(memc);
3683
3684 if (test_rc != TEST_SUCCESS)
3685 return test_rc;
3686
3687 /*
3688 * Make sure that we store the item on all servers
3689 * (master + replicas == number of servers)
3690 */
3691 memcached_return_t rc;
3692 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS,
3693 memcached_server_count(memc) - 1);
3694 test_true(rc == MEMCACHED_SUCCESS);
3695 test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS) == memcached_server_count(memc) - 1);
3696
3697 return rc == MEMCACHED_SUCCESS ? TEST_SUCCESS : TEST_SKIPPED;
3698 }
3699
3700
3701 static test_return_t pre_replication_noblock(memcached_st *memc)
3702 {
3703 test_return_t rc;
3704
3705 rc= pre_replication(memc);
3706 if (rc != TEST_SUCCESS)
3707 return rc;
3708
3709 rc= pre_nonblock(memc);
3710
3711 return rc;
3712 }
3713
3714
3715 static void my_free(const memcached_st *ptr __attribute__((unused)), void *mem, void *context)
3716 {
3717 (void) context;
3718 #ifdef HARD_MALLOC_TESTS
3719 void *real_ptr= (mem == NULL) ? mem : (void*)((caddr_t)mem - 8);
3720 free(real_ptr);
3721 #else
3722 free(mem);
3723 #endif
3724 }
3725
3726
3727 static void *my_malloc(const memcached_st *ptr __attribute__((unused)), const size_t size, void *context)
3728 {
3729 (void)context;
3730 #ifdef HARD_MALLOC_TESTS
3731 void *ret= malloc(size + 8);
3732 if (ret != NULL)
3733 {
3734 ret= (void*)((caddr_t)ret + 8);
3735 }
3736 #else
3737 void *ret= malloc(size);
3738 #endif
3739
3740 if (ret != NULL)
3741 {
3742 memset(ret, 0xff, size);
3743 }
3744
3745 return ret;
3746 }
3747
3748
3749 static void *my_realloc(const memcached_st *ptr __attribute__((unused)), void *mem, const size_t size, void *context)
3750 {
3751 (void)context;
3752 #ifdef HARD_MALLOC_TESTS
3753 void *real_ptr= (mem == NULL) ? NULL : (void*)((caddr_t)mem - 8);
3754 void *nmem= realloc(real_ptr, size + 8);
3755
3756 void *ret= NULL;
3757 if (nmem != NULL)
3758 {
3759 ret= (void*)((caddr_t)nmem + 8);
3760 }
3761
3762 return ret;
3763 #else
3764 return realloc(mem, size);
3765 #endif
3766 }
3767
3768
3769 static void *my_calloc(const memcached_st *ptr __attribute__((unused)), size_t nelem, const size_t size, void *context)
3770 {
3771 (void)context;
3772 #ifdef HARD_MALLOC_TESTS
3773 void *mem= my_malloc(ptr, nelem * size);
3774 if (mem)
3775 {
3776 memset(mem, 0, nelem * size);
3777 }
3778
3779 return mem;
3780 #else
3781 return calloc(nelem, size);
3782 #endif
3783 }
3784
3785
3786 static test_return_t set_prefix(memcached_st *memc)
3787 {
3788 memcached_return_t rc;
3789 const char *key= "mine";
3790 char *value;
3791
3792 /* Make sure be default none exists */
3793 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3794 test_true(rc == MEMCACHED_FAILURE);
3795
3796 /* Test a clean set */
3797 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, (void *)key);
3798 test_true(rc == MEMCACHED_SUCCESS);
3799
3800 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3801 test_true(memcmp(value, key, 4) == 0);
3802 test_true(rc == MEMCACHED_SUCCESS);
3803
3804 /* Test that we can turn it off */
3805 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, NULL);
3806 test_true(rc == MEMCACHED_SUCCESS);
3807
3808 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3809 test_true(rc == MEMCACHED_FAILURE);
3810
3811 /* Now setup for main test */
3812 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, (void *)key);
3813 test_true(rc == MEMCACHED_SUCCESS);
3814
3815 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3816 test_true(rc == MEMCACHED_SUCCESS);
3817 test_true(memcmp(value, key, 4) == 0);
3818
3819 /* Set to Zero, and then Set to something too large */
3820 {
3821 char long_key[255];
3822 memset(long_key, 0, 255);
3823
3824 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, NULL);
3825 test_true(rc == MEMCACHED_SUCCESS);
3826
3827 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3828 test_true(rc == MEMCACHED_FAILURE);
3829 test_true(value == NULL);
3830
3831 /* Test a long key for failure */
3832 /* TODO, extend test to determine based on setting, what result should be */
3833 strcpy(long_key, "Thisismorethentheallottednumberofcharacters");
3834 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, long_key);
3835 //test_true(rc == MEMCACHED_BAD_KEY_PROVIDED);
3836 test_true(rc == MEMCACHED_SUCCESS);
3837
3838 /* Now test a key with spaces (which will fail from long key, since bad key is not set) */
3839 strcpy(long_key, "This is more then the allotted number of characters");
3840 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, long_key);
3841 test_true(rc == MEMCACHED_BAD_KEY_PROVIDED);
3842
3843 /* Test for a bad prefix, but with a short key */
3844 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_VERIFY_KEY, 1);
3845 test_true(rc == MEMCACHED_SUCCESS);
3846
3847 strcpy(long_key, "dog cat");
3848 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, long_key);
3849 test_true(rc == MEMCACHED_BAD_KEY_PROVIDED);
3850 }
3851
3852 return TEST_SUCCESS;
3853 }
3854
3855
3856 #ifdef MEMCACHED_ENABLE_DEPRECATED
3857 static test_return_t deprecated_set_memory_alloc(memcached_st *memc)
3858 {
3859 void *test_ptr= NULL;
3860 void *cb_ptr= NULL;
3861 {
3862 memcached_malloc_fn malloc_cb=
3863 (memcached_malloc_fn)my_malloc;
3864 cb_ptr= *(void **)&malloc_cb;
3865 memcached_return_t rc;
3866
3867 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_MALLOC_FUNCTION, cb_ptr);
3868 test_true(rc == MEMCACHED_SUCCESS);
3869 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_MALLOC_FUNCTION, &rc);
3870 test_true(rc == MEMCACHED_SUCCESS);
3871 test_true(test_ptr == cb_ptr);
3872 }
3873
3874 {
3875 memcached_realloc_fn realloc_cb=
3876 (memcached_realloc_fn)my_realloc;
3877 cb_ptr= *(void **)&realloc_cb;
3878 memcached_return_t rc;
3879
3880 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_REALLOC_FUNCTION, cb_ptr);
3881 test_true(rc == MEMCACHED_SUCCESS);
3882 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_REALLOC_FUNCTION, &rc);
3883 test_true(rc == MEMCACHED_SUCCESS);
3884 test_true(test_ptr == cb_ptr);
3885 }
3886
3887 {
3888 memcached_free_fn free_cb=
3889 (memcached_free_fn)my_free;
3890 cb_ptr= *(void **)&free_cb;
3891 memcached_return_t rc;
3892
3893 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_FREE_FUNCTION, cb_ptr);
3894 test_true(rc == MEMCACHED_SUCCESS);
3895 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_FREE_FUNCTION, &rc);
3896 test_true(rc == MEMCACHED_SUCCESS);
3897 test_true(test_ptr == cb_ptr);
3898 }
3899
3900 return TEST_SUCCESS;
3901 }
3902 #endif
3903
3904
3905 static test_return_t set_memory_alloc(memcached_st *memc)
3906 {
3907 memcached_return_t rc;
3908 rc= memcached_set_memory_allocators(memc, NULL, my_free,
3909 my_realloc, my_calloc, NULL);
3910 test_true(rc == MEMCACHED_FAILURE);
3911
3912 rc= memcached_set_memory_allocators(memc, my_malloc, my_free,
3913 my_realloc, my_calloc, NULL);
3914
3915 memcached_malloc_fn mem_malloc;
3916 memcached_free_fn mem_free;
3917 memcached_realloc_fn mem_realloc;
3918 memcached_calloc_fn mem_calloc;
3919 memcached_get_memory_allocators(memc, &mem_malloc, &mem_free,
3920 &mem_realloc, &mem_calloc);
3921
3922 test_true(mem_malloc == my_malloc);
3923 test_true(mem_realloc == my_realloc);
3924 test_true(mem_calloc == my_calloc);
3925 test_true(mem_free == my_free);
3926
3927 return TEST_SUCCESS;
3928 }
3929
3930 static test_return_t enable_consistent_crc(memcached_st *memc)
3931 {
3932 test_return_t rc;
3933 memcached_server_distribution_t value= MEMCACHED_DISTRIBUTION_CONSISTENT;
3934 memcached_hash_t hash;
3935 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, value);
3936 if ((rc= pre_crc(memc)) != TEST_SUCCESS)
3937 return rc;
3938
3939 value= (memcached_server_distribution_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION);
3940 test_true(value == MEMCACHED_DISTRIBUTION_CONSISTENT);
3941
3942 hash= (memcached_hash_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
3943
3944 if (hash != MEMCACHED_HASH_CRC)
3945 return TEST_SKIPPED;
3946
3947 return TEST_SUCCESS;
3948 }
3949
3950 static test_return_t enable_consistent_hsieh(memcached_st *memc)
3951 {
3952 test_return_t rc;
3953 memcached_server_distribution_t value= MEMCACHED_DISTRIBUTION_CONSISTENT;
3954 memcached_hash_t hash;
3955 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, value);
3956 if ((rc= pre_hsieh(memc)) != TEST_SUCCESS)
3957 return rc;
3958
3959 value= (memcached_server_distribution_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION);
3960 test_true(value == MEMCACHED_DISTRIBUTION_CONSISTENT);
3961
3962 hash= (memcached_hash_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
3963
3964 if (hash != MEMCACHED_HASH_HSIEH)
3965 return TEST_SKIPPED;
3966
3967
3968 return TEST_SUCCESS;
3969 }
3970
3971 static test_return_t enable_cas(memcached_st *memc)
3972 {
3973 unsigned int set= 1;
3974
3975 memcached_server_instance_st instance=
3976 memcached_server_instance_by_position(memc, 0);
3977
3978 memcached_version(memc);
3979
3980 if ((instance->major_version >= 1 && (instance->minor_version == 2 && instance->micro_version >= 4))
3981 || instance->minor_version > 2)
3982 {
3983 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, set);
3984
3985 return TEST_SUCCESS;
3986 }
3987
3988 return TEST_SKIPPED;
3989 }
3990
3991 static test_return_t check_for_1_2_3(memcached_st *memc)
3992 {
3993 memcached_version(memc);
3994
3995 memcached_server_instance_st instance=
3996 memcached_server_instance_by_position(memc, 0);
3997
3998 if ((instance->major_version >= 1 && (instance->minor_version == 2 && instance->micro_version >= 4))
3999 || instance->minor_version > 2)
4000 return TEST_SUCCESS;
4001
4002 return TEST_SKIPPED;
4003 }
4004
4005 static test_return_t pre_unix_socket(memcached_st *memc)
4006 {
4007 memcached_return_t rc;
4008 struct stat buf;
4009
4010 memcached_servers_reset(memc);
4011
4012 if (stat("/tmp/memcached.socket", &buf))
4013 return TEST_SKIPPED;
4014
4015 rc= memcached_server_add_unix_socket_with_weight(memc, "/tmp/memcached.socket", 0);
4016
4017 return ( rc == MEMCACHED_SUCCESS ? TEST_SUCCESS : TEST_FAILURE );
4018 }
4019
4020 static test_return_t pre_nodelay(memcached_st *memc)
4021 {
4022 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
4023 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 0);
4024
4025 return TEST_SUCCESS;
4026 }
4027
4028 static test_return_t pre_settimer(memcached_st *memc)
4029 {
4030 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SND_TIMEOUT, 1000);
4031 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RCV_TIMEOUT, 1000);
4032
4033 return TEST_SUCCESS;
4034 }
4035
4036 static test_return_t poll_timeout(memcached_st *memc)
4037 {
4038 size_t timeout;
4039
4040 timeout= 100;
4041
4042 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, timeout);
4043
4044 timeout= (size_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT);
4045
4046 test_true(timeout == 100);
4047
4048 return TEST_SUCCESS;
4049 }
4050
4051 static test_return_t noreply_test(memcached_st *memc)
4052 {
4053 memcached_return_t ret;
4054 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1);
4055 test_true(ret == MEMCACHED_SUCCESS);
4056 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
4057 test_true(ret == MEMCACHED_SUCCESS);
4058 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, 1);
4059 test_true(ret == MEMCACHED_SUCCESS);
4060 test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NOREPLY) == 1);
4061 test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS) == 1);
4062 test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS) == 1);
4063
4064 for (int count=0; count < 5; ++count)
4065 {
4066 for (size_t x= 0; x < 100; ++x)
4067 {
4068 char key[10];
4069 size_t len= (size_t)sprintf(key, "%zu", x);
4070 switch (count)
4071 {
4072 case 0:
4073 ret= memcached_add(memc, key, len, key, len, 0, 0);
4074 break;
4075 case 1:
4076 ret= memcached_replace(memc, key, len, key, len, 0, 0);
4077 break;
4078 case 2:
4079 ret= memcached_set(memc, key, len, key, len, 0, 0);
4080 break;
4081 case 3:
4082 ret= memcached_append(memc, key, len, key, len, 0, 0);
4083 break;
4084 case 4:
4085 ret= memcached_prepend(memc, key, len, key, len, 0, 0);
4086 break;
4087 default:
4088 test_true(count);
4089 break;
4090 }
4091 test_true(ret == MEMCACHED_SUCCESS || ret == MEMCACHED_BUFFERED);
4092 }
4093
4094 /*
4095 ** NOTE: Don't ever do this in your code! this is not a supported use of the
4096 ** API and is _ONLY_ done this way to verify that the library works the
4097 ** way it is supposed to do!!!!
4098 */
4099 int no_msg=0;
4100 for (uint32_t x= 0; x < memcached_server_count(memc); ++x)
4101 {
4102 memcached_server_instance_st instance=
4103 memcached_server_instance_by_position(memc, x);
4104 no_msg+=(int)(instance->cursor_active);
4105 }
4106
4107 test_true(no_msg == 0);
4108 test_true(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
4109
4110 /*
4111 ** Now validate that all items was set properly!
4112 */
4113 for (size_t x= 0; x < 100; ++x)
4114 {
4115 char key[10];
4116
4117 size_t len= (size_t)sprintf(key, "%zu", x);
4118 size_t length;
4119 uint32_t flags;
4120 char* value=memcached_get(memc, key, strlen(key),
4121 &length, &flags, &ret);
4122 test_true(ret == MEMCACHED_SUCCESS && value != NULL);
4123 switch (count)
4124 {
4125 case 0: /* FALLTHROUGH */
4126 case 1: /* FALLTHROUGH */
4127 case 2:
4128 test_true(strncmp(value, key, len) == 0);
4129 test_true(len == length);
4130 break;
4131 case 3:
4132 test_true(length == len * 2);
4133 break;
4134 case 4:
4135 test_true(length == len * 3);
4136 break;
4137 default:
4138 test_true(count);
4139 break;
4140 }
4141 free(value);
4142 }
4143 }
4144
4145 /* Try setting an illegal cas value (should not return an error to
4146 * the caller (because we don't expect a return message from the server)
4147 */
4148 const char* keys[]= {"0"};
4149 size_t lengths[]= {1};
4150 size_t length;
4151 uint32_t flags;
4152 memcached_result_st results_obj;
4153 memcached_result_st *results;
4154 ret= memcached_mget(memc, keys, lengths, 1);
4155 test_true(ret == MEMCACHED_SUCCESS);
4156
4157 results= memcached_result_create(memc, &results_obj);
4158 test_true(results);
4159 results= memcached_fetch_result(memc, &results_obj, &ret);
4160 test_true(results);
4161 test_true(ret == MEMCACHED_SUCCESS);
4162 uint64_t cas= memcached_result_cas(results);
4163 memcached_result_free(&results_obj);
4164
4165 ret= memcached_cas(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0, cas);
4166 test_true(ret == MEMCACHED_SUCCESS);
4167
4168 /*
4169 * The item will have a new cas value, so try to set it again with the old
4170 * value. This should fail!
4171 */
4172 ret= memcached_cas(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0, cas);
4173 test_true(ret == MEMCACHED_SUCCESS);
4174 test_true(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
4175 char* value=memcached_get(memc, keys[0], lengths[0], &length, &flags, &ret);
4176 test_true(ret == MEMCACHED_SUCCESS && value != NULL);
4177 free(value);
4178
4179 return TEST_SUCCESS;
4180 }
4181
4182 static test_return_t analyzer_test(memcached_st *memc)
4183 {
4184 memcached_return_t rc;
4185 memcached_stat_st *memc_stat;
4186 memcached_analysis_st *report;
4187
4188 memc_stat= memcached_stat(memc, NULL, &rc);
4189 test_true(rc == MEMCACHED_SUCCESS);
4190 test_true(memc_stat);
4191
4192 report= memcached_analyze(memc, memc_stat, &rc);
4193 test_true(rc == MEMCACHED_SUCCESS);
4194 test_true(report);
4195
4196 free(report);
4197 memcached_stat_free(NULL, memc_stat);
4198
4199 return TEST_SUCCESS;
4200 }
4201
4202 /* Count the objects */
4203 static memcached_return_t callback_dump_counter(const memcached_st *ptr __attribute__((unused)),
4204 const char *key __attribute__((unused)),
4205 size_t key_length __attribute__((unused)),
4206 void *context)
4207 {
4208 size_t *counter= (size_t *)context;
4209
4210 *counter= *counter + 1;
4211
4212 return MEMCACHED_SUCCESS;
4213 }
4214
4215 static test_return_t dump_test(memcached_st *memc)
4216 {
4217 memcached_return_t rc;
4218 size_t counter= 0;
4219 memcached_dump_fn callbacks[1];
4220 test_return_t main_rc;
4221
4222 callbacks[0]= &callback_dump_counter;
4223
4224 /* No support for Binary protocol yet */
4225 if (memc->flags.binary_protocol)
4226 return TEST_SUCCESS;
4227
4228 main_rc= set_test3(memc);
4229
4230 test_true (main_rc == TEST_SUCCESS);
4231
4232 rc= memcached_dump(memc, callbacks, (void *)&counter, 1);
4233 test_true(rc == MEMCACHED_SUCCESS);
4234
4235 /* We may have more then 32 if our previous flush has not completed */
4236 test_true(counter >= 32);
4237
4238 return TEST_SUCCESS;
4239 }
4240
4241 #ifdef HAVE_LIBMEMCACHEDUTIL
4242 static void* connection_release(void *arg)
4243 {
4244 struct {
4245 memcached_pool_st* pool;
4246 memcached_st* mmc;
4247 } *resource= arg;
4248
4249 usleep(250);
4250 assert(memcached_pool_push(resource->pool, resource->mmc) == MEMCACHED_SUCCESS);
4251 return arg;
4252 }
4253
4254 static test_return_t connection_pool_test(memcached_st *memc)
4255 {
4256 memcached_pool_st* pool= memcached_pool_create(memc, 5, 10);
4257 test_true(pool != NULL);
4258 memcached_st* mmc[10];
4259 memcached_return_t rc;
4260
4261 for (size_t x= 0; x < 10; ++x)
4262 {
4263 mmc[x]= memcached_pool_pop(pool, false, &rc);
4264 test_true(mmc[x] != NULL);
4265 test_true(rc == MEMCACHED_SUCCESS);
4266 }
4267
4268 test_true(memcached_pool_pop(pool, false, &rc) == NULL);
4269 test_true(rc == MEMCACHED_SUCCESS);
4270
4271 pthread_t tid;
4272 struct {
4273 memcached_pool_st* pool;
4274 memcached_st* mmc;
4275 } item= { .pool = pool, .mmc = mmc[9] };
4276 pthread_create(&tid, NULL, connection_release, &item);
4277 mmc[9]= memcached_pool_pop(pool, true, &rc);
4278 test_true(rc == MEMCACHED_SUCCESS);
4279 pthread_join(tid, NULL);
4280 test_true(mmc[9] == item.mmc);
4281 const char *key= "key";
4282 size_t keylen= strlen(key);
4283
4284 // verify that I can do ops with all connections
4285 rc= memcached_set(mmc[0], key, keylen, "0", 1, 0, 0);
4286 test_true(rc == MEMCACHED_SUCCESS);
4287
4288 for (size_t x= 0; x < 10; ++x)
4289 {
4290 uint64_t number_value;
4291 rc= memcached_increment(mmc[x], key, keylen, 1, &number_value);
4292 test_true(rc == MEMCACHED_SUCCESS);
4293 test_true(number_value == (x+1));
4294 }
4295
4296 // Release them..
4297 for (size_t x= 0; x < 10; ++x)
4298 {
4299 test_true(memcached_pool_push(pool, mmc[x]) == MEMCACHED_SUCCESS);
4300 }
4301
4302
4303 /* verify that I can set behaviors on the pool when I don't have all
4304 * of the connections in the pool. It should however be enabled
4305 * when I push the item into the pool
4306 */
4307 mmc[0]= memcached_pool_pop(pool, false, &rc);
4308 test_true(mmc[0] != NULL);
4309
4310 rc= memcached_pool_behavior_set(pool, MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK, 9999);
4311 test_true(rc == MEMCACHED_SUCCESS);
4312
4313 mmc[1]= memcached_pool_pop(pool, false, &rc);
4314 test_true(mmc[1] != NULL);
4315
4316 test_true(memcached_behavior_get(mmc[1], MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK) == 9999);
4317 test_true(memcached_pool_push(pool, mmc[1]) == MEMCACHED_SUCCESS);
4318 test_true(memcached_pool_push(pool, mmc[0]) == MEMCACHED_SUCCESS);
4319
4320 mmc[0]= memcached_pool_pop(pool, false, &rc);
4321 test_true(memcached_behavior_get(mmc[0], MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK) == 9999);
4322 test_true(memcached_pool_push(pool, mmc[0]) == MEMCACHED_SUCCESS);
4323
4324
4325 test_true(memcached_pool_destroy(pool) == memc);
4326 return TEST_SUCCESS;
4327 }
4328 #endif
4329
4330 static test_return_t replication_set_test(memcached_st *memc)
4331 {
4332 memcached_return_t rc;
4333 memcached_st *memc_clone= memcached_clone(NULL, memc);
4334 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 0);
4335
4336 rc= memcached_set(memc, "bubba", 5, "0", 1, 0, 0);
4337 test_true(rc == MEMCACHED_SUCCESS);
4338
4339 /*
4340 ** We are using the quiet commands to store the replicas, so we need
4341 ** to ensure that all of them are processed before we can continue.
4342 ** In the test we go directly from storing the object to trying to
4343 ** receive the object from all of the different servers, so we
4344 ** could end up in a race condition (the memcached server hasn't yet
4345 ** processed the quiet command from the replication set when it process
4346 ** the request from the other client (created by the clone)). As a
4347 ** workaround for that we call memcached_quit to send the quit command
4348 ** to the server and wait for the response ;-) If you use the test code
4349 ** as an example for your own code, please note that you shouldn't need
4350 ** to do this ;-)
4351 */
4352 memcached_quit(memc);
4353
4354 /*
4355 ** "bubba" should now be stored on all of our servers. We don't have an
4356 ** easy to use API to address each individual server, so I'll just iterate
4357 ** through a bunch of "master keys" and I should most likely hit all of the
4358 ** servers...
4359 */
4360 for (int x= 'a'; x <= 'z'; ++x)
4361 {
4362 char key[2]= { [0]= (char)x };
4363 size_t len;
4364 uint32_t flags;
4365 char *val= memcached_get_by_key(memc_clone, key, 1, "bubba", 5,
4366 &len, &flags, &rc);
4367 test_true(rc == MEMCACHED_SUCCESS);
4368 test_true(val != NULL);
4369 free(val);
4370 }
4371
4372 memcached_free(memc_clone);
4373
4374 return TEST_SUCCESS;
4375 }
4376
4377 static test_return_t replication_get_test(memcached_st *memc)
4378 {
4379 memcached_return_t rc;
4380
4381 /*
4382 * Don't do the following in your code. I am abusing the internal details
4383 * within the library, and this is not a supported interface.
4384 * This is to verify correct behavior in the library
4385 */
4386 for (uint32_t host= 0; host < memcached_server_count(memc); ++host)
4387 {
4388 memcached_st *memc_clone= memcached_clone(NULL, memc);
4389 memcached_server_instance_st instance=
4390 memcached_server_instance_by_position(memc_clone, host);
4391
4392 ((memcached_server_write_instance_st)instance)->port= 0;
4393
4394 for (int x= 'a'; x <= 'z'; ++x)
4395 {
4396 char key[2]= { [0]= (char)x };
4397 size_t len;
4398 uint32_t flags;
4399 char *val= memcached_get_by_key(memc_clone, key, 1, "bubba", 5,
4400 &len, &flags, &rc);
4401 test_true(rc == MEMCACHED_SUCCESS);
4402 test_true(val != NULL);
4403 free(val);
4404 }
4405
4406 memcached_free(memc_clone);
4407 }
4408
4409 return TEST_SUCCESS;
4410 }
4411
4412 static test_return_t replication_mget_test(memcached_st *memc)
4413 {
4414 memcached_return_t rc;
4415 memcached_st *memc_clone= memcached_clone(NULL, memc);
4416 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 0);
4417
4418 const char *keys[]= { "bubba", "key1", "key2", "key3" };
4419 size_t len[]= { 5, 4, 4, 4 };
4420
4421 for (size_t x= 0; x< 4; ++x)
4422 {
4423 rc= memcached_set(memc, keys[x], len[x], "0", 1, 0, 0);
4424 test_true(rc == MEMCACHED_SUCCESS);
4425 }
4426
4427 /*
4428 ** We are using the quiet commands to store the replicas, so we need
4429 ** to ensure that all of them are processed before we can continue.
4430 ** In the test we go directly from storing the object to trying to
4431 ** receive the object from all of the different servers, so we
4432 ** could end up in a race condition (the memcached server hasn't yet
4433 ** processed the quiet command from the replication set when it process
4434 ** the request from the other client (created by the clone)). As a
4435 ** workaround for that we call memcached_quit to send the quit command
4436 ** to the server and wait for the response ;-) If you use the test code
4437 ** as an example for your own code, please note that you shouldn't need
4438 ** to do this ;-)
4439 */
4440 memcached_quit(memc);
4441
4442 /*
4443 * Don't do the following in your code. I am abusing the internal details
4444 * within the library, and this is not a supported interface.
4445 * This is to verify correct behavior in the library
4446 */
4447 memcached_result_st result_obj;
4448 for (uint32_t host= 0; host < memc_clone->number_of_hosts; host++)
4449 {
4450 memcached_st *new_clone= memcached_clone(NULL, memc);
4451 memcached_server_instance_st instance=
4452 memcached_server_instance_by_position(new_clone, host);
4453 ((memcached_server_write_instance_st)instance)->port= 0;
4454
4455 for (int x= 'a'; x <= 'z'; ++x)
4456 {
4457 char key[2]= { [0]= (char)x, [1]= 0 };
4458
4459 rc= memcached_mget_by_key(new_clone, key, 1, keys, len, 4);
4460 test_true(rc == MEMCACHED_SUCCESS);
4461
4462 memcached_result_st *results= memcached_result_create(new_clone, &result_obj);
4463 test_true(results);
4464
4465 int hits= 0;
4466 while ((results= memcached_fetch_result(new_clone, &result_obj, &rc)) != NULL)
4467 {
4468 hits++;
4469 }
4470 test_true(hits == 4);
4471 memcached_result_free(&result_obj);
4472 }
4473
4474 memcached_free(new_clone);
4475 }
4476
4477 memcached_free(memc_clone);
4478
4479 return TEST_SUCCESS;
4480 }
4481
4482 static test_return_t replication_randomize_mget_test(memcached_st *memc)
4483 {
4484 memcached_result_st result_obj;
4485 memcached_return_t rc;
4486 memcached_st *memc_clone= memcached_clone(NULL, memc);
4487 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 3);
4488 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_RANDOMIZE_REPLICA_READ, 1);
4489
4490 const char *keys[]= { "key1", "key2", "key3", "key4", "key5", "key6", "key7" };
4491 size_t len[]= { 4, 4, 4, 4, 4, 4, 4 };
4492
4493 for (size_t x= 0; x< 7; ++x)
4494 {
4495 rc= memcached_set(memc, keys[x], len[x], "1", 1, 0, 0);
4496 test_true(rc == MEMCACHED_SUCCESS);
4497 }
4498
4499 memcached_quit(memc);
4500
4501 for (size_t x= 0; x< 7; ++x)
4502 {
4503 const char key[2]= { [0]= (const char)x };
4504
4505 rc= memcached_mget_by_key(memc_clone, key, 1, keys, len, 7);
4506 test_true(rc == MEMCACHED_SUCCESS);
4507
4508 memcached_result_st *results= memcached_result_create(memc_clone, &result_obj);
4509 test_true(results);
4510
4511 int hits= 0;
4512 while ((results= memcached_fetch_result(memc_clone, &result_obj, &rc)) != NULL)
4513 {
4514 ++hits;
4515 }
4516 test_true(hits == 7);
4517 memcached_result_free(&result_obj);
4518 }
4519 memcached_free(memc_clone);
4520 return TEST_SUCCESS;
4521 }
4522
4523 static test_return_t replication_delete_test(memcached_st *memc)
4524 {
4525 memcached_return_t rc;
4526 memcached_st *memc_clone= memcached_clone(NULL, memc);
4527 /* Delete the items from all of the servers except 1 */
4528 uint64_t repl= memcached_behavior_get(memc,
4529 MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS);
4530 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, --repl);
4531
4532 const char *keys[]= { "bubba", "key1", "key2", "key3" };
4533 size_t len[]= { 5, 4, 4, 4 };
4534
4535 for (size_t x= 0; x< 4; ++x)
4536 {
4537 rc= memcached_delete_by_key(memc, keys[0], len[0], keys[x], len[x], 0);
4538 test_true(rc == MEMCACHED_SUCCESS);
4539 }
4540
4541 /*
4542 * Don't do the following in your code. I am abusing the internal details
4543 * within the library, and this is not a supported interface.
4544 * This is to verify correct behavior in the library
4545 */
4546 uint32_t hash= memcached_generate_hash(memc, keys[0], len[0]);
4547 for (uint32_t x= 0; x < (repl + 1); ++x)
4548 {
4549 memcached_server_instance_st instance=
4550 memcached_server_instance_by_position(memc_clone, x);
4551
4552 ((memcached_server_write_instance_st)instance)->port= 0;
4553 if (++hash == memc_clone->number_of_hosts)
4554 hash= 0;
4555 }
4556
4557 memcached_result_st result_obj;
4558 for (uint32_t host= 0; host < memc_clone->number_of_hosts; ++host)
4559 {
4560 for (size_t x= 'a'; x <= 'z'; ++x)
4561 {
4562 const char key[2]= { [0]= (const char)x };
4563
4564 rc= memcached_mget_by_key(memc_clone, key, 1, keys, len, 4);
4565 test_true(rc == MEMCACHED_SUCCESS);
4566
4567 memcached_result_st *results= memcached_result_create(memc_clone, &result_obj);
4568 test_true(results);
4569
4570 int hits= 0;
4571 while ((results= memcached_fetch_result(memc_clone, &result_obj, &rc)) != NULL)
4572 {
4573 ++hits;
4574 }
4575 test_true(hits == 4);
4576 memcached_result_free(&result_obj);
4577 }
4578 }
4579 memcached_free(memc_clone);
4580
4581 return TEST_SUCCESS;
4582 }
4583
4584 #if 0
4585 static test_return_t hash_sanity_test (memcached_st *memc)
4586 {
4587 (void)memc;
4588
4589 assert(MEMCACHED_HASH_DEFAULT == MEMCACHED_HASH_DEFAULT);
4590 assert(MEMCACHED_HASH_MD5 == MEMCACHED_HASH_MD5);
4591 assert(MEMCACHED_HASH_CRC == MEMCACHED_HASH_CRC);
4592 assert(MEMCACHED_HASH_FNV1_64 == MEMCACHED_HASH_FNV1_64);
4593 assert(MEMCACHED_HASH_FNV1A_64 == MEMCACHED_HASH_FNV1A_64);
4594 assert(MEMCACHED_HASH_FNV1_32 == MEMCACHED_HASH_FNV1_32);
4595 assert(MEMCACHED_HASH_FNV1A_32 == MEMCACHED_HASH_FNV1A_32);
4596 #ifdef HAVE_HSIEH_HASH
4597 assert(MEMCACHED_HASH_HSIEH == MEMCACHED_HASH_HSIEH);
4598 #endif
4599 assert(MEMCACHED_HASH_MURMUR == MEMCACHED_HASH_MURMUR);
4600 assert(MEMCACHED_HASH_JENKINS == MEMCACHED_HASH_JENKINS);
4601 assert(MEMCACHED_HASH_MAX == MEMCACHED_HASH_MAX);
4602
4603 return TEST_SUCCESS;
4604 }
4605 #endif
4606
4607 static test_return_t hsieh_avaibility_test (memcached_st *memc)
4608 {
4609 memcached_return_t expected_rc= MEMCACHED_FAILURE;
4610 #ifdef HAVE_HSIEH_HASH
4611 expected_rc= MEMCACHED_SUCCESS;
4612 #endif
4613 memcached_return_t rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH,
4614 (uint64_t)MEMCACHED_HASH_HSIEH);
4615 test_true(rc == expected_rc);
4616
4617 return TEST_SUCCESS;
4618 }
4619
4620 static test_return_t one_at_a_time_run (memcached_st *memc __attribute__((unused)))
4621 {
4622 uint32_t x;
4623 const char **ptr;
4624
4625 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4626 {
4627 uint32_t hash_val;
4628
4629 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_DEFAULT);
4630 test_true(one_at_a_time_values[x] == hash_val);
4631 }
4632
4633 return TEST_SUCCESS;
4634 }
4635
4636 static test_return_t md5_run (memcached_st *memc __attribute__((unused)))
4637 {
4638 uint32_t x;
4639 const char **ptr;
4640
4641 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4642 {
4643 uint32_t hash_val;
4644
4645 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_MD5);
4646 test_true(md5_values[x] == hash_val);
4647 }
4648
4649 return TEST_SUCCESS;
4650 }
4651
4652 static test_return_t crc_run (memcached_st *memc __attribute__((unused)))
4653 {
4654 uint32_t x;
4655 const char **ptr;
4656
4657 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4658 {
4659 uint32_t hash_val;
4660
4661 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_CRC);
4662 test_true(crc_values[x] == hash_val);
4663 }
4664
4665 return TEST_SUCCESS;
4666 }
4667
4668 static test_return_t fnv1_64_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_FNV1_64);
4678 test_true(fnv1_64_values[x] == hash_val);
4679 }
4680
4681 return TEST_SUCCESS;
4682 }
4683
4684 static test_return_t fnv1a_64_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_FNV1A_64);
4694 test_true(fnv1a_64_values[x] == hash_val);
4695 }
4696
4697 return TEST_SUCCESS;
4698 }
4699
4700 static test_return_t fnv1_32_run (memcached_st *memc __attribute__((unused)))
4701 {
4702 uint32_t x;
4703 const char **ptr;
4704
4705
4706 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4707 {
4708 uint32_t hash_val;
4709
4710 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1_32);
4711 test_true(fnv1_32_values[x] == hash_val);
4712 }
4713
4714 return TEST_SUCCESS;
4715 }
4716
4717 static test_return_t fnv1a_32_run (memcached_st *memc __attribute__((unused)))
4718 {
4719 uint32_t x;
4720 const char **ptr;
4721
4722 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4723 {
4724 uint32_t hash_val;
4725
4726 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1A_32);
4727 test_true(fnv1a_32_values[x] == hash_val);
4728 }
4729
4730 return TEST_SUCCESS;
4731 }
4732
4733 static test_return_t hsieh_run (memcached_st *memc __attribute__((unused)))
4734 {
4735 uint32_t x;
4736 const char **ptr;
4737
4738 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4739 {
4740 uint32_t hash_val;
4741
4742 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_HSIEH);
4743 test_true(hsieh_values[x] == hash_val);
4744 }
4745
4746 return TEST_SUCCESS;
4747 }
4748
4749 static test_return_t murmur_run (memcached_st *memc __attribute__((unused)))
4750 {
4751 #ifdef __sparc
4752 return TEST_SKIPPED;
4753 #else
4754 uint32_t x;
4755 const char **ptr;
4756
4757 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4758 {
4759 uint32_t hash_val;
4760
4761 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_MURMUR);
4762 test_true(murmur_values[x] == hash_val);
4763 }
4764
4765 return TEST_SUCCESS;
4766 #endif
4767 }
4768
4769 static test_return_t jenkins_run (memcached_st *memc __attribute__((unused)))
4770 {
4771 uint32_t x;
4772 const char **ptr;
4773
4774
4775 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4776 {
4777 uint32_t hash_val;
4778
4779 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_JENKINS);
4780 test_true(jenkins_values[x] == hash_val);
4781 }
4782
4783 return TEST_SUCCESS;
4784 }
4785
4786 static uint32_t hash_md5_test_function(const char *string, size_t string_length, void *context)
4787 {
4788 (void)context;
4789 return libhashkit_md5(string, string_length);
4790 }
4791
4792 static uint32_t hash_crc_test_function(const char *string, size_t string_length, void *context)
4793 {
4794 (void)context;
4795 return libhashkit_crc32(string, string_length);
4796 }
4797
4798 static test_return_t memcached_get_hashkit_test (memcached_st *memc)
4799 {
4800 uint32_t x;
4801 const char **ptr;
4802 const hashkit_st *kit;
4803 hashkit_st new_kit;
4804 hashkit_return_t hash_rc;
4805
4806 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};
4807 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};
4808
4809 kit= memcached_get_hashkit(memc);
4810
4811 hashkit_clone(&new_kit, kit);
4812 hash_rc= hashkit_set_custom_function(&new_kit, hash_md5_test_function, NULL);
4813 test_true(hash_rc == HASHKIT_SUCCESS);
4814
4815 memcached_set_hashkit(memc, &new_kit);
4816
4817 /*
4818 Verify Setting the hash.
4819 */
4820 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4821 {
4822 uint32_t hash_val;
4823
4824 hash_val= hashkit_digest(kit, *ptr, strlen(*ptr));
4825 test_true(md5_values[x] == hash_val);
4826 }
4827
4828
4829 /*
4830 Now check memcached_st.
4831 */
4832 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4833 {
4834 uint32_t hash_val;
4835
4836 hash_val= memcached_generate_hash(memc, *ptr, strlen(*ptr));
4837 test_true(md5_hosts[x] == hash_val);
4838 }
4839
4840 hash_rc= hashkit_set_custom_function(&new_kit, hash_crc_test_function, NULL);
4841 test_true(hash_rc == HASHKIT_SUCCESS);
4842
4843 memcached_set_hashkit(memc, &new_kit);
4844
4845 /*
4846 Verify Setting the hash.
4847 */
4848 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4849 {
4850 uint32_t hash_val;
4851
4852 hash_val= hashkit_digest(kit, *ptr, strlen(*ptr));
4853 test_true(crc_values[x] == hash_val);
4854 }
4855
4856 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4857 {
4858 uint32_t hash_val;
4859
4860 hash_val= memcached_generate_hash(memc, *ptr, strlen(*ptr));
4861 test_true(crc_hosts[x] == hash_val);
4862 }
4863
4864 return TEST_SUCCESS;
4865 }
4866
4867
4868 static test_return_t ketama_compatibility_libmemcached(memcached_st *trash)
4869 {
4870 memcached_return_t rc;
4871 uint64_t value;
4872 int x;
4873 memcached_server_st *server_pool;
4874 memcached_st *memc;
4875
4876 (void)trash;
4877
4878 memc= memcached_create(NULL);
4879 test_true(memc);
4880
4881 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
4882 test_true(rc == MEMCACHED_SUCCESS);
4883
4884 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
4885 test_true(value == 1);
4886
4887 test_true(memcached_behavior_set_distribution(memc, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA) == MEMCACHED_SUCCESS);
4888 test_true(memcached_behavior_get_distribution(memc) == MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA);
4889
4890
4891 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");
4892 memcached_server_push(memc, server_pool);
4893
4894 /* verify that the server list was parsed okay. */
4895 test_true(memcached_server_count(memc) == 8);
4896 test_strcmp(server_pool[0].hostname, "10.0.1.1");
4897 test_true(server_pool[0].port == 11211);
4898 test_true(server_pool[0].weight == 600);
4899 test_strcmp(server_pool[2].hostname, "10.0.1.3");
4900 test_true(server_pool[2].port == 11211);
4901 test_true(server_pool[2].weight == 200);
4902 test_strcmp(server_pool[7].hostname, "10.0.1.8");
4903 test_true(server_pool[7].port == 11211);
4904 test_true(server_pool[7].weight == 100);
4905
4906 /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets
4907 * us test the boundary wraparound.
4908 */
4909 test_true(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->continuum[0].index);
4910
4911 /* verify the standard ketama set. */
4912 for (x= 0; x < 99; x++)
4913 {
4914 uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
4915 memcached_server_instance_st instance=
4916 memcached_server_instance_by_position(memc, server_idx);
4917 const char *hostname = memcached_server_name(instance);
4918
4919 test_strcmp(hostname, ketama_test_cases[x].server);
4920 }
4921
4922 memcached_server_list_free(server_pool);
4923 memcached_free(memc);
4924
4925 return TEST_SUCCESS;
4926 }
4927
4928 static test_return_t ketama_compatibility_spymemcached(memcached_st *trash)
4929 {
4930 memcached_return_t rc;
4931 uint64_t value;
4932 int x;
4933 memcached_server_st *server_pool;
4934 memcached_st *memc;
4935
4936 (void)trash;
4937
4938 memc= memcached_create(NULL);
4939 test_true(memc);
4940
4941 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
4942 test_true(rc == MEMCACHED_SUCCESS);
4943
4944 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
4945 test_true(value == 1);
4946
4947 test_true(memcached_behavior_set_distribution(memc, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY) == MEMCACHED_SUCCESS);
4948 test_true(memcached_behavior_get_distribution(memc) == MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY);
4949
4950 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");
4951 memcached_server_push(memc, server_pool);
4952
4953 /* verify that the server list was parsed okay. */
4954 test_true(memcached_server_count(memc) == 8);
4955 test_strcmp(server_pool[0].hostname, "10.0.1.1");
4956 test_true(server_pool[0].port == 11211);
4957 test_true(server_pool[0].weight == 600);
4958 test_strcmp(server_pool[2].hostname, "10.0.1.3");
4959 test_true(server_pool[2].port == 11211);
4960 test_true(server_pool[2].weight == 200);
4961 test_strcmp(server_pool[7].hostname, "10.0.1.8");
4962 test_true(server_pool[7].port == 11211);
4963 test_true(server_pool[7].weight == 100);
4964
4965 /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets
4966 * us test the boundary wraparound.
4967 */
4968 test_true(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->continuum[0].index);
4969
4970 /* verify the standard ketama set. */
4971 for (x= 0; x < 99; x++)
4972 {
4973 uint32_t server_idx= memcached_generate_hash(memc, ketama_test_cases_spy[x].key, strlen(ketama_test_cases_spy[x].key));
4974
4975 memcached_server_instance_st instance=
4976 memcached_server_instance_by_position(memc, server_idx);
4977
4978 const char *hostname= memcached_server_name(instance);
4979
4980 test_strcmp(hostname, ketama_test_cases_spy[x].server);
4981 }
4982
4983 memcached_server_list_free(server_pool);
4984 memcached_free(memc);
4985
4986 return TEST_SUCCESS;
4987 }
4988
4989 static test_return_t regression_bug_434484(memcached_st *memc)
4990 {
4991 test_return_t test_rc;
4992 test_rc= pre_binary(memc);
4993
4994 if (test_rc != TEST_SUCCESS)
4995 return test_rc;
4996
4997 memcached_return_t ret;
4998 const char *key= "regression_bug_434484";
4999 size_t keylen= strlen(key);
5000
5001 ret= memcached_append(memc, key, keylen, key, keylen, 0, 0);
5002 test_true(ret == MEMCACHED_NOTSTORED);
5003
5004 size_t size= 2048 * 1024;
5005 void *data= calloc(1, size);
5006 test_true(data != NULL);
5007 ret= memcached_set(memc, key, keylen, data, size, 0, 0);
5008 test_true(ret == MEMCACHED_E2BIG);
5009 free(data);
5010
5011 return TEST_SUCCESS;
5012 }
5013
5014 static test_return_t regression_bug_434843(memcached_st *memc)
5015 {
5016 test_return_t test_rc;
5017 test_rc= pre_binary(memc);
5018
5019 if (test_rc != TEST_SUCCESS)
5020 return test_rc;
5021
5022 memcached_return_t rc;
5023 size_t counter= 0;
5024 memcached_execute_fn callbacks[1]= { [0]= &callback_counter };
5025
5026 /*
5027 * I only want to hit only _one_ server so I know the number of requests I'm
5028 * sending in the pipleine to the server. Let's try to do a multiget of
5029 * 1024 (that should satisfy most users don't you think?). Future versions
5030 * will include a mget_execute function call if you need a higher number.
5031 */
5032 uint32_t number_of_hosts= memcached_server_count(memc);
5033 memc->number_of_hosts= 1;
5034 const size_t max_keys= 1024;
5035 char **keys= calloc(max_keys, sizeof(char*));
5036 size_t *key_length=calloc(max_keys, sizeof(size_t));
5037
5038 for (size_t x= 0; x < max_keys; ++x)
5039 {
5040 char k[251];
5041
5042 key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%zu", x);
5043 keys[x]= strdup(k);
5044 test_true(keys[x] != NULL);
5045 }
5046
5047 /*
5048 * Run two times.. the first time we should have 100% cache miss,
5049 * and the second time we should have 100% cache hits
5050 */
5051 for (size_t y= 0; y < 2; y++)
5052 {
5053 rc= memcached_mget(memc, (const char**)keys, key_length, max_keys);
5054 test_true(rc == MEMCACHED_SUCCESS);
5055 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
5056
5057 if (y == 0)
5058 {
5059 /* The first iteration should give me a 100% cache miss. verify that*/
5060 char blob[1024]= { 0 };
5061
5062 test_true(counter == 0);
5063
5064 for (size_t x= 0; x < max_keys; ++x)
5065 {
5066 rc= memcached_add(memc, keys[x], key_length[x],
5067 blob, sizeof(blob), 0, 0);
5068 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5069 }
5070 }
5071 else
5072 {
5073 /* Verify that we received all of the key/value pairs */
5074 test_true(counter == max_keys);
5075 }
5076 }
5077
5078 /* Release allocated resources */
5079 for (size_t x= 0; x < max_keys; ++x)
5080 {
5081 free(keys[x]);
5082 }
5083 free(keys);
5084 free(key_length);
5085
5086 memc->number_of_hosts= number_of_hosts;
5087
5088 return TEST_SUCCESS;
5089 }
5090
5091 static test_return_t regression_bug_434843_buffered(memcached_st *memc)
5092 {
5093 memcached_return_t rc;
5094 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
5095 test_true(rc == MEMCACHED_SUCCESS);
5096
5097 return regression_bug_434843(memc);
5098 }
5099
5100 static test_return_t regression_bug_421108(memcached_st *memc)
5101 {
5102 memcached_return_t rc;
5103 memcached_stat_st *memc_stat= memcached_stat(memc, NULL, &rc);
5104 test_true(rc == MEMCACHED_SUCCESS);
5105
5106 char *bytes= memcached_stat_get_value(memc, memc_stat, "bytes", &rc);
5107 test_true(rc == MEMCACHED_SUCCESS);
5108 test_true(bytes != NULL);
5109 char *bytes_read= memcached_stat_get_value(memc, memc_stat,
5110 "bytes_read", &rc);
5111 test_true(rc == MEMCACHED_SUCCESS);
5112 test_true(bytes_read != NULL);
5113
5114 char *bytes_written= memcached_stat_get_value(memc, memc_stat,
5115 "bytes_written", &rc);
5116 test_true(rc == MEMCACHED_SUCCESS);
5117 test_true(bytes_written != NULL);
5118
5119 test_true(strcmp(bytes, bytes_read) != 0);
5120 test_true(strcmp(bytes, bytes_written) != 0);
5121
5122 /* Release allocated resources */
5123 free(bytes);
5124 free(bytes_read);
5125 free(bytes_written);
5126 memcached_stat_free(NULL, memc_stat);
5127
5128 return TEST_SUCCESS;
5129 }
5130
5131 /*
5132 * The test case isn't obvious so I should probably document why
5133 * it works the way it does. Bug 442914 was caused by a bug
5134 * in the logic in memcached_purge (it did not handle the case
5135 * where the number of bytes sent was equal to the watermark).
5136 * In this test case, create messages so that we hit that case
5137 * and then disable noreply mode and issue a new command to
5138 * verify that it isn't stuck. If we change the format for the
5139 * delete command or the watermarks, we need to update this
5140 * test....
5141 */
5142 static test_return_t regression_bug_442914(memcached_st *memc)
5143 {
5144 memcached_return_t rc;
5145 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1);
5146 test_true(rc == MEMCACHED_SUCCESS);
5147 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 1);
5148
5149 uint32_t number_of_hosts= memcached_server_count(memc);
5150 memc->number_of_hosts= 1;
5151
5152 char k[250];
5153 size_t len;
5154
5155 for (uint32_t x= 0; x < 250; ++x)
5156 {
5157 len= (size_t)snprintf(k, sizeof(k), "%0250u", x);
5158 rc= memcached_delete(memc, k, len, 0);
5159 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5160 }
5161
5162 (void)snprintf(k, sizeof(k), "%037u", 251U);
5163 len= strlen(k);
5164
5165 rc= memcached_delete(memc, k, len, 0);
5166 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5167
5168 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 0);
5169 test_true(rc == MEMCACHED_SUCCESS);
5170 rc= memcached_delete(memc, k, len, 0);
5171 test_true(rc == MEMCACHED_NOTFOUND);
5172
5173 memc->number_of_hosts= number_of_hosts;
5174
5175 return TEST_SUCCESS;
5176 }
5177
5178 static test_return_t regression_bug_447342(memcached_st *memc)
5179 {
5180 memcached_server_instance_st instance_one;
5181 memcached_server_instance_st instance_two;
5182
5183 if (memcached_server_count(memc) < 3 || pre_replication(memc) != MEMCACHED_SUCCESS)
5184 return TEST_SKIPPED;
5185
5186 memcached_return_t rc;
5187
5188 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 2);
5189 test_true(rc == MEMCACHED_SUCCESS);
5190
5191 const size_t max_keys= 100;
5192 char **keys= calloc(max_keys, sizeof(char*));
5193 size_t *key_length= calloc(max_keys, sizeof(size_t));
5194
5195 for (size_t x= 0; x < max_keys; ++x)
5196 {
5197 char k[251];
5198
5199 key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%zu", x);
5200 keys[x]= strdup(k);
5201 test_true(keys[x] != NULL);
5202 rc= memcached_set(memc, k, key_length[x], k, key_length[x], 0, 0);
5203 test_true(rc == MEMCACHED_SUCCESS);
5204 }
5205
5206 /*
5207 ** We are using the quiet commands to store the replicas, so we need
5208 ** to ensure that all of them are processed before we can continue.
5209 ** In the test we go directly from storing the object to trying to
5210 ** receive the object from all of the different servers, so we
5211 ** could end up in a race condition (the memcached server hasn't yet
5212 ** processed the quiet command from the replication set when it process
5213 ** the request from the other client (created by the clone)). As a
5214 ** workaround for that we call memcached_quit to send the quit command
5215 ** to the server and wait for the response ;-) If you use the test code
5216 ** as an example for your own code, please note that you shouldn't need
5217 ** to do this ;-)
5218 */
5219 memcached_quit(memc);
5220
5221 /* Verify that all messages are stored, and we didn't stuff too much
5222 * into the servers
5223 */
5224 rc= memcached_mget(memc, (const char* const *)keys, key_length, max_keys);
5225 test_true(rc == MEMCACHED_SUCCESS);
5226
5227 size_t counter= 0;
5228 memcached_execute_fn callbacks[1]= { [0]= &callback_counter };
5229 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
5230 /* Verify that we received all of the key/value pairs */
5231 test_true(counter == max_keys);
5232
5233 memcached_quit(memc);
5234 /*
5235 * Don't do the following in your code. I am abusing the internal details
5236 * within the library, and this is not a supported interface.
5237 * This is to verify correct behavior in the library. Fake that two servers
5238 * are dead..
5239 */
5240 instance_one= memcached_server_instance_by_position(memc, 0);
5241 instance_two= memcached_server_instance_by_position(memc, 2);
5242 in_port_t port0= instance_one->port;
5243 in_port_t port2= instance_two->port;
5244
5245 ((memcached_server_write_instance_st)instance_one)->port= 0;
5246 ((memcached_server_write_instance_st)instance_two)->port= 0;
5247
5248 rc= memcached_mget(memc, (const char* const *)keys, key_length, max_keys);
5249 test_true(rc == MEMCACHED_SUCCESS);
5250
5251 counter= 0;
5252 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
5253 test_true(counter == (unsigned int)max_keys);
5254
5255 /* restore the memc handle */
5256 ((memcached_server_write_instance_st)instance_one)->port= port0;
5257 ((memcached_server_write_instance_st)instance_two)->port= port2;
5258
5259 memcached_quit(memc);
5260
5261 /* Remove half of the objects */
5262 for (size_t x= 0; x < max_keys; ++x)
5263 {
5264 if (x & 1)
5265 {
5266 rc= memcached_delete(memc, keys[x], key_length[x], 0);
5267 test_true(rc == MEMCACHED_SUCCESS);
5268 }
5269 }
5270
5271 memcached_quit(memc);
5272 ((memcached_server_write_instance_st)instance_one)->port= 0;
5273 ((memcached_server_write_instance_st)instance_two)->port= 0;
5274
5275 /* now retry the command, this time we should have cache misses */
5276 rc= memcached_mget(memc, (const char* const *)keys, key_length, max_keys);
5277 test_true(rc == MEMCACHED_SUCCESS);
5278
5279 counter= 0;
5280 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
5281 test_true(counter == (unsigned int)(max_keys >> 1));
5282
5283 /* Release allocated resources */
5284 for (size_t x= 0; x < max_keys; ++x)
5285 {
5286 free(keys[x]);
5287 }
5288 free(keys);
5289 free(key_length);
5290
5291 /* restore the memc handle */
5292 ((memcached_server_write_instance_st)instance_one)->port= port0;
5293 ((memcached_server_write_instance_st)instance_two)->port= port2;
5294
5295 return TEST_SUCCESS;
5296 }
5297
5298 static test_return_t regression_bug_463297(memcached_st *memc)
5299 {
5300 memcached_st *memc_clone= memcached_clone(NULL, memc);
5301 test_true(memc_clone != NULL);
5302 test_true(memcached_version(memc_clone) == MEMCACHED_SUCCESS);
5303
5304 memcached_server_instance_st instance=
5305 memcached_server_instance_by_position(memc_clone, 0);
5306
5307 if (instance->major_version > 1 ||
5308 (instance->major_version == 1 &&
5309 instance->minor_version > 2))
5310 {
5311 /* Binary protocol doesn't support deferred delete */
5312 memcached_st *bin_clone= memcached_clone(NULL, memc);
5313 test_true(bin_clone != NULL);
5314 test_true(memcached_behavior_set(bin_clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1) == MEMCACHED_SUCCESS);
5315 test_true(memcached_delete(bin_clone, "foo", 3, 1) == MEMCACHED_INVALID_ARGUMENTS);
5316 memcached_free(bin_clone);
5317
5318 memcached_quit(memc_clone);
5319
5320 /* If we know the server version, deferred delete should fail
5321 * with invalid arguments */
5322 test_true(memcached_delete(memc_clone, "foo", 3, 1) == MEMCACHED_INVALID_ARGUMENTS);
5323
5324 /* If we don't know the server version, we should get a protocol error */
5325 memcached_return_t rc= memcached_delete(memc, "foo", 3, 1);
5326
5327 /* but there is a bug in some of the memcached servers (1.4) that treats
5328 * the counter as noreply so it doesn't send the proper error message
5329 */
5330 test_true(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR);
5331
5332 /* And buffered mode should be disabled and we should get protocol error */
5333 test_true(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1) == MEMCACHED_SUCCESS);
5334 rc= memcached_delete(memc, "foo", 3, 1);
5335 test_true(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR);
5336
5337 /* Same goes for noreply... */
5338 test_true(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1) == MEMCACHED_SUCCESS);
5339 rc= memcached_delete(memc, "foo", 3, 1);
5340 test_true(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR);
5341
5342 /* but a normal request should go through (and be buffered) */
5343 test_true((rc= memcached_delete(memc, "foo", 3, 0)) == MEMCACHED_BUFFERED);
5344 test_true(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
5345
5346 test_true(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 0) == MEMCACHED_SUCCESS);
5347 /* unbuffered noreply should be success */
5348 test_true(memcached_delete(memc, "foo", 3, 0) == MEMCACHED_SUCCESS);
5349 /* unbuffered with reply should be not found... */
5350 test_true(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 0) == MEMCACHED_SUCCESS);
5351 test_true(memcached_delete(memc, "foo", 3, 0) == MEMCACHED_NOTFOUND);
5352 }
5353
5354 memcached_free(memc_clone);
5355 return TEST_SUCCESS;
5356 }
5357
5358
5359 /* Test memcached_server_get_last_disconnect
5360 * For a working server set, shall be NULL
5361 * For a set of non existing server, shall not be NULL
5362 */
5363 static test_return_t test_get_last_disconnect(memcached_st *memc)
5364 {
5365 memcached_return_t rc;
5366 memcached_server_instance_st disconnected_server;
5367
5368 /* With the working set of server */
5369 const char *key= "marmotte";
5370 const char *value= "milka";
5371
5372 rc= memcached_set(memc, key, strlen(key),
5373 value, strlen(value),
5374 (time_t)0, (uint32_t)0);
5375 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5376
5377 disconnected_server = memcached_server_get_last_disconnect(memc);
5378 test_true(disconnected_server == NULL);
5379
5380 /* With a non existing server */
5381 memcached_st *mine;
5382 memcached_server_st *servers;
5383
5384 const char *server_list= "localhost:9";
5385
5386 servers= memcached_servers_parse(server_list);
5387 test_true(servers);
5388 mine= memcached_create(NULL);
5389 rc= memcached_server_push(mine, servers);
5390 test_true(rc == MEMCACHED_SUCCESS);
5391 memcached_server_list_free(servers);
5392 test_true(mine);
5393
5394 rc= memcached_set(mine, key, strlen(key),
5395 value, strlen(value),
5396 (time_t)0, (uint32_t)0);
5397 test_true(rc != MEMCACHED_SUCCESS);
5398
5399 disconnected_server = memcached_server_get_last_disconnect(mine);
5400 test_true(disconnected_server != NULL);
5401 test_true(memcached_server_port(disconnected_server)== 9);
5402 test_true(strncmp(memcached_server_name(disconnected_server),"localhost",9) == 0);
5403
5404 memcached_quit(mine);
5405 memcached_free(mine);
5406
5407 return TEST_SUCCESS;
5408 }
5409
5410 static test_return_t test_verbosity(memcached_st *memc)
5411 {
5412 memcached_verbosity(memc, 3);
5413
5414 return TEST_SUCCESS;
5415 }
5416
5417 /*
5418 * This test ensures that the failure counter isn't incremented during
5419 * normal termination of the memcached instance.
5420 */
5421 static test_return_t wrong_failure_counter_test(memcached_st *memc)
5422 {
5423 memcached_return_t rc;
5424 memcached_server_instance_st instance;
5425
5426 /* Set value to force connection to the server */
5427 const char *key= "marmotte";
5428 const char *value= "milka";
5429
5430 /*
5431 * Please note that I'm abusing the internal structures in libmemcached
5432 * in a non-portable way and you shouldn't be doing this. I'm only
5433 * doing this in order to verify that the library works the way it should
5434 */
5435 uint32_t number_of_hosts= memcached_server_count(memc);
5436 memc->number_of_hosts= 1;
5437
5438 /* Ensure that we are connected to the server by setting a value */
5439 rc= memcached_set(memc, key, strlen(key),
5440 value, strlen(value),
5441 (time_t)0, (uint32_t)0);
5442 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5443
5444
5445 instance= memcached_server_instance_by_position(memc, 0);
5446 /* The test is to see that the memcached_quit doesn't increase the
5447 * the server failure conter, so let's ensure that it is zero
5448 * before sending quit
5449 */
5450 ((memcached_server_write_instance_st)instance)->server_failure_counter= 0;
5451
5452 memcached_quit(memc);
5453
5454 /* Verify that it memcached_quit didn't increment the failure counter
5455 * Please note that this isn't bullet proof, because an error could
5456 * occur...
5457 */
5458 test_true(instance->server_failure_counter == 0);
5459
5460 /* restore the instance */
5461 memc->number_of_hosts= number_of_hosts;
5462
5463 return TEST_SUCCESS;
5464 }
5465
5466
5467
5468
5469 /*
5470 * Test that ensures mget_execute does not end into recursive calls that finally fails
5471 */
5472 static test_return_t regression_bug_490486(memcached_st *memc)
5473 {
5474 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
5475 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 1);
5476 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, 1000);
5477 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, 1);
5478 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 3600);
5479
5480 /*
5481 * I only want to hit _one_ server so I know the number of requests I'm
5482 * sending in the pipeline.
5483 */
5484 uint32_t number_of_hosts= memc->number_of_hosts;
5485 memc->number_of_hosts= 1;
5486 size_t max_keys= 20480;
5487
5488
5489 char **keys= calloc(max_keys, sizeof(char*));
5490 size_t *key_length=calloc(max_keys, sizeof(size_t));
5491
5492 /* First add all of the items.. */
5493 char blob[1024]= { 0 };
5494 memcached_return rc;
5495 for (size_t x= 0; x < max_keys; ++x)
5496 {
5497 char k[251];
5498 key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%zu", x);
5499 keys[x]= strdup(k);
5500 assert(keys[x] != NULL);
5501 rc= memcached_set(memc, keys[x], key_length[x], blob, sizeof(blob), 0, 0);
5502 assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5503 }
5504
5505 /* Try to get all of them with a large multiget */
5506 size_t counter= 0;
5507 memcached_execute_function callbacks[1]= { [0]= &callback_counter };
5508 rc= memcached_mget_execute(memc, (const char**)keys, key_length,
5509 (size_t)max_keys, callbacks, &counter, 1);
5510
5511 assert(rc == MEMCACHED_SUCCESS);
5512 char* the_value= NULL;
5513 char the_key[MEMCACHED_MAX_KEY];
5514 size_t the_key_length;
5515 size_t the_value_length;
5516 uint32_t the_flags;
5517
5518 do {
5519 the_value= memcached_fetch(memc, the_key, &the_key_length, &the_value_length, &the_flags, &rc);
5520
5521 if ((the_value!= NULL) && (rc == MEMCACHED_SUCCESS))
5522 {
5523 ++counter;
5524 free(the_value);
5525 }
5526
5527 } while ( (the_value!= NULL) && (rc == MEMCACHED_SUCCESS));
5528
5529
5530 assert(rc == MEMCACHED_END);
5531
5532 /* Verify that we got all of the items */
5533 assert(counter == max_keys);
5534
5535 /* Release all allocated resources */
5536 for (size_t x= 0; x < max_keys; ++x)
5537 {
5538 free(keys[x]);
5539 }
5540 free(keys);
5541 free(key_length);
5542
5543 memc->number_of_hosts= number_of_hosts;
5544
5545 return TEST_SUCCESS;
5546 }
5547
5548 /*
5549 * Test that the sasl authentication works. We cannot use the default
5550 * pool of servers, because that would require that all servers we want
5551 * to test supports SASL authentication, and that they use the default
5552 * creds.
5553 */
5554 static test_return_t sasl_auth_test(memcached_st *memc)
5555 {
5556 #ifdef LIBMEMCACHED_WITH_SASL_SUPPORT
5557 memcached_return_t rc;
5558
5559 rc= memcached_set(memc, "foo", 3, "bar", 3, (time_t)0, (uint32_t)0);
5560 test_true(rc == MEMCACHED_SUCCESS);
5561 test_true((rc= memcached_delete(memc, "foo", 3, 0)) == MEMCACHED_SUCCESS);
5562 test_true((rc= memcached_destroy_sasl_auth_data(memc)) == MEMCACHED_SUCCESS);
5563 test_true((rc= memcached_destroy_sasl_auth_data(memc)) == MEMCACHED_FAILURE);
5564 test_true((rc= memcached_destroy_sasl_auth_data(NULL)) == MEMCACHED_FAILURE);
5565 memcached_quit(memc);
5566
5567 rc= memcached_set_sasl_auth_data(memc,
5568 getenv("LIBMEMCACHED_TEST_SASL_USERNAME"),
5569 getenv("LIBMEMCACHED_TEST_SASL_SERVER"));
5570 test_true(rc == MEMCACHED_SUCCESS);
5571
5572 rc= memcached_set(memc, "foo", 3, "bar", 3, (time_t)0, (uint32_t)0);
5573 test_true(rc == MEMCACHED_AUTH_FAILURE);
5574 test_true(memcached_destroy_sasl_auth_data(memc) == MEMCACHED_SUCCESS);
5575
5576 memcached_quit(memc);
5577 return TEST_SUCCESS;
5578 #else
5579 (void)memc;
5580 return TEST_FAILURE;
5581 #endif
5582 }
5583
5584 /* Clean the server before beginning testing */
5585 test_st tests[] ={
5586 {"flush", 0, (test_callback_fn)flush_test },
5587 {"init", 0, (test_callback_fn)init_test },
5588 {"allocation", 0, (test_callback_fn)allocation_test },
5589 {"server_list_null_test", 0, (test_callback_fn)server_list_null_test},
5590 {"server_unsort", 0, (test_callback_fn)server_unsort_test},
5591 {"server_sort", 0, (test_callback_fn)server_sort_test},
5592 {"server_sort2", 0, (test_callback_fn)server_sort2_test},
5593 {"memcached_server_remove", 0, (test_callback_fn)memcached_server_remove_test},
5594 {"clone_test", 0, (test_callback_fn)clone_test },
5595 {"connection_test", 0, (test_callback_fn)connection_test},
5596 {"callback_test", 0, (test_callback_fn)callback_test},
5597 {"userdata_test", 0, (test_callback_fn)userdata_test},
5598 {"error", 0, (test_callback_fn)error_test },
5599 {"set", 0, (test_callback_fn)set_test },
5600 {"set2", 0, (test_callback_fn)set_test2 },
5601 {"set3", 0, (test_callback_fn)set_test3 },
5602 {"dump", 1, (test_callback_fn)dump_test},
5603 {"add", 1, (test_callback_fn)add_test },
5604 {"replace", 1, (test_callback_fn)replace_test },
5605 {"delete", 1, (test_callback_fn)delete_test },
5606 {"get", 1, (test_callback_fn)get_test },
5607 {"get2", 0, (test_callback_fn)get_test2 },
5608 {"get3", 0, (test_callback_fn)get_test3 },
5609 {"get4", 0, (test_callback_fn)get_test4 },
5610 {"partial mget", 0, (test_callback_fn)get_test5 },
5611 {"stats_servername", 0, (test_callback_fn)stats_servername_test },
5612 {"increment", 0, (test_callback_fn)increment_test },
5613 {"increment_with_initial", 1, (test_callback_fn)increment_with_initial_test },
5614 {"decrement", 0, (test_callback_fn)decrement_test },
5615 {"decrement_with_initial", 1, (test_callback_fn)decrement_with_initial_test },
5616 {"increment_by_key", 0, (test_callback_fn)increment_by_key_test },
5617 {"increment_with_initial_by_key", 1, (test_callback_fn)increment_with_initial_by_key_test },
5618 {"decrement_by_key", 0, (test_callback_fn)decrement_by_key_test },
5619 {"decrement_with_initial_by_key", 1, (test_callback_fn)decrement_with_initial_by_key_test },
5620 {"quit", 0, (test_callback_fn)quit_test },
5621 {"mget", 1, (test_callback_fn)mget_test },
5622 {"mget_result", 1, (test_callback_fn)mget_result_test },
5623 {"mget_result_alloc", 1, (test_callback_fn)mget_result_alloc_test },
5624 {"mget_result_function", 1, (test_callback_fn)mget_result_function },
5625 {"mget_execute", 1, (test_callback_fn)mget_execute },
5626 {"mget_end", 0, (test_callback_fn)mget_end },
5627 {"get_stats", 0, (test_callback_fn)get_stats },
5628 {"add_host_test", 0, (test_callback_fn)add_host_test },
5629 {"add_host_test_1", 0, (test_callback_fn)add_host_test1 },
5630 {"get_stats_keys", 0, (test_callback_fn)get_stats_keys },
5631 {"version_string_test", 0, (test_callback_fn)version_string_test},
5632 {"bad_key", 1, (test_callback_fn)bad_key_test },
5633 {"memcached_server_cursor", 1, (test_callback_fn)memcached_server_cursor_test },
5634 {"read_through", 1, (test_callback_fn)read_through },
5635 {"delete_through", 1, (test_callback_fn)delete_through },
5636 {"noreply", 1, (test_callback_fn)noreply_test},
5637 {"analyzer", 1, (test_callback_fn)analyzer_test},
5638 #ifdef HAVE_LIBMEMCACHEDUTIL
5639 {"connectionpool", 1, (test_callback_fn)connection_pool_test },
5640 #endif
5641 {"test_get_last_disconnect", 1, (test_callback_fn)test_get_last_disconnect},
5642 {"verbosity", 1, (test_callback_fn)test_verbosity},
5643 {0, 0, 0}
5644 };
5645
5646 test_st behavior_tests[] ={
5647 {"behavior_test", 0, (test_callback_fn)behavior_test},
5648 {"MEMCACHED_BEHAVIOR_CORK", 0, (test_callback_fn)MEMCACHED_BEHAVIOR_CORK_test},
5649 {0, 0, 0}
5650 };
5651
5652 test_st async_tests[] ={
5653 {"add", 1, (test_callback_fn)add_wrapper },
5654 {0, 0, 0}
5655 };
5656
5657 test_st string_tests[] ={
5658 {"string static with null", 0, (test_callback_fn)string_static_null },
5659 {"string alloc with null", 0, (test_callback_fn)string_alloc_null },
5660 {"string alloc with 1K", 0, (test_callback_fn)string_alloc_with_size },
5661 {"string alloc with malloc failure", 0, (test_callback_fn)string_alloc_with_size_toobig },
5662 {"string append", 0, (test_callback_fn)string_alloc_append },
5663 {"string append failure (too big)", 0, (test_callback_fn)string_alloc_append_toobig },
5664 {0, 0, (test_callback_fn)0}
5665 };
5666
5667 test_st result_tests[] ={
5668 {"result static", 0, (test_callback_fn)result_static},
5669 {"result alloc", 0, (test_callback_fn)result_alloc},
5670 {0, 0, (test_callback_fn)0}
5671 };
5672
5673 test_st version_1_2_3[] ={
5674 {"append", 0, (test_callback_fn)append_test },
5675 {"prepend", 0, (test_callback_fn)prepend_test },
5676 {"cas", 0, (test_callback_fn)cas_test },
5677 {"cas2", 0, (test_callback_fn)cas2_test },
5678 {"append_binary", 0, (test_callback_fn)append_binary_test },
5679 {0, 0, (test_callback_fn)0}
5680 };
5681
5682 test_st user_tests[] ={
5683 {"user_supplied_bug1", 0, (test_callback_fn)user_supplied_bug1 },
5684 {"user_supplied_bug2", 0, (test_callback_fn)user_supplied_bug2 },
5685 {"user_supplied_bug3", 0, (test_callback_fn)user_supplied_bug3 },
5686 {"user_supplied_bug4", 0, (test_callback_fn)user_supplied_bug4 },
5687 {"user_supplied_bug5", 1, (test_callback_fn)user_supplied_bug5 },
5688 {"user_supplied_bug6", 1, (test_callback_fn)user_supplied_bug6 },
5689 {"user_supplied_bug7", 1, (test_callback_fn)user_supplied_bug7 },
5690 {"user_supplied_bug8", 1, (test_callback_fn)user_supplied_bug8 },
5691 {"user_supplied_bug9", 1, (test_callback_fn)user_supplied_bug9 },
5692 {"user_supplied_bug10", 1, (test_callback_fn)user_supplied_bug10 },
5693 {"user_supplied_bug11", 1, (test_callback_fn)user_supplied_bug11 },
5694 {"user_supplied_bug12", 1, (test_callback_fn)user_supplied_bug12 },
5695 {"user_supplied_bug13", 1, (test_callback_fn)user_supplied_bug13 },
5696 {"user_supplied_bug14", 1, (test_callback_fn)user_supplied_bug14 },
5697 {"user_supplied_bug15", 1, (test_callback_fn)user_supplied_bug15 },
5698 {"user_supplied_bug16", 1, (test_callback_fn)user_supplied_bug16 },
5699 #ifndef __sun
5700 /*
5701 ** It seems to be something weird with the character sets..
5702 ** value_fetch is unable to parse the value line (iscntrl "fails"), so I
5703 ** guess I need to find out how this is supposed to work.. Perhaps I need
5704 ** to run the test in a specific locale (I tried zh_CN.UTF-8 without success,
5705 ** so just disable the code for now...).
5706 */
5707 {"user_supplied_bug17", 1, (test_callback_fn)user_supplied_bug17 },
5708 #endif
5709 {"user_supplied_bug18", 1, (test_callback_fn)user_supplied_bug18 },
5710 {"user_supplied_bug19", 1, (test_callback_fn)user_supplied_bug19 },
5711 {"user_supplied_bug20", 1, (test_callback_fn)user_supplied_bug20 },
5712 {"user_supplied_bug21", 1, (test_callback_fn)user_supplied_bug21 },
5713 {"wrong_failure_counter_test", 1, (test_callback_fn)wrong_failure_counter_test},
5714 {0, 0, (test_callback_fn)0}
5715 };
5716
5717 test_st replication_tests[]= {
5718 {"set", 1, (test_callback_fn)replication_set_test },
5719 {"get", 0, (test_callback_fn)replication_get_test },
5720 {"mget", 0, (test_callback_fn)replication_mget_test },
5721 {"delete", 0, (test_callback_fn)replication_delete_test },
5722 {"rand_mget", 0, (test_callback_fn)replication_randomize_mget_test },
5723 {0, 0, (test_callback_fn)0}
5724 };
5725
5726 /*
5727 * The following test suite is used to verify that we don't introduce
5728 * regression bugs. If you want more information about the bug / test,
5729 * you should look in the bug report at
5730 * http://bugs.launchpad.net/libmemcached
5731 */
5732 test_st regression_tests[]= {
5733 {"lp:434484", 1, (test_callback_fn)regression_bug_434484 },
5734 {"lp:434843", 1, (test_callback_fn)regression_bug_434843 },
5735 {"lp:434843 buffered", 1, (test_callback_fn)regression_bug_434843_buffered },
5736 {"lp:421108", 1, (test_callback_fn)regression_bug_421108 },
5737 {"lp:442914", 1, (test_callback_fn)regression_bug_442914 },
5738 {"lp:447342", 1, (test_callback_fn)regression_bug_447342 },
5739 {"lp:463297", 1, (test_callback_fn)regression_bug_463297 },
5740 {"lp:490486", 1, (test_callback_fn)regression_bug_490486 },
5741 {0, 0, (test_callback_fn)0}
5742 };
5743
5744 test_st sasl_auth_tests[]= {
5745 {"sasl_auth", 1, (test_callback_fn)sasl_auth_test },
5746 {0, 0, (test_callback_fn)0}
5747 };
5748
5749 test_st ketama_compatibility[]= {
5750 {"libmemcached", 1, (test_callback_fn)ketama_compatibility_libmemcached },
5751 {"spymemcached", 1, (test_callback_fn)ketama_compatibility_spymemcached },
5752 {0, 0, (test_callback_fn)0}
5753 };
5754
5755 test_st generate_tests[] ={
5756 {"generate_pairs", 1, (test_callback_fn)generate_pairs },
5757 {"generate_data", 1, (test_callback_fn)generate_data },
5758 {"get_read", 0, (test_callback_fn)get_read },
5759 {"delete_generate", 0, (test_callback_fn)delete_generate },
5760 {"generate_buffer_data", 1, (test_callback_fn)generate_buffer_data },
5761 {"delete_buffer", 0, (test_callback_fn)delete_buffer_generate},
5762 {"generate_data", 1, (test_callback_fn)generate_data },
5763 {"mget_read", 0, (test_callback_fn)mget_read },
5764 {"mget_read_result", 0, (test_callback_fn)mget_read_result },
5765 {"mget_read_function", 0, (test_callback_fn)mget_read_function },
5766 {"cleanup", 1, (test_callback_fn)cleanup_pairs },
5767 {"generate_large_pairs", 1, (test_callback_fn)generate_large_pairs },
5768 {"generate_data", 1, (test_callback_fn)generate_data },
5769 {"generate_buffer_data", 1, (test_callback_fn)generate_buffer_data },
5770 {"cleanup", 1, (test_callback_fn)cleanup_pairs },
5771 {0, 0, (test_callback_fn)0}
5772 };
5773
5774 test_st consistent_tests[] ={
5775 {"generate_pairs", 1, (test_callback_fn)generate_pairs },
5776 {"generate_data", 1, (test_callback_fn)generate_data },
5777 {"get_read", 0, (test_callback_fn)get_read_count },
5778 {"cleanup", 1, (test_callback_fn)cleanup_pairs },
5779 {0, 0, (test_callback_fn)0}
5780 };
5781
5782 test_st consistent_weighted_tests[] ={
5783 {"generate_pairs", 1, (test_callback_fn)generate_pairs },
5784 {"generate_data", 1, (test_callback_fn)generate_data_with_stats },
5785 {"get_read", 0, (test_callback_fn)get_read_count },
5786 {"cleanup", 1, (test_callback_fn)cleanup_pairs },
5787 {0, 0, (test_callback_fn)0}
5788 };
5789
5790 test_st hsieh_availability[] ={
5791 {"hsieh_avaibility_test", 0, (test_callback_fn)hsieh_avaibility_test},
5792 {0, 0, (test_callback_fn)0}
5793 };
5794
5795 #if 0
5796 test_st hash_sanity[] ={
5797 {"hash sanity", 0, (test_callback_fn)hash_sanity_test},
5798 {0, 0, (test_callback_fn)0}
5799 };
5800 #endif
5801
5802 test_st ketama_auto_eject_hosts[] ={
5803 {"auto_eject_hosts", 1, (test_callback_fn)auto_eject_hosts },
5804 {"output_ketama_weighted_keys", 1, (test_callback_fn)output_ketama_weighted_keys },
5805 {0, 0, (test_callback_fn)0}
5806 };
5807
5808 test_st hash_tests[] ={
5809 {"one_at_a_time_run", 0, (test_callback_fn)one_at_a_time_run },
5810 {"md5", 0, (test_callback_fn)md5_run },
5811 {"crc", 0, (test_callback_fn)crc_run },
5812 {"fnv1_64", 0, (test_callback_fn)fnv1_64_run },
5813 {"fnv1a_64", 0, (test_callback_fn)fnv1a_64_run },
5814 {"fnv1_32", 0, (test_callback_fn)fnv1_32_run },
5815 {"fnv1a_32", 0, (test_callback_fn)fnv1a_32_run },
5816 {"hsieh", 0, (test_callback_fn)hsieh_run },
5817 {"murmur", 0, (test_callback_fn)murmur_run },
5818 {"jenkis", 0, (test_callback_fn)jenkins_run },
5819 {"memcached_get_hashkit", 0, (test_callback_fn)memcached_get_hashkit_test },
5820 {0, 0, (test_callback_fn)0}
5821 };
5822
5823 collection_st collection[] ={
5824 #if 0
5825 {"hash_sanity", 0, 0, hash_sanity},
5826 #endif
5827 {"hsieh_availability", 0, 0, hsieh_availability},
5828 {"block", 0, 0, tests},
5829 {"binary", (test_callback_fn)pre_binary, 0, tests},
5830 {"nonblock", (test_callback_fn)pre_nonblock, 0, tests},
5831 {"nodelay", (test_callback_fn)pre_nodelay, 0, tests},
5832 {"settimer", (test_callback_fn)pre_settimer, 0, tests},
5833 {"md5", (test_callback_fn)pre_md5, 0, tests},
5834 {"crc", (test_callback_fn)pre_crc, 0, tests},
5835 {"hsieh", (test_callback_fn)pre_hsieh, 0, tests},
5836 {"jenkins", (test_callback_fn)pre_jenkins, 0, tests},
5837 {"fnv1_64", (test_callback_fn)pre_hash_fnv1_64, 0, tests},
5838 {"fnv1a_64", (test_callback_fn)pre_hash_fnv1a_64, 0, tests},
5839 {"fnv1_32", (test_callback_fn)pre_hash_fnv1_32, 0, tests},
5840 {"fnv1a_32", (test_callback_fn)pre_hash_fnv1a_32, 0, tests},
5841 {"ketama", (test_callback_fn)pre_behavior_ketama, 0, tests},
5842 {"ketama_auto_eject_hosts", (test_callback_fn)pre_behavior_ketama, 0, ketama_auto_eject_hosts},
5843 {"unix_socket", (test_callback_fn)pre_unix_socket, 0, tests},
5844 {"unix_socket_nodelay", (test_callback_fn)pre_nodelay, 0, tests},
5845 {"poll_timeout", (test_callback_fn)poll_timeout, 0, tests},
5846 {"gets", (test_callback_fn)enable_cas, 0, tests},
5847 {"consistent_crc", (test_callback_fn)enable_consistent_crc, 0, tests},
5848 {"consistent_hsieh", (test_callback_fn)enable_consistent_hsieh, 0, tests},
5849 #ifdef MEMCACHED_ENABLE_DEPRECATED
5850 {"deprecated_memory_allocators", (test_callback_fn)deprecated_set_memory_alloc, 0, tests},
5851 #endif
5852 {"memory_allocators", (test_callback_fn)set_memory_alloc, 0, tests},
5853 {"prefix", (test_callback_fn)set_prefix, 0, tests},
5854 {"sasl_auth", (test_callback_fn)pre_sasl, 0, sasl_auth_tests },
5855 {"sasl", (test_callback_fn)pre_sasl, 0, tests },
5856 {"version_1_2_3", (test_callback_fn)check_for_1_2_3, 0, version_1_2_3},
5857 {"string", 0, 0, string_tests},
5858 {"result", 0, 0, result_tests},
5859 {"async", (test_callback_fn)pre_nonblock, 0, async_tests},
5860 {"async_binary", (test_callback_fn)pre_nonblock_binary, 0, async_tests},
5861 {"user", 0, 0, user_tests},
5862 {"generate", 0, 0, generate_tests},
5863 {"generate_hsieh", (test_callback_fn)pre_hsieh, 0, generate_tests},
5864 {"generate_ketama", (test_callback_fn)pre_behavior_ketama, 0, generate_tests},
5865 {"generate_hsieh_consistent", (test_callback_fn)enable_consistent_hsieh, 0, generate_tests},
5866 {"generate_md5", (test_callback_fn)pre_md5, 0, generate_tests},
5867 {"generate_murmur", (test_callback_fn)pre_murmur, 0, generate_tests},
5868 {"generate_jenkins", (test_callback_fn)pre_jenkins, 0, generate_tests},
5869 {"generate_nonblock", (test_callback_fn)pre_nonblock, 0, generate_tests},
5870 // Too slow
5871 {"generate_corked", (test_callback_fn)pre_cork, 0, generate_tests},
5872 {"generate_corked_and_nonblock", (test_callback_fn)pre_cork_and_nonblock, 0, generate_tests},
5873 {"consistent_not", 0, 0, consistent_tests},
5874 {"consistent_ketama", (test_callback_fn)pre_behavior_ketama, 0, consistent_tests},
5875 {"consistent_ketama_weighted", (test_callback_fn)pre_behavior_ketama_weighted, 0, consistent_weighted_tests},
5876 {"ketama_compat", 0, 0, ketama_compatibility},
5877 {"test_hashes", 0, 0, hash_tests},
5878 {"replication", (test_callback_fn)pre_replication, 0, replication_tests},
5879 {"replication_noblock", (test_callback_fn)pre_replication_noblock, 0, replication_tests},
5880 {"regression", 0, 0, regression_tests},
5881 {"behaviors", 0, 0, behavior_tests},
5882 {0, 0, 0, 0}
5883 };
5884
5885 #define SERVERS_TO_CREATE 5
5886
5887 #include "libmemcached_world.h"
5888
5889 void get_world(world_st *world)
5890 {
5891 world->collections= collection;
5892
5893 world->create= (test_callback_create_fn)world_create;
5894 world->destroy= (test_callback_fn)world_destroy;
5895
5896 world->test.startup= (test_callback_fn)world_test_startup;
5897 world->test.flush= (test_callback_fn)world_flush;
5898 world->test.pre_run= (test_callback_fn)world_pre_run;
5899 world->test.post_run= (test_callback_fn)world_post_run;
5900 world->test.on_error= (test_callback_error_fn)world_on_error;
5901
5902 world->collection.startup= (test_callback_fn)world_container_startup;
5903 world->collection.shutdown= (test_callback_fn)world_container_shutdown;
5904
5905 world->runner= &defualt_libmemcached_runner;
5906 }