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