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