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