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