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