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