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