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