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