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