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