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