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