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