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