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