Final bits of abstraction.
[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
3522 memc_clone= memcached_clone(NULL, memc);
3523 test_truth(memc_clone);
3524 // The memcached_version needs to be done on a clone, because the server
3525 // will not toggle protocol on an connection.
3526 memcached_version(memc_clone);
3527
3528 instance= memcached_server_instance_fetch(memc_clone, 0);
3529
3530 if (instance->major_version >= 1 && instance->minor_version > 2)
3531 {
3532 rc = memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
3533 test_truth(rc == MEMCACHED_SUCCESS);
3534 test_truth(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 1);
3535 }
3536
3537 memcached_free(memc_clone);
3538
3539 return rc == MEMCACHED_SUCCESS ? TEST_SUCCESS : TEST_SKIPPED;
3540 }
3541
3542
3543 static test_return_t pre_replication(memcached_st *memc)
3544 {
3545 test_return_t test_rc;
3546 test_rc= pre_binary(memc);
3547
3548 if (test_rc != TEST_SUCCESS)
3549 return test_rc;
3550
3551 /*
3552 * Make sure that we store the item on all servers
3553 * (master + replicas == number of servers)
3554 */
3555 memcached_return_t rc;
3556 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS,
3557 memcached_server_count(memc) - 1);
3558 test_truth(rc == MEMCACHED_SUCCESS);
3559 test_truth(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS) == memcached_server_count(memc) - 1);
3560
3561 return rc == MEMCACHED_SUCCESS ? TEST_SUCCESS : TEST_SKIPPED;
3562 }
3563
3564
3565 static test_return_t pre_replication_noblock(memcached_st *memc)
3566 {
3567 test_return_t rc;
3568
3569 rc= pre_replication(memc);
3570 if (rc != TEST_SUCCESS)
3571 return rc;
3572
3573 rc= pre_nonblock(memc);
3574
3575 return rc;
3576 }
3577
3578
3579 static void my_free(memcached_st *ptr __attribute__((unused)), void *mem)
3580 {
3581 #ifdef HARD_MALLOC_TESTS
3582 void *real_ptr= (mem == NULL) ? mem : (void*)((caddr_t)mem - 8);
3583 free(real_ptr);
3584 #else
3585 free(mem);
3586 #endif
3587 }
3588
3589
3590 static void *my_malloc(memcached_st *ptr __attribute__((unused)), const size_t size)
3591 {
3592 #ifdef HARD_MALLOC_TESTS
3593 void *ret= malloc(size + 8);
3594 if (ret != NULL)
3595 {
3596 ret= (void*)((caddr_t)ret + 8);
3597 }
3598 #else
3599 void *ret= malloc(size);
3600 #endif
3601
3602 if (ret != NULL)
3603 {
3604 memset(ret, 0xff, size);
3605 }
3606
3607 return ret;
3608 }
3609
3610
3611 static void *my_realloc(memcached_st *ptr __attribute__((unused)), void *mem, const size_t size)
3612 {
3613 #ifdef HARD_MALLOC_TESTS
3614 void *real_ptr= (mem == NULL) ? NULL : (void*)((caddr_t)mem - 8);
3615 void *nmem= realloc(real_ptr, size + 8);
3616
3617 void *ret= NULL;
3618 if (nmem != NULL)
3619 {
3620 ret= (void*)((caddr_t)nmem + 8);
3621 }
3622
3623 return ret;
3624 #else
3625 return realloc(mem, size);
3626 #endif
3627 }
3628
3629
3630 static void *my_calloc(memcached_st *ptr __attribute__((unused)), size_t nelem, const size_t size)
3631 {
3632 #ifdef HARD_MALLOC_TESTS
3633 void *mem= my_malloc(ptr, nelem * size);
3634 if (mem)
3635 {
3636 memset(mem, 0, nelem * size);
3637 }
3638
3639 return mem;
3640 #else
3641 return calloc(nelem, size);
3642 #endif
3643 }
3644
3645
3646 static test_return_t set_prefix(memcached_st *memc)
3647 {
3648 memcached_return_t rc;
3649 const char *key= "mine";
3650 char *value;
3651
3652 /* Make sure be default none exists */
3653 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3654 test_truth(rc == MEMCACHED_FAILURE);
3655
3656 /* Test a clean set */
3657 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, (void *)key);
3658 test_truth(rc == MEMCACHED_SUCCESS);
3659
3660 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3661 test_truth(memcmp(value, key, 4) == 0);
3662 test_truth(rc == MEMCACHED_SUCCESS);
3663
3664 /* Test that we can turn it off */
3665 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, NULL);
3666 test_truth(rc == MEMCACHED_SUCCESS);
3667
3668 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3669 test_truth(rc == MEMCACHED_FAILURE);
3670
3671 /* Now setup for main test */
3672 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, (void *)key);
3673 test_truth(rc == MEMCACHED_SUCCESS);
3674
3675 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3676 test_truth(rc == MEMCACHED_SUCCESS);
3677 test_truth(memcmp(value, key, 4) == 0);
3678
3679 /* Set to Zero, and then Set to something too large */
3680 {
3681 char long_key[255];
3682 memset(long_key, 0, 255);
3683
3684 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, NULL);
3685 test_truth(rc == MEMCACHED_SUCCESS);
3686
3687 value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc);
3688 test_truth(rc == MEMCACHED_FAILURE);
3689 test_truth(value == NULL);
3690
3691 /* Test a long key for failure */
3692 /* TODO, extend test to determine based on setting, what result should be */
3693 strcpy(long_key, "Thisismorethentheallottednumberofcharacters");
3694 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, long_key);
3695 //test_truth(rc == MEMCACHED_BAD_KEY_PROVIDED);
3696 test_truth(rc == MEMCACHED_SUCCESS);
3697
3698 /* Now test a key with spaces (which will fail from long key, since bad key is not set) */
3699 strcpy(long_key, "This is more then the allotted number of characters");
3700 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, long_key);
3701 test_truth(rc == MEMCACHED_BAD_KEY_PROVIDED);
3702
3703 /* Test for a bad prefix, but with a short key */
3704 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_VERIFY_KEY, 1);
3705 test_truth(rc == MEMCACHED_SUCCESS);
3706
3707 strcpy(long_key, "dog cat");
3708 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, long_key);
3709 test_truth(rc == MEMCACHED_BAD_KEY_PROVIDED);
3710 }
3711
3712 return TEST_SUCCESS;
3713 }
3714
3715
3716 #ifdef MEMCACHED_ENABLE_DEPRECATED
3717 static test_return_t deprecated_set_memory_alloc(memcached_st *memc)
3718 {
3719 void *test_ptr= NULL;
3720 void *cb_ptr= NULL;
3721 {
3722 memcached_malloc_fn malloc_cb=
3723 (memcached_malloc_fn)my_malloc;
3724 cb_ptr= *(void **)&malloc_cb;
3725 memcached_return_t rc;
3726
3727 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_MALLOC_FUNCTION, cb_ptr);
3728 test_truth(rc == MEMCACHED_SUCCESS);
3729 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_MALLOC_FUNCTION, &rc);
3730 test_truth(rc == MEMCACHED_SUCCESS);
3731 test_truth(test_ptr == cb_ptr);
3732 }
3733
3734 {
3735 memcached_realloc_fn realloc_cb=
3736 (memcached_realloc_fn)my_realloc;
3737 cb_ptr= *(void **)&realloc_cb;
3738 memcached_return_t rc;
3739
3740 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_REALLOC_FUNCTION, cb_ptr);
3741 test_truth(rc == MEMCACHED_SUCCESS);
3742 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_REALLOC_FUNCTION, &rc);
3743 test_truth(rc == MEMCACHED_SUCCESS);
3744 test_truth(test_ptr == cb_ptr);
3745 }
3746
3747 {
3748 memcached_free_fn free_cb=
3749 (memcached_free_fn)my_free;
3750 cb_ptr= *(void **)&free_cb;
3751 memcached_return_t rc;
3752
3753 rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_FREE_FUNCTION, cb_ptr);
3754 test_truth(rc == MEMCACHED_SUCCESS);
3755 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_FREE_FUNCTION, &rc);
3756 test_truth(rc == MEMCACHED_SUCCESS);
3757 test_truth(test_ptr == cb_ptr);
3758 }
3759
3760 return TEST_SUCCESS;
3761 }
3762 #endif
3763
3764
3765 static test_return_t set_memory_alloc(memcached_st *memc)
3766 {
3767 memcached_return_t rc;
3768 rc= memcached_set_memory_allocators(memc, NULL, my_free,
3769 my_realloc, my_calloc);
3770 test_truth(rc == MEMCACHED_FAILURE);
3771
3772 rc= memcached_set_memory_allocators(memc, my_malloc, my_free,
3773 my_realloc, my_calloc);
3774
3775 memcached_malloc_fn mem_malloc;
3776 memcached_free_fn mem_free;
3777 memcached_realloc_fn mem_realloc;
3778 memcached_calloc_fn mem_calloc;
3779 memcached_get_memory_allocators(memc, &mem_malloc, &mem_free,
3780 &mem_realloc, &mem_calloc);
3781
3782 test_truth(mem_malloc == my_malloc);
3783 test_truth(mem_realloc == my_realloc);
3784 test_truth(mem_calloc == my_calloc);
3785 test_truth(mem_free == my_free);
3786
3787 return TEST_SUCCESS;
3788 }
3789
3790 static test_return_t enable_consistent_crc(memcached_st *memc)
3791 {
3792 test_return_t rc;
3793 memcached_server_distribution_t value= MEMCACHED_DISTRIBUTION_CONSISTENT;
3794 memcached_hash_t hash;
3795 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, value);
3796 if ((rc= pre_crc(memc)) != TEST_SUCCESS)
3797 return rc;
3798
3799 value= (memcached_server_distribution_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION);
3800 test_truth(value == MEMCACHED_DISTRIBUTION_CONSISTENT);
3801
3802 hash= (memcached_hash_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
3803
3804 if (hash != MEMCACHED_HASH_CRC)
3805 return TEST_SKIPPED;
3806
3807 return TEST_SUCCESS;
3808 }
3809
3810 static test_return_t enable_consistent_hsieh(memcached_st *memc)
3811 {
3812 test_return_t rc;
3813 memcached_server_distribution_t value= MEMCACHED_DISTRIBUTION_CONSISTENT;
3814 memcached_hash_t hash;
3815 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, value);
3816 if ((rc= pre_hsieh(memc)) != TEST_SUCCESS)
3817 return rc;
3818
3819 value= (memcached_server_distribution_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION);
3820 test_truth(value == MEMCACHED_DISTRIBUTION_CONSISTENT);
3821
3822 hash= (memcached_hash_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
3823
3824 if (hash != MEMCACHED_HASH_HSIEH)
3825 return TEST_SKIPPED;
3826
3827
3828 return TEST_SUCCESS;
3829 }
3830
3831 static test_return_t enable_cas(memcached_st *memc)
3832 {
3833 unsigned int set= 1;
3834
3835 memcached_server_instance_st *instance=
3836 memcached_server_instance_fetch(memc, 0);
3837
3838 memcached_version(memc);
3839
3840 if ((instance->major_version >= 1 && (instance->minor_version == 2 && instance->micro_version >= 4))
3841 || instance->minor_version > 2)
3842 {
3843 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, set);
3844
3845 return TEST_SUCCESS;
3846 }
3847
3848 return TEST_SKIPPED;
3849 }
3850
3851 static test_return_t check_for_1_2_3(memcached_st *memc)
3852 {
3853 memcached_version(memc);
3854 memcached_server_instance_st *instance=
3855 memcached_server_instance_fetch(memc, 0);
3856
3857 if ((instance->major_version >= 1 && (instance->minor_version == 2 && instance->micro_version >= 4))
3858 || instance->minor_version > 2)
3859 return TEST_SUCCESS;
3860
3861 return TEST_SKIPPED;
3862 }
3863
3864 static test_return_t pre_unix_socket(memcached_st *memc)
3865 {
3866 memcached_return_t rc;
3867 struct stat buf;
3868
3869 memcached_servers_reset(memc);
3870
3871 if (stat("/tmp/memcached.socket", &buf))
3872 return TEST_SKIPPED;
3873
3874 rc= memcached_server_add_unix_socket_with_weight(memc, "/tmp/memcached.socket", 0);
3875
3876 return ( rc == MEMCACHED_SUCCESS ? TEST_SUCCESS : TEST_FAILURE );
3877 }
3878
3879 static test_return_t pre_nodelay(memcached_st *memc)
3880 {
3881 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
3882 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 0);
3883
3884 return TEST_SUCCESS;
3885 }
3886
3887 static test_return_t pre_settimer(memcached_st *memc)
3888 {
3889 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SND_TIMEOUT, 1000);
3890 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RCV_TIMEOUT, 1000);
3891
3892 return TEST_SUCCESS;
3893 }
3894
3895 static test_return_t poll_timeout(memcached_st *memc)
3896 {
3897 size_t timeout;
3898
3899 timeout= 100;
3900
3901 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, timeout);
3902
3903 timeout= (size_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT);
3904
3905 test_truth(timeout == 100);
3906
3907 return TEST_SUCCESS;
3908 }
3909
3910 static test_return_t noreply_test(memcached_st *memc)
3911 {
3912 memcached_return_t ret;
3913 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1);
3914 test_truth(ret == MEMCACHED_SUCCESS);
3915 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
3916 test_truth(ret == MEMCACHED_SUCCESS);
3917 ret= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, 1);
3918 test_truth(ret == MEMCACHED_SUCCESS);
3919 test_truth(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NOREPLY) == 1);
3920 test_truth(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS) == 1);
3921 test_truth(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS) == 1);
3922
3923 for (int count=0; count < 5; ++count)
3924 {
3925 for (int x=0; x < 100; ++x)
3926 {
3927 char key[10];
3928 size_t len= (size_t)sprintf(key, "%d", x);
3929 switch (count)
3930 {
3931 case 0:
3932 ret= memcached_add(memc, key, len, key, len, 0, 0);
3933 break;
3934 case 1:
3935 ret= memcached_replace(memc, key, len, key, len, 0, 0);
3936 break;
3937 case 2:
3938 ret= memcached_set(memc, key, len, key, len, 0, 0);
3939 break;
3940 case 3:
3941 ret= memcached_append(memc, key, len, key, len, 0, 0);
3942 break;
3943 case 4:
3944 ret= memcached_prepend(memc, key, len, key, len, 0, 0);
3945 break;
3946 default:
3947 test_truth(count);
3948 break;
3949 }
3950 test_truth(ret == MEMCACHED_SUCCESS || ret == MEMCACHED_BUFFERED);
3951 }
3952
3953 /*
3954 ** NOTE: Don't ever do this in your code! this is not a supported use of the
3955 ** API and is _ONLY_ done this way to verify that the library works the
3956 ** way it is supposed to do!!!!
3957 */
3958 int no_msg=0;
3959 for (uint32_t x=0; x < memcached_server_count(memc); ++x)
3960 {
3961 memcached_server_instance_st *instance=
3962 memcached_server_instance_fetch(memc, x);
3963 no_msg+=(int)(instance->cursor_active);
3964 }
3965
3966 test_truth(no_msg == 0);
3967 test_truth(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
3968
3969 /*
3970 ** Now validate that all items was set properly!
3971 */
3972 for (int x=0; x < 100; ++x)
3973 {
3974 char key[10];
3975 size_t len= (size_t)sprintf(key, "%d", x);
3976 size_t length;
3977 uint32_t flags;
3978 char* value=memcached_get(memc, key, strlen(key),
3979 &length, &flags, &ret);
3980 test_truth(ret == MEMCACHED_SUCCESS && value != NULL);
3981 switch (count)
3982 {
3983 case 0: /* FALLTHROUGH */
3984 case 1: /* FALLTHROUGH */
3985 case 2:
3986 test_truth(strncmp(value, key, len) == 0);
3987 test_truth(len == length);
3988 break;
3989 case 3:
3990 test_truth(length == len * 2);
3991 break;
3992 case 4:
3993 test_truth(length == len * 3);
3994 break;
3995 default:
3996 test_truth(count);
3997 break;
3998 }
3999 free(value);
4000 }
4001 }
4002
4003 /* Try setting an illegal cas value (should not return an error to
4004 * the caller (because we don't expect a return message from the server)
4005 */
4006 const char* keys[]= {"0"};
4007 size_t lengths[]= {1};
4008 size_t length;
4009 uint32_t flags;
4010 memcached_result_st results_obj;
4011 memcached_result_st *results;
4012 ret= memcached_mget(memc, keys, lengths, 1);
4013 test_truth(ret == MEMCACHED_SUCCESS);
4014
4015 results= memcached_result_create(memc, &results_obj);
4016 test_truth(results);
4017 results= memcached_fetch_result(memc, &results_obj, &ret);
4018 test_truth(results);
4019 test_truth(ret == MEMCACHED_SUCCESS);
4020 uint64_t cas= memcached_result_cas(results);
4021 memcached_result_free(&results_obj);
4022
4023 ret= memcached_cas(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0, cas);
4024 test_truth(ret == MEMCACHED_SUCCESS);
4025
4026 /*
4027 * The item will have a new cas value, so try to set it again with the old
4028 * value. This should fail!
4029 */
4030 ret= memcached_cas(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0, cas);
4031 test_truth(ret == MEMCACHED_SUCCESS);
4032 test_truth(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
4033 char* value=memcached_get(memc, keys[0], lengths[0], &length, &flags, &ret);
4034 test_truth(ret == MEMCACHED_SUCCESS && value != NULL);
4035 free(value);
4036
4037 return TEST_SUCCESS;
4038 }
4039
4040 static test_return_t analyzer_test(memcached_st *memc)
4041 {
4042 memcached_return_t rc;
4043 memcached_stat_st *memc_stat;
4044 memcached_analysis_st *report;
4045
4046 memc_stat= memcached_stat(memc, NULL, &rc);
4047 test_truth(rc == MEMCACHED_SUCCESS);
4048 test_truth(memc_stat);
4049
4050 report= memcached_analyze(memc, memc_stat, &rc);
4051 test_truth(rc == MEMCACHED_SUCCESS);
4052 test_truth(report);
4053
4054 free(report);
4055 memcached_stat_free(NULL, memc_stat);
4056
4057 return TEST_SUCCESS;
4058 }
4059
4060 /* Count the objects */
4061 static memcached_return_t callback_dump_counter(memcached_st *ptr __attribute__((unused)),
4062 const char *key __attribute__((unused)),
4063 size_t key_length __attribute__((unused)),
4064 void *context)
4065 {
4066 uint32_t *counter= (uint32_t *)context;
4067
4068 *counter= *counter + 1;
4069
4070 return MEMCACHED_SUCCESS;
4071 }
4072
4073 static test_return_t dump_test(memcached_st *memc)
4074 {
4075 memcached_return_t rc;
4076 uint32_t counter= 0;
4077 memcached_dump_fn callbacks[1];
4078 test_return_t main_rc;
4079
4080 callbacks[0]= &callback_dump_counter;
4081
4082 /* No support for Binary protocol yet */
4083 if (memc->flags.binary_protocol)
4084 return TEST_SUCCESS;
4085
4086 main_rc= set_test3(memc);
4087
4088 test_truth (main_rc == TEST_SUCCESS);
4089
4090 rc= memcached_dump(memc, callbacks, (void *)&counter, 1);
4091 test_truth(rc == MEMCACHED_SUCCESS);
4092
4093 /* We may have more then 32 if our previous flush has not completed */
4094 test_truth(counter >= 32);
4095
4096 return TEST_SUCCESS;
4097 }
4098
4099 #ifdef HAVE_LIBMEMCACHEDUTIL
4100 static void* connection_release(void *arg)
4101 {
4102 struct {
4103 memcached_pool_st* pool;
4104 memcached_st* mmc;
4105 } *resource= arg;
4106
4107 usleep(250);
4108 assert(memcached_pool_push(resource->pool, resource->mmc) == MEMCACHED_SUCCESS);
4109 return arg;
4110 }
4111
4112 static test_return_t connection_pool_test(memcached_st *memc)
4113 {
4114 memcached_pool_st* pool= memcached_pool_create(memc, 5, 10);
4115 test_truth(pool != NULL);
4116 memcached_st* mmc[10];
4117 memcached_return_t rc;
4118
4119 for (int x= 0; x < 10; ++x) {
4120 mmc[x]= memcached_pool_pop(pool, false, &rc);
4121 test_truth(mmc[x] != NULL);
4122 test_truth(rc == MEMCACHED_SUCCESS);
4123 }
4124
4125 test_truth(memcached_pool_pop(pool, false, &rc) == NULL);
4126 test_truth(rc == MEMCACHED_SUCCESS);
4127
4128 pthread_t tid;
4129 struct {
4130 memcached_pool_st* pool;
4131 memcached_st* mmc;
4132 } item= { .pool = pool, .mmc = mmc[9] };
4133 pthread_create(&tid, NULL, connection_release, &item);
4134 mmc[9]= memcached_pool_pop(pool, true, &rc);
4135 test_truth(rc == MEMCACHED_SUCCESS);
4136 pthread_join(tid, NULL);
4137 test_truth(mmc[9] == item.mmc);
4138 const char *key= "key";
4139 size_t keylen= strlen(key);
4140
4141 // verify that I can do ops with all connections
4142 rc= memcached_set(mmc[0], key, keylen, "0", 1, 0, 0);
4143 test_truth(rc == MEMCACHED_SUCCESS);
4144
4145 for (unsigned int x= 0; x < 10; ++x) {
4146 uint64_t number_value;
4147 rc= memcached_increment(mmc[x], key, keylen, 1, &number_value);
4148 test_truth(rc == MEMCACHED_SUCCESS);
4149 test_truth(number_value == (x+1));
4150 }
4151
4152 // Release them..
4153 for (int x= 0; x < 10; ++x)
4154 test_truth(memcached_pool_push(pool, mmc[x]) == MEMCACHED_SUCCESS);
4155
4156
4157 /* verify that I can set behaviors on the pool when I don't have all
4158 * of the connections in the pool. It should however be enabled
4159 * when I push the item into the pool
4160 */
4161 mmc[0]= memcached_pool_pop(pool, false, &rc);
4162 test_truth(mmc[0] != NULL);
4163
4164 rc= memcached_pool_behavior_set(pool, MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK, 9999);
4165 test_truth(rc == MEMCACHED_SUCCESS);
4166
4167 mmc[1]= memcached_pool_pop(pool, false, &rc);
4168 test_truth(mmc[1] != NULL);
4169
4170 test_truth(memcached_behavior_get(mmc[1], MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK) == 9999);
4171 test_truth(memcached_pool_push(pool, mmc[1]) == MEMCACHED_SUCCESS);
4172 test_truth(memcached_pool_push(pool, mmc[0]) == MEMCACHED_SUCCESS);
4173
4174 mmc[0]= memcached_pool_pop(pool, false, &rc);
4175 test_truth(memcached_behavior_get(mmc[0], MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK) == 9999);
4176 test_truth(memcached_pool_push(pool, mmc[0]) == MEMCACHED_SUCCESS);
4177
4178
4179 test_truth(memcached_pool_destroy(pool) == memc);
4180 return TEST_SUCCESS;
4181 }
4182 #endif
4183
4184 static test_return_t replication_set_test(memcached_st *memc)
4185 {
4186 memcached_return_t rc;
4187 memcached_st *memc_clone= memcached_clone(NULL, memc);
4188 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 0);
4189
4190 rc= memcached_set(memc, "bubba", 5, "0", 1, 0, 0);
4191 test_truth(rc == MEMCACHED_SUCCESS);
4192
4193 /*
4194 ** We are using the quiet commands to store the replicas, so we need
4195 ** to ensure that all of them are processed before we can continue.
4196 ** In the test we go directly from storing the object to trying to
4197 ** receive the object from all of the different servers, so we
4198 ** could end up in a race condition (the memcached server hasn't yet
4199 ** processed the quiet command from the replication set when it process
4200 ** the request from the other client (created by the clone)). As a
4201 ** workaround for that we call memcached_quit to send the quit command
4202 ** to the server and wait for the response ;-) If you use the test code
4203 ** as an example for your own code, please note that you shouldn't need
4204 ** to do this ;-)
4205 */
4206 memcached_quit(memc);
4207
4208 /*
4209 ** "bubba" should now be stored on all of our servers. We don't have an
4210 ** easy to use API to address each individual server, so I'll just iterate
4211 ** through a bunch of "master keys" and I should most likely hit all of the
4212 ** servers...
4213 */
4214 for (int x= 'a'; x <= 'z'; ++x)
4215 {
4216 char key[2]= { [0]= (char)x };
4217 size_t len;
4218 uint32_t flags;
4219 char *val= memcached_get_by_key(memc_clone, key, 1, "bubba", 5,
4220 &len, &flags, &rc);
4221 test_truth(rc == MEMCACHED_SUCCESS);
4222 test_truth(val != NULL);
4223 free(val);
4224 }
4225
4226 memcached_free(memc_clone);
4227
4228 return TEST_SUCCESS;
4229 }
4230
4231 static test_return_t replication_get_test(memcached_st *memc)
4232 {
4233 memcached_return_t rc;
4234
4235 /*
4236 * Don't do the following in your code. I am abusing the internal details
4237 * within the library, and this is not a supported interface.
4238 * This is to verify correct behavior in the library
4239 */
4240 for (uint32_t host= 0; host < memcached_server_count(memc); ++host)
4241 {
4242 memcached_st *memc_clone= memcached_clone(NULL, memc);
4243 memcached_server_instance_st *instance=
4244 memcached_server_instance_fetch(memc_clone, host);
4245
4246 instance->port= 0;
4247
4248 for (int x= 'a'; x <= 'z'; ++x)
4249 {
4250 char key[2]= { [0]= (char)x };
4251 size_t len;
4252 uint32_t flags;
4253 char *val= memcached_get_by_key(memc_clone, key, 1, "bubba", 5,
4254 &len, &flags, &rc);
4255 test_truth(rc == MEMCACHED_SUCCESS);
4256 test_truth(val != NULL);
4257 free(val);
4258 }
4259
4260 memcached_free(memc_clone);
4261 }
4262
4263 return TEST_SUCCESS;
4264 }
4265
4266 static test_return_t replication_mget_test(memcached_st *memc)
4267 {
4268 memcached_return_t rc;
4269 memcached_st *memc_clone= memcached_clone(NULL, memc);
4270 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 0);
4271
4272 const char *keys[]= { "bubba", "key1", "key2", "key3" };
4273 size_t len[]= { 5, 4, 4, 4 };
4274
4275 for (int x=0; x< 4; ++x)
4276 {
4277 rc= memcached_set(memc, keys[x], len[x], "0", 1, 0, 0);
4278 test_truth(rc == MEMCACHED_SUCCESS);
4279 }
4280
4281 /*
4282 ** We are using the quiet commands to store the replicas, so we need
4283 ** to ensure that all of them are processed before we can continue.
4284 ** In the test we go directly from storing the object to trying to
4285 ** receive the object from all of the different servers, so we
4286 ** could end up in a race condition (the memcached server hasn't yet
4287 ** processed the quiet command from the replication set when it process
4288 ** the request from the other client (created by the clone)). As a
4289 ** workaround for that we call memcached_quit to send the quit command
4290 ** to the server and wait for the response ;-) If you use the test code
4291 ** as an example for your own code, please note that you shouldn't need
4292 ** to do this ;-)
4293 */
4294 memcached_quit(memc);
4295
4296 /*
4297 * Don't do the following in your code. I am abusing the internal details
4298 * within the library, and this is not a supported interface.
4299 * This is to verify correct behavior in the library
4300 */
4301 memcached_result_st result_obj;
4302 for (uint32_t host= 0; host < memc_clone->number_of_hosts; host++)
4303 {
4304 memcached_st *new_clone= memcached_clone(NULL, memc);
4305 memcached_server_instance_st *instance=
4306 memcached_server_instance_fetch(new_clone, host);
4307 instance->port= 0;
4308
4309 for (int x= 'a'; x <= 'z'; ++x)
4310 {
4311 const char key[2]= { [0]= (const char)x };
4312
4313 rc= memcached_mget_by_key(new_clone, key, 1, keys, len, 4);
4314 test_truth(rc == MEMCACHED_SUCCESS);
4315
4316 memcached_result_st *results= memcached_result_create(new_clone, &result_obj);
4317 test_truth(results);
4318
4319 int hits= 0;
4320 while ((results= memcached_fetch_result(new_clone, &result_obj, &rc)) != NULL)
4321 {
4322 hits++;
4323 }
4324 test_truth(hits == 4);
4325 memcached_result_free(&result_obj);
4326 }
4327
4328 memcached_free(new_clone);
4329 }
4330
4331 memcached_free(memc_clone);
4332
4333 return TEST_SUCCESS;
4334 }
4335
4336 static test_return_t replication_randomize_mget_test(memcached_st *memc)
4337 {
4338 memcached_result_st result_obj;
4339 memcached_return_t rc;
4340 memcached_st *memc_clone= memcached_clone(NULL, memc);
4341 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 3);
4342 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_RANDOMIZE_REPLICA_READ, 1);
4343
4344 const char *keys[]= { "key1", "key2", "key3", "key4", "key5", "key6", "key7" };
4345 size_t len[]= { 4, 4, 4, 4, 4, 4, 4 };
4346
4347 for (int x=0; x< 7; ++x)
4348 {
4349 rc= memcached_set(memc, keys[x], len[x], "1", 1, 0, 0);
4350 test_truth(rc == MEMCACHED_SUCCESS);
4351 }
4352
4353 memcached_quit(memc);
4354
4355 for (int x=0; x< 7; ++x) {
4356 const char key[2]= { [0]= (const char)x };
4357
4358 rc= memcached_mget_by_key(memc_clone, key, 1, keys, len, 7);
4359 test_truth(rc == MEMCACHED_SUCCESS);
4360
4361 memcached_result_st *results= memcached_result_create(memc_clone, &result_obj);
4362 test_truth(results);
4363
4364 int hits= 0;
4365 while ((results= memcached_fetch_result(memc_clone, &result_obj, &rc)) != NULL)
4366 {
4367 ++hits;
4368 }
4369 test_truth(hits == 7);
4370 memcached_result_free(&result_obj);
4371 }
4372 memcached_free(memc_clone);
4373 return TEST_SUCCESS;
4374 }
4375
4376 static test_return_t replication_delete_test(memcached_st *memc)
4377 {
4378 memcached_return_t rc;
4379 memcached_st *memc_clone= memcached_clone(NULL, memc);
4380 /* Delete the items from all of the servers except 1 */
4381 uint64_t repl= memcached_behavior_get(memc,
4382 MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS);
4383 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, --repl);
4384
4385 const char *keys[]= { "bubba", "key1", "key2", "key3" };
4386 size_t len[]= { 5, 4, 4, 4 };
4387
4388 for (int x=0; x< 4; ++x)
4389 {
4390 rc= memcached_delete_by_key(memc, keys[0], len[0], keys[x], len[x], 0);
4391 test_truth(rc == MEMCACHED_SUCCESS);
4392 }
4393
4394 /*
4395 * Don't do the following in your code. I am abusing the internal details
4396 * within the library, and this is not a supported interface.
4397 * This is to verify correct behavior in the library
4398 */
4399 uint32_t hash= memcached_generate_hash(memc, keys[0], len[0]);
4400 for (uint32_t x= 0; x < (repl + 1); ++x)
4401 {
4402 memcached_server_instance_st *instance=
4403 memcached_server_instance_fetch(memc_clone, x);
4404
4405 instance->port= 0;
4406 if (++hash == memc_clone->number_of_hosts)
4407 hash= 0;
4408 }
4409
4410 memcached_result_st result_obj;
4411 for (uint32_t host= 0; host < memc_clone->number_of_hosts; ++host)
4412 {
4413 for (int x= 'a'; x <= 'z'; ++x)
4414 {
4415 const char key[2]= { [0]= (const char)x };
4416
4417 rc= memcached_mget_by_key(memc_clone, key, 1, keys, len, 4);
4418 test_truth(rc == MEMCACHED_SUCCESS);
4419
4420 memcached_result_st *results= memcached_result_create(memc_clone, &result_obj);
4421 test_truth(results);
4422
4423 int hits= 0;
4424 while ((results= memcached_fetch_result(memc_clone, &result_obj, &rc)) != NULL)
4425 {
4426 ++hits;
4427 }
4428 test_truth(hits == 4);
4429 memcached_result_free(&result_obj);
4430 }
4431 }
4432 memcached_free(memc_clone);
4433
4434 return TEST_SUCCESS;
4435 }
4436
4437 static void increment_request_id(uint16_t *id)
4438 {
4439 (*id)++;
4440 if ((*id & UDP_REQUEST_ID_THREAD_MASK) != 0)
4441 *id= 0;
4442 }
4443
4444 static uint16_t *get_udp_request_ids(memcached_st *memc)
4445 {
4446 uint16_t *ids= malloc(sizeof(uint16_t) * memcached_server_count(memc));
4447 assert(ids != NULL);
4448 unsigned int x;
4449
4450 for (x= 0; x < memcached_server_count(memc); x++)
4451 {
4452 memcached_server_instance_st *instance=
4453 memcached_server_instance_fetch(memc, x);
4454
4455 ids[x]= get_udp_datagram_request_id((struct udp_datagram_header_st *) instance->write_buffer);
4456 }
4457
4458 return ids;
4459 }
4460
4461 static test_return_t post_udp_op_check(memcached_st *memc, uint16_t *expected_req_ids)
4462 {
4463 unsigned int x;
4464 memcached_server_st *cur_server = memcached_server_list(memc);
4465 uint16_t *cur_req_ids = get_udp_request_ids(memc);
4466
4467 for (x= 0; x < memcached_server_count(memc); x++)
4468 {
4469 test_truth(cur_server[x].cursor_active == 0);
4470 test_truth(cur_req_ids[x] == expected_req_ids[x]);
4471 }
4472 free(expected_req_ids);
4473 free(cur_req_ids);
4474
4475 return TEST_SUCCESS;
4476 }
4477
4478 /*
4479 ** There is a little bit of a hack here, instead of removing
4480 ** the servers, I just set num host to 0 and them add then new udp servers
4481 **/
4482 static test_return_t init_udp(memcached_st *memc)
4483 {
4484 memcached_version(memc);
4485 memcached_server_instance_st *instance=
4486 memcached_server_instance_fetch(memc, 0);
4487
4488 /* For the time being, only support udp test for >= 1.2.6 && < 1.3 */
4489 if (instance->major_version != 1 || instance->minor_version != 2
4490 || instance->micro_version < 6)
4491 return TEST_SKIPPED;
4492
4493 uint32_t num_hosts= memcached_server_count(memc);
4494 unsigned int x= 0;
4495 memcached_server_st servers[num_hosts];
4496 memcpy(servers, memcached_server_list(memc), sizeof(memcached_server_st) * num_hosts);
4497 for (x= 0; x < num_hosts; x++)
4498 {
4499 memcached_server_instance_st *set_instance=
4500 memcached_server_instance_fetch(memc, x);
4501
4502 memcached_server_free(set_instance);
4503 }
4504
4505 memc->number_of_hosts= 0;
4506 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_USE_UDP, 1);
4507 for (x= 0; x < num_hosts; x++)
4508 {
4509 memcached_server_instance_st *set_instance=
4510 memcached_server_instance_fetch(memc, x);
4511
4512 test_truth(memcached_server_add_udp(memc, servers[x].hostname, servers[x].port) == MEMCACHED_SUCCESS);
4513 test_truth(set_instance->write_buffer_offset == UDP_DATAGRAM_HEADER_LENGTH);
4514 }
4515
4516 return TEST_SUCCESS;
4517 }
4518
4519 static test_return_t binary_init_udp(memcached_st *memc)
4520 {
4521 test_return_t test_rc;
4522 test_rc= pre_binary(memc);
4523
4524 if (test_rc != TEST_SUCCESS)
4525 return test_rc;
4526
4527 return init_udp(memc);
4528 }
4529
4530 /* Make sure that I cant add a tcp server to a udp client */
4531 static test_return_t add_tcp_server_udp_client_test(memcached_st *memc)
4532 {
4533 (void)memc;
4534 #if 0
4535 memcached_server_st server;
4536 memcached_server_instance_st *instance=
4537 memcached_server_instance_fetch(memc, 0);
4538 memcached_server_clone(&server, &memc->hosts[0]);
4539 test_truth(memcached_server_remove(&(memc->hosts[0])) == MEMCACHED_SUCCESS);
4540 test_truth(memcached_server_add(memc, server.hostname, server.port) == MEMCACHED_INVALID_HOST_PROTOCOL);
4541 #endif
4542 return TEST_SUCCESS;
4543 }
4544
4545 /* Make sure that I cant add a udp server to a tcp client */
4546 static test_return_t add_udp_server_tcp_client_test(memcached_st *memc)
4547 {
4548 (void)memc;
4549 #if 0
4550 memcached_server_st server;
4551 memcached_server_instance_st *instance=
4552 memcached_server_instance_fetch(memc, 0);
4553 memcached_server_clone(&server, &memc->hosts[0]);
4554 test_truth(memcached_server_remove(&(memc->hosts[0])) == MEMCACHED_SUCCESS);
4555
4556 memcached_st tcp_client;
4557 memcached_create(&tcp_client);
4558 test_truth(memcached_server_add_udp(&tcp_client, server.hostname, server.port) == MEMCACHED_INVALID_HOST_PROTOCOL);
4559 #endif
4560
4561 return TEST_SUCCESS;
4562 }
4563
4564 static test_return_t set_udp_behavior_test(memcached_st *memc)
4565 {
4566
4567 memcached_quit(memc);
4568 memc->number_of_hosts= 0;
4569 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, memc->distribution);
4570 test_truth(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_USE_UDP, 1) == MEMCACHED_SUCCESS);
4571 test_truth(memc->flags.use_udp);
4572 test_truth(memc->flags.no_reply);
4573
4574 test_truth(memcached_server_count(memc) == 0);
4575
4576 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_USE_UDP,0);
4577 test_truth(! (memc->flags.use_udp));
4578 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY,0);
4579 test_truth(! (memc->flags.no_reply));
4580
4581 return TEST_SUCCESS;
4582 }
4583
4584 static test_return_t udp_set_test(memcached_st *memc)
4585 {
4586 unsigned int x= 0;
4587 unsigned int num_iters= 1025; //request id rolls over at 1024
4588 for (x= 0; x < num_iters;x++)
4589 {
4590 memcached_return_t rc;
4591 const char *key= "foo";
4592 const char *value= "when we sanitize";
4593 uint16_t *expected_ids= get_udp_request_ids(memc);
4594 unsigned int server_key= memcached_generate_hash(memc, key, strlen(key));
4595 memcached_server_instance_st *instance=
4596 memcached_server_instance_fetch(memc, server_key);
4597 size_t init_offset= instance->write_buffer_offset;
4598
4599 rc= memcached_set(memc, key, strlen(key),
4600 value, strlen(value),
4601 (time_t)0, (uint32_t)0);
4602 test_truth(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
4603 /** NB, the check below assumes that if new write_ptr is less than
4604 * the original write_ptr that we have flushed. For large payloads, this
4605 * maybe an invalid assumption, but for the small payload we have it is OK
4606 */
4607 if (rc == MEMCACHED_SUCCESS ||
4608 instance->write_buffer_offset < init_offset)
4609 increment_request_id(&expected_ids[server_key]);
4610
4611 if (rc == MEMCACHED_SUCCESS)
4612 {
4613 test_truth(instance->write_buffer_offset == UDP_DATAGRAM_HEADER_LENGTH);
4614 }
4615 else
4616 {
4617 test_truth(instance->write_buffer_offset != UDP_DATAGRAM_HEADER_LENGTH);
4618 test_truth(instance->write_buffer_offset <= MAX_UDP_DATAGRAM_LENGTH);
4619 }
4620 test_truth(post_udp_op_check(memc, expected_ids) == TEST_SUCCESS);
4621 }
4622 return TEST_SUCCESS;
4623 }
4624
4625 static test_return_t udp_buffered_set_test(memcached_st *memc)
4626 {
4627 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
4628 return udp_set_test(memc);
4629 }
4630
4631 static test_return_t udp_set_too_big_test(memcached_st *memc)
4632 {
4633 memcached_return_t rc;
4634 const char *key= "bar";
4635 char value[MAX_UDP_DATAGRAM_LENGTH];
4636 uint16_t *expected_ids= get_udp_request_ids(memc);
4637 rc= memcached_set(memc, key, strlen(key),
4638 value, MAX_UDP_DATAGRAM_LENGTH,
4639 (time_t)0, (uint32_t)0);
4640 test_truth(rc == MEMCACHED_WRITE_FAILURE);
4641 return post_udp_op_check(memc,expected_ids);
4642 }
4643
4644 static test_return_t udp_delete_test(memcached_st *memc)
4645 {
4646 unsigned int x= 0;
4647 unsigned int num_iters= 1025; //request id rolls over at 1024
4648 for (x= 0; x < num_iters;x++)
4649 {
4650 memcached_return_t rc;
4651 const char *key= "foo";
4652 uint16_t *expected_ids=get_udp_request_ids(memc);
4653 unsigned int server_key= memcached_generate_hash(memc, key, strlen(key));
4654 memcached_server_instance_st *instance=
4655 memcached_server_instance_fetch(memc, server_key);
4656 size_t init_offset= instance->write_buffer_offset;
4657
4658 rc= memcached_delete(memc, key, strlen(key), 0);
4659 test_truth(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
4660
4661 if (rc == MEMCACHED_SUCCESS || instance->write_buffer_offset < init_offset)
4662 increment_request_id(&expected_ids[server_key]);
4663 if (rc == MEMCACHED_SUCCESS)
4664 {
4665 test_truth(instance->write_buffer_offset == UDP_DATAGRAM_HEADER_LENGTH);
4666 }
4667 else
4668 {
4669 test_truth(instance->write_buffer_offset != UDP_DATAGRAM_HEADER_LENGTH);
4670 test_truth(instance->write_buffer_offset <= MAX_UDP_DATAGRAM_LENGTH);
4671 }
4672 test_truth(post_udp_op_check(memc,expected_ids) == TEST_SUCCESS);
4673 }
4674 return TEST_SUCCESS;
4675 }
4676
4677 static test_return_t udp_buffered_delete_test(memcached_st *memc)
4678 {
4679 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
4680 return udp_delete_test(memc);
4681 }
4682
4683 static test_return_t udp_verbosity_test(memcached_st *memc)
4684 {
4685 memcached_return_t rc;
4686 uint16_t *expected_ids= get_udp_request_ids(memc);
4687 unsigned int x;
4688 for (x= 0; x < memcached_server_count(memc); x++)
4689 increment_request_id(&expected_ids[x]);
4690
4691 rc= memcached_verbosity(memc,3);
4692 test_truth(rc == MEMCACHED_SUCCESS);
4693 return post_udp_op_check(memc,expected_ids);
4694 }
4695
4696 static test_return_t udp_quit_test(memcached_st *memc)
4697 {
4698 uint16_t *expected_ids= get_udp_request_ids(memc);
4699 memcached_quit(memc);
4700 return post_udp_op_check(memc, expected_ids);
4701 }
4702
4703 static test_return_t udp_flush_test(memcached_st *memc)
4704 {
4705 memcached_return_t rc;
4706 uint16_t *expected_ids= get_udp_request_ids(memc);
4707 unsigned int x;
4708 for (x= 0; x < memcached_server_count(memc);x++)
4709 increment_request_id(&expected_ids[x]);
4710
4711 rc= memcached_flush(memc,0);
4712 test_truth(rc == MEMCACHED_SUCCESS);
4713 return post_udp_op_check(memc,expected_ids);
4714 }
4715
4716 static test_return_t udp_incr_test(memcached_st *memc)
4717 {
4718 memcached_return_t rc;
4719 const char *key= "incr";
4720 const char *value= "1";
4721 rc= memcached_set(memc, key, strlen(key),
4722 value, strlen(value),
4723 (time_t)0, (uint32_t)0);
4724
4725 test_truth(rc == MEMCACHED_SUCCESS);
4726 uint16_t *expected_ids= get_udp_request_ids(memc);
4727 unsigned int server_key= memcached_generate_hash(memc, key, strlen(key));
4728 increment_request_id(&expected_ids[server_key]);
4729 uint64_t newvalue;
4730 rc= memcached_increment(memc, key, strlen(key), 1, &newvalue);
4731 test_truth(rc == MEMCACHED_SUCCESS);
4732 return post_udp_op_check(memc, expected_ids);
4733 }
4734
4735 static test_return_t udp_decr_test(memcached_st *memc)
4736 {
4737 memcached_return_t rc;
4738 const char *key= "decr";
4739 const char *value= "1";
4740 rc= memcached_set(memc, key, strlen(key),
4741 value, strlen(value),
4742 (time_t)0, (uint32_t)0);
4743
4744 test_truth(rc == MEMCACHED_SUCCESS);
4745 uint16_t *expected_ids= get_udp_request_ids(memc);
4746 unsigned int server_key= memcached_generate_hash(memc, key, strlen(key));
4747 increment_request_id(&expected_ids[server_key]);
4748 uint64_t newvalue;
4749 rc= memcached_decrement(memc, key, strlen(key), 1, &newvalue);
4750 test_truth(rc == MEMCACHED_SUCCESS);
4751 return post_udp_op_check(memc, expected_ids);
4752 }
4753
4754
4755 static test_return_t udp_stat_test(memcached_st *memc)
4756 {
4757 memcached_stat_st * rv= NULL;
4758 memcached_return_t rc;
4759 char args[]= "";
4760 uint16_t *expected_ids = get_udp_request_ids(memc);
4761 rv = memcached_stat(memc, args, &rc);
4762 free(rv);
4763 test_truth(rc == MEMCACHED_NOT_SUPPORTED);
4764 return post_udp_op_check(memc, expected_ids);
4765 }
4766
4767 static test_return_t udp_version_test(memcached_st *memc)
4768 {
4769 memcached_return_t rc;
4770 uint16_t *expected_ids = get_udp_request_ids(memc);
4771 rc = memcached_version(memc);
4772 test_truth(rc == MEMCACHED_NOT_SUPPORTED);
4773 return post_udp_op_check(memc, expected_ids);
4774 }
4775
4776 static test_return_t udp_get_test(memcached_st *memc)
4777 {
4778 memcached_return_t rc;
4779 const char *key= "foo";
4780 size_t vlen;
4781 uint16_t *expected_ids = get_udp_request_ids(memc);
4782 char *val= memcached_get(memc, key, strlen(key), &vlen, (uint32_t)0, &rc);
4783 test_truth(rc == MEMCACHED_NOT_SUPPORTED);
4784 test_truth(val == NULL);
4785 return post_udp_op_check(memc, expected_ids);
4786 }
4787
4788 static test_return_t udp_mixed_io_test(memcached_st *memc)
4789 {
4790 test_st current_op;
4791 test_st mixed_io_ops [] ={
4792 {"udp_set_test", 0,
4793 (test_callback_fn)udp_set_test},
4794 {"udp_set_too_big_test", 0,
4795 (test_callback_fn)udp_set_too_big_test},
4796 {"udp_delete_test", 0,
4797 (test_callback_fn)udp_delete_test},
4798 {"udp_verbosity_test", 0,
4799 (test_callback_fn)udp_verbosity_test},
4800 {"udp_quit_test", 0,
4801 (test_callback_fn)udp_quit_test},
4802 {"udp_flush_test", 0,
4803 (test_callback_fn)udp_flush_test},
4804 {"udp_incr_test", 0,
4805 (test_callback_fn)udp_incr_test},
4806 {"udp_decr_test", 0,
4807 (test_callback_fn)udp_decr_test},
4808 {"udp_version_test", 0,
4809 (test_callback_fn)udp_version_test}
4810 };
4811 unsigned int x= 0;
4812 for (x= 0; x < 500; x++)
4813 {
4814 current_op= mixed_io_ops[random() % 9];
4815 test_truth(current_op.test_fn(memc) == TEST_SUCCESS);
4816 }
4817 return TEST_SUCCESS;
4818 }
4819
4820 #if 0
4821 static test_return_t hash_sanity_test (memcached_st *memc)
4822 {
4823 (void)memc;
4824
4825 assert(MEMCACHED_HASH_DEFAULT == MEMCACHED_HASH_DEFAULT);
4826 assert(MEMCACHED_HASH_MD5 == MEMCACHED_HASH_MD5);
4827 assert(MEMCACHED_HASH_CRC == MEMCACHED_HASH_CRC);
4828 assert(MEMCACHED_HASH_FNV1_64 == MEMCACHED_HASH_FNV1_64);
4829 assert(MEMCACHED_HASH_FNV1A_64 == MEMCACHED_HASH_FNV1A_64);
4830 assert(MEMCACHED_HASH_FNV1_32 == MEMCACHED_HASH_FNV1_32);
4831 assert(MEMCACHED_HASH_FNV1A_32 == MEMCACHED_HASH_FNV1A_32);
4832 #ifdef HAVE_HSIEH_HASH
4833 assert(MEMCACHED_HASH_HSIEH == MEMCACHED_HASH_HSIEH);
4834 #endif
4835 assert(MEMCACHED_HASH_MURMUR == MEMCACHED_HASH_MURMUR);
4836 assert(MEMCACHED_HASH_JENKINS == MEMCACHED_HASH_JENKINS);
4837 assert(MEMCACHED_HASH_MAX == MEMCACHED_HASH_MAX);
4838
4839 return TEST_SUCCESS;
4840 }
4841 #endif
4842
4843 static test_return_t hsieh_avaibility_test (memcached_st *memc)
4844 {
4845 memcached_return_t expected_rc= MEMCACHED_FAILURE;
4846 #ifdef HAVE_HSIEH_HASH
4847 expected_rc= MEMCACHED_SUCCESS;
4848 #endif
4849 memcached_return_t rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH,
4850 (uint64_t)MEMCACHED_HASH_HSIEH);
4851 test_truth(rc == expected_rc);
4852 return TEST_SUCCESS;
4853 }
4854
4855 static test_return_t md5_run (memcached_st *memc __attribute__((unused)))
4856 {
4857 uint32_t x;
4858 const char **ptr;
4859
4860 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4861 {
4862 uint32_t hash_val;
4863
4864 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_MD5);
4865 test_truth(md5_values[x] == hash_val);
4866 }
4867
4868 return TEST_SUCCESS;
4869 }
4870
4871 static test_return_t crc_run (memcached_st *memc __attribute__((unused)))
4872 {
4873 uint32_t x;
4874 const char **ptr;
4875
4876 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4877 {
4878 uint32_t hash_val;
4879
4880 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_CRC);
4881 test_truth(crc_values[x] == hash_val);
4882 }
4883
4884 return TEST_SUCCESS;
4885 }
4886
4887 static test_return_t fnv1_64_run (memcached_st *memc __attribute__((unused)))
4888 {
4889 uint32_t x;
4890 const char **ptr;
4891
4892 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4893 {
4894 uint32_t hash_val;
4895
4896 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1_64);
4897 test_truth(fnv1_64_values[x] == hash_val);
4898 }
4899
4900 return TEST_SUCCESS;
4901 }
4902
4903 static test_return_t fnv1a_64_run (memcached_st *memc __attribute__((unused)))
4904 {
4905 uint32_t x;
4906 const char **ptr;
4907
4908 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4909 {
4910 uint32_t hash_val;
4911
4912 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1A_64);
4913 test_truth(fnv1a_64_values[x] == hash_val);
4914 }
4915
4916 return TEST_SUCCESS;
4917 }
4918
4919 static test_return_t fnv1_32_run (memcached_st *memc __attribute__((unused)))
4920 {
4921 uint32_t x;
4922 const char **ptr;
4923
4924
4925 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4926 {
4927 uint32_t hash_val;
4928
4929 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1_32);
4930 test_truth(fnv1_32_values[x] == hash_val);
4931 }
4932
4933 return TEST_SUCCESS;
4934 }
4935
4936 static test_return_t fnv1a_32_run (memcached_st *memc __attribute__((unused)))
4937 {
4938 uint32_t x;
4939 const char **ptr;
4940
4941 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4942 {
4943 uint32_t hash_val;
4944
4945 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1A_32);
4946 test_truth(fnv1a_32_values[x] == hash_val);
4947 }
4948
4949 return TEST_SUCCESS;
4950 }
4951
4952 static test_return_t hsieh_run (memcached_st *memc __attribute__((unused)))
4953 {
4954 uint32_t x;
4955 const char **ptr;
4956
4957 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4958 {
4959 uint32_t hash_val;
4960
4961 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_HSIEH);
4962 test_truth(hsieh_values[x] == hash_val);
4963 }
4964
4965 return TEST_SUCCESS;
4966 }
4967
4968 static test_return_t murmur_run (memcached_st *memc __attribute__((unused)))
4969 {
4970 #ifdef __sparc
4971 return TEST_SKIPPED;
4972 #else
4973 uint32_t x;
4974 const char **ptr;
4975
4976 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4977 {
4978 uint32_t hash_val;
4979
4980 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_MURMUR);
4981 test_truth(murmur_values[x] == hash_val);
4982 }
4983
4984 return TEST_SUCCESS;
4985 #endif
4986 }
4987
4988 static test_return_t jenkins_run (memcached_st *memc __attribute__((unused)))
4989 {
4990 uint32_t x;
4991 const char **ptr;
4992
4993
4994 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
4995 {
4996 uint32_t hash_val;
4997
4998 hash_val= memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_JENKINS);
4999 test_truth(jenkins_values[x] == hash_val);
5000 }
5001
5002 return TEST_SUCCESS;
5003 }
5004
5005
5006 static test_return_t ketama_compatibility_libmemcached(memcached_st *trash)
5007 {
5008 memcached_return_t rc;
5009 uint64_t value;
5010 int x;
5011 memcached_server_st *server_pool;
5012 memcached_st *memc;
5013
5014 (void)trash;
5015
5016 memc= memcached_create(NULL);
5017 test_truth(memc);
5018
5019 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
5020 test_truth(rc == MEMCACHED_SUCCESS);
5021
5022 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
5023 test_truth(value == 1);
5024
5025 test_truth(memcached_behavior_set_distribution(memc, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA) == MEMCACHED_SUCCESS);
5026 test_truth(memcached_behavior_get_distribution(memc) == MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA);
5027
5028
5029 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");
5030 memcached_server_push(memc, server_pool);
5031
5032 /* verify that the server list was parsed okay. */
5033 test_truth(memcached_server_count(memc) == 8);
5034 test_strcmp(server_pool[0].hostname, "10.0.1.1");
5035 test_truth(server_pool[0].port == 11211);
5036 test_truth(server_pool[0].weight == 600);
5037 test_strcmp(server_pool[2].hostname, "10.0.1.3");
5038 test_truth(server_pool[2].port == 11211);
5039 test_truth(server_pool[2].weight == 200);
5040 test_strcmp(server_pool[7].hostname, "10.0.1.8");
5041 test_truth(server_pool[7].port == 11211);
5042 test_truth(server_pool[7].weight == 100);
5043
5044 /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets
5045 * us test the boundary wraparound.
5046 */
5047 test_truth(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->continuum[0].index);
5048
5049 /* verify the standard ketama set. */
5050 for (x= 0; x < 99; x++)
5051 {
5052 uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
5053 memcached_server_instance_st *instance=
5054 memcached_server_instance_fetch(memc, server_idx);
5055 char *hostname = instance->hostname;
5056
5057 test_strcmp(hostname, ketama_test_cases[x].server);
5058 }
5059
5060 memcached_server_list_free(server_pool);
5061 memcached_free(memc);
5062
5063 return TEST_SUCCESS;
5064 }
5065
5066 static test_return_t ketama_compatibility_spymemcached(memcached_st *trash)
5067 {
5068 memcached_return_t rc;
5069 uint64_t value;
5070 int x;
5071 memcached_server_st *server_pool;
5072 memcached_st *memc;
5073
5074 (void)trash;
5075
5076 memc= memcached_create(NULL);
5077 test_truth(memc);
5078
5079 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
5080 test_truth(rc == MEMCACHED_SUCCESS);
5081
5082 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
5083 test_truth(value == 1);
5084
5085 test_truth(memcached_behavior_set_distribution(memc, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY) == MEMCACHED_SUCCESS);
5086 test_truth(memcached_behavior_get_distribution(memc) == MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY);
5087
5088 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");
5089 memcached_server_push(memc, server_pool);
5090
5091 /* verify that the server list was parsed okay. */
5092 test_truth(memcached_server_count(memc) == 8);
5093 test_strcmp(server_pool[0].hostname, "10.0.1.1");
5094 test_truth(server_pool[0].port == 11211);
5095 test_truth(server_pool[0].weight == 600);
5096 test_strcmp(server_pool[2].hostname, "10.0.1.3");
5097 test_truth(server_pool[2].port == 11211);
5098 test_truth(server_pool[2].weight == 200);
5099 test_strcmp(server_pool[7].hostname, "10.0.1.8");
5100 test_truth(server_pool[7].port == 11211);
5101 test_truth(server_pool[7].weight == 100);
5102
5103 /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets
5104 * us test the boundary wraparound.
5105 */
5106 test_truth(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->continuum[0].index);
5107
5108 /* verify the standard ketama set. */
5109 for (x= 0; x < 99; x++)
5110 {
5111 uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases_spy[x].key, strlen(ketama_test_cases_spy[x].key));
5112 memcached_server_instance_st *instance=
5113 memcached_server_instance_fetch(memc, server_idx);
5114 char *hostname = instance->hostname;
5115 test_strcmp(hostname, ketama_test_cases_spy[x].server);
5116 }
5117
5118 memcached_server_list_free(server_pool);
5119 memcached_free(memc);
5120
5121 return TEST_SUCCESS;
5122 }
5123
5124 static test_return_t regression_bug_434484(memcached_st *memc)
5125 {
5126 test_return_t test_rc;
5127 test_rc= pre_binary(memc);
5128
5129 if (test_rc != TEST_SUCCESS)
5130 return test_rc;
5131
5132 memcached_return_t ret;
5133 const char *key= "regression_bug_434484";
5134 size_t keylen= strlen(key);
5135
5136 ret= memcached_append(memc, key, keylen, key, keylen, 0, 0);
5137 test_truth(ret == MEMCACHED_NOTSTORED);
5138
5139 size_t size= 2048 * 1024;
5140 void *data= calloc(1, size);
5141 test_truth(data != NULL);
5142 ret= memcached_set(memc, key, keylen, data, size, 0, 0);
5143 test_truth(ret == MEMCACHED_E2BIG);
5144 free(data);
5145
5146 return TEST_SUCCESS;
5147 }
5148
5149 static test_return_t regression_bug_434843(memcached_st *memc)
5150 {
5151 test_return_t test_rc;
5152 test_rc= pre_binary(memc);
5153
5154 if (test_rc != TEST_SUCCESS)
5155 return test_rc;
5156
5157 memcached_return_t rc;
5158 unsigned int counter= 0;
5159 memcached_execute_fn callbacks[1]= { [0]= &callback_counter };
5160
5161 /*
5162 * I only want to hit only _one_ server so I know the number of requests I'm
5163 * sending in the pipleine to the server. Let's try to do a multiget of
5164 * 1024 (that should satisfy most users don't you think?). Future versions
5165 * will include a mget_execute function call if you need a higher number.
5166 */
5167 uint32_t number_of_hosts= memcached_server_count(memc);
5168 memc->number_of_hosts= 1;
5169 const size_t max_keys= 1024;
5170 char **keys= calloc(max_keys, sizeof(char*));
5171 size_t *key_length=calloc(max_keys, sizeof(size_t));
5172
5173 for (int x= 0; x < (int)max_keys; ++x)
5174 {
5175 char k[251];
5176 key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%u", x);
5177 keys[x]= strdup(k);
5178 test_truth(keys[x] != NULL);
5179 }
5180
5181 /*
5182 * Run two times.. the first time we should have 100% cache miss,
5183 * and the second time we should have 100% cache hits
5184 */
5185 for (int y= 0; y < 2; ++y)
5186 {
5187 rc= memcached_mget(memc, (const char**)keys, key_length, max_keys);
5188 test_truth(rc == MEMCACHED_SUCCESS);
5189 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
5190 if (y == 0)
5191 {
5192 /* The first iteration should give me a 100% cache miss. verify that*/
5193 test_truth(counter == 0);
5194 char blob[1024]= { 0 };
5195 for (int x= 0; x < (int)max_keys; ++x)
5196 {
5197 rc= memcached_add(memc, keys[x], key_length[x],
5198 blob, sizeof(blob), 0, 0);
5199 test_truth(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5200 }
5201 }
5202 else
5203 {
5204 /* Verify that we received all of the key/value pairs */
5205 test_truth(counter == (unsigned int)max_keys);
5206 }
5207 }
5208
5209 /* Release allocated resources */
5210 for (size_t x= 0; x < max_keys; ++x)
5211 free(keys[x]);
5212 free(keys);
5213 free(key_length);
5214
5215 memc->number_of_hosts= number_of_hosts;
5216
5217 return TEST_SUCCESS;
5218 }
5219
5220 static test_return_t regression_bug_434843_buffered(memcached_st *memc)
5221 {
5222 memcached_return_t rc;
5223 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
5224 test_truth(rc == MEMCACHED_SUCCESS);
5225
5226 return regression_bug_434843(memc);
5227 }
5228
5229 static test_return_t regression_bug_421108(memcached_st *memc)
5230 {
5231 memcached_return_t rc;
5232 memcached_stat_st *memc_stat= memcached_stat(memc, NULL, &rc);
5233 test_truth(rc == MEMCACHED_SUCCESS);
5234
5235 char *bytes= memcached_stat_get_value(memc, memc_stat, "bytes", &rc);
5236 test_truth(rc == MEMCACHED_SUCCESS);
5237 test_truth(bytes != NULL);
5238 char *bytes_read= memcached_stat_get_value(memc, memc_stat,
5239 "bytes_read", &rc);
5240 test_truth(rc == MEMCACHED_SUCCESS);
5241 test_truth(bytes_read != NULL);
5242
5243 char *bytes_written= memcached_stat_get_value(memc, memc_stat,
5244 "bytes_written", &rc);
5245 test_truth(rc == MEMCACHED_SUCCESS);
5246 test_truth(bytes_written != NULL);
5247
5248 test_truth(strcmp(bytes, bytes_read) != 0);
5249 test_truth(strcmp(bytes, bytes_written) != 0);
5250
5251 /* Release allocated resources */
5252 free(bytes);
5253 free(bytes_read);
5254 free(bytes_written);
5255 memcached_stat_free(NULL, memc_stat);
5256
5257 return TEST_SUCCESS;
5258 }
5259
5260 /*
5261 * The test case isn't obvious so I should probably document why
5262 * it works the way it does. Bug 442914 was caused by a bug
5263 * in the logic in memcached_purge (it did not handle the case
5264 * where the number of bytes sent was equal to the watermark).
5265 * In this test case, create messages so that we hit that case
5266 * and then disable noreply mode and issue a new command to
5267 * verify that it isn't stuck. If we change the format for the
5268 * delete command or the watermarks, we need to update this
5269 * test....
5270 */
5271 static test_return_t regression_bug_442914(memcached_st *memc)
5272 {
5273 memcached_return_t rc;
5274 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1);
5275 test_truth(rc == MEMCACHED_SUCCESS);
5276 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 1);
5277
5278 uint32_t number_of_hosts= memcached_server_count(memc);
5279 memc->number_of_hosts= 1;
5280
5281 char k[250];
5282 size_t len;
5283
5284 for (int x= 0; x < 250; ++x)
5285 {
5286 len= (size_t)snprintf(k, sizeof(k), "%0250u", x);
5287 rc= memcached_delete(memc, k, len, 0);
5288 test_truth(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5289 }
5290
5291 len= (size_t)snprintf(k, sizeof(k), "%037u", 251);
5292 rc= memcached_delete(memc, k, len, 0);
5293 test_truth(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5294
5295 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 0);
5296 test_truth(rc == MEMCACHED_SUCCESS);
5297 rc= memcached_delete(memc, k, len, 0);
5298 test_truth(rc == MEMCACHED_NOTFOUND);
5299
5300 memc->number_of_hosts= number_of_hosts;
5301
5302 return TEST_SUCCESS;
5303 }
5304
5305 static test_return_t regression_bug_447342(memcached_st *memc)
5306 {
5307 memcached_server_instance_st *instance_one;
5308 memcached_server_instance_st *instance_two;
5309
5310 if (memcached_server_count(memc) < 3 || pre_replication(memc) != MEMCACHED_SUCCESS)
5311 return TEST_SKIPPED;
5312
5313 memcached_return_t rc;
5314
5315 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 2);
5316 test_truth(rc == MEMCACHED_SUCCESS);
5317
5318 const size_t max_keys= 100;
5319 char **keys= calloc(max_keys, sizeof(char*));
5320 size_t *key_length= calloc(max_keys, sizeof(size_t));
5321
5322 for (uint64_t x= 0; x < max_keys; ++x)
5323 {
5324 char k[251];
5325 key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%"PRIu64, x);
5326 keys[x]= strdup(k);
5327 test_truth(keys[x] != NULL);
5328 rc= memcached_set(memc, k, key_length[x], k, key_length[x], 0, 0);
5329 test_truth(rc == MEMCACHED_SUCCESS);
5330 }
5331
5332 /*
5333 ** We are using the quiet commands to store the replicas, so we need
5334 ** to ensure that all of them are processed before we can continue.
5335 ** In the test we go directly from storing the object to trying to
5336 ** receive the object from all of the different servers, so we
5337 ** could end up in a race condition (the memcached server hasn't yet
5338 ** processed the quiet command from the replication set when it process
5339 ** the request from the other client (created by the clone)). As a
5340 ** workaround for that we call memcached_quit to send the quit command
5341 ** to the server and wait for the response ;-) If you use the test code
5342 ** as an example for your own code, please note that you shouldn't need
5343 ** to do this ;-)
5344 */
5345 memcached_quit(memc);
5346
5347 /* Verify that all messages are stored, and we didn't stuff too much
5348 * into the servers
5349 */
5350 rc= memcached_mget(memc, (const char* const *)keys, key_length, max_keys);
5351 test_truth(rc == MEMCACHED_SUCCESS);
5352
5353 unsigned int counter= 0;
5354 memcached_execute_fn callbacks[1]= { [0]= &callback_counter };
5355 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
5356 /* Verify that we received all of the key/value pairs */
5357 test_truth(counter == (unsigned int)max_keys);
5358
5359 memcached_quit(memc);
5360 /*
5361 * Don't do the following in your code. I am abusing the internal details
5362 * within the library, and this is not a supported interface.
5363 * This is to verify correct behavior in the library. Fake that two servers
5364 * are dead..
5365 */
5366 instance_one= memcached_server_instance_fetch(memc, 0);
5367 instance_two= memcached_server_instance_fetch(memc, 2);
5368 in_port_t port0= instance_one->port;
5369 in_port_t port2= instance_two->port;
5370
5371 instance_one->port= 0;
5372 instance_two->port= 0;
5373
5374 rc= memcached_mget(memc, (const char* const *)keys, key_length, max_keys);
5375 test_truth(rc == MEMCACHED_SUCCESS);
5376
5377 counter= 0;
5378 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
5379 test_truth(counter == (unsigned int)max_keys);
5380
5381 /* restore the memc handle */
5382 instance_one->port= port0;
5383 instance_two->port= port2;
5384
5385 memcached_quit(memc);
5386
5387 /* Remove half of the objects */
5388 for (size_t x= 0; x < max_keys; ++x)
5389 {
5390 if (x & 1)
5391 {
5392 rc= memcached_delete(memc, keys[x], key_length[x], 0);
5393 test_truth(rc == MEMCACHED_SUCCESS);
5394 }
5395 }
5396
5397 memcached_quit(memc);
5398 instance_one->port= 0;
5399 instance_two->port= 0;
5400
5401 /* now retry the command, this time we should have cache misses */
5402 rc= memcached_mget(memc, (const char* const *)keys, key_length, max_keys);
5403 test_truth(rc == MEMCACHED_SUCCESS);
5404
5405 counter= 0;
5406 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
5407 test_truth(counter == (unsigned int)(max_keys >> 1));
5408
5409 /* Release allocated resources */
5410 for (size_t x= 0; x < max_keys; ++x)
5411 {
5412 free(keys[x]);
5413 }
5414 free(keys);
5415 free(key_length);
5416
5417 /* restore the memc handle */
5418 instance_one->port= port0;
5419 instance_two->port= port2;
5420
5421 return TEST_SUCCESS;
5422 }
5423
5424 static test_return_t regression_bug_463297(memcached_st *memc)
5425 {
5426 memcached_st *memc_clone= memcached_clone(NULL, memc);
5427 test_truth(memc_clone != NULL);
5428 test_truth(memcached_version(memc_clone) == MEMCACHED_SUCCESS);
5429
5430 memcached_server_instance_st *instance=
5431 memcached_server_instance_fetch(memc_clone, 0);
5432
5433 if (instance->major_version > 1 ||
5434 (instance->major_version == 1 &&
5435 instance->minor_version > 2))
5436 {
5437 /* Binary protocol doesn't support deferred delete */
5438 memcached_st *bin_clone= memcached_clone(NULL, memc);
5439 test_truth(bin_clone != NULL);
5440 test_truth(memcached_behavior_set(bin_clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1) == MEMCACHED_SUCCESS);
5441 test_truth(memcached_delete(bin_clone, "foo", 3, 1) == MEMCACHED_INVALID_ARGUMENTS);
5442 memcached_free(bin_clone);
5443
5444 memcached_quit(memc_clone);
5445
5446 /* If we know the server version, deferred delete should fail
5447 * with invalid arguments */
5448 test_truth(memcached_delete(memc_clone, "foo", 3, 1) == MEMCACHED_INVALID_ARGUMENTS);
5449
5450 /* If we don't know the server version, we should get a protocol error */
5451 memcached_return_t rc= memcached_delete(memc, "foo", 3, 1);
5452
5453 /* but there is a bug in some of the memcached servers (1.4) that treats
5454 * the counter as noreply so it doesn't send the proper error message
5455 */
5456 test_truth(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR);
5457
5458 /* And buffered mode should be disabled and we should get protocol error */
5459 test_truth(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1) == MEMCACHED_SUCCESS);
5460 rc= memcached_delete(memc, "foo", 3, 1);
5461 test_truth(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR);
5462
5463 /* Same goes for noreply... */
5464 test_truth(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1) == MEMCACHED_SUCCESS);
5465 rc= memcached_delete(memc, "foo", 3, 1);
5466 test_truth(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR);
5467
5468 /* but a normal request should go through (and be buffered) */
5469 test_truth((rc= memcached_delete(memc, "foo", 3, 0)) == MEMCACHED_BUFFERED);
5470 test_truth(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
5471
5472 test_truth(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 0) == MEMCACHED_SUCCESS);
5473 /* unbuffered noreply should be success */
5474 test_truth(memcached_delete(memc, "foo", 3, 0) == MEMCACHED_SUCCESS);
5475 /* unbuffered with reply should be not found... */
5476 test_truth(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 0) == MEMCACHED_SUCCESS);
5477 test_truth(memcached_delete(memc, "foo", 3, 0) == MEMCACHED_NOTFOUND);
5478 }
5479
5480 memcached_free(memc_clone);
5481 return TEST_SUCCESS;
5482 }
5483
5484
5485 /* Test memcached_server_get_last_disconnect
5486 * For a working server set, shall be NULL
5487 * For a set of non existing server, shall not be NULL
5488 */
5489 static test_return_t test_get_last_disconnect(memcached_st *memc)
5490 {
5491 memcached_return_t rc;
5492 memcached_server_st *disconnected_server;
5493
5494 /* With the working set of server */
5495 const char *key= "marmotte";
5496 const char *value= "milka";
5497
5498 rc= memcached_set(memc, key, strlen(key),
5499 value, strlen(value),
5500 (time_t)0, (uint32_t)0);
5501 test_truth(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5502
5503 disconnected_server = memcached_server_get_last_disconnect(memc);
5504 test_truth(disconnected_server == NULL);
5505
5506 /* With a non existing server */
5507 memcached_st *mine;
5508 memcached_server_st *servers;
5509
5510 const char *server_list= "localhost:9";
5511
5512 servers= memcached_servers_parse(server_list);
5513 test_truth(servers);
5514 mine= memcached_create(NULL);
5515 rc= memcached_server_push(mine, servers);
5516 test_truth(rc == MEMCACHED_SUCCESS);
5517 memcached_server_list_free(servers);
5518 test_truth(mine);
5519
5520 rc= memcached_set(mine, key, strlen(key),
5521 value, strlen(value),
5522 (time_t)0, (uint32_t)0);
5523 test_truth(rc != MEMCACHED_SUCCESS);
5524
5525 disconnected_server = memcached_server_get_last_disconnect(mine);
5526 test_truth(disconnected_server != NULL);
5527 test_truth(disconnected_server->port == 9);
5528 test_truth(strncmp(disconnected_server->hostname,"localhost",9) == 0);
5529
5530 memcached_quit(mine);
5531 memcached_free(mine);
5532
5533 return TEST_SUCCESS;
5534 }
5535
5536 /*
5537 * This test ensures that the failure counter isn't incremented during
5538 * normal termination of the memcached instance.
5539 */
5540 static test_return_t wrong_failure_counter_test(memcached_st *memc)
5541 {
5542 memcached_return_t rc;
5543 memcached_server_instance_st *instance;
5544
5545 /* Set value to force connection to the server */
5546 const char *key= "marmotte";
5547 const char *value= "milka";
5548
5549 /*
5550 * Please note that I'm abusing the internal structures in libmemcached
5551 * in a non-portable way and you shouldn't be doing this. I'm only
5552 * doing this in order to verify that the library works the way it should
5553 */
5554 uint32_t number_of_hosts= memcached_server_count(memc);
5555 memc->number_of_hosts= 1;
5556
5557 /* Ensure that we are connected to the server by setting a value */
5558 rc= memcached_set(memc, key, strlen(key),
5559 value, strlen(value),
5560 (time_t)0, (uint32_t)0);
5561 test_truth(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5562
5563
5564 instance= memcached_server_instance_fetch(memc, 0);
5565 /* The test is to see that the memcached_quit doesn't increase the
5566 * the server failure conter, so let's ensure that it is zero
5567 * before sending quit
5568 */
5569 instance->server_failure_counter= 0;
5570
5571 memcached_quit(memc);
5572
5573 /* Verify that it memcached_quit didn't increment the failure counter
5574 * Please note that this isn't bullet proof, because an error could
5575 * occur...
5576 */
5577 test_truth(instance->server_failure_counter == 0);
5578
5579 /* restore the instance */
5580 memc->number_of_hosts= number_of_hosts;
5581
5582 return TEST_SUCCESS;
5583 }
5584
5585 test_st udp_setup_server_tests[] ={
5586 {"set_udp_behavior_test", 0, (test_callback_fn)set_udp_behavior_test},
5587 {"add_tcp_server_udp_client_test", 0, (test_callback_fn)add_tcp_server_udp_client_test},
5588 {"add_udp_server_tcp_client_test", 0, (test_callback_fn)add_udp_server_tcp_client_test},
5589 {0, 0, 0}
5590 };
5591
5592 test_st upd_io_tests[] ={
5593 {"udp_set_test", 0, (test_callback_fn)udp_set_test},
5594 {"udp_buffered_set_test", 0, (test_callback_fn)udp_buffered_set_test},
5595 {"udp_set_too_big_test", 0, (test_callback_fn)udp_set_too_big_test},
5596 {"udp_delete_test", 0, (test_callback_fn)udp_delete_test},
5597 {"udp_buffered_delete_test", 0, (test_callback_fn)udp_buffered_delete_test},
5598 {"udp_verbosity_test", 0, (test_callback_fn)udp_verbosity_test},
5599 {"udp_quit_test", 0, (test_callback_fn)udp_quit_test},
5600 {"udp_flush_test", 0, (test_callback_fn)udp_flush_test},
5601 {"udp_incr_test", 0, (test_callback_fn)udp_incr_test},
5602 {"udp_decr_test", 0, (test_callback_fn)udp_decr_test},
5603 {"udp_stat_test", 0, (test_callback_fn)udp_stat_test},
5604 {"udp_version_test", 0, (test_callback_fn)udp_version_test},
5605 {"udp_get_test", 0, (test_callback_fn)udp_get_test},
5606 {"udp_mixed_io_test", 0, (test_callback_fn)udp_mixed_io_test},
5607 {0, 0, 0}
5608 };
5609
5610 /* Clean the server before beginning testing */
5611 test_st tests[] ={
5612 {"flush", 0, (test_callback_fn)flush_test },
5613 {"init", 0, (test_callback_fn)init_test },
5614 {"allocation", 0, (test_callback_fn)allocation_test },
5615 {"server_list_null_test", 0, (test_callback_fn)server_list_null_test},
5616 {"server_unsort", 0, (test_callback_fn)server_unsort_test},
5617 {"server_sort", 0, (test_callback_fn)server_sort_test},
5618 {"server_sort2", 0, (test_callback_fn)server_sort2_test},
5619 {"clone_test", 0, (test_callback_fn)clone_test },
5620 {"connection_test", 0, (test_callback_fn)connection_test},
5621 {"callback_test", 0, (test_callback_fn)callback_test},
5622 {"userdata_test", 0, (test_callback_fn)userdata_test},
5623 {"error", 0, (test_callback_fn)error_test },
5624 {"set", 0, (test_callback_fn)set_test },
5625 {"set2", 0, (test_callback_fn)set_test2 },
5626 {"set3", 0, (test_callback_fn)set_test3 },
5627 {"dump", 1, (test_callback_fn)dump_test},
5628 {"add", 1, (test_callback_fn)add_test },
5629 {"replace", 1, (test_callback_fn)replace_test },
5630 {"delete", 1, (test_callback_fn)delete_test },
5631 {"get", 1, (test_callback_fn)get_test },
5632 {"get2", 0, (test_callback_fn)get_test2 },
5633 {"get3", 0, (test_callback_fn)get_test3 },
5634 {"get4", 0, (test_callback_fn)get_test4 },
5635 {"partial mget", 0, (test_callback_fn)get_test5 },
5636 {"stats_servername", 0, (test_callback_fn)stats_servername_test },
5637 {"increment", 0, (test_callback_fn)increment_test },
5638 {"increment_with_initial", 1, (test_callback_fn)increment_with_initial_test },
5639 {"decrement", 0, (test_callback_fn)decrement_test },
5640 {"decrement_with_initial", 1, (test_callback_fn)decrement_with_initial_test },
5641 {"increment_by_key", 0, (test_callback_fn)increment_by_key_test },
5642 {"increment_with_initial_by_key", 1, (test_callback_fn)increment_with_initial_by_key_test },
5643 {"decrement_by_key", 0, (test_callback_fn)decrement_by_key_test },
5644 {"decrement_with_initial_by_key", 1, (test_callback_fn)decrement_with_initial_by_key_test },
5645 {"quit", 0, (test_callback_fn)quit_test },
5646 {"mget", 1, (test_callback_fn)mget_test },
5647 {"mget_result", 1, (test_callback_fn)mget_result_test },
5648 {"mget_result_alloc", 1, (test_callback_fn)mget_result_alloc_test },
5649 {"mget_result_function", 1, (test_callback_fn)mget_result_function },
5650 {"mget_execute", 1, (test_callback_fn)mget_execute },
5651 {"mget_end", 0, (test_callback_fn)mget_end },
5652 {"get_stats", 0, (test_callback_fn)get_stats },
5653 {"add_host_test", 0, (test_callback_fn)add_host_test },
5654 {"add_host_test_1", 0, (test_callback_fn)add_host_test1 },
5655 {"get_stats_keys", 0, (test_callback_fn)get_stats_keys },
5656 {"version_string_test", 0, (test_callback_fn)version_string_test},
5657 {"bad_key", 1, (test_callback_fn)bad_key_test },
5658 {"memcached_server_cursor", 1, (test_callback_fn)memcached_server_cursor_test },
5659 {"read_through", 1, (test_callback_fn)read_through },
5660 {"delete_through", 1, (test_callback_fn)delete_through },
5661 {"noreply", 1, (test_callback_fn)noreply_test},
5662 {"analyzer", 1, (test_callback_fn)analyzer_test},
5663 #ifdef HAVE_LIBMEMCACHEDUTIL
5664 {"connectionpool", 1, (test_callback_fn)connection_pool_test },
5665 #endif
5666 {"test_get_last_disconnect", 1, (test_callback_fn)test_get_last_disconnect},
5667 {0, 0, 0}
5668 };
5669
5670 test_st behavior_tests[] ={
5671 {"behavior_test", 0, (test_callback_fn)behavior_test},
5672 {0, 0, 0}
5673 };
5674
5675 test_st async_tests[] ={
5676 {"add", 1, (test_callback_fn)add_wrapper },
5677 {0, 0, 0}
5678 };
5679
5680 test_st string_tests[] ={
5681 {"string static with null", 0, (test_callback_fn)string_static_null },
5682 {"string alloc with null", 0, (test_callback_fn)string_alloc_null },
5683 {"string alloc with 1K", 0, (test_callback_fn)string_alloc_with_size },
5684 {"string alloc with malloc failure", 0, (test_callback_fn)string_alloc_with_size_toobig },
5685 {"string append", 0, (test_callback_fn)string_alloc_append },
5686 {"string append failure (too big)", 0, (test_callback_fn)string_alloc_append_toobig },
5687 {0, 0, (test_callback_fn)0}
5688 };
5689
5690 test_st result_tests[] ={
5691 {"result static", 0, (test_callback_fn)result_static},
5692 {"result alloc", 0, (test_callback_fn)result_alloc},
5693 {0, 0, (test_callback_fn)0}
5694 };
5695
5696 test_st version_1_2_3[] ={
5697 {"append", 0, (test_callback_fn)append_test },
5698 {"prepend", 0, (test_callback_fn)prepend_test },
5699 {"cas", 0, (test_callback_fn)cas_test },
5700 {"cas2", 0, (test_callback_fn)cas2_test },
5701 {"append_binary", 0, (test_callback_fn)append_binary_test },
5702 {0, 0, (test_callback_fn)0}
5703 };
5704
5705 test_st user_tests[] ={
5706 {"user_supplied_bug1", 0, (test_callback_fn)user_supplied_bug1 },
5707 {"user_supplied_bug2", 0, (test_callback_fn)user_supplied_bug2 },
5708 {"user_supplied_bug3", 0, (test_callback_fn)user_supplied_bug3 },
5709 {"user_supplied_bug4", 0, (test_callback_fn)user_supplied_bug4 },
5710 {"user_supplied_bug5", 1, (test_callback_fn)user_supplied_bug5 },
5711 {"user_supplied_bug6", 1, (test_callback_fn)user_supplied_bug6 },
5712 {"user_supplied_bug7", 1, (test_callback_fn)user_supplied_bug7 },
5713 {"user_supplied_bug8", 1, (test_callback_fn)user_supplied_bug8 },
5714 {"user_supplied_bug9", 1, (test_callback_fn)user_supplied_bug9 },
5715 {"user_supplied_bug10", 1, (test_callback_fn)user_supplied_bug10 },
5716 {"user_supplied_bug11", 1, (test_callback_fn)user_supplied_bug11 },
5717 {"user_supplied_bug12", 1, (test_callback_fn)user_supplied_bug12 },
5718 {"user_supplied_bug13", 1, (test_callback_fn)user_supplied_bug13 },
5719 {"user_supplied_bug14", 1, (test_callback_fn)user_supplied_bug14 },
5720 {"user_supplied_bug15", 1, (test_callback_fn)user_supplied_bug15 },
5721 {"user_supplied_bug16", 1, (test_callback_fn)user_supplied_bug16 },
5722 #ifndef __sun
5723 /*
5724 ** It seems to be something weird with the character sets..
5725 ** value_fetch is unable to parse the value line (iscntrl "fails"), so I
5726 ** guess I need to find out how this is supposed to work.. Perhaps I need
5727 ** to run the test in a specific locale (I tried zh_CN.UTF-8 without success,
5728 ** so just disable the code for now...).
5729 */
5730 {"user_supplied_bug17", 1, (test_callback_fn)user_supplied_bug17 },
5731 #endif
5732 {"user_supplied_bug18", 1, (test_callback_fn)user_supplied_bug18 },
5733 {"user_supplied_bug19", 1, (test_callback_fn)user_supplied_bug19 },
5734 {"user_supplied_bug20", 1, (test_callback_fn)user_supplied_bug20 },
5735 {"user_supplied_bug21", 1, (test_callback_fn)user_supplied_bug21 },
5736 {"wrong_failure_counter_test", 1, (test_callback_fn)wrong_failure_counter_test},
5737 {0, 0, (test_callback_fn)0}
5738 };
5739
5740 test_st replication_tests[]= {
5741 {"set", 1, (test_callback_fn)replication_set_test },
5742 {"get", 0, (test_callback_fn)replication_get_test },
5743 {"mget", 0, (test_callback_fn)replication_mget_test },
5744 {"delete", 0, (test_callback_fn)replication_delete_test },
5745 {"rand_mget", 0, (test_callback_fn)replication_randomize_mget_test },
5746 {0, 0, (test_callback_fn)0}
5747 };
5748
5749 /*
5750 * The following test suite is used to verify that we don't introduce
5751 * regression bugs. If you want more information about the bug / test,
5752 * you should look in the bug report at
5753 * http://bugs.launchpad.net/libmemcached
5754 */
5755 test_st regression_tests[]= {
5756 {"lp:434484", 1, (test_callback_fn)regression_bug_434484 },
5757 {"lp:434843", 1, (test_callback_fn)regression_bug_434843 },
5758 {"lp:434843 buffered", 1, (test_callback_fn)regression_bug_434843_buffered },
5759 {"lp:421108", 1, (test_callback_fn)regression_bug_421108 },
5760 {"lp:442914", 1, (test_callback_fn)regression_bug_442914 },
5761 {"lp:447342", 1, (test_callback_fn)regression_bug_447342 },
5762 {"lp:463297", 1, (test_callback_fn)regression_bug_463297 },
5763 {0, 0, (test_callback_fn)0}
5764 };
5765
5766 test_st ketama_compatibility[]= {
5767 {"libmemcached", 1, (test_callback_fn)ketama_compatibility_libmemcached },
5768 {"spymemcached", 1, (test_callback_fn)ketama_compatibility_spymemcached },
5769 {0, 0, (test_callback_fn)0}
5770 };
5771
5772 test_st generate_tests[] ={
5773 {"generate_pairs", 1, (test_callback_fn)generate_pairs },
5774 {"generate_data", 1, (test_callback_fn)generate_data },
5775 {"get_read", 0, (test_callback_fn)get_read },
5776 {"delete_generate", 0, (test_callback_fn)delete_generate },
5777 {"generate_buffer_data", 1, (test_callback_fn)generate_buffer_data },
5778 {"delete_buffer", 0, (test_callback_fn)delete_buffer_generate},
5779 {"generate_data", 1, (test_callback_fn)generate_data },
5780 {"mget_read", 0, (test_callback_fn)mget_read },
5781 {"mget_read_result", 0, (test_callback_fn)mget_read_result },
5782 {"mget_read_function", 0, (test_callback_fn)mget_read_function },
5783 {"cleanup", 1, (test_callback_fn)cleanup_pairs },
5784 {"generate_large_pairs", 1, (test_callback_fn)generate_large_pairs },
5785 {"generate_data", 1, (test_callback_fn)generate_data },
5786 {"generate_buffer_data", 1, (test_callback_fn)generate_buffer_data },
5787 {"cleanup", 1, (test_callback_fn)cleanup_pairs },
5788 {0, 0, (test_callback_fn)0}
5789 };
5790
5791 test_st consistent_tests[] ={
5792 {"generate_pairs", 1, (test_callback_fn)generate_pairs },
5793 {"generate_data", 1, (test_callback_fn)generate_data },
5794 {"get_read", 0, (test_callback_fn)get_read_count },
5795 {"cleanup", 1, (test_callback_fn)cleanup_pairs },
5796 {0, 0, (test_callback_fn)0}
5797 };
5798
5799 test_st consistent_weighted_tests[] ={
5800 {"generate_pairs", 1, (test_callback_fn)generate_pairs },
5801 {"generate_data", 1, (test_callback_fn)generate_data_with_stats },
5802 {"get_read", 0, (test_callback_fn)get_read_count },
5803 {"cleanup", 1, (test_callback_fn)cleanup_pairs },
5804 {0, 0, (test_callback_fn)0}
5805 };
5806
5807 test_st hsieh_availability[] ={
5808 {"hsieh_avaibility_test", 0, (test_callback_fn)hsieh_avaibility_test},
5809 {0, 0, (test_callback_fn)0}
5810 };
5811
5812 #if 0
5813 test_st hash_sanity[] ={
5814 {"hash sanity", 0, (test_callback_fn)hash_sanity_test},
5815 {0, 0, (test_callback_fn)0}
5816 };
5817 #endif
5818
5819 test_st ketama_auto_eject_hosts[] ={
5820 {"auto_eject_hosts", 1, (test_callback_fn)auto_eject_hosts },
5821 {"output_ketama_weighted_keys", 1, (test_callback_fn)output_ketama_weighted_keys },
5822 {0, 0, (test_callback_fn)0}
5823 };
5824
5825 test_st hash_tests[] ={
5826 {"md5", 0, (test_callback_fn)md5_run },
5827 {"crc", 0, (test_callback_fn)crc_run },
5828 {"fnv1_64", 0, (test_callback_fn)fnv1_64_run },
5829 {"fnv1a_64", 0, (test_callback_fn)fnv1a_64_run },
5830 {"fnv1_32", 0, (test_callback_fn)fnv1_32_run },
5831 {"fnv1a_32", 0, (test_callback_fn)fnv1a_32_run },
5832 {"hsieh", 0, (test_callback_fn)hsieh_run },
5833 {"murmur", 0, (test_callback_fn)murmur_run },
5834 {"jenkis", 0, (test_callback_fn)jenkins_run },
5835 {0, 0, (test_callback_fn)0}
5836 };
5837
5838 collection_st collection[] ={
5839 #if 0
5840 {"hash_sanity", 0, 0, hash_sanity},
5841 #endif
5842 {"hsieh_availability", 0, 0, hsieh_availability},
5843 {"udp_setup", (test_callback_fn)init_udp, 0, udp_setup_server_tests},
5844 {"udp_io", (test_callback_fn)init_udp, 0, upd_io_tests},
5845 {"udp_binary_io", (test_callback_fn)binary_init_udp, 0, upd_io_tests},
5846 {"block", 0, 0, tests},
5847 {"binary", (test_callback_fn)pre_binary, 0, tests},
5848 {"nonblock", (test_callback_fn)pre_nonblock, 0, tests},
5849 {"nodelay", (test_callback_fn)pre_nodelay, 0, tests},
5850 {"settimer", (test_callback_fn)pre_settimer, 0, tests},
5851 {"md5", (test_callback_fn)pre_md5, 0, tests},
5852 {"crc", (test_callback_fn)pre_crc, 0, tests},
5853 {"hsieh", (test_callback_fn)pre_hsieh, 0, tests},
5854 {"jenkins", (test_callback_fn)pre_jenkins, 0, tests},
5855 {"fnv1_64", (test_callback_fn)pre_hash_fnv1_64, 0, tests},
5856 {"fnv1a_64", (test_callback_fn)pre_hash_fnv1a_64, 0, tests},
5857 {"fnv1_32", (test_callback_fn)pre_hash_fnv1_32, 0, tests},
5858 {"fnv1a_32", (test_callback_fn)pre_hash_fnv1a_32, 0, tests},
5859 {"ketama", (test_callback_fn)pre_behavior_ketama, 0, tests},
5860 {"ketama_auto_eject_hosts", (test_callback_fn)pre_behavior_ketama, 0, ketama_auto_eject_hosts},
5861 {"unix_socket", (test_callback_fn)pre_unix_socket, 0, tests},
5862 {"unix_socket_nodelay", (test_callback_fn)pre_nodelay, 0, tests},
5863 {"poll_timeout", (test_callback_fn)poll_timeout, 0, tests},
5864 {"gets", (test_callback_fn)enable_cas, 0, tests},
5865 {"consistent_crc", (test_callback_fn)enable_consistent_crc, 0, tests},
5866 {"consistent_hsieh", (test_callback_fn)enable_consistent_hsieh, 0, tests},
5867 #ifdef MEMCACHED_ENABLE_DEPRECATED
5868 {"deprecated_memory_allocators", (test_callback_fn)deprecated_set_memory_alloc, 0, tests},
5869 #endif
5870 {"memory_allocators", (test_callback_fn)set_memory_alloc, 0, tests},
5871 {"prefix", (test_callback_fn)set_prefix, 0, tests},
5872 {"version_1_2_3", (test_callback_fn)check_for_1_2_3, 0, version_1_2_3},
5873 {"string", 0, 0, string_tests},
5874 {"result", 0, 0, result_tests},
5875 {"async", (test_callback_fn)pre_nonblock, 0, async_tests},
5876 {"async_binary", (test_callback_fn)pre_nonblock_binary, 0, async_tests},
5877 {"user", 0, 0, user_tests},
5878 {"generate", 0, 0, generate_tests},
5879 {"generate_hsieh", (test_callback_fn)pre_hsieh, 0, generate_tests},
5880 {"generate_ketama", (test_callback_fn)pre_behavior_ketama, 0, generate_tests},
5881 {"generate_hsieh_consistent", (test_callback_fn)enable_consistent_hsieh, 0, generate_tests},
5882 {"generate_md5", (test_callback_fn)pre_md5, 0, generate_tests},
5883 {"generate_murmur", (test_callback_fn)pre_murmur, 0, generate_tests},
5884 {"generate_jenkins", (test_callback_fn)pre_jenkins, 0, generate_tests},
5885 {"generate_nonblock", (test_callback_fn)pre_nonblock, 0, generate_tests},
5886 {"consistent_not", 0, 0, consistent_tests},
5887 {"consistent_ketama", (test_callback_fn)pre_behavior_ketama, 0, consistent_tests},
5888 {"consistent_ketama_weighted", (test_callback_fn)pre_behavior_ketama_weighted, 0, consistent_weighted_tests},
5889 {"ketama_compat", 0, 0, ketama_compatibility},
5890 {"test_hashes", 0, 0, hash_tests},
5891 {"replication", (test_callback_fn)pre_replication, 0, replication_tests},
5892 {"replication_noblock", (test_callback_fn)pre_replication_noblock, 0, replication_tests},
5893 {"regression", 0, 0, regression_tests},
5894 {"behaviors", 0, 0, behavior_tests},
5895 {0, 0, 0, 0}
5896 };
5897
5898 #define SERVERS_TO_CREATE 5
5899
5900 #include "libmemcached_world.h"
5901
5902 void get_world(world_st *world)
5903 {
5904 world->collections= collection;
5905
5906 world->create= (test_callback_create_fn)world_create;
5907 world->destroy= (test_callback_fn)world_destroy;
5908
5909 world->test.startup= (test_callback_fn)world_test_startup;
5910 world->test.flush= (test_callback_fn)world_flush;
5911 world->test.pre_run= (test_callback_fn)world_pre_run;
5912 world->test.post_run= (test_callback_fn)world_post_run;
5913 world->test.on_error= (test_callback_error_fn)world_on_error;
5914
5915 world->collection.startup= (test_callback_fn)world_container_startup;
5916 world->collection.shutdown= (test_callback_fn)world_container_shutdown;
5917
5918 world->runner= &defualt_libmemcached_runner;
5919 }