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