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