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