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