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