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