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