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