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