Merge Trond --without-docs
[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 #if !defined(__sun) && !defined(__OpenBSD__)
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, (uint8_t)(instance->micro_version -1));
4429 else if (instance->minor_version > 0)
4430 if_successful= libmemcached_util_version_check(memc, instance->major_version, (uint8_t)(instance->minor_version - 1), instance->micro_version);
4431 else if (instance->major_version > 0)
4432 if_successful= libmemcached_util_version_check(memc, (uint8_t)(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, (uint8_t)(instance->micro_version +1));
4438 else if (instance->minor_version > 0)
4439 if_successful= libmemcached_util_version_check(memc, instance->major_version, (uint8_t)(instance->minor_version +1), instance->micro_version);
4440 else if (instance->major_version > 0)
4441 if_successful= libmemcached_util_version_check(memc, (uint8_t)(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 test_false(value);
5032 test_true(len == 0);
5033 test_true(rc == MEMCACHED_ERRNO);
5034
5035 memcached_free(tl_memc_h);
5036
5037 return TEST_SUCCESS;
5038 }
5039
5040 /*
5041 We connect to a server which exists, but search for a key that does not exist.
5042 */
5043 static test_return_t memcached_get_MEMCACHED_NOTFOUND(memcached_st *memc)
5044 {
5045 const char *key= "MemcachedKeyNotEXIST";
5046 size_t len;
5047 uint32_t flags;
5048 memcached_return rc;
5049 char *value;
5050
5051 // See if memcached is reachable.
5052 value= memcached_get(memc, key, strlen(key), &len, &flags, &rc);
5053
5054 test_false(value);
5055 test_true(len == 0);
5056 test_true(rc == MEMCACHED_NOTFOUND);
5057
5058 return TEST_SUCCESS;
5059 }
5060
5061 /*
5062 Test case adapted from John Gorman <johngorman2@gmail.com>
5063
5064 We are testing the error condition when we connect to a server via memcached_get_by_key()
5065 but find that the server is not available.
5066 */
5067 static test_return_t memcached_get_by_key_MEMCACHED_ERRNO(memcached_st *memc)
5068 {
5069 (void)memc;
5070 memcached_st *tl_memc_h;
5071 memcached_server_st *servers;
5072
5073 const char *key= "MemcachedLives";
5074 size_t len;
5075 uint32_t flags;
5076 memcached_return rc;
5077 char *value;
5078
5079 // Create a handle.
5080 tl_memc_h= memcached_create(NULL);
5081 servers= memcached_servers_parse("localhost:9898,localhost:9899"); // This server should not exist
5082 memcached_server_push(tl_memc_h, servers);
5083 memcached_server_list_free(servers);
5084
5085 // See if memcached is reachable.
5086 value= memcached_get_by_key(tl_memc_h, key, strlen(key), key, strlen(key), &len, &flags, &rc);
5087
5088 test_false(value);
5089 test_true(len == 0);
5090 test_true(rc == MEMCACHED_ERRNO);
5091
5092 memcached_free(tl_memc_h);
5093
5094 return TEST_SUCCESS;
5095 }
5096
5097 /*
5098 We connect to a server which exists, but search for a key that does not exist.
5099 */
5100 static test_return_t memcached_get_by_key_MEMCACHED_NOTFOUND(memcached_st *memc)
5101 {
5102 const char *key= "MemcachedKeyNotEXIST";
5103 size_t len;
5104 uint32_t flags;
5105 memcached_return rc;
5106 char *value;
5107
5108 // See if memcached is reachable.
5109 value= memcached_get_by_key(memc, key, strlen(key), key, strlen(key), &len, &flags, &rc);
5110
5111 test_false(value);
5112 test_true(len == 0);
5113 test_true(rc == MEMCACHED_NOTFOUND);
5114
5115 return TEST_SUCCESS;
5116 }
5117
5118
5119 static test_return_t ketama_compatibility_libmemcached(memcached_st *trash)
5120 {
5121 memcached_return_t rc;
5122 uint64_t value;
5123 int x;
5124 memcached_server_st *server_pool;
5125 memcached_st *memc;
5126
5127 (void)trash;
5128
5129 memc= memcached_create(NULL);
5130 test_true(memc);
5131
5132 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
5133 test_true(rc == MEMCACHED_SUCCESS);
5134
5135 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
5136 test_true(value == 1);
5137
5138 test_true(memcached_behavior_set_distribution(memc, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA) == MEMCACHED_SUCCESS);
5139 test_true(memcached_behavior_get_distribution(memc) == MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA);
5140
5141
5142 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");
5143 memcached_server_push(memc, server_pool);
5144
5145 /* verify that the server list was parsed okay. */
5146 test_true(memcached_server_count(memc) == 8);
5147 test_strcmp(server_pool[0].hostname, "10.0.1.1");
5148 test_true(server_pool[0].port == 11211);
5149 test_true(server_pool[0].weight == 600);
5150 test_strcmp(server_pool[2].hostname, "10.0.1.3");
5151 test_true(server_pool[2].port == 11211);
5152 test_true(server_pool[2].weight == 200);
5153 test_strcmp(server_pool[7].hostname, "10.0.1.8");
5154 test_true(server_pool[7].port == 11211);
5155 test_true(server_pool[7].weight == 100);
5156
5157 /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets
5158 * us test the boundary wraparound.
5159 */
5160 test_true(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->continuum[0].index);
5161
5162 /* verify the standard ketama set. */
5163 for (x= 0; x < 99; x++)
5164 {
5165 uint32_t server_idx = memcached_generate_hash(memc, ketama_test_cases[x].key, strlen(ketama_test_cases[x].key));
5166 memcached_server_instance_st instance=
5167 memcached_server_instance_by_position(memc, server_idx);
5168 const char *hostname = memcached_server_name(instance);
5169
5170 test_strcmp(hostname, ketama_test_cases[x].server);
5171 }
5172
5173 memcached_server_list_free(server_pool);
5174 memcached_free(memc);
5175
5176 return TEST_SUCCESS;
5177 }
5178
5179 static test_return_t ketama_compatibility_spymemcached(memcached_st *trash)
5180 {
5181 memcached_return_t rc;
5182 uint64_t value;
5183 int x;
5184 memcached_server_st *server_pool;
5185 memcached_st *memc;
5186
5187 (void)trash;
5188
5189 memc= memcached_create(NULL);
5190 test_true(memc);
5191
5192 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, 1);
5193 test_true(rc == MEMCACHED_SUCCESS);
5194
5195 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
5196 test_true(value == 1);
5197
5198 test_true(memcached_behavior_set_distribution(memc, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY) == MEMCACHED_SUCCESS);
5199 test_true(memcached_behavior_get_distribution(memc) == MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY);
5200
5201 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");
5202 memcached_server_push(memc, server_pool);
5203
5204 /* verify that the server list was parsed okay. */
5205 test_true(memcached_server_count(memc) == 8);
5206 test_strcmp(server_pool[0].hostname, "10.0.1.1");
5207 test_true(server_pool[0].port == 11211);
5208 test_true(server_pool[0].weight == 600);
5209 test_strcmp(server_pool[2].hostname, "10.0.1.3");
5210 test_true(server_pool[2].port == 11211);
5211 test_true(server_pool[2].weight == 200);
5212 test_strcmp(server_pool[7].hostname, "10.0.1.8");
5213 test_true(server_pool[7].port == 11211);
5214 test_true(server_pool[7].weight == 100);
5215
5216 /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets
5217 * us test the boundary wraparound.
5218 */
5219 test_true(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->continuum[0].index);
5220
5221 /* verify the standard ketama set. */
5222 for (x= 0; x < 99; x++)
5223 {
5224 uint32_t server_idx= memcached_generate_hash(memc, ketama_test_cases_spy[x].key, strlen(ketama_test_cases_spy[x].key));
5225
5226 memcached_server_instance_st instance=
5227 memcached_server_instance_by_position(memc, server_idx);
5228
5229 const char *hostname= memcached_server_name(instance);
5230
5231 test_strcmp(hostname, ketama_test_cases_spy[x].server);
5232 }
5233
5234 memcached_server_list_free(server_pool);
5235 memcached_free(memc);
5236
5237 return TEST_SUCCESS;
5238 }
5239
5240 static test_return_t regression_bug_434484(memcached_st *memc)
5241 {
5242 test_return_t test_rc;
5243 test_rc= pre_binary(memc);
5244
5245 if (test_rc != TEST_SUCCESS)
5246 return test_rc;
5247
5248 memcached_return_t ret;
5249 const char *key= "regression_bug_434484";
5250 size_t keylen= strlen(key);
5251
5252 ret= memcached_append(memc, key, keylen, key, keylen, 0, 0);
5253 test_true(ret == MEMCACHED_NOTSTORED);
5254
5255 size_t size= 2048 * 1024;
5256 void *data= calloc(1, size);
5257 test_true(data != NULL);
5258 ret= memcached_set(memc, key, keylen, data, size, 0, 0);
5259 test_true(ret == MEMCACHED_E2BIG);
5260 free(data);
5261
5262 return TEST_SUCCESS;
5263 }
5264
5265 static test_return_t regression_bug_434843(memcached_st *memc)
5266 {
5267 test_return_t test_rc;
5268 test_rc= pre_binary(memc);
5269
5270 if (test_rc != TEST_SUCCESS)
5271 return test_rc;
5272
5273 memcached_return_t rc;
5274 size_t counter= 0;
5275 memcached_execute_fn callbacks[1]= { [0]= &callback_counter };
5276
5277 /*
5278 * I only want to hit only _one_ server so I know the number of requests I'm
5279 * sending in the pipleine to the server. Let's try to do a multiget of
5280 * 1024 (that should satisfy most users don't you think?). Future versions
5281 * will include a mget_execute function call if you need a higher number.
5282 */
5283 uint32_t number_of_hosts= memcached_server_count(memc);
5284 memc->number_of_hosts= 1;
5285 const size_t max_keys= 1024;
5286 char **keys= calloc(max_keys, sizeof(char*));
5287 size_t *key_length=calloc(max_keys, sizeof(size_t));
5288
5289 for (size_t x= 0; x < max_keys; ++x)
5290 {
5291 char k[251];
5292
5293 key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%zu", x);
5294 keys[x]= strdup(k);
5295 test_true(keys[x] != NULL);
5296 }
5297
5298 /*
5299 * Run two times.. the first time we should have 100% cache miss,
5300 * and the second time we should have 100% cache hits
5301 */
5302 for (size_t y= 0; y < 2; y++)
5303 {
5304 rc= memcached_mget(memc, (const char**)keys, key_length, max_keys);
5305 test_true(rc == MEMCACHED_SUCCESS);
5306 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
5307
5308 if (y == 0)
5309 {
5310 /* The first iteration should give me a 100% cache miss. verify that*/
5311 char blob[1024]= { 0 };
5312
5313 test_true(counter == 0);
5314
5315 for (size_t x= 0; x < max_keys; ++x)
5316 {
5317 rc= memcached_add(memc, keys[x], key_length[x],
5318 blob, sizeof(blob), 0, 0);
5319 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5320 }
5321 }
5322 else
5323 {
5324 /* Verify that we received all of the key/value pairs */
5325 test_true(counter == max_keys);
5326 }
5327 }
5328
5329 /* Release allocated resources */
5330 for (size_t x= 0; x < max_keys; ++x)
5331 {
5332 free(keys[x]);
5333 }
5334 free(keys);
5335 free(key_length);
5336
5337 memc->number_of_hosts= number_of_hosts;
5338
5339 return TEST_SUCCESS;
5340 }
5341
5342 static test_return_t regression_bug_434843_buffered(memcached_st *memc)
5343 {
5344 memcached_return_t rc;
5345 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1);
5346 test_true(rc == MEMCACHED_SUCCESS);
5347
5348 return regression_bug_434843(memc);
5349 }
5350
5351 static test_return_t regression_bug_421108(memcached_st *memc)
5352 {
5353 memcached_return_t rc;
5354 memcached_stat_st *memc_stat= memcached_stat(memc, NULL, &rc);
5355 test_true(rc == MEMCACHED_SUCCESS);
5356
5357 char *bytes= memcached_stat_get_value(memc, memc_stat, "bytes", &rc);
5358 test_true(rc == MEMCACHED_SUCCESS);
5359 test_true(bytes != NULL);
5360 char *bytes_read= memcached_stat_get_value(memc, memc_stat,
5361 "bytes_read", &rc);
5362 test_true(rc == MEMCACHED_SUCCESS);
5363 test_true(bytes_read != NULL);
5364
5365 char *bytes_written= memcached_stat_get_value(memc, memc_stat,
5366 "bytes_written", &rc);
5367 test_true(rc == MEMCACHED_SUCCESS);
5368 test_true(bytes_written != NULL);
5369
5370 test_true(strcmp(bytes, bytes_read) != 0);
5371 test_true(strcmp(bytes, bytes_written) != 0);
5372
5373 /* Release allocated resources */
5374 free(bytes);
5375 free(bytes_read);
5376 free(bytes_written);
5377 memcached_stat_free(NULL, memc_stat);
5378
5379 return TEST_SUCCESS;
5380 }
5381
5382 /*
5383 * The test case isn't obvious so I should probably document why
5384 * it works the way it does. Bug 442914 was caused by a bug
5385 * in the logic in memcached_purge (it did not handle the case
5386 * where the number of bytes sent was equal to the watermark).
5387 * In this test case, create messages so that we hit that case
5388 * and then disable noreply mode and issue a new command to
5389 * verify that it isn't stuck. If we change the format for the
5390 * delete command or the watermarks, we need to update this
5391 * test....
5392 */
5393 static test_return_t regression_bug_442914(memcached_st *memc)
5394 {
5395 memcached_return_t rc;
5396 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1);
5397 test_true(rc == MEMCACHED_SUCCESS);
5398 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 1);
5399
5400 uint32_t number_of_hosts= memcached_server_count(memc);
5401 memc->number_of_hosts= 1;
5402
5403 char k[250];
5404 size_t len;
5405
5406 for (uint32_t x= 0; x < 250; ++x)
5407 {
5408 len= (size_t)snprintf(k, sizeof(k), "%0250u", x);
5409 rc= memcached_delete(memc, k, len, 0);
5410 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5411 }
5412
5413 (void)snprintf(k, sizeof(k), "%037u", 251U);
5414 len= strlen(k);
5415
5416 rc= memcached_delete(memc, k, len, 0);
5417 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5418
5419 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 0);
5420 test_true(rc == MEMCACHED_SUCCESS);
5421 rc= memcached_delete(memc, k, len, 0);
5422 test_true(rc == MEMCACHED_NOTFOUND);
5423
5424 memc->number_of_hosts= number_of_hosts;
5425
5426 return TEST_SUCCESS;
5427 }
5428
5429 static test_return_t regression_bug_447342(memcached_st *memc)
5430 {
5431 memcached_server_instance_st instance_one;
5432 memcached_server_instance_st instance_two;
5433
5434 if (memcached_server_count(memc) < 3 || pre_replication(memc) != MEMCACHED_SUCCESS)
5435 return TEST_SKIPPED;
5436
5437 memcached_return_t rc;
5438
5439 rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 2);
5440 test_true(rc == MEMCACHED_SUCCESS);
5441
5442 const size_t max_keys= 100;
5443 char **keys= calloc(max_keys, sizeof(char*));
5444 size_t *key_length= calloc(max_keys, sizeof(size_t));
5445
5446 for (size_t x= 0; x < max_keys; ++x)
5447 {
5448 char k[251];
5449
5450 key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%zu", x);
5451 keys[x]= strdup(k);
5452 test_true(keys[x] != NULL);
5453 rc= memcached_set(memc, k, key_length[x], k, key_length[x], 0, 0);
5454 test_true(rc == MEMCACHED_SUCCESS);
5455 }
5456
5457 /*
5458 ** We are using the quiet commands to store the replicas, so we need
5459 ** to ensure that all of them are processed before we can continue.
5460 ** In the test we go directly from storing the object to trying to
5461 ** receive the object from all of the different servers, so we
5462 ** could end up in a race condition (the memcached server hasn't yet
5463 ** processed the quiet command from the replication set when it process
5464 ** the request from the other client (created by the clone)). As a
5465 ** workaround for that we call memcached_quit to send the quit command
5466 ** to the server and wait for the response ;-) If you use the test code
5467 ** as an example for your own code, please note that you shouldn't need
5468 ** to do this ;-)
5469 */
5470 memcached_quit(memc);
5471
5472 /* Verify that all messages are stored, and we didn't stuff too much
5473 * into the servers
5474 */
5475 rc= memcached_mget(memc, (const char* const *)keys, key_length, max_keys);
5476 test_true(rc == MEMCACHED_SUCCESS);
5477
5478 size_t counter= 0;
5479 memcached_execute_fn callbacks[1]= { [0]= &callback_counter };
5480 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
5481 /* Verify that we received all of the key/value pairs */
5482 test_true(counter == max_keys);
5483
5484 memcached_quit(memc);
5485 /*
5486 * Don't do the following in your code. I am abusing the internal details
5487 * within the library, and this is not a supported interface.
5488 * This is to verify correct behavior in the library. Fake that two servers
5489 * are dead..
5490 */
5491 instance_one= memcached_server_instance_by_position(memc, 0);
5492 instance_two= memcached_server_instance_by_position(memc, 2);
5493 in_port_t port0= instance_one->port;
5494 in_port_t port2= instance_two->port;
5495
5496 ((memcached_server_write_instance_st)instance_one)->port= 0;
5497 ((memcached_server_write_instance_st)instance_two)->port= 0;
5498
5499 rc= memcached_mget(memc, (const char* const *)keys, key_length, max_keys);
5500 test_true(rc == MEMCACHED_SUCCESS);
5501
5502 counter= 0;
5503 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
5504 test_true(counter == (unsigned int)max_keys);
5505
5506 /* restore the memc handle */
5507 ((memcached_server_write_instance_st)instance_one)->port= port0;
5508 ((memcached_server_write_instance_st)instance_two)->port= port2;
5509
5510 memcached_quit(memc);
5511
5512 /* Remove half of the objects */
5513 for (size_t x= 0; x < max_keys; ++x)
5514 {
5515 if (x & 1)
5516 {
5517 rc= memcached_delete(memc, keys[x], key_length[x], 0);
5518 test_true(rc == MEMCACHED_SUCCESS);
5519 }
5520 }
5521
5522 memcached_quit(memc);
5523 ((memcached_server_write_instance_st)instance_one)->port= 0;
5524 ((memcached_server_write_instance_st)instance_two)->port= 0;
5525
5526 /* now retry the command, this time we should have cache misses */
5527 rc= memcached_mget(memc, (const char* const *)keys, key_length, max_keys);
5528 test_true(rc == MEMCACHED_SUCCESS);
5529
5530 counter= 0;
5531 rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
5532 test_true(counter == (unsigned int)(max_keys >> 1));
5533
5534 /* Release allocated resources */
5535 for (size_t x= 0; x < max_keys; ++x)
5536 {
5537 free(keys[x]);
5538 }
5539 free(keys);
5540 free(key_length);
5541
5542 /* restore the memc handle */
5543 ((memcached_server_write_instance_st)instance_one)->port= port0;
5544 ((memcached_server_write_instance_st)instance_two)->port= port2;
5545
5546 return TEST_SUCCESS;
5547 }
5548
5549 static test_return_t regression_bug_463297(memcached_st *memc)
5550 {
5551 memcached_st *memc_clone= memcached_clone(NULL, memc);
5552 test_true(memc_clone != NULL);
5553 test_true(memcached_version(memc_clone) == MEMCACHED_SUCCESS);
5554
5555 memcached_server_instance_st instance=
5556 memcached_server_instance_by_position(memc_clone, 0);
5557
5558 if (instance->major_version > 1 ||
5559 (instance->major_version == 1 &&
5560 instance->minor_version > 2))
5561 {
5562 /* Binary protocol doesn't support deferred delete */
5563 memcached_st *bin_clone= memcached_clone(NULL, memc);
5564 test_true(bin_clone != NULL);
5565 test_true(memcached_behavior_set(bin_clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1) == MEMCACHED_SUCCESS);
5566 test_true(memcached_delete(bin_clone, "foo", 3, 1) == MEMCACHED_INVALID_ARGUMENTS);
5567 memcached_free(bin_clone);
5568
5569 memcached_quit(memc_clone);
5570
5571 /* If we know the server version, deferred delete should fail
5572 * with invalid arguments */
5573 test_true(memcached_delete(memc_clone, "foo", 3, 1) == MEMCACHED_INVALID_ARGUMENTS);
5574
5575 /* If we don't know the server version, we should get a protocol error */
5576 memcached_return_t rc= memcached_delete(memc, "foo", 3, 1);
5577
5578 /* but there is a bug in some of the memcached servers (1.4) that treats
5579 * the counter as noreply so it doesn't send the proper error message
5580 */
5581 test_true(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR);
5582
5583 /* And buffered mode should be disabled and we should get protocol error */
5584 test_true(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1) == MEMCACHED_SUCCESS);
5585 rc= memcached_delete(memc, "foo", 3, 1);
5586 test_true(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR);
5587
5588 /* Same goes for noreply... */
5589 test_true(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1) == MEMCACHED_SUCCESS);
5590 rc= memcached_delete(memc, "foo", 3, 1);
5591 test_true(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR);
5592
5593 /* but a normal request should go through (and be buffered) */
5594 test_true((rc= memcached_delete(memc, "foo", 3, 0)) == MEMCACHED_BUFFERED);
5595 test_true(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
5596
5597 test_true(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 0) == MEMCACHED_SUCCESS);
5598 /* unbuffered noreply should be success */
5599 test_true(memcached_delete(memc, "foo", 3, 0) == MEMCACHED_SUCCESS);
5600 /* unbuffered with reply should be not found... */
5601 test_true(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 0) == MEMCACHED_SUCCESS);
5602 test_true(memcached_delete(memc, "foo", 3, 0) == MEMCACHED_NOTFOUND);
5603 }
5604
5605 memcached_free(memc_clone);
5606 return TEST_SUCCESS;
5607 }
5608
5609
5610 /* Test memcached_server_get_last_disconnect
5611 * For a working server set, shall be NULL
5612 * For a set of non existing server, shall not be NULL
5613 */
5614 static test_return_t test_get_last_disconnect(memcached_st *memc)
5615 {
5616 memcached_return_t rc;
5617 memcached_server_instance_st disconnected_server;
5618
5619 /* With the working set of server */
5620 const char *key= "marmotte";
5621 const char *value= "milka";
5622
5623 memcached_reset_last_disconnected_server(memc);
5624 rc= memcached_set(memc, key, strlen(key),
5625 value, strlen(value),
5626 (time_t)0, (uint32_t)0);
5627 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5628
5629 disconnected_server = memcached_server_get_last_disconnect(memc);
5630 test_true(disconnected_server == NULL);
5631
5632 /* With a non existing server */
5633 memcached_st *mine;
5634 memcached_server_st *servers;
5635
5636 const char *server_list= "localhost:9";
5637
5638 servers= memcached_servers_parse(server_list);
5639 test_true(servers);
5640 mine= memcached_create(NULL);
5641 rc= memcached_server_push(mine, servers);
5642 test_true(rc == MEMCACHED_SUCCESS);
5643 memcached_server_list_free(servers);
5644 test_true(mine);
5645
5646 rc= memcached_set(mine, key, strlen(key),
5647 value, strlen(value),
5648 (time_t)0, (uint32_t)0);
5649 test_true(rc != MEMCACHED_SUCCESS);
5650
5651 disconnected_server= memcached_server_get_last_disconnect(mine);
5652 if (disconnected_server == NULL)
5653 {
5654 fprintf(stderr, "RC %s\n", memcached_strerror(mine, rc));
5655 abort();
5656 }
5657 test_true(disconnected_server != NULL);
5658 test_true(memcached_server_port(disconnected_server)== 9);
5659 test_true(strncmp(memcached_server_name(disconnected_server),"localhost",9) == 0);
5660
5661 memcached_quit(mine);
5662 memcached_free(mine);
5663
5664 return TEST_SUCCESS;
5665 }
5666
5667 static test_return_t test_verbosity(memcached_st *memc)
5668 {
5669 memcached_verbosity(memc, 3);
5670
5671 return TEST_SUCCESS;
5672 }
5673
5674 static test_return_t test_server_failure(memcached_st *memc)
5675 {
5676 memcached_st *local_memc;
5677 memcached_server_instance_st instance= memcached_server_instance_by_position(memc, 0);
5678
5679 local_memc= memcached_create(NULL);
5680
5681 memcached_server_add(local_memc, memcached_server_name(instance), memcached_server_port(instance));
5682 memcached_behavior_set(local_memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, 2);
5683
5684 uint32_t server_count= memcached_server_count(local_memc);
5685
5686 test_true(server_count == 1);
5687
5688 // Disable the server
5689 instance= memcached_server_instance_by_position(local_memc, 0);
5690 ((memcached_server_write_instance_st)instance)->server_failure_counter= 2;
5691
5692 memcached_return_t rc;
5693 rc= memcached_set(local_memc, "foo", strlen("foo"),
5694 NULL, 0,
5695 (time_t)0, (uint32_t)0);
5696 test_true(rc == MEMCACHED_SERVER_MARKED_DEAD);
5697
5698 ((memcached_server_write_instance_st)instance)->server_failure_counter= 0;
5699 rc= memcached_set(local_memc, "foo", strlen("foo"),
5700 NULL, 0,
5701 (time_t)0, (uint32_t)0);
5702 test_true(rc == MEMCACHED_SUCCESS);
5703
5704
5705 memcached_free(local_memc);
5706
5707 return TEST_SUCCESS;
5708 }
5709
5710 static test_return_t test_cull_servers(memcached_st *memc)
5711 {
5712 uint32_t count = memcached_server_count(memc);
5713
5714 // Do not do this in your code, it is not supported.
5715 memc->servers[1].state.is_dead= true;
5716 memc->state.is_time_for_rebuild= true;
5717
5718 uint32_t new_count= memcached_server_count(memc);
5719 test_true(count == new_count);
5720
5721 #if 0
5722 test_true(count == new_count + 1 );
5723 #endif
5724
5725 return TEST_SUCCESS;
5726 }
5727
5728
5729 static memcached_return_t stat_printer(memcached_server_instance_st server,
5730 const char *key, size_t key_length,
5731 const char *value, size_t value_length,
5732 void *context)
5733 {
5734 (void)server;
5735 (void)context;
5736 (void)key;
5737 (void)key_length;
5738 (void)value;
5739 (void)value_length;
5740
5741 return MEMCACHED_SUCCESS;
5742 }
5743
5744 static test_return_t memcached_stat_execute_test(memcached_st *memc)
5745 {
5746 memcached_return_t rc= memcached_stat_execute(memc, NULL, stat_printer, NULL);
5747 test_true(rc == MEMCACHED_SUCCESS);
5748
5749 rc= memcached_stat_execute(memc, "slabs", stat_printer, NULL);
5750 test_true(rc == MEMCACHED_SUCCESS);
5751
5752 rc= memcached_stat_execute(memc, "items", stat_printer, NULL);
5753 test_true(rc == MEMCACHED_SUCCESS);
5754
5755 rc= memcached_stat_execute(memc, "sizes", stat_printer, NULL);
5756 test_true(rc == MEMCACHED_SUCCESS);
5757
5758 return TEST_SUCCESS;
5759 }
5760
5761 /*
5762 * This test ensures that the failure counter isn't incremented during
5763 * normal termination of the memcached instance.
5764 */
5765 static test_return_t wrong_failure_counter_test(memcached_st *memc)
5766 {
5767 memcached_return_t rc;
5768 memcached_server_instance_st instance;
5769
5770 /* Set value to force connection to the server */
5771 const char *key= "marmotte";
5772 const char *value= "milka";
5773
5774 /*
5775 * Please note that I'm abusing the internal structures in libmemcached
5776 * in a non-portable way and you shouldn't be doing this. I'm only
5777 * doing this in order to verify that the library works the way it should
5778 */
5779 uint32_t number_of_hosts= memcached_server_count(memc);
5780 memc->number_of_hosts= 1;
5781
5782 /* Ensure that we are connected to the server by setting a value */
5783 rc= memcached_set(memc, key, strlen(key),
5784 value, strlen(value),
5785 (time_t)0, (uint32_t)0);
5786 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
5787
5788
5789 instance= memcached_server_instance_by_position(memc, 0);
5790 /* The test is to see that the memcached_quit doesn't increase the
5791 * the server failure conter, so let's ensure that it is zero
5792 * before sending quit
5793 */
5794 ((memcached_server_write_instance_st)instance)->server_failure_counter= 0;
5795
5796 memcached_quit(memc);
5797
5798 /* Verify that it memcached_quit didn't increment the failure counter
5799 * Please note that this isn't bullet proof, because an error could
5800 * occur...
5801 */
5802 test_true(instance->server_failure_counter == 0);
5803
5804 /* restore the instance */
5805 memc->number_of_hosts= number_of_hosts;
5806
5807 return TEST_SUCCESS;
5808 }
5809
5810
5811
5812
5813 /*
5814 * Test that ensures mget_execute does not end into recursive calls that finally fails
5815 */
5816 static test_return_t regression_bug_490486(memcached_st *memc)
5817 {
5818 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
5819 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 1);
5820 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, 1000);
5821 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, 1);
5822 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 3600);
5823
5824 #ifdef __APPLE__
5825 return TEST_SKIPPED; // My MAC can't handle this test
5826 #endif
5827
5828 /*
5829 * I only want to hit _one_ server so I know the number of requests I'm
5830 * sending in the pipeline.
5831 */
5832 uint32_t number_of_hosts= memc->number_of_hosts;
5833 memc->number_of_hosts= 1;
5834 size_t max_keys= 20480;
5835
5836
5837 char **keys= calloc(max_keys, sizeof(char*));
5838 size_t *key_length=calloc(max_keys, sizeof(size_t));
5839
5840 /* First add all of the items.. */
5841 bool slept= false;
5842 char blob[1024]= { 0 };
5843 memcached_return rc;
5844 for (size_t x= 0; x < max_keys; ++x)
5845 {
5846 char k[251];
5847 key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%zu", x);
5848 keys[x]= strdup(k);
5849 assert(keys[x] != NULL);
5850 rc= memcached_set(memc, keys[x], key_length[x], blob, sizeof(blob), 0, 0);
5851 #ifdef __APPLE__
5852 if (rc == MEMCACHED_SERVER_MARKED_DEAD)
5853 {
5854 break; // We are out of business
5855 }
5856 #endif
5857 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED || rc == MEMCACHED_TIMEOUT); // MEMCACHED_TIMEOUT <-- only observed on OSX
5858
5859 if (rc == MEMCACHED_TIMEOUT && slept == false)
5860 {
5861 x++;
5862 sleep(1);// We will try to sleep
5863 slept= true;
5864 }
5865 else if (rc == MEMCACHED_TIMEOUT && slept == true)
5866 {
5867 // We failed to send everything.
5868 break;
5869 }
5870 }
5871
5872 if (rc != MEMCACHED_SERVER_MARKED_DEAD)
5873 {
5874
5875 /* Try to get all of them with a large multiget */
5876 size_t counter= 0;
5877 memcached_execute_function callbacks[1]= { [0]= &callback_counter };
5878 rc= memcached_mget_execute(memc, (const char**)keys, key_length,
5879 (size_t)max_keys, callbacks, &counter, 1);
5880
5881 assert(rc == MEMCACHED_SUCCESS);
5882 char* the_value= NULL;
5883 char the_key[MEMCACHED_MAX_KEY];
5884 size_t the_key_length;
5885 size_t the_value_length;
5886 uint32_t the_flags;
5887
5888 do {
5889 the_value= memcached_fetch(memc, the_key, &the_key_length, &the_value_length, &the_flags, &rc);
5890
5891 if ((the_value!= NULL) && (rc == MEMCACHED_SUCCESS))
5892 {
5893 ++counter;
5894 free(the_value);
5895 }
5896
5897 } while ( (the_value!= NULL) && (rc == MEMCACHED_SUCCESS));
5898
5899
5900 assert(rc == MEMCACHED_END);
5901
5902 /* Verify that we got all of the items */
5903 assert(counter == max_keys);
5904 }
5905
5906 /* Release all allocated resources */
5907 for (size_t x= 0; x < max_keys; ++x)
5908 {
5909 free(keys[x]);
5910 }
5911 free(keys);
5912 free(key_length);
5913
5914 memc->number_of_hosts= number_of_hosts;
5915
5916 return TEST_SUCCESS;
5917 }
5918
5919 static test_return_t regression_bug_583031(memcached_st *unused)
5920 {
5921 (void)unused;
5922
5923 memcached_st *memc= memcached_create(NULL);
5924 assert(memc);
5925 memcached_server_add(memc, "10.2.3.4", 11211);
5926
5927 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT, 1000);
5928 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 1000);
5929 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SND_TIMEOUT, 1000);
5930 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RCV_TIMEOUT, 1000);
5931 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, 1000);
5932 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, 3);
5933
5934 memcached_return_t rc;
5935 size_t length;
5936 uint32_t flags;
5937
5938 (void)memcached_get(memc, "dsf", 3, &length, &flags, &rc);
5939
5940 test_true(rc == MEMCACHED_TIMEOUT);
5941
5942 memcached_free(memc);
5943
5944 return TEST_SUCCESS;
5945 }
5946
5947 static void memcached_die(memcached_st* mc, memcached_return error, const char* what, uint32_t it)
5948 {
5949 fprintf(stderr, "Iteration #%u: ", it);
5950
5951 if(error == MEMCACHED_ERRNO)
5952 {
5953 fprintf(stderr, "system error %d from %s: %s\n",
5954 errno, what, strerror(errno));
5955 }
5956 else
5957 {
5958 fprintf(stderr, "error %d from %s: %s\n", error, what,
5959 memcached_strerror(mc, error));
5960 }
5961 }
5962
5963 #define TEST_CONSTANT_CREATION 200
5964
5965 static test_return_t regression_bug_(memcached_st *memc)
5966 {
5967 const char *remote_server;
5968 (void)memc;
5969
5970 if (! (remote_server= getenv("LIBMEMCACHED_REMOTE_SERVER")))
5971 {
5972 return TEST_SKIPPED;
5973 }
5974
5975 for (uint32_t x= 0; x < TEST_CONSTANT_CREATION; x++)
5976 {
5977 memcached_st* mc= memcached_create(NULL);
5978 memcached_return rc;
5979
5980 rc= memcached_behavior_set(mc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
5981 if (rc != MEMCACHED_SUCCESS)
5982 {
5983 memcached_die(mc, rc, "memcached_behavior_set", x);
5984 }
5985
5986 rc= memcached_behavior_set(mc, MEMCACHED_BEHAVIOR_CACHE_LOOKUPS, 1);
5987 if (rc != MEMCACHED_SUCCESS)
5988 {
5989 memcached_die(mc, rc, "memcached_behavior_set", x);
5990 }
5991
5992 rc= memcached_server_add(mc, remote_server, 0);
5993 if (rc != MEMCACHED_SUCCESS)
5994 {
5995 memcached_die(mc, rc, "memcached_server_add", x);
5996 }
5997
5998 const char *set_key= "akey";
5999 const size_t set_key_len= strlen(set_key);
6000 const char *set_value= "a value";
6001 const size_t set_value_len= strlen(set_value);
6002
6003 if (rc == MEMCACHED_SUCCESS)
6004 {
6005 if (x > 0)
6006 {
6007 size_t get_value_len;
6008 char *get_value;
6009 uint32_t get_value_flags;
6010
6011 get_value= memcached_get(mc, set_key, set_key_len, &get_value_len,
6012 &get_value_flags, &rc);
6013 if (rc != MEMCACHED_SUCCESS)
6014 {
6015 memcached_die(mc, rc, "memcached_get", x);
6016 }
6017 else
6018 {
6019
6020 if (x != 0 &&
6021 (get_value_len != set_value_len
6022 || 0!=strncmp(get_value, set_value, get_value_len)))
6023 {
6024 fprintf(stderr, "Values don't match?\n");
6025 rc= MEMCACHED_FAILURE;
6026 }
6027 free(get_value);
6028 }
6029 }
6030
6031 rc= memcached_set(mc,
6032 set_key, set_key_len,
6033 set_value, set_value_len,
6034 0, /* time */
6035 0 /* flags */
6036 );
6037 if (rc != MEMCACHED_SUCCESS)
6038 {
6039 memcached_die(mc, rc, "memcached_set", x);
6040 }
6041 }
6042
6043 memcached_quit(mc);
6044 memcached_free(mc);
6045
6046 if (rc != MEMCACHED_SUCCESS)
6047 {
6048 break;
6049 }
6050 }
6051
6052 return TEST_SUCCESS;
6053 }
6054
6055 /*
6056 * Test that the sasl authentication works. We cannot use the default
6057 * pool of servers, because that would require that all servers we want
6058 * to test supports SASL authentication, and that they use the default
6059 * creds.
6060 */
6061 static test_return_t sasl_auth_test(memcached_st *memc)
6062 {
6063 #ifdef LIBMEMCACHED_WITH_SASL_SUPPORT
6064 memcached_return_t rc;
6065
6066 rc= memcached_set(memc, "foo", 3, "bar", 3, (time_t)0, (uint32_t)0);
6067 test_true(rc == MEMCACHED_SUCCESS);
6068 test_true((rc= memcached_delete(memc, "foo", 3, 0)) == MEMCACHED_SUCCESS);
6069 test_true((rc= memcached_destroy_sasl_auth_data(memc)) == MEMCACHED_SUCCESS);
6070 test_true((rc= memcached_destroy_sasl_auth_data(memc)) == MEMCACHED_FAILURE);
6071 test_true((rc= memcached_destroy_sasl_auth_data(NULL)) == MEMCACHED_FAILURE);
6072 memcached_quit(memc);
6073
6074 rc= memcached_set_sasl_auth_data(memc,
6075 getenv("LIBMEMCACHED_TEST_SASL_USERNAME"),
6076 getenv("LIBMEMCACHED_TEST_SASL_SERVER"));
6077 test_true(rc == MEMCACHED_SUCCESS);
6078
6079 rc= memcached_set(memc, "foo", 3, "bar", 3, (time_t)0, (uint32_t)0);
6080 test_true(rc == MEMCACHED_AUTH_FAILURE);
6081 test_true(memcached_destroy_sasl_auth_data(memc) == MEMCACHED_SUCCESS);
6082
6083 memcached_quit(memc);
6084 return TEST_SUCCESS;
6085 #else
6086 (void)memc;
6087 return TEST_FAILURE;
6088 #endif
6089 }
6090
6091 /* Clean the server before beginning testing */
6092 test_st tests[] ={
6093 {"util_version", 1, (test_callback_fn)util_version_test },
6094 {"flush", 0, (test_callback_fn)flush_test },
6095 {"init", 0, (test_callback_fn)init_test },
6096 {"allocation", 0, (test_callback_fn)allocation_test },
6097 {"server_list_null_test", 0, (test_callback_fn)server_list_null_test},
6098 {"server_unsort", 0, (test_callback_fn)server_unsort_test},
6099 {"server_sort", 0, (test_callback_fn)server_sort_test},
6100 {"server_sort2", 0, (test_callback_fn)server_sort2_test},
6101 {"memcached_server_remove", 0, (test_callback_fn)memcached_server_remove_test},
6102 {"clone_test", 0, (test_callback_fn)clone_test },
6103 {"connection_test", 0, (test_callback_fn)connection_test},
6104 {"callback_test", 0, (test_callback_fn)callback_test},
6105 {"userdata_test", 0, (test_callback_fn)userdata_test},
6106 {"error", 0, (test_callback_fn)error_test },
6107 {"set", 0, (test_callback_fn)set_test },
6108 {"set2", 0, (test_callback_fn)set_test2 },
6109 {"set3", 0, (test_callback_fn)set_test3 },
6110 {"dump", 1, (test_callback_fn)dump_test},
6111 {"add", 1, (test_callback_fn)add_test },
6112 {"replace", 1, (test_callback_fn)replace_test },
6113 {"delete", 1, (test_callback_fn)delete_test },
6114 {"get", 1, (test_callback_fn)get_test },
6115 {"get2", 0, (test_callback_fn)get_test2 },
6116 {"get3", 0, (test_callback_fn)get_test3 },
6117 {"get4", 0, (test_callback_fn)get_test4 },
6118 {"partial mget", 0, (test_callback_fn)get_test5 },
6119 {"stats_servername", 0, (test_callback_fn)stats_servername_test },
6120 {"increment", 0, (test_callback_fn)increment_test },
6121 {"increment_with_initial", 1, (test_callback_fn)increment_with_initial_test },
6122 {"decrement", 0, (test_callback_fn)decrement_test },
6123 {"decrement_with_initial", 1, (test_callback_fn)decrement_with_initial_test },
6124 {"increment_by_key", 0, (test_callback_fn)increment_by_key_test },
6125 {"increment_with_initial_by_key", 1, (test_callback_fn)increment_with_initial_by_key_test },
6126 {"decrement_by_key", 0, (test_callback_fn)decrement_by_key_test },
6127 {"decrement_with_initial_by_key", 1, (test_callback_fn)decrement_with_initial_by_key_test },
6128 {"quit", 0, (test_callback_fn)quit_test },
6129 {"mget", 1, (test_callback_fn)mget_test },
6130 {"mget_result", 1, (test_callback_fn)mget_result_test },
6131 {"mget_result_alloc", 1, (test_callback_fn)mget_result_alloc_test },
6132 {"mget_result_function", 1, (test_callback_fn)mget_result_function },
6133 {"mget_execute", 1, (test_callback_fn)mget_execute },
6134 {"mget_end", 0, (test_callback_fn)mget_end },
6135 {"get_stats", 0, (test_callback_fn)get_stats },
6136 {"add_host_test", 0, (test_callback_fn)add_host_test },
6137 {"add_host_test_1", 0, (test_callback_fn)add_host_test1 },
6138 {"get_stats_keys", 0, (test_callback_fn)get_stats_keys },
6139 {"version_string_test", 0, (test_callback_fn)version_string_test},
6140 {"bad_key", 1, (test_callback_fn)bad_key_test },
6141 {"memcached_server_cursor", 1, (test_callback_fn)memcached_server_cursor_test },
6142 {"read_through", 1, (test_callback_fn)read_through },
6143 {"delete_through", 1, (test_callback_fn)delete_through },
6144 {"noreply", 1, (test_callback_fn)noreply_test},
6145 {"analyzer", 1, (test_callback_fn)analyzer_test},
6146 #ifdef HAVE_LIBMEMCACHEDUTIL
6147 {"connectionpool", 1, (test_callback_fn)connection_pool_test },
6148 {"ping", 1, (test_callback_fn)ping_test },
6149 #endif
6150 {"test_get_last_disconnect", 1, (test_callback_fn)test_get_last_disconnect},
6151 {"verbosity", 1, (test_callback_fn)test_verbosity},
6152 {"test_server_failure", 1, (test_callback_fn)test_server_failure},
6153 {"cull_servers", 1, (test_callback_fn)test_cull_servers},
6154 {"memcached_stat_execute", 1, (test_callback_fn)memcached_stat_execute_test},
6155 {0, 0, 0}
6156 };
6157
6158 test_st behavior_tests[] ={
6159 {"behavior_test", 0, (test_callback_fn)behavior_test},
6160 {"MEMCACHED_BEHAVIOR_CORK", 0, (test_callback_fn)MEMCACHED_BEHAVIOR_CORK_test},
6161 {"MEMCACHED_BEHAVIOR_TCP_KEEPALIVE", 0, (test_callback_fn)MEMCACHED_BEHAVIOR_TCP_KEEPALIVE_test},
6162 {"MEMCACHED_BEHAVIOR_TCP_KEEPIDLE", 0, (test_callback_fn)MEMCACHED_BEHAVIOR_TCP_KEEPIDLE_test},
6163 {0, 0, 0}
6164 };
6165
6166 test_st regression_binary_vs_block[] ={
6167 {"block add", 1, (test_callback_fn)block_add_regression},
6168 {"binary add", 1, (test_callback_fn)binary_add_regression},
6169 {0, 0, 0}
6170 };
6171
6172 test_st async_tests[] ={
6173 {"add", 1, (test_callback_fn)add_wrapper },
6174 {0, 0, 0}
6175 };
6176
6177 test_st string_tests[] ={
6178 {"string static with null", 0, (test_callback_fn)string_static_null },
6179 {"string alloc with null", 0, (test_callback_fn)string_alloc_null },
6180 {"string alloc with 1K", 0, (test_callback_fn)string_alloc_with_size },
6181 {"string alloc with malloc failure", 0, (test_callback_fn)string_alloc_with_size_toobig },
6182 {"string append", 0, (test_callback_fn)string_alloc_append },
6183 {"string append failure (too big)", 0, (test_callback_fn)string_alloc_append_toobig },
6184 {0, 0, (test_callback_fn)0}
6185 };
6186
6187 test_st result_tests[] ={
6188 {"result static", 0, (test_callback_fn)result_static},
6189 {"result alloc", 0, (test_callback_fn)result_alloc},
6190 {0, 0, (test_callback_fn)0}
6191 };
6192
6193 test_st version_1_2_3[] ={
6194 {"append", 0, (test_callback_fn)append_test },
6195 {"prepend", 0, (test_callback_fn)prepend_test },
6196 {"cas", 0, (test_callback_fn)cas_test },
6197 {"cas2", 0, (test_callback_fn)cas2_test },
6198 {"append_binary", 0, (test_callback_fn)append_binary_test },
6199 {0, 0, (test_callback_fn)0}
6200 };
6201
6202 test_st user_tests[] ={
6203 {"user_supplied_bug1", 0, (test_callback_fn)user_supplied_bug1 },
6204 {"user_supplied_bug2", 0, (test_callback_fn)user_supplied_bug2 },
6205 {"user_supplied_bug3", 0, (test_callback_fn)user_supplied_bug3 },
6206 {"user_supplied_bug4", 0, (test_callback_fn)user_supplied_bug4 },
6207 {"user_supplied_bug5", 1, (test_callback_fn)user_supplied_bug5 },
6208 {"user_supplied_bug6", 1, (test_callback_fn)user_supplied_bug6 },
6209 {"user_supplied_bug7", 1, (test_callback_fn)user_supplied_bug7 },
6210 {"user_supplied_bug8", 1, (test_callback_fn)user_supplied_bug8 },
6211 {"user_supplied_bug9", 1, (test_callback_fn)user_supplied_bug9 },
6212 {"user_supplied_bug10", 1, (test_callback_fn)user_supplied_bug10 },
6213 {"user_supplied_bug11", 1, (test_callback_fn)user_supplied_bug11 },
6214 {"user_supplied_bug12", 1, (test_callback_fn)user_supplied_bug12 },
6215 {"user_supplied_bug13", 1, (test_callback_fn)user_supplied_bug13 },
6216 {"user_supplied_bug14", 1, (test_callback_fn)user_supplied_bug14 },
6217 {"user_supplied_bug15", 1, (test_callback_fn)user_supplied_bug15 },
6218 {"user_supplied_bug16", 1, (test_callback_fn)user_supplied_bug16 },
6219 #if !defined(__sun) && !defined(__OpenBSD__)
6220 /*
6221 ** It seems to be something weird with the character sets..
6222 ** value_fetch is unable to parse the value line (iscntrl "fails"), so I
6223 ** guess I need to find out how this is supposed to work.. Perhaps I need
6224 ** to run the test in a specific locale (I tried zh_CN.UTF-8 without success,
6225 ** so just disable the code for now...).
6226 */
6227 {"user_supplied_bug17", 1, (test_callback_fn)user_supplied_bug17 },
6228 #endif
6229 {"user_supplied_bug18", 1, (test_callback_fn)user_supplied_bug18 },
6230 {"user_supplied_bug19", 1, (test_callback_fn)user_supplied_bug19 },
6231 {"user_supplied_bug20", 1, (test_callback_fn)user_supplied_bug20 },
6232 {"user_supplied_bug21", 1, (test_callback_fn)user_supplied_bug21 },
6233 {"wrong_failure_counter_test", 1, (test_callback_fn)wrong_failure_counter_test},
6234 {0, 0, (test_callback_fn)0}
6235 };
6236
6237 test_st replication_tests[]= {
6238 {"set", 1, (test_callback_fn)replication_set_test },
6239 {"get", 0, (test_callback_fn)replication_get_test },
6240 {"mget", 0, (test_callback_fn)replication_mget_test },
6241 {"delete", 0, (test_callback_fn)replication_delete_test },
6242 {"rand_mget", 0, (test_callback_fn)replication_randomize_mget_test },
6243 {0, 0, (test_callback_fn)0}
6244 };
6245
6246 /*
6247 * The following test suite is used to verify that we don't introduce
6248 * regression bugs. If you want more information about the bug / test,
6249 * you should look in the bug report at
6250 * http://bugs.launchpad.net/libmemcached
6251 */
6252 test_st regression_tests[]= {
6253 {"lp:434484", 1, (test_callback_fn)regression_bug_434484 },
6254 {"lp:434843", 1, (test_callback_fn)regression_bug_434843 },
6255 {"lp:434843-buffered", 1, (test_callback_fn)regression_bug_434843_buffered },
6256 {"lp:421108", 1, (test_callback_fn)regression_bug_421108 },
6257 {"lp:442914", 1, (test_callback_fn)regression_bug_442914 },
6258 {"lp:447342", 1, (test_callback_fn)regression_bug_447342 },
6259 {"lp:463297", 1, (test_callback_fn)regression_bug_463297 },
6260 {"lp:490486", 1, (test_callback_fn)regression_bug_490486 },
6261 {"lp:583031", 1, (test_callback_fn)regression_bug_583031 },
6262 {"lp:?", 1, (test_callback_fn)regression_bug_ },
6263 {0, 0, (test_callback_fn)0}
6264 };
6265
6266 test_st sasl_auth_tests[]= {
6267 {"sasl_auth", 1, (test_callback_fn)sasl_auth_test },
6268 {0, 0, (test_callback_fn)0}
6269 };
6270
6271 test_st ketama_compatibility[]= {
6272 {"libmemcached", 1, (test_callback_fn)ketama_compatibility_libmemcached },
6273 {"spymemcached", 1, (test_callback_fn)ketama_compatibility_spymemcached },
6274 {0, 0, (test_callback_fn)0}
6275 };
6276
6277 test_st generate_tests[] ={
6278 {"generate_pairs", 1, (test_callback_fn)generate_pairs },
6279 {"generate_data", 1, (test_callback_fn)generate_data },
6280 {"get_read", 0, (test_callback_fn)get_read },
6281 {"delete_generate", 0, (test_callback_fn)delete_generate },
6282 {"generate_buffer_data", 1, (test_callback_fn)generate_buffer_data },
6283 {"delete_buffer", 0, (test_callback_fn)delete_buffer_generate},
6284 {"generate_data", 1, (test_callback_fn)generate_data },
6285 {"mget_read", 0, (test_callback_fn)mget_read },
6286 {"mget_read_result", 0, (test_callback_fn)mget_read_result },
6287 {"mget_read_function", 0, (test_callback_fn)mget_read_function },
6288 {"cleanup", 1, (test_callback_fn)cleanup_pairs },
6289 {"generate_large_pairs", 1, (test_callback_fn)generate_large_pairs },
6290 {"generate_data", 1, (test_callback_fn)generate_data },
6291 {"generate_buffer_data", 1, (test_callback_fn)generate_buffer_data },
6292 {"cleanup", 1, (test_callback_fn)cleanup_pairs },
6293 {0, 0, (test_callback_fn)0}
6294 };
6295
6296 test_st consistent_tests[] ={
6297 {"generate_pairs", 1, (test_callback_fn)generate_pairs },
6298 {"generate_data", 1, (test_callback_fn)generate_data },
6299 {"get_read", 0, (test_callback_fn)get_read_count },
6300 {"cleanup", 1, (test_callback_fn)cleanup_pairs },
6301 {0, 0, (test_callback_fn)0}
6302 };
6303
6304 test_st consistent_weighted_tests[] ={
6305 {"generate_pairs", 1, (test_callback_fn)generate_pairs },
6306 {"generate_data", 1, (test_callback_fn)generate_data_with_stats },
6307 {"get_read", 0, (test_callback_fn)get_read_count },
6308 {"cleanup", 1, (test_callback_fn)cleanup_pairs },
6309 {0, 0, (test_callback_fn)0}
6310 };
6311
6312 test_st hsieh_availability[] ={
6313 {"hsieh_avaibility_test", 0, (test_callback_fn)hsieh_avaibility_test},
6314 {0, 0, (test_callback_fn)0}
6315 };
6316
6317 #if 0
6318 test_st hash_sanity[] ={
6319 {"hash sanity", 0, (test_callback_fn)hash_sanity_test},
6320 {0, 0, (test_callback_fn)0}
6321 };
6322 #endif
6323
6324 test_st ketama_auto_eject_hosts[] ={
6325 {"auto_eject_hosts", 1, (test_callback_fn)auto_eject_hosts },
6326 {"output_ketama_weighted_keys", 1, (test_callback_fn)output_ketama_weighted_keys },
6327 {0, 0, (test_callback_fn)0}
6328 };
6329
6330 test_st hash_tests[] ={
6331 {"one_at_a_time_run", 0, (test_callback_fn)one_at_a_time_run },
6332 {"md5", 0, (test_callback_fn)md5_run },
6333 {"crc", 0, (test_callback_fn)crc_run },
6334 {"fnv1_64", 0, (test_callback_fn)fnv1_64_run },
6335 {"fnv1a_64", 0, (test_callback_fn)fnv1a_64_run },
6336 {"fnv1_32", 0, (test_callback_fn)fnv1_32_run },
6337 {"fnv1a_32", 0, (test_callback_fn)fnv1a_32_run },
6338 {"hsieh", 0, (test_callback_fn)hsieh_run },
6339 {"murmur", 0, (test_callback_fn)murmur_run },
6340 {"jenkis", 0, (test_callback_fn)jenkins_run },
6341 {"memcached_get_hashkit", 0, (test_callback_fn)memcached_get_hashkit_test },
6342 {0, 0, (test_callback_fn)0}
6343 };
6344
6345 test_st error_conditions[] ={
6346 {"memcached_get_MEMCACHED_ERRNO", 0, (test_callback_fn)memcached_get_MEMCACHED_ERRNO },
6347 {"memcached_get_MEMCACHED_NOTFOUND", 0, (test_callback_fn)memcached_get_MEMCACHED_NOTFOUND },
6348 {"memcached_get_by_key_MEMCACHED_ERRNO", 0, (test_callback_fn)memcached_get_by_key_MEMCACHED_ERRNO },
6349 {"memcached_get_by_key_MEMCACHED_NOTFOUND", 0, (test_callback_fn)memcached_get_by_key_MEMCACHED_NOTFOUND },
6350 {0, 0, (test_callback_fn)0}
6351 };
6352
6353 collection_st collection[] ={
6354 #if 0
6355 {"hash_sanity", 0, 0, hash_sanity},
6356 #endif
6357 {"hsieh_availability", 0, 0, hsieh_availability},
6358 {"block", 0, 0, tests},
6359 {"binary", (test_callback_fn)pre_binary, 0, tests},
6360 {"nonblock", (test_callback_fn)pre_nonblock, 0, tests},
6361 {"nodelay", (test_callback_fn)pre_nodelay, 0, tests},
6362 {"settimer", (test_callback_fn)pre_settimer, 0, tests},
6363 {"md5", (test_callback_fn)pre_md5, 0, tests},
6364 {"crc", (test_callback_fn)pre_crc, 0, tests},
6365 {"hsieh", (test_callback_fn)pre_hsieh, 0, tests},
6366 {"jenkins", (test_callback_fn)pre_jenkins, 0, tests},
6367 {"fnv1_64", (test_callback_fn)pre_hash_fnv1_64, 0, tests},
6368 {"fnv1a_64", (test_callback_fn)pre_hash_fnv1a_64, 0, tests},
6369 {"fnv1_32", (test_callback_fn)pre_hash_fnv1_32, 0, tests},
6370 {"fnv1a_32", (test_callback_fn)pre_hash_fnv1a_32, 0, tests},
6371 {"ketama", (test_callback_fn)pre_behavior_ketama, 0, tests},
6372 {"ketama_auto_eject_hosts", (test_callback_fn)pre_behavior_ketama, 0, ketama_auto_eject_hosts},
6373 {"unix_socket", (test_callback_fn)pre_unix_socket, 0, tests},
6374 {"unix_socket_nodelay", (test_callback_fn)pre_nodelay, 0, tests},
6375 {"poll_timeout", (test_callback_fn)poll_timeout, 0, tests},
6376 {"gets", (test_callback_fn)enable_cas, 0, tests},
6377 {"consistent_crc", (test_callback_fn)enable_consistent_crc, 0, tests},
6378 {"consistent_hsieh", (test_callback_fn)enable_consistent_hsieh, 0, tests},
6379 #ifdef MEMCACHED_ENABLE_DEPRECATED
6380 {"deprecated_memory_allocators", (test_callback_fn)deprecated_set_memory_alloc, 0, tests},
6381 #endif
6382 {"memory_allocators", (test_callback_fn)set_memory_alloc, 0, tests},
6383 {"prefix", (test_callback_fn)set_prefix, 0, tests},
6384 {"sasl_auth", (test_callback_fn)pre_sasl, 0, sasl_auth_tests },
6385 {"sasl", (test_callback_fn)pre_sasl, 0, tests },
6386 {"version_1_2_3", (test_callback_fn)check_for_1_2_3, 0, version_1_2_3},
6387 {"string", 0, 0, string_tests},
6388 {"result", 0, 0, result_tests},
6389 {"async", (test_callback_fn)pre_nonblock, 0, async_tests},
6390 {"async_binary", (test_callback_fn)pre_nonblock_binary, 0, async_tests},
6391 {"user", 0, 0, user_tests},
6392 {"generate", 0, 0, generate_tests},
6393 {"generate_hsieh", (test_callback_fn)pre_hsieh, 0, generate_tests},
6394 {"generate_ketama", (test_callback_fn)pre_behavior_ketama, 0, generate_tests},
6395 {"generate_hsieh_consistent", (test_callback_fn)enable_consistent_hsieh, 0, generate_tests},
6396 {"generate_md5", (test_callback_fn)pre_md5, 0, generate_tests},
6397 {"generate_murmur", (test_callback_fn)pre_murmur, 0, generate_tests},
6398 {"generate_jenkins", (test_callback_fn)pre_jenkins, 0, generate_tests},
6399 {"generate_nonblock", (test_callback_fn)pre_nonblock, 0, generate_tests},
6400 // Too slow
6401 {"generate_corked", (test_callback_fn)pre_cork, 0, generate_tests},
6402 {"generate_corked_and_nonblock", (test_callback_fn)pre_cork_and_nonblock, 0, generate_tests},
6403 {"consistent_not", 0, 0, consistent_tests},
6404 {"consistent_ketama", (test_callback_fn)pre_behavior_ketama, 0, consistent_tests},
6405 {"consistent_ketama_weighted", (test_callback_fn)pre_behavior_ketama_weighted, 0, consistent_weighted_tests},
6406 {"ketama_compat", 0, 0, ketama_compatibility},
6407 {"test_hashes", 0, 0, hash_tests},
6408 {"replication", (test_callback_fn)pre_replication, 0, replication_tests},
6409 {"replication_noblock", (test_callback_fn)pre_replication_noblock, 0, replication_tests},
6410 {"regression", 0, 0, regression_tests},
6411 {"behaviors", 0, 0, behavior_tests},
6412 {"regression_binary_vs_block", (test_callback_fn)key_setup, (test_callback_fn)key_teardown, regression_binary_vs_block},
6413 {"error_conditions", 0, 0, error_conditions},
6414 {0, 0, 0, 0}
6415 };
6416
6417 #define SERVERS_TO_CREATE 5
6418
6419 #include "libmemcached_world.h"
6420
6421 void get_world(world_st *world)
6422 {
6423 world->collections= collection;
6424
6425 world->create= (test_callback_create_fn)world_create;
6426 world->destroy= (test_callback_fn)world_destroy;
6427
6428 world->test.startup= (test_callback_fn)world_test_startup;
6429 world->test.flush= (test_callback_fn)world_flush;
6430 world->test.pre_run= (test_callback_fn)world_pre_run;
6431 world->test.post_run= (test_callback_fn)world_post_run;
6432 world->test.on_error= (test_callback_error_fn)world_on_error;
6433
6434 world->collection.startup= (test_callback_fn)world_container_startup;
6435 world->collection.shutdown= (test_callback_fn)world_container_shutdown;
6436
6437 world->runner= &defualt_libmemcached_runner;
6438 }