Merge lp:~tangent-org/libmemcached/1.0-build/ Build: jenkins-Libmemcached-170
[awesomized/libmemcached] / tests / libmemcached-1.0 / 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 <mem_config.h>
39 #include <libtest/test.hpp>
40
41 #if defined(HAVE_LIBUUID) && HAVE_LIBUUID
42 #include <uuid/uuid.h>
43 #endif
44
45 /*
46 Test cases
47 */
48
49 #include <libmemcached-1.0/memcached.h>
50 #include <libmemcached/is.h>
51 #include <libmemcached/server_instance.h>
52
53 #include <libhashkit-1.0/hashkit.h>
54
55 #include <libtest/memcached.hpp>
56
57 #include <cerrno>
58 #include <memory>
59 #include <pthread.h>
60 #include <semaphore.h>
61 #include <signal.h>
62 #include <sys/stat.h>
63 #include <sys/time.h>
64 #include <sys/types.h>
65 #include <unistd.h>
66
67 #include <iostream>
68
69 #include <libtest/server.h>
70
71 #include "clients/generator.h"
72
73 #define SMALL_STRING_LEN 1024
74
75 #include <libtest/test.hpp>
76
77 using namespace libtest;
78
79 #include <libmemcachedutil-1.0/util.h>
80
81 #include "tests/hash_results.h"
82
83 #include "tests/libmemcached-1.0/callback_counter.h"
84 #include "tests/libmemcached-1.0/fetch_all_results.h"
85 #include "tests/libmemcached-1.0/mem_functions.h"
86 #include "tests/libmemcached-1.0/setup_and_teardowns.h"
87 #include "tests/print.h"
88 #include "tests/debug.h"
89 #include "tests/memc.hpp"
90
91 #define UUID_STRING_MAXLENGTH 36
92
93 #include "tests/keys.hpp"
94
95 #include "libmemcached/instance.hpp"
96
97 static memcached_st * create_single_instance_memcached(const memcached_st *original_memc, const char *options)
98 {
99 /*
100 If no options are given, copy over at least the binary flag.
101 */
102 char options_buffer[1024]= { 0 };
103 if (options == NULL)
104 {
105 if (memcached_is_binary(original_memc))
106 {
107 snprintf(options_buffer, sizeof(options_buffer), "--BINARY");
108 }
109 }
110
111 /*
112 * I only want to hit _one_ server so I know the number of requests I'm
113 * sending in the pipeline.
114 */
115 memcached_server_instance_st instance= memcached_server_instance_by_position(original_memc, 0);
116
117 char server_string[1024];
118 int server_string_length;
119 if (instance->type == MEMCACHED_CONNECTION_UNIX_SOCKET)
120 {
121 if (options)
122 {
123 server_string_length= snprintf(server_string, sizeof(server_string), "--SOCKET=\"%s\" %s",
124 memcached_server_name(instance), options);
125 }
126 else
127 {
128 server_string_length= snprintf(server_string, sizeof(server_string), "--SOCKET=\"%s\"",
129 memcached_server_name(instance));
130 }
131 }
132 else
133 {
134 if (options)
135 {
136 server_string_length= snprintf(server_string, sizeof(server_string), "--server=%s:%d %s",
137 memcached_server_name(instance), int(memcached_server_port(instance)),
138 options);
139 }
140 else
141 {
142 server_string_length= snprintf(server_string, sizeof(server_string), "--server=%s:%d",
143 memcached_server_name(instance), int(memcached_server_port(instance)));
144 }
145 }
146
147 if (server_string_length <= 0)
148 {
149 return NULL;
150 }
151
152 char errror_buffer[1024];
153 if (memcached_failed(libmemcached_check_configuration(server_string, server_string_length, errror_buffer, sizeof(errror_buffer))))
154 {
155 Error << "Failed to parse (" << server_string << ") " << errror_buffer;
156 return NULL;
157 }
158
159 return memcached(server_string, server_string_length);
160 }
161
162
163 test_return_t init_test(memcached_st *not_used)
164 {
165 memcached_st memc;
166 (void)not_used;
167
168 (void)memcached_create(&memc);
169 memcached_free(&memc);
170
171 return TEST_SUCCESS;
172 }
173
174 #define TEST_PORT_COUNT 7
175 in_port_t test_ports[TEST_PORT_COUNT];
176
177 static memcached_return_t server_display_function(const memcached_st *ptr,
178 memcached_server_instance_st server,
179 void *context)
180 {
181 /* Do Nothing */
182 size_t bigger= *((size_t *)(context));
183 (void)ptr;
184 fatal_assert(bigger <= memcached_server_port(server));
185 *((size_t *)(context))= memcached_server_port(server);
186
187 return MEMCACHED_SUCCESS;
188 }
189
190 static memcached_return_t dump_server_information(const memcached_st *ptr,
191 memcached_server_instance_st instance,
192 void *context)
193 {
194 /* Do Nothing */
195 FILE *stream= (FILE *)context;
196 (void)ptr;
197
198 fprintf(stream, "Memcached Server: %s %u Version %u.%u.%u\n",
199 memcached_server_name(instance),
200 memcached_server_port(instance),
201 instance->major_version,
202 instance->minor_version,
203 instance->micro_version);
204
205 return MEMCACHED_SUCCESS;
206 }
207
208 test_return_t server_sort_test(memcached_st *ptr)
209 {
210 size_t bigger= 0; /* Prime the value for the test_true in server_display_function */
211
212 memcached_return_t rc;
213 memcached_server_fn callbacks[1];
214 memcached_st *local_memc;
215 (void)ptr;
216
217 local_memc= memcached_create(NULL);
218 test_true(local_memc);
219 memcached_behavior_set(local_memc, MEMCACHED_BEHAVIOR_SORT_HOSTS, 1);
220
221 for (uint32_t x= 0; x < TEST_PORT_COUNT; x++)
222 {
223 test_ports[x]= (in_port_t)random() % 64000;
224 rc= memcached_server_add_with_weight(local_memc, "localhost", test_ports[x], 0);
225 test_compare(memcached_server_count(local_memc), x +1);
226 #if 0 // Rewrite
227 test_true(memcached_server_list_count(memcached_server_list(local_memc)) == x+1);
228 #endif
229 test_compare(MEMCACHED_SUCCESS, rc);
230 }
231
232 callbacks[0]= server_display_function;
233 memcached_server_cursor(local_memc, callbacks, (void *)&bigger, 1);
234
235
236 memcached_free(local_memc);
237
238 return TEST_SUCCESS;
239 }
240
241 test_return_t server_sort2_test(memcached_st *ptr)
242 {
243 size_t bigger= 0; /* Prime the value for the test_true in server_display_function */
244 memcached_server_fn callbacks[1];
245 memcached_st *local_memc;
246 memcached_server_instance_st instance;
247 (void)ptr;
248
249 local_memc= memcached_create(NULL);
250 test_true(local_memc);
251 test_compare(MEMCACHED_SUCCESS,
252 memcached_behavior_set(local_memc, MEMCACHED_BEHAVIOR_SORT_HOSTS, 1));
253
254 test_compare(MEMCACHED_SUCCESS,
255 memcached_server_add_with_weight(local_memc, "MEMCACHED_BEHAVIOR_SORT_HOSTS", 43043, 0));
256 instance= memcached_server_instance_by_position(local_memc, 0);
257 test_compare(in_port_t(43043), memcached_server_port(instance));
258
259 test_compare(MEMCACHED_SUCCESS,
260 memcached_server_add_with_weight(local_memc, "MEMCACHED_BEHAVIOR_SORT_HOSTS", 43042, 0));
261
262 instance= memcached_server_instance_by_position(local_memc, 0);
263 test_compare(in_port_t(43042), memcached_server_port(instance));
264
265 instance= memcached_server_instance_by_position(local_memc, 1);
266 test_compare(in_port_t(43043), memcached_server_port(instance));
267
268 callbacks[0]= server_display_function;
269 memcached_server_cursor(local_memc, callbacks, (void *)&bigger, 1);
270
271
272 memcached_free(local_memc);
273
274 return TEST_SUCCESS;
275 }
276
277 test_return_t memcached_server_remove_test(memcached_st*)
278 {
279 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";
280 char buffer[BUFSIZ];
281
282 test_compare(MEMCACHED_SUCCESS,
283 libmemcached_check_configuration(server_string, strlen(server_string), buffer, sizeof(buffer)));
284 memcached_st *memc= memcached(server_string, strlen(server_string));
285 test_true(memc);
286
287 memcached_server_fn callbacks[1];
288 callbacks[0]= server_print_callback;
289 memcached_server_cursor(memc, callbacks, NULL, 1);
290
291 memcached_free(memc);
292
293 return TEST_SUCCESS;
294 }
295
296 static memcached_return_t server_display_unsort_function(const memcached_st*,
297 memcached_server_instance_st server,
298 void *context)
299 {
300 /* Do Nothing */
301 uint32_t x= *((uint32_t *)(context));
302
303 if (! (test_ports[x] == memcached_server_port(server)))
304 {
305 fprintf(stderr, "%lu -> %lu\n", (unsigned long)test_ports[x], (unsigned long)memcached_server_port(server));
306 return MEMCACHED_FAILURE;
307 }
308
309 *((uint32_t *)(context))= ++x;
310
311 return MEMCACHED_SUCCESS;
312 }
313
314 test_return_t server_unsort_test(memcached_st *ptr)
315 {
316 size_t counter= 0; /* Prime the value for the test_true in server_display_function */
317 size_t bigger= 0; /* Prime the value for the test_true in server_display_function */
318 memcached_server_fn callbacks[1];
319 memcached_st *local_memc;
320 (void)ptr;
321
322 local_memc= memcached_create(NULL);
323 test_true(local_memc);
324
325 for (uint32_t x= 0; x < TEST_PORT_COUNT; x++)
326 {
327 test_ports[x]= (in_port_t)(random() % 64000);
328 test_compare(MEMCACHED_SUCCESS,
329 memcached_server_add_with_weight(local_memc, "localhost", test_ports[x], 0));
330 test_compare(memcached_server_count(local_memc), x +1);
331 #if 0 // Rewrite
332 test_true(memcached_server_list_count(memcached_server_list(local_memc)) == x+1);
333 #endif
334 }
335
336 callbacks[0]= server_display_unsort_function;
337 memcached_server_cursor(local_memc, callbacks, (void *)&counter, 1);
338
339 /* Now we sort old data! */
340 memcached_behavior_set(local_memc, MEMCACHED_BEHAVIOR_SORT_HOSTS, 1);
341 callbacks[0]= server_display_function;
342 memcached_server_cursor(local_memc, callbacks, (void *)&bigger, 1);
343
344
345 memcached_free(local_memc);
346
347 return TEST_SUCCESS;
348 }
349
350 test_return_t allocation_test(memcached_st *not_used)
351 {
352 (void)not_used;
353 memcached_st *memc;
354 memc= memcached_create(NULL);
355 test_true(memc);
356 memcached_free(memc);
357
358 return TEST_SUCCESS;
359 }
360
361 test_return_t clone_test(memcached_st *memc)
362 {
363 /* All null? */
364 {
365 memcached_st *memc_clone;
366 memc_clone= memcached_clone(NULL, NULL);
367 test_true(memc_clone);
368 memcached_free(memc_clone);
369 }
370
371 /* Can we init from null? */
372 {
373 memcached_st *memc_clone;
374 memc_clone= memcached_clone(NULL, memc);
375 test_true(memc_clone);
376
377 { // Test allocators
378 test_true(memc_clone->allocators.free == memc->allocators.free);
379 test_true(memc_clone->allocators.malloc == memc->allocators.malloc);
380 test_true(memc_clone->allocators.realloc == memc->allocators.realloc);
381 test_true(memc_clone->allocators.calloc == memc->allocators.calloc);
382 }
383
384 test_true(memc_clone->connect_timeout == memc->connect_timeout);
385 test_true(memc_clone->delete_trigger == memc->delete_trigger);
386 test_true(memc_clone->distribution == memc->distribution);
387 { // Test all of the flags
388 test_true(memc_clone->flags.no_block == memc->flags.no_block);
389 test_true(memc_clone->flags.tcp_nodelay == memc->flags.tcp_nodelay);
390 test_true(memc_clone->flags.support_cas == memc->flags.support_cas);
391 test_true(memc_clone->flags.buffer_requests == memc->flags.buffer_requests);
392 test_true(memc_clone->flags.use_sort_hosts == memc->flags.use_sort_hosts);
393 test_true(memc_clone->flags.verify_key == memc->flags.verify_key);
394 test_true(memc_clone->ketama.weighted_ == memc->ketama.weighted_);
395 test_true(memc_clone->flags.binary_protocol == memc->flags.binary_protocol);
396 test_true(memc_clone->flags.hash_with_namespace == memc->flags.hash_with_namespace);
397 test_true(memc_clone->flags.reply == memc->flags.reply);
398 test_true(memc_clone->flags.use_udp == memc->flags.use_udp);
399 test_true(memc_clone->flags.auto_eject_hosts == memc->flags.auto_eject_hosts);
400 test_true(memc_clone->flags.randomize_replica_read == memc->flags.randomize_replica_read);
401 }
402 test_true(memc_clone->get_key_failure == memc->get_key_failure);
403 test_true(hashkit_compare(&memc_clone->hashkit, &memc->hashkit));
404 test_true(memc_clone->io_bytes_watermark == memc->io_bytes_watermark);
405 test_true(memc_clone->io_msg_watermark == memc->io_msg_watermark);
406 test_true(memc_clone->io_key_prefetch == memc->io_key_prefetch);
407 test_true(memc_clone->on_cleanup == memc->on_cleanup);
408 test_true(memc_clone->on_clone == memc->on_clone);
409 test_true(memc_clone->poll_timeout == memc->poll_timeout);
410 test_true(memc_clone->rcv_timeout == memc->rcv_timeout);
411 test_true(memc_clone->recv_size == memc->recv_size);
412 test_true(memc_clone->retry_timeout == memc->retry_timeout);
413 test_true(memc_clone->send_size == memc->send_size);
414 test_true(memc_clone->server_failure_limit == memc->server_failure_limit);
415 test_true(memc_clone->snd_timeout == memc->snd_timeout);
416 test_true(memc_clone->user_data == memc->user_data);
417
418 memcached_free(memc_clone);
419 }
420
421 /* Can we init from struct? */
422 {
423 memcached_st declared_clone;
424 memcached_st *memc_clone;
425 memset(&declared_clone, 0 , sizeof(memcached_st));
426 memc_clone= memcached_clone(&declared_clone, NULL);
427 test_true(memc_clone);
428 memcached_free(memc_clone);
429 }
430
431 /* Can we init from struct? */
432 {
433 memcached_st declared_clone;
434 memcached_st *memc_clone;
435 memset(&declared_clone, 0 , sizeof(memcached_st));
436 memc_clone= memcached_clone(&declared_clone, memc);
437 test_true(memc_clone);
438 memcached_free(memc_clone);
439 }
440
441 return TEST_SUCCESS;
442 }
443
444 test_return_t userdata_test(memcached_st *memc)
445 {
446 void* foo= NULL;
447 test_false(memcached_set_user_data(memc, foo));
448 test_true(memcached_get_user_data(memc) == foo);
449 test_true(memcached_set_user_data(memc, NULL) == foo);
450
451 return TEST_SUCCESS;
452 }
453
454 test_return_t connection_test(memcached_st *memc)
455 {
456 test_compare(MEMCACHED_SUCCESS,
457 memcached_server_add_with_weight(memc, "localhost", 0, 0));
458
459 return TEST_SUCCESS;
460 }
461
462 test_return_t libmemcached_string_behavior_test(memcached_st *)
463 {
464 for (int x= MEMCACHED_BEHAVIOR_NO_BLOCK; x < int(MEMCACHED_BEHAVIOR_MAX); ++x)
465 {
466 test_true(libmemcached_string_behavior(memcached_behavior_t(x)));
467 }
468 test_compare(37, int(MEMCACHED_BEHAVIOR_MAX));
469
470 return TEST_SUCCESS;
471 }
472
473 test_return_t libmemcached_string_distribution_test(memcached_st *)
474 {
475 for (int x= MEMCACHED_DISTRIBUTION_MODULA; x < int(MEMCACHED_DISTRIBUTION_CONSISTENT_MAX); ++x)
476 {
477 test_true(libmemcached_string_distribution(memcached_server_distribution_t(x)));
478 }
479 test_compare(7, int(MEMCACHED_DISTRIBUTION_CONSISTENT_MAX));
480
481 return TEST_SUCCESS;
482 }
483
484 test_return_t memcached_return_t_TEST(memcached_st *memc)
485 {
486 uint32_t values[] = { 851992627U, 2337886783U, 4109241422U, 4001849190U,
487 982370485U, 1263635348U, 4242906218U, 3829656100U,
488 1891735253U, 334139633U, 2257084983U, 3351789013U,
489 13199785U, 2542027183U, 1097051614U, 199566778U,
490 2748246961U, 2465192557U, 1664094137U, 2405439045U,
491 1842224848U, 692413798U, 3479807801U, 919913813U,
492 4269430871U, 610793021U, 527273862U, 1437122909U,
493 2300930706U, 2943759320U, 674306647U, 2400528935U,
494 54481931U, 4186304426U, 1741088401U, 2979625118U,
495 4159057246U, 3425930182U, 2593724503U, 1868899624U,
496 1769812374U, 2302537950U, 1110330676U, 3365377466U,
497 1336171666U, 3021258493U, 2334992265U, 3861994737U,
498 3582734124U, 3365377466U };
499
500 // You have updated the memcache_error messages but not updated docs/tests.
501 for (int rc= int(MEMCACHED_SUCCESS); rc < int(MEMCACHED_MAXIMUM_RETURN); ++rc)
502 {
503 uint32_t hash_val;
504 const char *msg= memcached_strerror(memc, memcached_return_t(rc));
505 hash_val= memcached_generate_hash_value(msg, strlen(msg),
506 MEMCACHED_HASH_JENKINS);
507 if (values[rc] != hash_val)
508 {
509 fprintf(stderr, "\n\nYou have updated memcached_return_t without updating the memcached_return_t_TEST\n");
510 fprintf(stderr, "%u, %s, (%u)\n\n", (uint32_t)rc, memcached_strerror(memc, memcached_return_t(rc)), hash_val);
511 }
512 test_compare(values[rc], hash_val);
513 }
514 test_compare(49, int(MEMCACHED_MAXIMUM_RETURN));
515
516 return TEST_SUCCESS;
517 }
518
519 test_return_t set_test(memcached_st *memc)
520 {
521 memcached_return_t rc= memcached_set(memc,
522 test_literal_param("foo"),
523 test_literal_param("when we sanitize"),
524 time_t(0), (uint32_t)0);
525 test_true(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED);
526
527 return TEST_SUCCESS;
528 }
529
530 test_return_t append_test(memcached_st *memc)
531 {
532 memcached_return_t rc;
533 const char *in_value= "we";
534 size_t value_length;
535 uint32_t flags;
536
537 test_compare(MEMCACHED_SUCCESS,
538 memcached_flush(memc, 0));
539
540 test_compare(MEMCACHED_SUCCESS,
541 memcached_set(memc,
542 test_literal_param(__func__),
543 in_value, strlen(in_value),
544 time_t(0), uint32_t(0)));
545
546 test_compare(MEMCACHED_SUCCESS,
547 memcached_append(memc,
548 test_literal_param(__func__),
549 " the", strlen(" the"),
550 time_t(0), uint32_t(0)));
551
552 test_compare(MEMCACHED_SUCCESS,
553 memcached_append(memc,
554 test_literal_param(__func__),
555 " people", strlen(" people"),
556 time_t(0), uint32_t(0)));
557
558 char *out_value= memcached_get(memc,
559 test_literal_param(__func__),
560 &value_length, &flags, &rc);
561 test_memcmp(out_value, "we the people", strlen("we the people"));
562 test_compare(strlen("we the people"), value_length);
563 test_compare(MEMCACHED_SUCCESS, rc);
564 free(out_value);
565
566 return TEST_SUCCESS;
567 }
568
569 test_return_t append_binary_test(memcached_st *memc)
570 {
571 uint32_t store_list[] = { 23, 56, 499, 98, 32847, 0 };
572
573 test_compare(MEMCACHED_SUCCESS,
574 memcached_flush(memc, 0));
575
576 test_compare(MEMCACHED_SUCCESS,
577 memcached_set(memc,
578 test_literal_param(__func__),
579 NULL, 0,
580 time_t(0), uint32_t(0)));
581
582 size_t count= 0;
583 for (uint32_t x= 0; store_list[x] ; x++)
584 {
585 test_compare(MEMCACHED_SUCCESS,
586 memcached_append(memc,
587 test_literal_param(__func__),
588 (char *)&store_list[x], sizeof(uint32_t),
589 time_t(0), uint32_t(0)));
590 count++;
591 }
592
593 size_t value_length;
594 uint32_t flags;
595 memcached_return_t rc;
596 uint32_t *value= (uint32_t *)memcached_get(memc,
597 test_literal_param(__func__),
598 &value_length, &flags, &rc);
599 test_compare(value_length, sizeof(uint32_t) * count);
600 test_compare(MEMCACHED_SUCCESS, rc);
601
602 for (uint32_t counter= uint32_t(count), *ptr= value; counter; counter--)
603 {
604 test_compare(*ptr, store_list[count - counter]);
605 ptr++;
606 }
607 free(value);
608
609 return TEST_SUCCESS;
610 }
611
612 test_return_t memcached_mget_mixed_memcached_get_TEST(memcached_st *memc)
613 {
614 keys_st keys(200);
615
616 for (libtest::vchar_ptr_t::iterator iter= keys.begin();
617 iter != keys.end();
618 ++iter)
619 {
620 test_compare_hint(MEMCACHED_SUCCESS,
621 memcached_set(memc,
622 (*iter), 36,
623 NULL, 0,
624 time_t(0), uint32_t(0)),
625 memcached_last_error_message(memc));
626 }
627
628 for (ptrdiff_t loop= 0; loop < 20; loop++)
629 {
630 if (random() %2)
631 {
632 test_compare(MEMCACHED_SUCCESS,
633 memcached_mget(memc, keys.keys_ptr(), keys.lengths_ptr(), keys.size()));
634
635 memcached_result_st *results= memcached_result_create(memc, NULL);
636 test_true(results);
637
638 size_t result_count= 0;
639 memcached_return_t rc;
640 while (memcached_fetch_result(memc, results, &rc))
641 {
642 result_count++;
643 }
644 test_true(keys.size() >= result_count);
645 }
646 else
647 {
648 int which_key= random() % int(keys.size());
649 size_t value_length;
650 uint32_t flags;
651 memcached_return_t rc;
652 char *out_value= memcached_get(memc, keys.key_at(which_key), keys.length_at(which_key),
653 &value_length, &flags, &rc);
654 if (rc == MEMCACHED_NOTFOUND)
655 { } // It is possible that the value has been purged.
656 else
657 {
658 test_compare(MEMCACHED_SUCCESS, rc);
659 }
660 test_null(out_value);
661 test_zero(value_length);
662 test_zero(flags);
663 }
664 }
665
666 return TEST_SUCCESS;
667 }
668
669 test_return_t cas2_test(memcached_st *memc)
670 {
671 const char *keys[]= {"fudge", "son", "food"};
672 size_t key_length[]= {5, 3, 4};
673 const char *value= "we the people";
674 size_t value_length= strlen("we the people");
675
676 test_compare(MEMCACHED_SUCCESS, memcached_flush(memc, 0));
677
678 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, true));
679
680 for (uint32_t x= 0; x < 3; x++)
681 {
682 test_compare(MEMCACHED_SUCCESS,
683 memcached_set(memc, keys[x], key_length[x],
684 keys[x], key_length[x],
685 time_t(50), uint32_t(9)));
686 }
687
688 test_compare(MEMCACHED_SUCCESS,
689 memcached_mget(memc, keys, key_length, 3));
690
691 memcached_result_st *results= memcached_result_create(memc, NULL);
692 test_true(results);
693
694 memcached_return_t rc;
695 results= memcached_fetch_result(memc, results, &rc);
696 test_true(results);
697 test_true(results->item_cas);
698 test_compare(MEMCACHED_SUCCESS, rc);
699 test_true(memcached_result_cas(results));
700
701 test_memcmp(value, "we the people", strlen("we the people"));
702 test_compare(strlen("we the people"), value_length);
703 test_compare(MEMCACHED_SUCCESS, rc);
704
705 memcached_result_free(results);
706
707 return TEST_SUCCESS;
708 }
709
710 test_return_t cas_test(memcached_st *memc)
711 {
712 const char* keys[2] = { __func__, NULL };
713 size_t keylengths[2] = { strlen(__func__), 0 };
714
715 memcached_result_st results_obj;
716
717 test_compare(MEMCACHED_SUCCESS, memcached_flush(memc, 0));
718
719 test_skip(true, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, true));
720
721 test_compare(MEMCACHED_SUCCESS,
722 memcached_set(memc,
723 test_literal_param(__func__),
724 test_literal_param("we the people"),
725 (time_t)0, (uint32_t)0));
726
727 test_compare(MEMCACHED_SUCCESS,
728 memcached_mget(memc, keys, keylengths, 1));
729
730 memcached_result_st *results= memcached_result_create(memc, &results_obj);
731 test_true(results);
732
733 memcached_return_t rc;
734 results= memcached_fetch_result(memc, &results_obj, &rc);
735 test_true(results);
736 test_compare(MEMCACHED_SUCCESS, rc);
737 test_true(memcached_result_cas(results));
738 test_memcmp("we the people", memcached_result_value(results), test_literal_param_size("we the people"));
739 test_compare(test_literal_param_size("we the people"),
740 strlen(memcached_result_value(results)));
741
742 uint64_t cas= memcached_result_cas(results);
743
744 #if 0
745 results= memcached_fetch_result(memc, &results_obj, &rc);
746 test_true(rc == MEMCACHED_END);
747 test_true(results == NULL);
748 #endif
749
750 test_compare(MEMCACHED_SUCCESS,
751 memcached_cas(memc,
752 test_literal_param(__func__),
753 test_literal_param("change the value"),
754 0, 0, cas));
755
756 /*
757 * The item will have a new cas value, so try to set it again with the old
758 * value. This should fail!
759 */
760 test_compare(MEMCACHED_DATA_EXISTS,
761 memcached_cas(memc,
762 test_literal_param(__func__),
763 test_literal_param("change the value"),
764 0, 0, cas));
765
766 memcached_result_free(&results_obj);
767
768 return TEST_SUCCESS;
769 }
770
771
772 test_return_t prepend_test(memcached_st *memc)
773 {
774 const char *key= "fig";
775 const char *value= "people";
776
777 test_compare(MEMCACHED_SUCCESS,
778 memcached_flush(memc, 0));
779
780 test_compare(MEMCACHED_SUCCESS,
781 memcached_set(memc, key, strlen(key),
782 value, strlen(value),
783 time_t(0), uint32_t(0)));
784
785 test_compare(MEMCACHED_SUCCESS,
786 memcached_prepend(memc, key, strlen(key),
787 "the ", strlen("the "),
788 time_t(0), uint32_t(0)));
789
790 test_compare(MEMCACHED_SUCCESS,
791 memcached_prepend(memc, key, strlen(key),
792 "we ", strlen("we "),
793 time_t(0), uint32_t(0)));
794
795 size_t value_length;
796 uint32_t flags;
797 memcached_return_t rc;
798 char *out_value= memcached_get(memc, key, strlen(key),
799 &value_length, &flags, &rc);
800 test_memcmp(out_value, "we the people", strlen("we the people"));
801 test_compare(strlen("we the people"), value_length);
802 test_compare(MEMCACHED_SUCCESS, rc);
803 free(out_value);
804
805 return TEST_SUCCESS;
806 }
807
808 /*
809 Set the value, then quit to make sure it is flushed.
810 Come back in and test that add fails.
811 */
812 test_return_t memcached_add_SUCCESS_TEST(memcached_st *memc)
813 {
814 memcached_return_t rc;
815 test_null(memcached_get(memc, test_literal_param(__func__), NULL, NULL, &rc));
816 test_compare(MEMCACHED_NOTFOUND, rc);
817
818 test_compare(MEMCACHED_SUCCESS,
819 memcached_add(memc,
820 test_literal_param(__func__),
821 test_literal_param("try something else"),
822 time_t(0), uint32_t(0)));
823
824 return TEST_SUCCESS;
825 }
826
827 test_return_t regression_1067242_TEST(memcached_st *memc)
828 {
829 test_compare(MEMCACHED_SUCCESS, memcached_set(memc,
830 test_literal_param(__func__),
831 test_literal_param("-2"),
832 0, 0));
833
834 memcached_return_t rc;
835 char* value;
836 test_true((value= memcached_get(memc, test_literal_param(__func__), NULL, NULL, &rc)));
837 test_compare(MEMCACHED_SUCCESS, rc);
838 free(value);
839
840 for (size_t x= 0; x < 10; x++)
841 {
842 uint64_t new_number;
843 test_compare(MEMCACHED_CLIENT_ERROR,
844 memcached_increment(memc,
845 test_literal_param(__func__), 1, &new_number));
846 test_compare(MEMCACHED_CLIENT_ERROR, memcached_last_error(memc));
847 test_true((value= memcached_get(memc, test_literal_param(__func__), NULL, NULL, &rc)));
848 test_compare(MEMCACHED_SUCCESS, rc);
849 free(value);
850 }
851
852 return TEST_SUCCESS;
853 }
854
855 /*
856 Set the value, then quit to make sure it is flushed.
857 Come back in and test that add fails.
858 */
859 test_return_t add_test(memcached_st *memc)
860 {
861 test_compare(return_value_based_on_buffering(memc),
862 memcached_set(memc,
863 test_literal_param(__func__),
864 test_literal_param("when we sanitize"),
865 time_t(0), uint32_t(0)));
866
867 memcached_quit(memc);
868
869 size_t value_length;
870 uint32_t flags;
871 memcached_return_t rc;
872 char *check_value= memcached_get(memc,
873 test_literal_param(__func__),
874 &value_length, &flags, &rc);
875 test_memcmp(check_value, "when we sanitize", strlen("when we sanitize"));
876 test_compare(test_literal_param_size("when we sanitize"), value_length);
877 test_compare(MEMCACHED_SUCCESS, rc);
878 free(check_value);
879
880 test_compare(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) ? MEMCACHED_DATA_EXISTS : MEMCACHED_NOTSTORED,
881 memcached_add(memc,
882 test_literal_param(__func__),
883 test_literal_param("try something else"),
884 time_t(0), uint32_t(0)));
885
886 return TEST_SUCCESS;
887 }
888
889 /*
890 ** There was a problem of leaking filedescriptors in the initial release
891 ** of MacOSX 10.5. This test case triggers the problem. On some Solaris
892 ** systems it seems that the kernel is slow on reclaiming the resources
893 ** because the connects starts to time out (the test doesn't do much
894 ** anyway, so just loop 10 iterations)
895 */
896 test_return_t add_wrapper(memcached_st *memc)
897 {
898 unsigned int max= 10000;
899 #ifdef __sun
900 max= 10;
901 #endif
902 #ifdef __APPLE__
903 max= 10;
904 #endif
905
906 for (uint32_t x= 0; x < max; x++)
907 {
908 add_test(memc);
909 }
910
911 return TEST_SUCCESS;
912 }
913
914 test_return_t replace_test(memcached_st *memc)
915 {
916 test_compare(return_value_based_on_buffering(memc),
917 memcached_set(memc,
918 test_literal_param(__func__),
919 test_literal_param("when we sanitize"),
920 time_t(0), uint32_t(0)));
921
922 test_compare(MEMCACHED_SUCCESS,
923 memcached_replace(memc,
924 test_literal_param(__func__),
925 test_literal_param("first we insert some data"),
926 time_t(0), uint32_t(0)));
927
928 return TEST_SUCCESS;
929 }
930
931 test_return_t delete_test(memcached_st *memc)
932 {
933 test_compare(return_value_based_on_buffering(memc),
934 memcached_set(memc,
935 test_literal_param(__func__),
936 test_literal_param("when we sanitize"),
937 time_t(0), uint32_t(0)));
938
939 test_compare(return_value_based_on_buffering(memc),
940 memcached_delete(memc,
941 test_literal_param(__func__),
942 time_t(0)));
943
944 return TEST_SUCCESS;
945 }
946
947 test_return_t flush_test(memcached_st *memc)
948 {
949 uint64_t query_id= memcached_query_id(memc);
950 test_compare(MEMCACHED_SUCCESS,
951 memcached_flush(memc, 0));
952 test_compare(query_id +1, memcached_query_id(memc));
953
954 return TEST_SUCCESS;
955 }
956
957 static memcached_return_t server_function(const memcached_st *,
958 memcached_server_instance_st,
959 void *)
960 {
961 /* Do Nothing */
962 return MEMCACHED_SUCCESS;
963 }
964
965 test_return_t memcached_server_cursor_test(memcached_st *memc)
966 {
967 char context[10];
968 strncpy(context, "foo bad", sizeof(context));
969 memcached_server_fn callbacks[1];
970
971 callbacks[0]= server_function;
972 memcached_server_cursor(memc, callbacks, context, 1);
973 return TEST_SUCCESS;
974 }
975
976 test_return_t bad_key_test(memcached_st *memc)
977 {
978 memcached_return_t rc;
979 const char *key= "foo bad";
980 uint32_t flags;
981
982 uint64_t query_id= memcached_query_id(memc);
983
984 // Just skip if we are in binary mode.
985 test_skip(false, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL));
986
987 test_compare(query_id, memcached_query_id(memc)); // We should not increase the query_id for memcached_behavior_get()
988
989 memcached_st *memc_clone= memcached_clone(NULL, memc);
990 test_true(memc_clone);
991
992 query_id= memcached_query_id(memc_clone);
993 test_compare(MEMCACHED_SUCCESS,
994 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_VERIFY_KEY, true));
995 test_compare(query_id, memcached_query_id(memc_clone)); // We should not increase the query_id for memcached_behavior_set()
996
997 /* All keys are valid in the binary protocol (except for length) */
998 if (memcached_behavior_get(memc_clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == false)
999 {
1000 uint64_t before_query_id= memcached_query_id(memc_clone);
1001 {
1002 size_t string_length;
1003 char *string= memcached_get(memc_clone, key, strlen(key),
1004 &string_length, &flags, &rc);
1005 test_compare(MEMCACHED_BAD_KEY_PROVIDED, rc);
1006 test_zero(string_length);
1007 test_false(string);
1008 }
1009 test_compare(before_query_id +1, memcached_query_id(memc_clone));
1010
1011 query_id= memcached_query_id(memc_clone);
1012 test_compare(MEMCACHED_SUCCESS,
1013 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_VERIFY_KEY, false));
1014 test_compare(query_id, memcached_query_id(memc_clone)); // We should not increase the query_id for memcached_behavior_set()
1015 {
1016 size_t string_length;
1017 char *string= memcached_get(memc_clone, key, strlen(key),
1018 &string_length, &flags, &rc);
1019 test_compare(MEMCACHED_NOTFOUND, rc);
1020 test_zero(string_length);
1021 test_false(string);
1022 }
1023
1024 /* Test multi key for bad keys */
1025 const char *keys[] = { "GoodKey", "Bad Key", "NotMine" };
1026 size_t key_lengths[] = { 7, 7, 7 };
1027 query_id= memcached_query_id(memc_clone);
1028 test_compare(MEMCACHED_SUCCESS,
1029 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_VERIFY_KEY, true));
1030 test_compare(query_id, memcached_query_id(memc_clone));
1031
1032 query_id= memcached_query_id(memc_clone);
1033 test_compare(MEMCACHED_BAD_KEY_PROVIDED,
1034 memcached_mget(memc_clone, keys, key_lengths, 3));
1035 test_compare(query_id +1, memcached_query_id(memc_clone));
1036
1037 query_id= memcached_query_id(memc_clone);
1038 // Grouping keys are not required to follow normal key behaviors
1039 test_compare(MEMCACHED_SUCCESS,
1040 memcached_mget_by_key(memc_clone, "foo daddy", 9, keys, key_lengths, 1));
1041 test_compare(query_id +1, memcached_query_id(memc_clone));
1042
1043 /* The following test should be moved to the end of this function when the
1044 memcached server is updated to allow max size length of the keys in the
1045 binary protocol
1046 */
1047 test_compare(MEMCACHED_SUCCESS,
1048 memcached_callback_set(memc_clone, MEMCACHED_CALLBACK_NAMESPACE, NULL));
1049
1050 libtest::vchar_t longkey;
1051 {
1052 libtest::vchar_t::iterator it= longkey.begin();
1053 longkey.insert(it, MEMCACHED_MAX_KEY, 'a');
1054 }
1055
1056 test_compare(longkey.size(), size_t(MEMCACHED_MAX_KEY));
1057 {
1058 size_t string_length;
1059 // We subtract 1
1060 test_null(memcached_get(memc_clone, &longkey[0], longkey.size() -1, &string_length, &flags, &rc));
1061 test_compare(MEMCACHED_NOTFOUND, rc);
1062 test_zero(string_length);
1063
1064 test_null(memcached_get(memc_clone, &longkey[0], longkey.size(), &string_length, &flags, &rc));
1065 test_compare(MEMCACHED_BAD_KEY_PROVIDED, rc);
1066 test_zero(string_length);
1067 }
1068 }
1069
1070 /* Make sure zero length keys are marked as bad */
1071 {
1072 test_compare(MEMCACHED_SUCCESS,
1073 memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_VERIFY_KEY, true));
1074 size_t string_length;
1075 char *string= memcached_get(memc_clone, key, 0,
1076 &string_length, &flags, &rc);
1077 test_compare(MEMCACHED_BAD_KEY_PROVIDED, rc);
1078 test_zero(string_length);
1079 test_false(string);
1080 }
1081
1082 memcached_free(memc_clone);
1083
1084 return TEST_SUCCESS;
1085 }
1086
1087 #define READ_THROUGH_VALUE "set for me"
1088 static memcached_return_t read_through_trigger(memcached_st *, // memc
1089 char *, // key
1090 size_t, // key_length,
1091 memcached_result_st *result)
1092 {
1093 return memcached_result_set_value(result, READ_THROUGH_VALUE, strlen(READ_THROUGH_VALUE));
1094 }
1095
1096 #ifndef __INTEL_COMPILER
1097 #pragma GCC diagnostic ignored "-Wstrict-aliasing"
1098 #endif
1099
1100 test_return_t read_through(memcached_st *memc)
1101 {
1102 memcached_trigger_key_fn cb= (memcached_trigger_key_fn)read_through_trigger;
1103
1104 size_t string_length;
1105 uint32_t flags;
1106 memcached_return_t rc;
1107 char *string= memcached_get(memc,
1108 test_literal_param(__func__),
1109 &string_length, &flags, &rc);
1110
1111 test_compare(MEMCACHED_NOTFOUND, rc);
1112 test_false(string_length);
1113 test_false(string);
1114
1115 test_compare(MEMCACHED_SUCCESS,
1116 memcached_callback_set(memc, MEMCACHED_CALLBACK_GET_FAILURE, *(void **)&cb));
1117
1118 string= memcached_get(memc,
1119 test_literal_param(__func__),
1120 &string_length, &flags, &rc);
1121
1122 test_compare(MEMCACHED_SUCCESS, rc);
1123 test_compare(sizeof(READ_THROUGH_VALUE) -1, string_length);
1124 test_compare(0, string[sizeof(READ_THROUGH_VALUE) -1]);
1125 test_strcmp(READ_THROUGH_VALUE, string);
1126 free(string);
1127
1128 string= memcached_get(memc,
1129 test_literal_param(__func__),
1130 &string_length, &flags, &rc);
1131
1132 test_compare(MEMCACHED_SUCCESS, rc);
1133 test_true(string);
1134 test_compare(string_length, sizeof(READ_THROUGH_VALUE) -1);
1135 test_true(string[sizeof(READ_THROUGH_VALUE) -1] == 0);
1136 test_strcmp(READ_THROUGH_VALUE, string);
1137 free(string);
1138
1139 return TEST_SUCCESS;
1140 }
1141
1142 test_return_t set_test2(memcached_st *memc)
1143 {
1144 for (uint32_t x= 0; x < 10; x++)
1145 {
1146 test_compare(return_value_based_on_buffering(memc),
1147 memcached_set(memc,
1148 test_literal_param("foo"),
1149 test_literal_param("train in the brain"),
1150 time_t(0), uint32_t(0)));
1151 }
1152
1153 return TEST_SUCCESS;
1154 }
1155
1156 test_return_t set_test3(memcached_st *memc)
1157 {
1158 size_t value_length= 8191;
1159
1160 libtest::vchar_t value;
1161 value.reserve(value_length);
1162 for (uint32_t x= 0; x < value_length; x++)
1163 {
1164 value.push_back(char(x % 127));
1165 }
1166
1167 /* The dump test relies on there being at least 32 items in memcached */
1168 for (uint32_t x= 0; x < 32; x++)
1169 {
1170 char key[16];
1171
1172 snprintf(key, sizeof(key), "foo%u", x);
1173
1174 uint64_t query_id= memcached_query_id(memc);
1175 test_compare(return_value_based_on_buffering(memc),
1176 memcached_set(memc, key, strlen(key),
1177 &value[0], value.size(),
1178 time_t(0), uint32_t(0)));
1179 test_compare(query_id +1, memcached_query_id(memc));
1180 }
1181
1182 return TEST_SUCCESS;
1183 }
1184
1185 test_return_t mget_end(memcached_st *memc)
1186 {
1187 const char *keys[]= { "foo", "foo2" };
1188 size_t lengths[]= { 3, 4 };
1189 const char *values[]= { "fjord", "41" };
1190
1191 // Set foo and foo2
1192 for (size_t x= 0; x < test_array_length(keys); x++)
1193 {
1194 test_compare(MEMCACHED_SUCCESS,
1195 memcached_set(memc,
1196 keys[x], lengths[x],
1197 values[x], strlen(values[x]),
1198 time_t(0), uint32_t(0)));
1199 }
1200
1201 char *string;
1202 size_t string_length;
1203 uint32_t flags;
1204
1205 // retrieve both via mget
1206 test_compare(MEMCACHED_SUCCESS,
1207 memcached_mget(memc,
1208 keys, lengths,
1209 test_array_length(keys)));
1210
1211 char key[MEMCACHED_MAX_KEY];
1212 size_t key_length;
1213 memcached_return_t rc;
1214
1215 // this should get both
1216 for (size_t x= 0; x < test_array_length(keys); x++)
1217 {
1218 string= memcached_fetch(memc, key, &key_length, &string_length,
1219 &flags, &rc);
1220 test_compare(MEMCACHED_SUCCESS, rc);
1221 int val = 0;
1222 if (key_length == 4)
1223 {
1224 val= 1;
1225 }
1226
1227 test_compare(string_length, strlen(values[val]));
1228 test_true(strncmp(values[val], string, string_length) == 0);
1229 free(string);
1230 }
1231
1232 // this should indicate end
1233 string= memcached_fetch(memc, key, &key_length, &string_length, &flags, &rc);
1234 test_compare(MEMCACHED_END, rc);
1235 test_null(string);
1236
1237 // now get just one
1238 test_compare(MEMCACHED_SUCCESS,
1239 memcached_mget(memc, keys, lengths, 1));
1240
1241 string= memcached_fetch(memc, key, &key_length, &string_length, &flags, &rc);
1242 test_compare(key_length, lengths[0]);
1243 test_true(strncmp(keys[0], key, key_length) == 0);
1244 test_compare(string_length, strlen(values[0]));
1245 test_true(strncmp(values[0], string, string_length) == 0);
1246 test_compare(MEMCACHED_SUCCESS, rc);
1247 free(string);
1248
1249 // this should indicate end
1250 string= memcached_fetch(memc, key, &key_length, &string_length, &flags, &rc);
1251 test_compare(MEMCACHED_END, rc);
1252 test_null(string);
1253
1254 return TEST_SUCCESS;
1255 }
1256
1257 /* Do not copy the style of this code, I just access hosts to testthis function */
1258 test_return_t stats_servername_test(memcached_st *memc)
1259 {
1260 memcached_stat_st memc_stat;
1261 memcached_server_instance_st instance=
1262 memcached_server_instance_by_position(memc, 0);
1263
1264 if (LIBMEMCACHED_WITH_SASL_SUPPORT and memcached_get_sasl_callbacks(memc))
1265 {
1266 return TEST_SKIPPED;
1267 }
1268
1269 test_compare(MEMCACHED_SUCCESS, memcached_stat_servername(&memc_stat, NULL,
1270 memcached_server_name(instance),
1271 memcached_server_port(instance)));
1272
1273 return TEST_SUCCESS;
1274 }
1275
1276 test_return_t increment_test(memcached_st *memc)
1277 {
1278 uint64_t new_number;
1279
1280 test_compare(MEMCACHED_SUCCESS,
1281 memcached_set(memc,
1282 test_literal_param("number"),
1283 test_literal_param("0"),
1284 (time_t)0, (uint32_t)0));
1285
1286 test_compare(MEMCACHED_SUCCESS,
1287 memcached_increment(memc, test_literal_param("number"), 1, &new_number));
1288 test_compare(uint64_t(1), new_number);
1289
1290 test_compare(MEMCACHED_SUCCESS,
1291 memcached_increment(memc, test_literal_param("number"), 1, &new_number));
1292 test_compare(uint64_t(2), new_number);
1293
1294 return TEST_SUCCESS;
1295 }
1296
1297 test_return_t increment_with_initial_test(memcached_st *memc)
1298 {
1299 test_skip(true, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL));
1300
1301 uint64_t new_number;
1302 uint64_t initial= 0;
1303
1304 test_compare(MEMCACHED_SUCCESS, memcached_flush_buffers(memc));
1305
1306 test_compare(MEMCACHED_SUCCESS,
1307 memcached_increment_with_initial(memc, test_literal_param("number"), 1, initial, 0, &new_number));
1308 test_compare(new_number, initial);
1309
1310 test_compare(MEMCACHED_SUCCESS,
1311 memcached_increment_with_initial(memc, test_literal_param("number"), 1, initial, 0, &new_number));
1312 test_compare(new_number, (initial +1));
1313
1314 return TEST_SUCCESS;
1315 }
1316
1317 test_return_t decrement_test(memcached_st *memc)
1318 {
1319 test_compare(return_value_based_on_buffering(memc),
1320 memcached_set(memc,
1321 test_literal_param(__func__),
1322 test_literal_param("3"),
1323 time_t(0), uint32_t(0)));
1324
1325 // Make sure we flush the value we just set
1326 test_compare(MEMCACHED_SUCCESS, memcached_flush_buffers(memc));
1327
1328 uint64_t new_number;
1329 test_compare(MEMCACHED_SUCCESS,
1330 memcached_decrement(memc,
1331 test_literal_param(__func__),
1332 1, &new_number));
1333 test_compare(uint64_t(2), new_number);
1334
1335 test_compare(MEMCACHED_SUCCESS,
1336 memcached_decrement(memc,
1337 test_literal_param(__func__),
1338 1, &new_number));
1339 test_compare(uint64_t(1), new_number);
1340
1341 return TEST_SUCCESS;
1342 }
1343
1344 test_return_t decrement_with_initial_test(memcached_st *memc)
1345 {
1346 test_skip(true, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL));
1347
1348 uint64_t initial= 3;
1349
1350 test_compare(MEMCACHED_SUCCESS, memcached_flush_buffers(memc));
1351
1352 uint64_t new_number;
1353 test_compare(MEMCACHED_SUCCESS,
1354 memcached_decrement_with_initial(memc,
1355 test_literal_param(__func__),
1356 1, initial,
1357 0, &new_number));
1358 test_compare(new_number, initial);
1359
1360 test_compare(MEMCACHED_SUCCESS,
1361 memcached_decrement_with_initial(memc,
1362 test_literal_param(__func__),
1363 1, initial,
1364 0, &new_number));
1365 test_compare(new_number, (initial - 1));
1366
1367 return TEST_SUCCESS;
1368 }
1369
1370 test_return_t increment_by_key_test(memcached_st *memc)
1371 {
1372 const char *master_key= "foo";
1373 const char *key= "number";
1374 const char *value= "0";
1375
1376 test_compare(return_value_based_on_buffering(memc),
1377 memcached_set_by_key(memc, master_key, strlen(master_key),
1378 key, strlen(key),
1379 value, strlen(value),
1380 time_t(0), uint32_t(0)));
1381
1382 // Make sure we flush the value we just set
1383 test_compare(MEMCACHED_SUCCESS, memcached_flush_buffers(memc));
1384
1385 uint64_t new_number;
1386 test_compare(MEMCACHED_SUCCESS,
1387 memcached_increment_by_key(memc, master_key, strlen(master_key),
1388 key, strlen(key), 1, &new_number));
1389 test_compare(uint64_t(1), new_number);
1390
1391 test_compare(MEMCACHED_SUCCESS,
1392 memcached_increment_by_key(memc, master_key, strlen(master_key),
1393 key, strlen(key), 1, &new_number));
1394 test_compare(uint64_t(2), new_number);
1395
1396 return TEST_SUCCESS;
1397 }
1398
1399 test_return_t increment_with_initial_by_key_test(memcached_st *memc)
1400 {
1401 test_skip(true, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL));
1402
1403 uint64_t new_number;
1404 const char *master_key= "foo";
1405 const char *key= "number";
1406 uint64_t initial= 0;
1407
1408 test_compare(MEMCACHED_SUCCESS,
1409 memcached_increment_with_initial_by_key(memc, master_key, strlen(master_key),
1410 key, strlen(key),
1411 1, initial, 0, &new_number));
1412 test_compare(new_number, initial);
1413
1414 test_compare(MEMCACHED_SUCCESS,
1415 memcached_increment_with_initial_by_key(memc, master_key, strlen(master_key),
1416 key, strlen(key),
1417 1, initial, 0, &new_number));
1418 test_compare(new_number, (initial +1));
1419
1420 return TEST_SUCCESS;
1421 }
1422
1423 test_return_t decrement_by_key_test(memcached_st *memc)
1424 {
1425 uint64_t new_number;
1426 const char *value= "3";
1427
1428 test_compare(return_value_based_on_buffering(memc),
1429 memcached_set_by_key(memc,
1430 test_literal_param("foo"),
1431 test_literal_param("number"),
1432 value, strlen(value),
1433 (time_t)0, (uint32_t)0));
1434
1435 test_compare(MEMCACHED_SUCCESS,
1436 memcached_decrement_by_key(memc,
1437 test_literal_param("foo"),
1438 test_literal_param("number"),
1439 1, &new_number));
1440 test_compare(uint64_t(2), new_number);
1441
1442 test_compare(MEMCACHED_SUCCESS,
1443 memcached_decrement_by_key(memc,
1444 test_literal_param("foo"),
1445 test_literal_param("number"),
1446 1, &new_number));
1447 test_compare(uint64_t(1), new_number);
1448
1449 return TEST_SUCCESS;
1450 }
1451
1452 test_return_t decrement_with_initial_by_key_test(memcached_st *memc)
1453 {
1454 test_skip(true, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL));
1455
1456 uint64_t new_number;
1457 uint64_t initial= 3;
1458
1459 test_compare(MEMCACHED_SUCCESS,
1460 memcached_decrement_with_initial_by_key(memc,
1461 test_literal_param("foo"),
1462 test_literal_param("number"),
1463 1, initial, 0, &new_number));
1464 test_compare(new_number, initial);
1465
1466 test_compare(MEMCACHED_SUCCESS,
1467 memcached_decrement_with_initial_by_key(memc,
1468 test_literal_param("foo"),
1469 test_literal_param("number"),
1470 1, initial, 0, &new_number));
1471 test_compare(new_number, (initial - 1));
1472
1473 return TEST_SUCCESS;
1474 }
1475 test_return_t binary_increment_with_prefix_test(memcached_st *memc)
1476 {
1477 test_skip(true, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL));
1478
1479 test_compare(MEMCACHED_SUCCESS, memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, (void *)"namespace:"));
1480
1481 test_compare(return_value_based_on_buffering(memc),
1482 memcached_set(memc,
1483 test_literal_param("number"),
1484 test_literal_param("0"),
1485 (time_t)0, (uint32_t)0));
1486
1487 uint64_t new_number;
1488 test_compare(MEMCACHED_SUCCESS, memcached_increment(memc,
1489 test_literal_param("number"),
1490 1, &new_number));
1491 test_compare(uint64_t(1), new_number);
1492
1493 test_compare(MEMCACHED_SUCCESS, memcached_increment(memc,
1494 test_literal_param("number"),
1495 1, &new_number));
1496 test_compare(uint64_t(2), new_number);
1497
1498 return TEST_SUCCESS;
1499 }
1500
1501 test_return_t quit_test(memcached_st *memc)
1502 {
1503 const char *value= "sanford and sun";
1504
1505 test_compare(return_value_based_on_buffering(memc),
1506 memcached_set(memc,
1507 test_literal_param(__func__),
1508 value, strlen(value),
1509 time_t(10), uint32_t(3)));
1510 memcached_quit(memc);
1511
1512 test_compare(return_value_based_on_buffering(memc),
1513 memcached_set(memc,
1514 test_literal_param(__func__),
1515 value, strlen(value),
1516 time_t(50), uint32_t(9)));
1517
1518 return TEST_SUCCESS;
1519 }
1520
1521 test_return_t mget_result_test(memcached_st *memc)
1522 {
1523 const char *keys[]= {"fudge", "son", "food"};
1524 size_t key_length[]= {5, 3, 4};
1525
1526 memcached_result_st results_obj;
1527 memcached_result_st *results= memcached_result_create(memc, &results_obj);
1528 test_true(results);
1529 test_true(&results_obj == results);
1530
1531 /* We need to empty the server before continueing test */
1532 test_compare(MEMCACHED_SUCCESS,
1533 memcached_flush(memc, 0));
1534
1535 test_compare(MEMCACHED_SUCCESS,
1536 memcached_mget(memc, keys, key_length, 3));
1537
1538 memcached_return_t rc;
1539 while ((results= memcached_fetch_result(memc, &results_obj, &rc)))
1540 {
1541 test_true(results);
1542 }
1543
1544 while ((results= memcached_fetch_result(memc, &results_obj, &rc))) { test_true(false); /* We should never see a value returned */ };
1545 test_false(results);
1546 test_compare(MEMCACHED_NOTFOUND, rc);
1547
1548 for (uint32_t x= 0; x < 3; x++)
1549 {
1550 rc= memcached_set(memc, keys[x], key_length[x],
1551 keys[x], key_length[x],
1552 (time_t)50, (uint32_t)9);
1553 test_true(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED);
1554 }
1555
1556 test_compare(MEMCACHED_SUCCESS,
1557 memcached_mget(memc, keys, key_length, 3));
1558
1559 while ((results= memcached_fetch_result(memc, &results_obj, &rc)))
1560 {
1561 test_true(results);
1562 test_true(&results_obj == results);
1563 test_compare(MEMCACHED_SUCCESS, rc);
1564 test_memcmp(memcached_result_key_value(results),
1565 memcached_result_value(results),
1566 memcached_result_length(results));
1567 test_compare(memcached_result_key_length(results), memcached_result_length(results));
1568 }
1569
1570 memcached_result_free(&results_obj);
1571
1572 return TEST_SUCCESS;
1573 }
1574
1575 test_return_t mget_result_alloc_test(memcached_st *memc)
1576 {
1577 const char *keys[]= {"fudge", "son", "food"};
1578 size_t key_length[]= {5, 3, 4};
1579
1580 memcached_result_st *results;
1581
1582 /* We need to empty the server before continueing test */
1583 test_compare(MEMCACHED_SUCCESS,
1584 memcached_flush(memc, 0));
1585
1586 test_compare(MEMCACHED_SUCCESS,
1587 memcached_mget(memc, keys, key_length, 3));
1588
1589 memcached_return_t rc;
1590 while ((results= memcached_fetch_result(memc, NULL, &rc)))
1591 {
1592 test_true(results);
1593 }
1594 test_false(results);
1595 test_compare(MEMCACHED_NOTFOUND, rc);
1596
1597 for (uint32_t x= 0; x < 3; x++)
1598 {
1599 rc= memcached_set(memc, keys[x], key_length[x],
1600 keys[x], key_length[x],
1601 (time_t)50, (uint32_t)9);
1602 test_true(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED);
1603 }
1604
1605 test_compare(MEMCACHED_SUCCESS,
1606 memcached_mget(memc, keys, key_length, 3));
1607
1608 uint32_t x= 0;
1609 while ((results= memcached_fetch_result(memc, NULL, &rc)))
1610 {
1611 test_true(results);
1612 test_compare(MEMCACHED_SUCCESS, rc);
1613 test_compare(memcached_result_key_length(results), memcached_result_length(results));
1614 test_memcmp(memcached_result_key_value(results),
1615 memcached_result_value(results),
1616 memcached_result_length(results));
1617 memcached_result_free(results);
1618 x++;
1619 }
1620
1621 return TEST_SUCCESS;
1622 }
1623
1624 test_return_t mget_result_function(memcached_st *memc)
1625 {
1626 const char *keys[]= {"fudge", "son", "food"};
1627 size_t key_length[]= {5, 3, 4};
1628 size_t counter;
1629 memcached_execute_fn callbacks[1];
1630
1631 for (uint32_t x= 0; x < 3; x++)
1632 {
1633 test_compare(return_value_based_on_buffering(memc),
1634 memcached_set(memc, keys[x], key_length[x],
1635 keys[x], key_length[x],
1636 time_t(50), uint32_t(9)));
1637 }
1638 test_compare(MEMCACHED_SUCCESS, memcached_flush_buffers(memc));
1639 memcached_quit(memc);
1640
1641 test_compare(MEMCACHED_SUCCESS,
1642 memcached_mget(memc, keys, key_length, 3));
1643
1644 callbacks[0]= &callback_counter;
1645 counter= 0;
1646
1647 test_compare(MEMCACHED_SUCCESS,
1648 memcached_fetch_execute(memc, callbacks, (void *)&counter, 1));
1649
1650 test_compare(size_t(3), counter);
1651
1652 return TEST_SUCCESS;
1653 }
1654
1655 test_return_t mget_test(memcached_st *memc)
1656 {
1657 const char *keys[]= {"fudge", "son", "food"};
1658 size_t key_length[]= {5, 3, 4};
1659
1660 char return_key[MEMCACHED_MAX_KEY];
1661 size_t return_key_length;
1662 char *return_value;
1663 size_t return_value_length;
1664
1665 test_compare(MEMCACHED_SUCCESS,
1666 memcached_mget(memc, keys, key_length, 3));
1667
1668 uint32_t flags;
1669 memcached_return_t rc;
1670 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
1671 &return_value_length, &flags, &rc)))
1672 {
1673 test_true(return_value);
1674 }
1675 test_false(return_value);
1676 test_zero(return_value_length);
1677 test_compare(MEMCACHED_NOTFOUND, rc);
1678
1679 for (uint32_t x= 0; x < 3; x++)
1680 {
1681 rc= memcached_set(memc, keys[x], key_length[x],
1682 keys[x], key_length[x],
1683 (time_t)50, (uint32_t)9);
1684 test_true(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED);
1685 }
1686 test_compare(MEMCACHED_SUCCESS,
1687 memcached_mget(memc, keys, key_length, 3));
1688
1689 uint32_t x= 0;
1690 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
1691 &return_value_length, &flags, &rc)))
1692 {
1693 test_true(return_value);
1694 test_compare(MEMCACHED_SUCCESS, rc);
1695 if (not memc->_namespace)
1696 {
1697 test_compare(return_key_length, return_value_length);
1698 test_memcmp(return_value, return_key, return_value_length);
1699 }
1700 free(return_value);
1701 x++;
1702 }
1703
1704 return TEST_SUCCESS;
1705 }
1706
1707 test_return_t mget_execute(memcached_st *original_memc)
1708 {
1709 test_skip(true, memcached_behavior_get(original_memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL));
1710
1711 memcached_st *memc= create_single_instance_memcached(original_memc, "--BINARY-PROTOCOL");
1712 test_true(memc);
1713
1714 keys_st keys(20480);
1715
1716 /* First add all of the items.. */
1717 char blob[1024] = {0};
1718
1719 for (size_t x= 0; x < keys.size(); ++x)
1720 {
1721 uint64_t query_id= memcached_query_id(memc);
1722 memcached_return_t rc= memcached_add(memc,
1723 keys.key_at(x), keys.length_at(x),
1724 blob, sizeof(blob),
1725 0, 0);
1726 test_true(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED);
1727 test_compare(query_id +1, memcached_query_id(memc));
1728 }
1729
1730 /* Try to get all of them with a large multiget */
1731 size_t counter= 0;
1732 memcached_execute_fn callbacks[]= { &callback_counter };
1733 test_compare(MEMCACHED_SUCCESS,
1734 memcached_mget_execute(memc,
1735 keys.keys_ptr(), keys.lengths_ptr(),
1736 keys.size(), callbacks, &counter, 1));
1737
1738 {
1739 uint64_t query_id= memcached_query_id(memc);
1740 test_compare(MEMCACHED_SUCCESS,
1741 memcached_fetch_execute(memc, callbacks, (void *)&counter, 1));
1742 test_compare(query_id, memcached_query_id(memc));
1743
1744 /* Verify that we got all of the items */
1745 test_compare(keys.size(), counter);
1746 }
1747
1748 memcached_free(memc);
1749
1750 return TEST_SUCCESS;
1751 }
1752
1753 #define REGRESSION_BINARY_VS_BLOCK_COUNT 20480
1754 static pairs_st *global_pairs= NULL;
1755
1756 test_return_t key_setup(memcached_st *memc)
1757 {
1758 test_skip(TEST_SUCCESS, pre_binary(memc));
1759
1760 global_pairs= pairs_generate(REGRESSION_BINARY_VS_BLOCK_COUNT, 0);
1761
1762 return TEST_SUCCESS;
1763 }
1764
1765 test_return_t key_teardown(memcached_st *)
1766 {
1767 pairs_free(global_pairs);
1768 global_pairs= NULL;
1769
1770 return TEST_SUCCESS;
1771 }
1772
1773 test_return_t block_add_regression(memcached_st *memc)
1774 {
1775 /* First add all of the items.. */
1776 for (ptrdiff_t x= 0; x < REGRESSION_BINARY_VS_BLOCK_COUNT; ++x)
1777 {
1778 libtest::vchar_t blob;
1779 libtest::vchar::make(blob, 1024);
1780
1781 memcached_return_t rc= memcached_add_by_key(memc,
1782 test_literal_param("bob"),
1783 global_pairs[x].key, global_pairs[x].key_length,
1784 &blob[0], blob.size(),
1785 time_t(0), uint32_t(0));
1786 if (rc == MEMCACHED_MEMORY_ALLOCATION_FAILURE)
1787 {
1788 Error << memcached_last_error_message(memc);
1789 return TEST_SKIPPED;
1790 }
1791 test_compare(*memc, MEMCACHED_SUCCESS);
1792 test_compare(rc, MEMCACHED_SUCCESS);
1793 }
1794
1795 return TEST_SUCCESS;
1796 }
1797
1798 test_return_t binary_add_regression(memcached_st *memc)
1799 {
1800 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, true));
1801 return block_add_regression(memc);
1802 }
1803
1804 test_return_t get_stats_keys(memcached_st *memc)
1805 {
1806 char **stat_list;
1807 char **ptr;
1808 memcached_stat_st memc_stat;
1809 memcached_return_t rc;
1810
1811 stat_list= memcached_stat_get_keys(memc, &memc_stat, &rc);
1812 test_compare(MEMCACHED_SUCCESS, rc);
1813 for (ptr= stat_list; *ptr; ptr++)
1814 test_true(*ptr);
1815
1816 free(stat_list);
1817
1818 return TEST_SUCCESS;
1819 }
1820
1821 test_return_t version_string_test(memcached_st *)
1822 {
1823 test_strcmp(LIBMEMCACHED_VERSION_STRING, memcached_lib_version());
1824
1825 return TEST_SUCCESS;
1826 }
1827
1828 test_return_t get_stats(memcached_st *memc)
1829 {
1830 memcached_return_t rc;
1831
1832 memcached_stat_st *memc_stat= memcached_stat(memc, NULL, &rc);
1833 test_compare(MEMCACHED_SUCCESS, rc);
1834 test_true(memc_stat);
1835
1836 for (uint32_t x= 0; x < memcached_server_count(memc); x++)
1837 {
1838 char **stat_list= memcached_stat_get_keys(memc, memc_stat+x, &rc);
1839 test_compare(MEMCACHED_SUCCESS, rc);
1840 for (char **ptr= stat_list; *ptr; ptr++) {};
1841
1842 free(stat_list);
1843 }
1844
1845 memcached_stat_free(NULL, memc_stat);
1846
1847 return TEST_SUCCESS;
1848 }
1849
1850 test_return_t add_host_test(memcached_st *memc)
1851 {
1852 char servername[]= "0.example.com";
1853
1854 memcached_return_t rc;
1855 memcached_server_st *servers= memcached_server_list_append_with_weight(NULL, servername, 400, 0, &rc);
1856 test_compare(1U, memcached_server_list_count(servers));
1857
1858 for (unsigned int x= 2; x < 20; x++)
1859 {
1860 char buffer[SMALL_STRING_LEN];
1861
1862 snprintf(buffer, SMALL_STRING_LEN, "%u.example.com", 400+x);
1863 servers= memcached_server_list_append_with_weight(servers, buffer, 401, 0,
1864 &rc);
1865 test_compare(MEMCACHED_SUCCESS, rc);
1866 test_compare(x, memcached_server_list_count(servers));
1867 }
1868
1869 test_compare(MEMCACHED_SUCCESS, memcached_server_push(memc, servers));
1870 test_compare(MEMCACHED_SUCCESS, memcached_server_push(memc, servers));
1871
1872 memcached_server_list_free(servers);
1873
1874 return TEST_SUCCESS;
1875 }
1876
1877 test_return_t regression_1048945_TEST(memcached_st*)
1878 {
1879 memcached_return status;
1880
1881 memcached_server_st* list= memcached_server_list_append_with_weight(NULL, "a", 11211, 0, &status);
1882 test_compare(status, MEMCACHED_SUCCESS);
1883
1884 list= memcached_server_list_append_with_weight(list, "b", 11211, 0, &status);
1885 test_compare(status, MEMCACHED_SUCCESS);
1886
1887 list= memcached_server_list_append_with_weight(list, "c", 11211, 0, &status);
1888 test_compare(status, MEMCACHED_SUCCESS);
1889
1890 memcached_st* memc= memcached_create(NULL);
1891
1892 status= memcached_server_push(memc, list);
1893 memcached_server_list_free(list);
1894 test_compare(status, MEMCACHED_SUCCESS);
1895
1896 memcached_server_instance_st server= memcached_server_by_key(memc, test_literal_param(__func__), &status);
1897 test_true(server);
1898 test_compare(status, MEMCACHED_SUCCESS);
1899
1900 memcached_free(memc);
1901
1902 return TEST_SUCCESS;
1903 }
1904
1905 test_return_t memcached_fetch_result_NOT_FOUND(memcached_st *memc)
1906 {
1907 memcached_return_t rc;
1908
1909 const char *key= "not_found";
1910 size_t key_length= test_literal_param_size("not_found");
1911
1912 test_compare(MEMCACHED_SUCCESS,
1913 memcached_mget(memc, &key, &key_length, 1));
1914
1915 memcached_result_st *result= memcached_fetch_result(memc, NULL, &rc);
1916 test_null(result);
1917 test_compare(MEMCACHED_NOTFOUND, rc);
1918
1919 memcached_result_free(result);
1920
1921 return TEST_SUCCESS;
1922 }
1923
1924 static memcached_return_t clone_test_callback(memcached_st *, memcached_st *)
1925 {
1926 return MEMCACHED_SUCCESS;
1927 }
1928
1929 static memcached_return_t cleanup_test_callback(memcached_st *)
1930 {
1931 return MEMCACHED_SUCCESS;
1932 }
1933
1934 test_return_t callback_test(memcached_st *memc)
1935 {
1936 /* Test User Data */
1937 {
1938 int x= 5;
1939 int *test_ptr;
1940 memcached_return_t rc;
1941
1942 test_compare(MEMCACHED_SUCCESS, memcached_callback_set(memc, MEMCACHED_CALLBACK_USER_DATA, &x));
1943 test_ptr= (int *)memcached_callback_get(memc, MEMCACHED_CALLBACK_USER_DATA, &rc);
1944 test_true(*test_ptr == x);
1945 }
1946
1947 /* Test Clone Callback */
1948 {
1949 memcached_clone_fn clone_cb= (memcached_clone_fn)clone_test_callback;
1950 void *clone_cb_ptr= *(void **)&clone_cb;
1951 void *temp_function= NULL;
1952
1953 test_compare(MEMCACHED_SUCCESS, memcached_callback_set(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION, clone_cb_ptr));
1954 memcached_return_t rc;
1955 temp_function= memcached_callback_get(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION, &rc);
1956 test_true(temp_function == clone_cb_ptr);
1957 test_compare(MEMCACHED_SUCCESS, rc);
1958 }
1959
1960 /* Test Cleanup Callback */
1961 {
1962 memcached_cleanup_fn cleanup_cb= (memcached_cleanup_fn)cleanup_test_callback;
1963 void *cleanup_cb_ptr= *(void **)&cleanup_cb;
1964 void *temp_function= NULL;
1965 memcached_return_t rc;
1966
1967 test_compare(MEMCACHED_SUCCESS, memcached_callback_set(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION, cleanup_cb_ptr));
1968 temp_function= memcached_callback_get(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION, &rc);
1969 test_true(temp_function == cleanup_cb_ptr);
1970 }
1971
1972 return TEST_SUCCESS;
1973 }
1974
1975 /* We don't test the behavior itself, we test the switches */
1976 test_return_t behavior_test(memcached_st *memc)
1977 {
1978 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 1);
1979 test_compare(true, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NO_BLOCK));
1980
1981 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 1);
1982 test_compare(true, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY));
1983
1984 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, MEMCACHED_HASH_MD5);
1985 test_compare(uint64_t(MEMCACHED_HASH_MD5), memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH));
1986
1987 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
1988 test_zero(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NO_BLOCK));
1989
1990 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 0);
1991 test_zero(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY));
1992
1993 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, MEMCACHED_HASH_DEFAULT);
1994 test_compare(uint64_t(MEMCACHED_HASH_DEFAULT), memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH));
1995
1996 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, MEMCACHED_HASH_CRC);
1997 test_compare(uint64_t(MEMCACHED_HASH_CRC), memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH));
1998
1999 test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE));
2000
2001 test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE));
2002
2003 uint64_t value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS);
2004 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, value +1);
2005 test_compare((value +1), memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS));
2006
2007 return TEST_SUCCESS;
2008 }
2009
2010 test_return_t MEMCACHED_BEHAVIOR_CORK_test(memcached_st *memc)
2011 {
2012 test_compare(MEMCACHED_DEPRECATED,
2013 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_CORK, true));
2014
2015 // Platform dependent
2016 #if 0
2017 bool value= (bool)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_CORK);
2018 test_false(value);
2019 #endif
2020
2021 return TEST_SUCCESS;
2022 }
2023
2024
2025 test_return_t MEMCACHED_BEHAVIOR_TCP_KEEPALIVE_test(memcached_st *memc)
2026 {
2027 memcached_return_t rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_KEEPALIVE, true);
2028 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_NOT_SUPPORTED);
2029
2030 bool value= (bool)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_TCP_KEEPALIVE);
2031
2032 if (memcached_success(rc))
2033 {
2034 test_true(value);
2035 }
2036 else
2037 {
2038 test_false(value);
2039 }
2040
2041 return TEST_SUCCESS;
2042 }
2043
2044
2045 test_return_t MEMCACHED_BEHAVIOR_TCP_KEEPIDLE_test(memcached_st *memc)
2046 {
2047 memcached_return_t rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_KEEPIDLE, true);
2048 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_NOT_SUPPORTED);
2049
2050 bool value= (bool)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_TCP_KEEPIDLE);
2051
2052 if (memcached_success(rc))
2053 {
2054 test_true(value);
2055 }
2056 else
2057 {
2058 test_false(value);
2059 }
2060
2061 return TEST_SUCCESS;
2062 }
2063
2064 /* Make sure we behave properly if server list has no values */
2065 test_return_t user_supplied_bug4(memcached_st *memc)
2066 {
2067 const char *keys[]= {"fudge", "son", "food"};
2068 size_t key_length[]= {5, 3, 4};
2069
2070 /* Here we free everything before running a bunch of mget tests */
2071 memcached_servers_reset(memc);
2072
2073
2074 /* We need to empty the server before continueing test */
2075 test_compare(MEMCACHED_NO_SERVERS,
2076 memcached_flush(memc, 0));
2077
2078 test_compare(MEMCACHED_NO_SERVERS,
2079 memcached_mget(memc, keys, key_length, 3));
2080
2081 {
2082 unsigned int keys_returned;
2083 memcached_return_t rc;
2084 test_compare(TEST_SUCCESS, fetch_all_results(memc, keys_returned, rc));
2085 test_compare(MEMCACHED_NOTFOUND, rc);
2086 test_zero(keys_returned);
2087 }
2088
2089 for (uint32_t x= 0; x < 3; x++)
2090 {
2091 test_compare(MEMCACHED_NO_SERVERS,
2092 memcached_set(memc, keys[x], key_length[x],
2093 keys[x], key_length[x],
2094 (time_t)50, (uint32_t)9));
2095 }
2096
2097 test_compare(MEMCACHED_NO_SERVERS,
2098 memcached_mget(memc, keys, key_length, 3));
2099
2100 {
2101 char *return_value;
2102 char return_key[MEMCACHED_MAX_KEY];
2103 memcached_return_t rc;
2104 size_t return_key_length;
2105 size_t return_value_length;
2106 uint32_t flags;
2107 uint32_t x= 0;
2108 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
2109 &return_value_length, &flags, &rc)))
2110 {
2111 test_true(return_value);
2112 test_compare(MEMCACHED_SUCCESS, rc);
2113 test_true(return_key_length == return_value_length);
2114 test_memcmp(return_value, return_key, return_value_length);
2115 free(return_value);
2116 x++;
2117 }
2118 }
2119
2120 return TEST_SUCCESS;
2121 }
2122
2123 #define VALUE_SIZE_BUG5 1048064
2124 test_return_t user_supplied_bug5(memcached_st *memc)
2125 {
2126 const char *keys[]= {"036790384900", "036790384902", "036790384904", "036790384906"};
2127 size_t key_length[]= {strlen("036790384900"), strlen("036790384902"), strlen("036790384904"), strlen("036790384906")};
2128 char *value;
2129 size_t value_length;
2130 uint32_t flags;
2131 char *insert_data= new (std::nothrow) char[VALUE_SIZE_BUG5];
2132
2133 for (uint32_t x= 0; x < VALUE_SIZE_BUG5; x++)
2134 {
2135 insert_data[x]= (signed char)rand();
2136 }
2137
2138 test_compare(MEMCACHED_SUCCESS,
2139 memcached_flush(memc, 0));
2140
2141 memcached_return_t rc;
2142 test_null(memcached_get(memc, keys[0], key_length[0], &value_length, &flags, &rc));
2143 test_compare(MEMCACHED_SUCCESS,
2144 memcached_mget(memc, keys, key_length, 4));
2145
2146 unsigned int count;
2147 test_compare(TEST_SUCCESS, fetch_all_results(memc, count, rc));
2148 test_compare(MEMCACHED_NOTFOUND, rc);
2149 test_zero(count);
2150
2151 for (uint32_t x= 0; x < 4; x++)
2152 {
2153 test_compare(MEMCACHED_SUCCESS,
2154 memcached_set(memc, keys[x], key_length[x],
2155 insert_data, VALUE_SIZE_BUG5,
2156 (time_t)0, (uint32_t)0));
2157 }
2158
2159 for (uint32_t x= 0; x < 10; x++)
2160 {
2161 value= memcached_get(memc, keys[0], key_length[0],
2162 &value_length, &flags, &rc);
2163 test_compare(rc, MEMCACHED_SUCCESS);
2164 test_true(value);
2165 ::free(value);
2166
2167 test_compare(MEMCACHED_SUCCESS,
2168 memcached_mget(memc, keys, key_length, 4));
2169
2170 test_compare(TEST_SUCCESS, fetch_all_results(memc, count));
2171 test_compare(4U, count);
2172 }
2173 delete [] insert_data;
2174
2175 return TEST_SUCCESS;
2176 }
2177
2178 test_return_t user_supplied_bug6(memcached_st *memc)
2179 {
2180 const char *keys[]= {"036790384900", "036790384902", "036790384904", "036790384906"};
2181 size_t key_length[]= {strlen("036790384900"), strlen("036790384902"), strlen("036790384904"), strlen("036790384906")};
2182 char return_key[MEMCACHED_MAX_KEY];
2183 size_t return_key_length;
2184 char *value;
2185 size_t value_length;
2186 uint32_t flags;
2187 char *insert_data= new (std::nothrow) char[VALUE_SIZE_BUG5];
2188
2189 for (uint32_t x= 0; x < VALUE_SIZE_BUG5; x++)
2190 {
2191 insert_data[x]= (signed char)rand();
2192 }
2193
2194 test_compare(MEMCACHED_SUCCESS, memcached_flush(memc, 0));
2195
2196 test_compare(TEST_SUCCESS, confirm_keys_dont_exist(memc, keys, test_array_length(keys)));
2197
2198 // We will now confirm that memcached_mget() returns success, but we will
2199 // then check to make sure that no actual keys are returned.
2200 test_compare(MEMCACHED_SUCCESS,
2201 memcached_mget(memc, keys, key_length, 4));
2202
2203 memcached_return_t rc;
2204 uint32_t count= 0;
2205 while ((value= memcached_fetch(memc, return_key, &return_key_length,
2206 &value_length, &flags, &rc)))
2207 {
2208 count++;
2209 }
2210 test_zero(count);
2211 test_compare(MEMCACHED_NOTFOUND, rc);
2212
2213 for (uint32_t x= 0; x < test_array_length(keys); x++)
2214 {
2215 test_compare(MEMCACHED_SUCCESS,
2216 memcached_set(memc, keys[x], key_length[x],
2217 insert_data, VALUE_SIZE_BUG5,
2218 (time_t)0, (uint32_t)0));
2219 }
2220 test_compare(TEST_SUCCESS, confirm_keys_exist(memc, keys, test_array_length(keys)));
2221
2222 for (uint32_t x= 0; x < 2; x++)
2223 {
2224 value= memcached_get(memc, keys[0], key_length[0],
2225 &value_length, &flags, &rc);
2226 test_true(value);
2227 free(value);
2228
2229 test_compare(MEMCACHED_SUCCESS,
2230 memcached_mget(memc, keys, key_length, 4));
2231 /* We test for purge of partial complete fetches */
2232 for (count= 3; count; count--)
2233 {
2234 value= memcached_fetch(memc, return_key, &return_key_length,
2235 &value_length, &flags, &rc);
2236 test_compare(MEMCACHED_SUCCESS, rc);
2237 test_memcmp(value, insert_data, value_length);
2238 test_true(value_length);
2239 free(value);
2240 }
2241 }
2242 delete [] insert_data;
2243
2244 return TEST_SUCCESS;
2245 }
2246
2247 test_return_t user_supplied_bug8(memcached_st *)
2248 {
2249 memcached_return_t rc;
2250 memcached_st *mine;
2251 memcached_st *memc_clone;
2252
2253 memcached_server_st *servers;
2254 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";
2255
2256 servers= memcached_servers_parse(server_list);
2257 test_true(servers);
2258
2259 mine= memcached_create(NULL);
2260 rc= memcached_server_push(mine, servers);
2261 test_compare(MEMCACHED_SUCCESS, rc);
2262 memcached_server_list_free(servers);
2263
2264 test_true(mine);
2265 memc_clone= memcached_clone(NULL, mine);
2266
2267 memcached_quit(mine);
2268 memcached_quit(memc_clone);
2269
2270
2271 memcached_free(mine);
2272 memcached_free(memc_clone);
2273
2274 return TEST_SUCCESS;
2275 }
2276
2277 /* Test flag store/retrieve */
2278 test_return_t user_supplied_bug7(memcached_st *memc)
2279 {
2280 char *insert_data= new (std::nothrow) char[VALUE_SIZE_BUG5];
2281 test_true(insert_data);
2282
2283 for (size_t x= 0; x < VALUE_SIZE_BUG5; x++)
2284 {
2285 insert_data[x]= (signed char)rand();
2286 }
2287
2288 memcached_flush(memc, 0);
2289
2290 const char *keys= "036790384900";
2291 size_t key_length= strlen(keys);
2292 test_compare(MEMCACHED_SUCCESS, memcached_set(memc, keys, key_length,
2293 insert_data, VALUE_SIZE_BUG5,
2294 time_t(0), 245U));
2295
2296 memcached_return_t rc;
2297 size_t value_length;
2298 uint32_t flags= 0;
2299 char *value= memcached_get(memc, keys, key_length,
2300 &value_length, &flags, &rc);
2301 test_compare(245U, flags);
2302 test_true(value);
2303 free(value);
2304
2305 test_compare(MEMCACHED_SUCCESS, memcached_mget(memc, &keys, &key_length, 1));
2306
2307 char return_key[MEMCACHED_MAX_KEY];
2308 size_t return_key_length;
2309 flags= 0;
2310 value= memcached_fetch(memc, return_key, &return_key_length,
2311 &value_length, &flags, &rc);
2312 test_compare(uint32_t(245), flags);
2313 test_true(value);
2314 free(value);
2315 delete [] insert_data;
2316
2317
2318 return TEST_SUCCESS;
2319 }
2320
2321 test_return_t user_supplied_bug9(memcached_st *memc)
2322 {
2323 const char *keys[]= {"UDATA:edevil@sapo.pt", "fudge&*@#", "for^#@&$not"};
2324 size_t key_length[3];
2325 uint32_t flags;
2326 unsigned count= 0;
2327
2328 char return_key[MEMCACHED_MAX_KEY];
2329 size_t return_key_length;
2330 char *return_value;
2331 size_t return_value_length;
2332
2333
2334 key_length[0]= strlen("UDATA:edevil@sapo.pt");
2335 key_length[1]= strlen("fudge&*@#");
2336 key_length[2]= strlen("for^#@&$not");
2337
2338
2339 for (unsigned int x= 0; x < 3; x++)
2340 {
2341 memcached_return_t rc= memcached_set(memc, keys[x], key_length[x],
2342 keys[x], key_length[x],
2343 (time_t)50, (uint32_t)9);
2344 test_compare(MEMCACHED_SUCCESS, rc);
2345 }
2346
2347 memcached_return_t rc= memcached_mget(memc, keys, key_length, 3);
2348 test_compare(MEMCACHED_SUCCESS, rc);
2349
2350 /* We need to empty the server before continueing test */
2351 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
2352 &return_value_length, &flags, &rc)) != NULL)
2353 {
2354 test_true(return_value);
2355 free(return_value);
2356 count++;
2357 }
2358 test_compare(3U, count);
2359
2360 return TEST_SUCCESS;
2361 }
2362
2363 /* We are testing with aggressive timeout to get failures */
2364 test_return_t user_supplied_bug10(memcached_st *memc)
2365 {
2366 test_skip(memc->servers[0].type, MEMCACHED_CONNECTION_TCP);
2367
2368 size_t value_length= 512;
2369 unsigned int set= 1;
2370 memcached_st *mclone= memcached_clone(NULL, memc);
2371
2372 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_NO_BLOCK, set);
2373 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_TCP_NODELAY, set);
2374 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, uint64_t(0));
2375
2376 libtest::vchar_t value;
2377 value.reserve(value_length);
2378 for (uint32_t x= 0; x < value_length; x++)
2379 {
2380 value.push_back(char(x % 127));
2381 }
2382
2383 for (unsigned int x= 1; x <= 100000; ++x)
2384 {
2385 memcached_return_t rc= memcached_set(mclone,
2386 test_literal_param("foo"),
2387 &value[0], value.size(),
2388 0, 0);
2389
2390 test_true((rc == MEMCACHED_SUCCESS or rc == MEMCACHED_WRITE_FAILURE or rc == MEMCACHED_BUFFERED or rc == MEMCACHED_TIMEOUT or rc == MEMCACHED_CONNECTION_FAILURE
2391 or rc == MEMCACHED_SERVER_TEMPORARILY_DISABLED));
2392
2393 if (rc == MEMCACHED_WRITE_FAILURE or rc == MEMCACHED_TIMEOUT)
2394 {
2395 x--;
2396 }
2397 }
2398
2399 memcached_free(mclone);
2400
2401 return TEST_SUCCESS;
2402 }
2403
2404 /*
2405 We are looking failures in the async protocol
2406 */
2407 test_return_t user_supplied_bug11(memcached_st *memc)
2408 {
2409 memcached_st *mclone= memcached_clone(NULL, memc);
2410
2411 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_NO_BLOCK, true);
2412 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_TCP_NODELAY, true);
2413 memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, size_t(-1));
2414
2415 test_compare(-1, int32_t(memcached_behavior_get(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT)));
2416
2417
2418 libtest::vchar_t value;
2419 value.reserve(512);
2420 for (unsigned int x= 0; x < 512; x++)
2421 {
2422 value.push_back(char(x % 127));
2423 }
2424
2425 for (unsigned int x= 1; x <= 100000; ++x)
2426 {
2427 memcached_return_t rc= memcached_set(mclone, test_literal_param("foo"), &value[0], value.size(), 0, 0);
2428 (void)rc;
2429 }
2430
2431 memcached_free(mclone);
2432
2433 return TEST_SUCCESS;
2434 }
2435
2436 /*
2437 Bug found where incr was not returning MEMCACHED_NOTFOUND when object did not exist.
2438 */
2439 test_return_t user_supplied_bug12(memcached_st *memc)
2440 {
2441 memcached_return_t rc;
2442 uint32_t flags;
2443 size_t value_length;
2444 char *value;
2445 uint64_t number_value;
2446
2447 value= memcached_get(memc, "autoincrement", strlen("autoincrement"),
2448 &value_length, &flags, &rc);
2449 test_null(value);
2450 test_compare(MEMCACHED_NOTFOUND, rc);
2451
2452 rc= memcached_increment(memc, "autoincrement", strlen("autoincrement"),
2453 1, &number_value);
2454 test_null(value);
2455 /* The binary protocol will set the key if it doesn't exist */
2456 if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 1)
2457 {
2458 test_compare(MEMCACHED_SUCCESS, rc);
2459 }
2460 else
2461 {
2462 test_compare(MEMCACHED_NOTFOUND, rc);
2463 }
2464
2465 test_compare(MEMCACHED_SUCCESS,
2466 memcached_set(memc, "autoincrement", strlen("autoincrement"), "1", 1, 0, 0));
2467
2468 value= memcached_get(memc, "autoincrement", strlen("autoincrement"), &value_length, &flags, &rc);
2469 test_true(value);
2470 free(value);
2471
2472 test_compare(MEMCACHED_SUCCESS,
2473 memcached_increment(memc, "autoincrement", strlen("autoincrement"), 1, &number_value));
2474 test_compare(2UL, number_value);
2475
2476 return TEST_SUCCESS;
2477 }
2478
2479 /*
2480 Bug found where command total one more than MEMCACHED_MAX_BUFFER
2481 set key34567890 0 0 8169 \r\n is sent followed by buffer of size 8169, followed by 8169
2482 */
2483 test_return_t user_supplied_bug13(memcached_st *memc)
2484 {
2485 char key[] = "key34567890";
2486
2487 char commandFirst[]= "set key34567890 0 0 ";
2488 char commandLast[] = " \r\n"; /* first line of command sent to server */
2489 size_t commandLength;
2490
2491 commandLength = strlen(commandFirst) + strlen(commandLast) + 4; /* 4 is number of characters in size, probably 8196 */
2492
2493 size_t overflowSize = MEMCACHED_MAX_BUFFER - commandLength;
2494
2495 for (size_t testSize= overflowSize - 1; testSize < overflowSize + 1; testSize++)
2496 {
2497 char *overflow= new (std::nothrow) char[testSize];
2498 test_true(overflow);
2499
2500 memset(overflow, 'x', testSize);
2501 test_compare(MEMCACHED_SUCCESS,
2502 memcached_set(memc, key, strlen(key),
2503 overflow, testSize, 0, 0));
2504 delete [] overflow;
2505 }
2506
2507 return TEST_SUCCESS;
2508 }
2509
2510
2511 /*
2512 Test values of many different sizes
2513 Bug found where command total one more than MEMCACHED_MAX_BUFFER
2514 set key34567890 0 0 8169 \r\n
2515 is sent followed by buffer of size 8169, followed by 8169
2516 */
2517 test_return_t user_supplied_bug14(memcached_st *memc)
2518 {
2519 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, true);
2520
2521 libtest::vchar_t value;
2522 value.reserve(18000);
2523 for (ptrdiff_t x= 0; x < 18000; x++)
2524 {
2525 value.push_back((char) (x % 127));
2526 }
2527
2528 for (size_t current_length= 1; current_length < value.size(); current_length++)
2529 {
2530 memcached_return_t rc= memcached_set(memc, test_literal_param("foo"),
2531 &value[0], current_length,
2532 (time_t)0, (uint32_t)0);
2533 test_true(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED);
2534
2535 size_t string_length;
2536 uint32_t flags;
2537 char *string= memcached_get(memc, test_literal_param("foo"),
2538 &string_length, &flags, &rc);
2539
2540 test_compare(MEMCACHED_SUCCESS, rc);
2541 test_compare(string_length, current_length);
2542 char buffer[1024];
2543 snprintf(buffer, sizeof(buffer), "%u", uint32_t(string_length));
2544 test_memcmp(string, &value[0], string_length);
2545
2546 free(string);
2547 }
2548
2549 return TEST_SUCCESS;
2550 }
2551
2552 /*
2553 Look for zero length value problems
2554 */
2555 test_return_t user_supplied_bug15(memcached_st *memc)
2556 {
2557 for (uint32_t x= 0; x < 2; x++)
2558 {
2559 memcached_return_t rc= memcached_set(memc, test_literal_param("mykey"),
2560 NULL, 0,
2561 (time_t)0, (uint32_t)0);
2562
2563 test_compare(MEMCACHED_SUCCESS, rc);
2564
2565 size_t length;
2566 uint32_t flags;
2567 char *value= memcached_get(memc, test_literal_param("mykey"),
2568 &length, &flags, &rc);
2569
2570 test_compare(MEMCACHED_SUCCESS, rc);
2571 test_false(value);
2572 test_zero(length);
2573 test_zero(flags);
2574
2575 value= memcached_get(memc, test_literal_param("mykey"),
2576 &length, &flags, &rc);
2577
2578 test_compare(MEMCACHED_SUCCESS, rc);
2579 test_null(value);
2580 test_zero(length);
2581 test_zero(flags);
2582 }
2583
2584 return TEST_SUCCESS;
2585 }
2586
2587 /* Check the return sizes on FLAGS to make sure it stores 32bit unsigned values correctly */
2588 test_return_t user_supplied_bug16(memcached_st *memc)
2589 {
2590 test_compare(MEMCACHED_SUCCESS, memcached_set(memc, test_literal_param("mykey"),
2591 NULL, 0,
2592 (time_t)0, UINT32_MAX));
2593
2594
2595 size_t length;
2596 uint32_t flags;
2597 memcached_return_t rc;
2598 char *value= memcached_get(memc, test_literal_param("mykey"),
2599 &length, &flags, &rc);
2600
2601 test_compare(MEMCACHED_SUCCESS, rc);
2602 test_null(value);
2603 test_zero(length);
2604 test_compare(flags, UINT32_MAX);
2605
2606 return TEST_SUCCESS;
2607 }
2608
2609 #if !defined(__sun) && !defined(__OpenBSD__)
2610 /* Check the validity of chinese key*/
2611 test_return_t user_supplied_bug17(memcached_st *memc)
2612 {
2613 const char *key= "豆瓣";
2614 const char *value="我们在炎热抑郁的夏天无法停止豆瓣";
2615 memcached_return_t rc= memcached_set(memc, key, strlen(key),
2616 value, strlen(value),
2617 (time_t)0, 0);
2618
2619 test_compare(MEMCACHED_SUCCESS, rc);
2620
2621 size_t length;
2622 uint32_t flags;
2623 char *value2= memcached_get(memc, key, strlen(key),
2624 &length, &flags, &rc);
2625
2626 test_compare(length, strlen(value));
2627 test_compare(MEMCACHED_SUCCESS, rc);
2628 test_memcmp(value, value2, length);
2629 free(value2);
2630
2631 return TEST_SUCCESS;
2632 }
2633 #endif
2634
2635 /*
2636 From Andrei on IRC
2637 */
2638
2639 test_return_t user_supplied_bug19(memcached_st *)
2640 {
2641 memcached_return_t res;
2642
2643 memcached_st *memc= memcached(test_literal_param("--server=localhost:11311/?100 --server=localhost:11312/?100"));
2644
2645 memcached_server_instance_st server= memcached_server_by_key(memc, "a", 1, &res);
2646 test_true(server);
2647
2648 memcached_free(memc);
2649
2650 return TEST_SUCCESS;
2651 }
2652
2653 /* CAS test from Andei */
2654 test_return_t user_supplied_bug20(memcached_st *memc)
2655 {
2656 const char *key= "abc";
2657 size_t key_len= strlen("abc");
2658
2659 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, true));
2660
2661 test_compare(MEMCACHED_SUCCESS,
2662 memcached_set(memc,
2663 test_literal_param("abc"),
2664 test_literal_param("foobar"),
2665 (time_t)0, (uint32_t)0));
2666
2667 test_compare(MEMCACHED_SUCCESS,
2668 memcached_mget(memc, &key, &key_len, 1));
2669
2670 memcached_result_st result_obj;
2671 memcached_result_st *result= memcached_result_create(memc, &result_obj);
2672 test_true(result);
2673
2674 memcached_result_create(memc, &result_obj);
2675 memcached_return_t status;
2676 result= memcached_fetch_result(memc, &result_obj, &status);
2677
2678 test_true(result);
2679 test_compare(MEMCACHED_SUCCESS, status);
2680
2681 memcached_result_free(result);
2682
2683 return TEST_SUCCESS;
2684 }
2685
2686 /* Large mget() of missing keys with binary proto
2687 *
2688 * If many binary quiet commands (such as getq's in an mget) fill the output
2689 * buffer and the server chooses not to respond, memcached_flush hangs. See
2690 * http://lists.tangent.org/pipermail/libmemcached/2009-August/000918.html
2691 */
2692
2693 /* sighandler_t function that always asserts false */
2694 static __attribute__((noreturn)) void fail(int)
2695 {
2696 fatal_assert(0);
2697 }
2698
2699
2700 test_return_t _user_supplied_bug21(memcached_st* memc, size_t key_count)
2701 {
2702 #ifdef WIN32
2703 (void)memc;
2704 (void)key_count;
2705 return TEST_SKIPPED;
2706 #else
2707 void (*oldalarm)(int);
2708
2709 memcached_st *memc_clone= memcached_clone(NULL, memc);
2710 test_true(memc_clone);
2711
2712 /* only binproto uses getq for mget */
2713 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, true));
2714
2715 /* empty the cache to ensure misses (hence non-responses) */
2716 test_compare(MEMCACHED_SUCCESS, memcached_flush(memc_clone, 0));
2717
2718 keys_st keys(key_count);
2719
2720 oldalarm= signal(SIGALRM, fail);
2721 alarm(5);
2722
2723 test_compare_got(MEMCACHED_SUCCESS,
2724 memcached_mget(memc_clone, keys.keys_ptr(), keys.lengths_ptr(), keys.size()),
2725 memcached_last_error_message(memc_clone));
2726
2727 alarm(0);
2728 signal(SIGALRM, oldalarm);
2729
2730 memcached_return_t rc;
2731 uint32_t flags;
2732 char return_key[MEMCACHED_MAX_KEY];
2733 size_t return_key_length;
2734 char *return_value;
2735 size_t return_value_length;
2736 while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
2737 &return_value_length, &flags, &rc)))
2738 {
2739 test_false(return_value); // There are no keys to fetch, so the value should never be returned
2740 }
2741 test_compare(MEMCACHED_NOTFOUND, rc);
2742 test_zero(return_value_length);
2743 test_zero(return_key_length);
2744 test_false(return_key[0]);
2745 test_false(return_value);
2746
2747 memcached_free(memc_clone);
2748
2749 return TEST_SUCCESS;
2750 #endif
2751 }
2752
2753 test_return_t user_supplied_bug21(memcached_st *memc)
2754 {
2755 test_skip(TEST_SUCCESS, pre_binary(memc));
2756
2757 /* should work as of r580 */
2758 test_compare(TEST_SUCCESS,
2759 _user_supplied_bug21(memc, 10));
2760
2761 /* should fail as of r580 */
2762 test_compare(TEST_SUCCESS,
2763 _user_supplied_bug21(memc, 1000));
2764
2765 return TEST_SUCCESS;
2766 }
2767
2768 test_return_t ketama_TEST(memcached_st *)
2769 {
2770 test::Memc memc("--server=10.0.1.1:11211 --server=10.0.1.2:11211");
2771
2772 test_compare(MEMCACHED_SUCCESS,
2773 memcached_behavior_set(&memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, true));
2774
2775 test_compare(memcached_behavior_get(&memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED), uint64_t(1));
2776
2777 test_compare(memcached_behavior_set(&memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5), MEMCACHED_SUCCESS);
2778
2779 test_compare(memcached_behavior_get(&memc, MEMCACHED_BEHAVIOR_KETAMA_HASH), MEMCACHED_HASH_MD5);
2780
2781 test_compare(memcached_behavior_set_distribution(&memc, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY), MEMCACHED_SUCCESS);
2782
2783
2784 return TEST_SUCCESS;
2785 }
2786
2787 test_return_t output_ketama_weighted_keys(memcached_st *)
2788 {
2789 memcached_st *memc= memcached_create(NULL);
2790 test_true(memc);
2791
2792
2793 test_compare(MEMCACHED_SUCCESS,
2794 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, true));
2795
2796 uint64_t value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
2797 test_compare(value, uint64_t(1));
2798
2799 test_compare(MEMCACHED_SUCCESS,
2800 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_MD5));
2801
2802 value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_HASH);
2803 test_true(value == MEMCACHED_HASH_MD5);
2804
2805
2806 test_true(memcached_behavior_set_distribution(memc, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY) == MEMCACHED_SUCCESS);
2807
2808 memcached_server_st *server_pool;
2809 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");
2810 memcached_server_push(memc, server_pool);
2811
2812 // @todo this needs to be refactored to actually test something.
2813 #if 0
2814 FILE *fp;
2815 if ((fp = fopen("ketama_keys.txt", "w")))
2816 {
2817 // noop
2818 } else {
2819 printf("cannot write to file ketama_keys.txt");
2820 return TEST_FAILURE;
2821 }
2822
2823 for (int x= 0; x < 10000; x++)
2824 {
2825 char key[10];
2826 snprintf(key, sizeof(key), "%d", x);
2827
2828 uint32_t server_idx = memcached_generate_hash(memc, key, strlen(key));
2829 char *hostname = memc->hosts[server_idx].hostname;
2830 in_port_t port = memc->hosts[server_idx].port;
2831 fprintf(fp, "key %s is on host /%s:%u\n", key, hostname, port);
2832 memcached_server_instance_st instance=
2833 memcached_server_instance_by_position(memc, host_index);
2834 }
2835 fclose(fp);
2836 #endif
2837 memcached_server_list_free(server_pool);
2838 memcached_free(memc);
2839
2840 return TEST_SUCCESS;
2841 }
2842
2843
2844 test_return_t result_static(memcached_st *memc)
2845 {
2846 memcached_result_st result;
2847 memcached_result_st *result_ptr= memcached_result_create(memc, &result);
2848 test_false(result.options.is_allocated);
2849 test_true(memcached_is_initialized(&result));
2850 test_true(result_ptr);
2851 test_true(result_ptr == &result);
2852
2853 memcached_result_free(&result);
2854
2855 test_false(result.options.is_allocated);
2856 test_false(memcached_is_initialized(&result));
2857
2858 return TEST_SUCCESS;
2859 }
2860
2861 test_return_t result_alloc(memcached_st *memc)
2862 {
2863 memcached_result_st *result_ptr= memcached_result_create(memc, NULL);
2864 test_true(result_ptr);
2865 test_true(result_ptr->options.is_allocated);
2866 test_true(memcached_is_initialized(result_ptr));
2867 memcached_result_free(result_ptr);
2868
2869 return TEST_SUCCESS;
2870 }
2871
2872
2873 test_return_t add_host_test1(memcached_st *memc)
2874 {
2875 memcached_return_t rc;
2876 char servername[]= "0.example.com";
2877
2878 memcached_server_st *servers= memcached_server_list_append_with_weight(NULL, servername, 400, 0, &rc);
2879 test_true(servers);
2880 test_compare(1U, memcached_server_list_count(servers));
2881
2882 for (uint32_t x= 2; x < 20; x++)
2883 {
2884 char buffer[SMALL_STRING_LEN];
2885
2886 snprintf(buffer, SMALL_STRING_LEN, "%lu.example.com", (unsigned long)(400 +x));
2887 servers= memcached_server_list_append_with_weight(servers, buffer, 401, 0,
2888 &rc);
2889 test_compare(MEMCACHED_SUCCESS, rc);
2890 test_compare(x, memcached_server_list_count(servers));
2891 }
2892
2893 test_compare(MEMCACHED_SUCCESS, memcached_server_push(memc, servers));
2894 test_compare(MEMCACHED_SUCCESS, memcached_server_push(memc, servers));
2895
2896 memcached_server_list_free(servers);
2897
2898 return TEST_SUCCESS;
2899 }
2900
2901
2902 static void my_free(const memcached_st *ptr, void *mem, void *context)
2903 {
2904 (void)context;
2905 (void)ptr;
2906 #ifdef HARD_MALLOC_TESTS
2907 void *real_ptr= (mem == NULL) ? mem : (void*)((caddr_t)mem - 8);
2908 free(real_ptr);
2909 #else
2910 free(mem);
2911 #endif
2912 }
2913
2914
2915 static void *my_malloc(const memcached_st *ptr, const size_t size, void *context)
2916 {
2917 (void)context;
2918 (void)ptr;
2919 #ifdef HARD_MALLOC_TESTS
2920 void *ret= malloc(size + 8);
2921 if (ret != NULL)
2922 {
2923 ret= (void*)((caddr_t)ret + 8);
2924 }
2925 #else
2926 void *ret= malloc(size);
2927 #endif
2928
2929 if (ret != NULL)
2930 {
2931 memset(ret, 0xff, size);
2932 }
2933
2934 return ret;
2935 }
2936
2937
2938 static void *my_realloc(const memcached_st *ptr, void *mem, const size_t size, void *)
2939 {
2940 #ifdef HARD_MALLOC_TESTS
2941 void *real_ptr= (mem == NULL) ? NULL : (void*)((caddr_t)mem - 8);
2942 void *nmem= realloc(real_ptr, size + 8);
2943
2944 void *ret= NULL;
2945 if (nmem != NULL)
2946 {
2947 ret= (void*)((caddr_t)nmem + 8);
2948 }
2949
2950 return ret;
2951 #else
2952 (void)ptr;
2953 return realloc(mem, size);
2954 #endif
2955 }
2956
2957
2958 static void *my_calloc(const memcached_st *ptr, size_t nelem, const size_t size, void *)
2959 {
2960 #ifdef HARD_MALLOC_TESTS
2961 void *mem= my_malloc(ptr, nelem * size);
2962 if (mem)
2963 {
2964 memset(mem, 0, nelem * size);
2965 }
2966
2967 return mem;
2968 #else
2969 (void)ptr;
2970 return calloc(nelem, size);
2971 #endif
2972 }
2973
2974 test_return_t selection_of_namespace_tests(memcached_st *memc)
2975 {
2976 memcached_return_t rc;
2977 const char *key= "mine";
2978 char *value;
2979
2980 /* Make sure be default none exists */
2981 value= (char*)memcached_callback_get(memc, MEMCACHED_CALLBACK_NAMESPACE, &rc);
2982 test_null(value);
2983 test_compare_got(MEMCACHED_SUCCESS, rc, memcached_strerror(NULL, rc));
2984
2985 /* Test a clean set */
2986 test_compare(MEMCACHED_SUCCESS,
2987 memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, (void *)key));
2988
2989 value= (char*)memcached_callback_get(memc, MEMCACHED_CALLBACK_NAMESPACE, &rc);
2990 test_true(value);
2991 test_memcmp(value, key, 4);
2992 test_compare_got(MEMCACHED_SUCCESS, rc, memcached_strerror(NULL, rc));
2993
2994 /* Test that we can turn it off */
2995 test_compare(MEMCACHED_SUCCESS,
2996 memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, NULL));
2997
2998 value= (char*)memcached_callback_get(memc, MEMCACHED_CALLBACK_NAMESPACE, &rc);
2999 test_null(value);
3000 test_compare_got(MEMCACHED_SUCCESS, rc, memcached_strerror(NULL, rc));
3001
3002 /* Now setup for main test */
3003 test_compare(MEMCACHED_SUCCESS,
3004 memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, (void *)key));
3005
3006 value= (char *)memcached_callback_get(memc, MEMCACHED_CALLBACK_NAMESPACE, &rc);
3007 test_true(value);
3008 test_compare_got(MEMCACHED_SUCCESS, rc, memcached_strerror(NULL, rc));
3009 test_memcmp(value, key, 4);
3010
3011 /* Set to Zero, and then Set to something too large */
3012 {
3013 char long_key[255];
3014 memset(long_key, 0, 255);
3015
3016 test_compare(MEMCACHED_SUCCESS,
3017 memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, NULL));
3018
3019 value= (char*)memcached_callback_get(memc, MEMCACHED_CALLBACK_NAMESPACE, &rc);
3020 test_null(value);
3021 test_compare(MEMCACHED_SUCCESS, rc);
3022
3023 /* Test a long key for failure */
3024 /* TODO, extend test to determine based on setting, what result should be */
3025 strncpy(long_key, "Thisismorethentheallottednumberofcharacters", sizeof(long_key));
3026 test_compare(MEMCACHED_SUCCESS,
3027 memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, long_key));
3028
3029 /* Now test a key with spaces (which will fail from long key, since bad key is not set) */
3030 strncpy(long_key, "This is more then the allotted number of characters", sizeof(long_key));
3031 test_compare(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) ? MEMCACHED_SUCCESS : MEMCACHED_BAD_KEY_PROVIDED,
3032 memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, long_key));
3033
3034 /* Test for a bad prefix, but with a short key */
3035 test_compare(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) ? MEMCACHED_INVALID_ARGUMENTS : MEMCACHED_SUCCESS,
3036 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_VERIFY_KEY, 1));
3037
3038 test_compare(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) ? MEMCACHED_SUCCESS : MEMCACHED_BAD_KEY_PROVIDED,
3039 memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, "dog cat"));
3040 }
3041
3042 return TEST_SUCCESS;
3043 }
3044
3045 test_return_t set_namespace(memcached_st *memc)
3046 {
3047 memcached_return_t rc;
3048 const char *key= "mine";
3049 char *value;
3050
3051 // Make sure we default to a null namespace
3052 value= (char*)memcached_callback_get(memc, MEMCACHED_CALLBACK_NAMESPACE, &rc);
3053 test_null(value);
3054 test_compare_got(MEMCACHED_SUCCESS, rc, memcached_strerror(NULL, rc));
3055
3056 /* Test a clean set */
3057 test_compare(MEMCACHED_SUCCESS,
3058 memcached_callback_set(memc, MEMCACHED_CALLBACK_NAMESPACE, (void *)key));
3059
3060 value= (char*)memcached_callback_get(memc, MEMCACHED_CALLBACK_NAMESPACE, &rc);
3061 test_true(value);
3062 test_memcmp(value, key, 4);
3063 test_compare_got(MEMCACHED_SUCCESS, rc, memcached_strerror(NULL, rc));
3064
3065 return TEST_SUCCESS;
3066 }
3067
3068 test_return_t set_namespace_and_binary(memcached_st *memc)
3069 {
3070 test_return_if(pre_binary(memc));
3071 test_return_if(set_namespace(memc));
3072
3073 return TEST_SUCCESS;
3074 }
3075
3076 #ifdef MEMCACHED_ENABLE_DEPRECATED
3077 test_return_t deprecated_set_memory_alloc(memcached_st *memc)
3078 {
3079 void *test_ptr= NULL;
3080 void *cb_ptr= NULL;
3081 {
3082 memcached_malloc_fn malloc_cb= (memcached_malloc_fn)my_malloc;
3083 cb_ptr= *(void **)&malloc_cb;
3084 memcached_return_t rc;
3085
3086 test_compare(MEMCACHED_SUCCESS,
3087 memcached_callback_set(memc, MEMCACHED_CALLBACK_MALLOC_FUNCTION, cb_ptr));
3088 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_MALLOC_FUNCTION, &rc);
3089 test_compare(MEMCACHED_SUCCESS, rc);
3090 test_true(test_ptr == cb_ptr);
3091 }
3092
3093 {
3094 memcached_realloc_fn realloc_cb=
3095 (memcached_realloc_fn)my_realloc;
3096 cb_ptr= *(void **)&realloc_cb;
3097 memcached_return_t rc;
3098
3099 test_compare(MEMCACHED_SUCCESS,
3100 memcached_callback_set(memc, MEMCACHED_CALLBACK_REALLOC_FUNCTION, cb_ptr));
3101 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_REALLOC_FUNCTION, &rc);
3102 test_compare(MEMCACHED_SUCCESS, rc);
3103 test_true(test_ptr == cb_ptr);
3104 }
3105
3106 {
3107 memcached_free_fn free_cb=
3108 (memcached_free_fn)my_free;
3109 cb_ptr= *(void **)&free_cb;
3110 memcached_return_t rc;
3111
3112 test_compare(MEMCACHED_SUCCESS,
3113 memcached_callback_set(memc, MEMCACHED_CALLBACK_FREE_FUNCTION, cb_ptr));
3114 test_ptr= memcached_callback_get(memc, MEMCACHED_CALLBACK_FREE_FUNCTION, &rc);
3115 test_compare(MEMCACHED_SUCCESS, rc);
3116 test_true(test_ptr == cb_ptr);
3117 }
3118
3119 return TEST_SUCCESS;
3120 }
3121 #endif
3122
3123
3124 test_return_t set_memory_alloc(memcached_st *memc)
3125 {
3126 test_compare(MEMCACHED_INVALID_ARGUMENTS,
3127 memcached_set_memory_allocators(memc, NULL, my_free,
3128 my_realloc, my_calloc, NULL));
3129
3130 test_compare(MEMCACHED_SUCCESS,
3131 memcached_set_memory_allocators(memc, my_malloc, my_free,
3132 my_realloc, my_calloc, NULL));
3133
3134 memcached_malloc_fn mem_malloc;
3135 memcached_free_fn mem_free;
3136 memcached_realloc_fn mem_realloc;
3137 memcached_calloc_fn mem_calloc;
3138 memcached_get_memory_allocators(memc, &mem_malloc, &mem_free,
3139 &mem_realloc, &mem_calloc);
3140
3141 test_true(mem_malloc == my_malloc);
3142 test_true(mem_realloc == my_realloc);
3143 test_true(mem_calloc == my_calloc);
3144 test_true(mem_free == my_free);
3145
3146 return TEST_SUCCESS;
3147 }
3148
3149 test_return_t enable_consistent_crc(memcached_st *memc)
3150 {
3151 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, MEMCACHED_DISTRIBUTION_CONSISTENT));
3152 test_compare(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION), uint64_t(MEMCACHED_DISTRIBUTION_CONSISTENT));
3153
3154 test_return_t rc;
3155 if ((rc= pre_crc(memc)) != TEST_SUCCESS)
3156 {
3157 return rc;
3158 }
3159
3160 test_compare(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION), uint64_t(MEMCACHED_DISTRIBUTION_CONSISTENT));
3161
3162 if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH) != MEMCACHED_HASH_CRC)
3163 {
3164 return TEST_SKIPPED;
3165 }
3166
3167 return TEST_SUCCESS;
3168 }
3169
3170 test_return_t enable_consistent_hsieh(memcached_st *memc)
3171 {
3172 test_return_t rc;
3173 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, MEMCACHED_DISTRIBUTION_CONSISTENT);
3174 if ((rc= pre_hsieh(memc)) != TEST_SUCCESS)
3175 {
3176 return rc;
3177 }
3178
3179 test_compare(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION), uint64_t(MEMCACHED_DISTRIBUTION_CONSISTENT));
3180
3181 if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH) != MEMCACHED_HASH_HSIEH)
3182 {
3183 return TEST_SKIPPED;
3184 }
3185
3186 return TEST_SUCCESS;
3187 }
3188
3189 test_return_t enable_cas(memcached_st *memc)
3190 {
3191 if (libmemcached_util_version_check(memc, 1, 2, 4))
3192 {
3193 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, true);
3194
3195 return TEST_SUCCESS;
3196 }
3197
3198 return TEST_SKIPPED;
3199 }
3200
3201 test_return_t check_for_1_2_3(memcached_st *memc)
3202 {
3203 memcached_version(memc);
3204
3205 memcached_server_instance_st instance=
3206 memcached_server_instance_by_position(memc, 0);
3207
3208 if ((instance->major_version >= 1 && (instance->minor_version == 2 && instance->micro_version >= 4))
3209 or instance->minor_version > 2)
3210 {
3211 return TEST_SUCCESS;
3212 }
3213
3214 return TEST_SKIPPED;
3215 }
3216
3217 test_return_t MEMCACHED_BEHAVIOR_POLL_TIMEOUT_test(memcached_st *memc)
3218 {
3219 const uint64_t timeout= 100; // Not using, just checking that it sets
3220
3221 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, timeout);
3222
3223 test_compare(timeout, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT));
3224
3225 return TEST_SUCCESS;
3226 }
3227
3228 test_return_t noreply_test(memcached_st *memc)
3229 {
3230 test_compare(MEMCACHED_SUCCESS,
3231 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, true));
3232 test_compare(MEMCACHED_SUCCESS,
3233 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, true));
3234 test_compare(MEMCACHED_SUCCESS,
3235 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, true));
3236 test_compare(1LLU, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NOREPLY));
3237 test_compare(1LLU, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS));
3238 test_compare(1LLU, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS));
3239
3240 memcached_return_t ret;
3241 for (int count= 0; count < 5; ++count)
3242 {
3243 for (size_t x= 0; x < 100; ++x)
3244 {
3245 char key[MEMCACHED_MAXIMUM_INTEGER_DISPLAY_LENGTH +1];
3246 int check_length= snprintf(key, sizeof(key), "%lu", (unsigned long)x);
3247 test_false((size_t)check_length >= sizeof(key) || check_length < 0);
3248
3249 size_t len= (size_t)check_length;
3250
3251 switch (count)
3252 {
3253 case 0:
3254 ret= memcached_add(memc, key, len, key, len, 0, 0);
3255 break;
3256 case 1:
3257 ret= memcached_replace(memc, key, len, key, len, 0, 0);
3258 break;
3259 case 2:
3260 ret= memcached_set(memc, key, len, key, len, 0, 0);
3261 break;
3262 case 3:
3263 ret= memcached_append(memc, key, len, key, len, 0, 0);
3264 break;
3265 case 4:
3266 ret= memcached_prepend(memc, key, len, key, len, 0, 0);
3267 break;
3268 default:
3269 test_true(count);
3270 break;
3271 }
3272 test_true_got(ret == MEMCACHED_SUCCESS or ret == MEMCACHED_BUFFERED,
3273 memcached_strerror(NULL, ret));
3274 }
3275
3276 /*
3277 ** NOTE: Don't ever do this in your code! this is not a supported use of the
3278 ** API and is _ONLY_ done this way to verify that the library works the
3279 ** way it is supposed to do!!!!
3280 */
3281 #if 0
3282 int no_msg=0;
3283 for (uint32_t x= 0; x < memcached_server_count(memc); ++x)
3284 {
3285 memcached_server_instance_st instance=
3286 memcached_server_instance_by_position(memc, x);
3287 no_msg+=(int)(instance->cursor_active);
3288 }
3289
3290 test_true(no_msg == 0);
3291 #endif
3292 test_compare(MEMCACHED_SUCCESS, memcached_flush_buffers(memc));
3293
3294 /*
3295 ** Now validate that all items was set properly!
3296 */
3297 for (size_t x= 0; x < 100; ++x)
3298 {
3299 char key[10];
3300
3301 int check_length= snprintf(key, sizeof(key), "%lu", (unsigned long)x);
3302
3303 test_false((size_t)check_length >= sizeof(key) || check_length < 0);
3304
3305 size_t len= (size_t)check_length;
3306 size_t length;
3307 uint32_t flags;
3308 char* value=memcached_get(memc, key, strlen(key),
3309 &length, &flags, &ret);
3310 // For the moment we will just go to the next key
3311 if (MEMCACHED_TIMEOUT == ret)
3312 {
3313 continue;
3314 }
3315 test_true(ret == MEMCACHED_SUCCESS and value != NULL);
3316 switch (count)
3317 {
3318 case 0: /* FALLTHROUGH */
3319 case 1: /* FALLTHROUGH */
3320 case 2:
3321 test_true(strncmp(value, key, len) == 0);
3322 test_true(len == length);
3323 break;
3324 case 3:
3325 test_true(length == len * 2);
3326 break;
3327 case 4:
3328 test_true(length == len * 3);
3329 break;
3330 default:
3331 test_true(count);
3332 break;
3333 }
3334 free(value);
3335 }
3336 }
3337
3338 /* Try setting an illegal cas value (should not return an error to
3339 * the caller (because we don't expect a return message from the server)
3340 */
3341 const char* keys[]= {"0"};
3342 size_t lengths[]= {1};
3343 size_t length;
3344 uint32_t flags;
3345 memcached_result_st results_obj;
3346 memcached_result_st *results;
3347 test_compare(MEMCACHED_SUCCESS,
3348 memcached_mget(memc, keys, lengths, 1));
3349
3350 results= memcached_result_create(memc, &results_obj);
3351 test_true(results);
3352 results= memcached_fetch_result(memc, &results_obj, &ret);
3353 test_true(results);
3354 test_compare(MEMCACHED_SUCCESS, ret);
3355 uint64_t cas= memcached_result_cas(results);
3356 memcached_result_free(&results_obj);
3357
3358 test_compare(MEMCACHED_SUCCESS,
3359 memcached_cas(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0, cas));
3360
3361 /*
3362 * The item will have a new cas value, so try to set it again with the old
3363 * value. This should fail!
3364 */
3365 test_compare(MEMCACHED_SUCCESS,
3366 memcached_cas(memc, keys[0], lengths[0], keys[0], lengths[0], 0, 0, cas));
3367 test_true(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
3368 char* value=memcached_get(memc, keys[0], lengths[0], &length, &flags, &ret);
3369 test_true(ret == MEMCACHED_SUCCESS && value != NULL);
3370 free(value);
3371
3372 return TEST_SUCCESS;
3373 }
3374
3375 test_return_t analyzer_test(memcached_st *memc)
3376 {
3377 memcached_analysis_st *report;
3378 memcached_return_t rc;
3379
3380 memcached_stat_st *memc_stat= memcached_stat(memc, NULL, &rc);
3381 test_compare(MEMCACHED_SUCCESS, rc);
3382 test_true(memc_stat);
3383
3384 report= memcached_analyze(memc, memc_stat, &rc);
3385 test_compare(MEMCACHED_SUCCESS, rc);
3386 test_true(report);
3387
3388 free(report);
3389 memcached_stat_free(NULL, memc_stat);
3390
3391 return TEST_SUCCESS;
3392 }
3393
3394 test_return_t util_version_test(memcached_st *memc)
3395 {
3396 test_compare(memcached_version(memc), MEMCACHED_SUCCESS);
3397 test_true(libmemcached_util_version_check(memc, 0, 0, 0));
3398
3399 bool if_successful= libmemcached_util_version_check(memc, 9, 9, 9);
3400
3401 // We expect failure
3402 if (if_successful)
3403 {
3404 fprintf(stderr, "\n----------------------------------------------------------------------\n");
3405 fprintf(stderr, "\nDumping Server Information\n\n");
3406 memcached_server_fn callbacks[1];
3407
3408 callbacks[0]= dump_server_information;
3409 memcached_server_cursor(memc, callbacks, (void *)stderr, 1);
3410 fprintf(stderr, "\n----------------------------------------------------------------------\n");
3411 }
3412 test_true(if_successful == false);
3413
3414 memcached_server_instance_st instance=
3415 memcached_server_instance_by_position(memc, 0);
3416
3417 memcached_version(memc);
3418
3419 // We only use one binary when we test, so this should be just fine.
3420 if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->minor_version, instance->micro_version);
3421 test_true(if_successful == true);
3422
3423 if (instance->micro_version > 0)
3424 {
3425 if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->minor_version, (uint8_t)(instance->micro_version -1));
3426 }
3427 else if (instance->minor_version > 0)
3428 {
3429 if_successful= libmemcached_util_version_check(memc, instance->major_version, (uint8_t)(instance->minor_version - 1), instance->micro_version);
3430 }
3431 else if (instance->major_version > 0)
3432 {
3433 if_successful= libmemcached_util_version_check(memc, (uint8_t)(instance->major_version -1), instance->minor_version, instance->micro_version);
3434 }
3435
3436 test_true(if_successful == true);
3437
3438 if (instance->micro_version > 0)
3439 {
3440 if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->minor_version, (uint8_t)(instance->micro_version +1));
3441 }
3442 else if (instance->minor_version > 0)
3443 {
3444 if_successful= libmemcached_util_version_check(memc, instance->major_version, (uint8_t)(instance->minor_version +1), instance->micro_version);
3445 }
3446 else if (instance->major_version > 0)
3447 {
3448 if_successful= libmemcached_util_version_check(memc, (uint8_t)(instance->major_version +1), instance->minor_version, instance->micro_version);
3449 }
3450
3451 test_true(if_successful == false);
3452
3453 return TEST_SUCCESS;
3454 }
3455
3456 test_return_t getpid_connection_failure_test(memcached_st *memc)
3457 {
3458 test_skip(memc->servers[0].type, MEMCACHED_CONNECTION_TCP);
3459 memcached_return_t rc;
3460 memcached_server_instance_st instance=
3461 memcached_server_instance_by_position(memc, 0);
3462
3463 // Test both the version that returns a code, and the one that does not.
3464 test_true(libmemcached_util_getpid(memcached_server_name(instance),
3465 memcached_server_port(instance) -1, NULL) == -1);
3466
3467 test_true(libmemcached_util_getpid(memcached_server_name(instance),
3468 memcached_server_port(instance) -1, &rc) == -1);
3469 test_compare_got(MEMCACHED_CONNECTION_FAILURE, rc, memcached_strerror(memc, rc));
3470
3471 return TEST_SUCCESS;
3472 }
3473
3474
3475 test_return_t getpid_test(memcached_st *memc)
3476 {
3477 memcached_return_t rc;
3478 memcached_server_instance_st instance=
3479 memcached_server_instance_by_position(memc, 0);
3480
3481 // Test both the version that returns a code, and the one that does not.
3482 test_true(libmemcached_util_getpid(memcached_server_name(instance),
3483 memcached_server_port(instance), NULL) > -1);
3484
3485 test_true(libmemcached_util_getpid(memcached_server_name(instance),
3486 memcached_server_port(instance), &rc) > -1);
3487 test_compare(MEMCACHED_SUCCESS, rc);
3488
3489 return TEST_SUCCESS;
3490 }
3491
3492 static memcached_return_t ping_each_server(const memcached_st*,
3493 memcached_server_instance_st instance,
3494 void*)
3495 {
3496 // Test both the version that returns a code, and the one that does not.
3497 memcached_return_t rc;
3498 if (libmemcached_util_ping(memcached_server_name(instance),
3499 memcached_server_port(instance), &rc) == false)
3500 {
3501 throw libtest::fatal(LIBYATL_DEFAULT_PARAM, "%s:%d %s", memcached_server_name(instance),
3502 memcached_server_port(instance), memcached_strerror(NULL, rc));
3503 }
3504
3505 if (libmemcached_util_ping(memcached_server_name(instance),
3506 memcached_server_port(instance), NULL) == false)
3507 {
3508 throw libtest::fatal(LIBYATL_DEFAULT_PARAM, "%s:%d", memcached_server_name(instance), memcached_server_port(instance));
3509 }
3510
3511 return MEMCACHED_SUCCESS;
3512 }
3513
3514 test_return_t libmemcached_util_ping_TEST(memcached_st *memc)
3515 {
3516 memcached_server_fn callbacks[1]= { ping_each_server };
3517 memcached_server_cursor(memc, callbacks, NULL, 1);
3518
3519 return TEST_SUCCESS;
3520 }
3521
3522
3523 #if 0
3524 test_return_t hash_sanity_test (memcached_st *memc)
3525 {
3526 (void)memc;
3527
3528 assert(MEMCACHED_HASH_DEFAULT == MEMCACHED_HASH_DEFAULT);
3529 assert(MEMCACHED_HASH_MD5 == MEMCACHED_HASH_MD5);
3530 assert(MEMCACHED_HASH_CRC == MEMCACHED_HASH_CRC);
3531 assert(MEMCACHED_HASH_FNV1_64 == MEMCACHED_HASH_FNV1_64);
3532 assert(MEMCACHED_HASH_FNV1A_64 == MEMCACHED_HASH_FNV1A_64);
3533 assert(MEMCACHED_HASH_FNV1_32 == MEMCACHED_HASH_FNV1_32);
3534 assert(MEMCACHED_HASH_FNV1A_32 == MEMCACHED_HASH_FNV1A_32);
3535 #ifdef HAVE_HSIEH_HASH
3536 assert(MEMCACHED_HASH_HSIEH == MEMCACHED_HASH_HSIEH);
3537 #endif
3538 assert(MEMCACHED_HASH_MURMUR == MEMCACHED_HASH_MURMUR);
3539 assert(MEMCACHED_HASH_JENKINS == MEMCACHED_HASH_JENKINS);
3540 assert(MEMCACHED_HASH_MAX == MEMCACHED_HASH_MAX);
3541
3542 return TEST_SUCCESS;
3543 }
3544 #endif
3545
3546 test_return_t hsieh_avaibility_test (memcached_st *memc)
3547 {
3548 test_skip(true, libhashkit_has_algorithm(HASHKIT_HASH_HSIEH));
3549
3550 test_compare(MEMCACHED_SUCCESS,
3551 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH,
3552 (uint64_t)MEMCACHED_HASH_HSIEH));
3553
3554 return TEST_SUCCESS;
3555 }
3556
3557 test_return_t murmur_avaibility_test (memcached_st *memc)
3558 {
3559 test_skip(true, libhashkit_has_algorithm(HASHKIT_HASH_MURMUR));
3560
3561 test_compare(MEMCACHED_SUCCESS,
3562 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MURMUR));
3563
3564 return TEST_SUCCESS;
3565 }
3566
3567 test_return_t one_at_a_time_run (memcached_st *)
3568 {
3569 uint32_t x;
3570 const char **ptr;
3571
3572 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3573 {
3574 test_compare(one_at_a_time_values[x],
3575 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_DEFAULT));
3576 }
3577
3578 return TEST_SUCCESS;
3579 }
3580
3581 test_return_t md5_run (memcached_st *)
3582 {
3583 uint32_t x;
3584 const char **ptr;
3585
3586 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3587 {
3588 test_compare(md5_values[x],
3589 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_MD5));
3590 }
3591
3592 return TEST_SUCCESS;
3593 }
3594
3595 test_return_t crc_run (memcached_st *)
3596 {
3597 uint32_t x;
3598 const char **ptr;
3599
3600 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3601 {
3602 test_compare(crc_values[x],
3603 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_CRC));
3604 }
3605
3606 return TEST_SUCCESS;
3607 }
3608
3609 test_return_t fnv1_64_run (memcached_st *)
3610 {
3611 test_skip(true, libhashkit_has_algorithm(HASHKIT_HASH_FNV1_64));
3612
3613 uint32_t x;
3614 const char **ptr;
3615
3616 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3617 {
3618 test_compare(fnv1_64_values[x],
3619 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1_64));
3620 }
3621
3622 return TEST_SUCCESS;
3623 }
3624
3625 test_return_t fnv1a_64_run (memcached_st *)
3626 {
3627 test_skip(true, libhashkit_has_algorithm(HASHKIT_HASH_FNV1A_64));
3628
3629 uint32_t x;
3630 const char **ptr;
3631
3632 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3633 {
3634 test_compare(fnv1a_64_values[x],
3635 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1A_64));
3636 }
3637
3638 return TEST_SUCCESS;
3639 }
3640
3641 test_return_t fnv1_32_run (memcached_st *)
3642 {
3643 uint32_t x;
3644 const char **ptr;
3645
3646 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3647 {
3648 test_compare(fnv1_32_values[x],
3649 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1_32));
3650 }
3651
3652 return TEST_SUCCESS;
3653 }
3654
3655 test_return_t fnv1a_32_run (memcached_st *)
3656 {
3657 uint32_t x;
3658 const char **ptr;
3659
3660 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3661 {
3662 test_compare(fnv1a_32_values[x],
3663 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_FNV1A_32));
3664 }
3665
3666 return TEST_SUCCESS;
3667 }
3668
3669 test_return_t hsieh_run (memcached_st *)
3670 {
3671 test_skip(true, libhashkit_has_algorithm(HASHKIT_HASH_HSIEH));
3672
3673 uint32_t x;
3674 const char **ptr;
3675
3676 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3677 {
3678 test_compare(hsieh_values[x],
3679 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_HSIEH));
3680 }
3681
3682 return TEST_SUCCESS;
3683 }
3684
3685 test_return_t murmur_run (memcached_st *)
3686 {
3687 test_skip(true, libhashkit_has_algorithm(HASHKIT_HASH_MURMUR));
3688
3689 #ifdef WORDS_BIGENDIAN
3690 (void)murmur_values;
3691 return TEST_SKIPPED;
3692 #else
3693 uint32_t x;
3694 const char **ptr;
3695
3696 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3697 {
3698 test_compare(murmur_values[x],
3699 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_MURMUR));
3700 }
3701
3702 return TEST_SUCCESS;
3703 #endif
3704 }
3705
3706 test_return_t murmur3_TEST(hashkit_st *)
3707 {
3708 test_skip(true, libhashkit_has_algorithm(HASHKIT_HASH_MURMUR3));
3709
3710 #ifdef WORDS_BIGENDIAN
3711 (void)murmur3_values;
3712 return TEST_SKIPPED;
3713 #else
3714 uint32_t x;
3715 const char **ptr;
3716
3717 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3718 {
3719 test_compare(murmur3_values[x],
3720 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_MURMUR3));
3721 }
3722
3723 return TEST_SUCCESS;
3724 #endif
3725 }
3726
3727 test_return_t jenkins_run (memcached_st *)
3728 {
3729 uint32_t x;
3730 const char **ptr;
3731
3732 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3733 {
3734 test_compare(jenkins_values[x],
3735 memcached_generate_hash_value(*ptr, strlen(*ptr), MEMCACHED_HASH_JENKINS));
3736 }
3737
3738 return TEST_SUCCESS;
3739 }
3740
3741 static uint32_t hash_md5_test_function(const char *string, size_t string_length, void *)
3742 {
3743 return libhashkit_md5(string, string_length);
3744 }
3745
3746 static uint32_t hash_crc_test_function(const char *string, size_t string_length, void *)
3747 {
3748 return libhashkit_crc32(string, string_length);
3749 }
3750
3751 test_return_t memcached_get_hashkit_test (memcached_st *)
3752 {
3753 uint32_t x;
3754 const char **ptr;
3755 hashkit_st new_kit;
3756
3757 memcached_st *memc= memcached(test_literal_param("--server=localhost:1 --server=localhost:2 --server=localhost:3 --server=localhost:4 --server=localhost5 --DISTRIBUTION=modula"));
3758
3759 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};
3760 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};
3761
3762 const hashkit_st *kit= memcached_get_hashkit(memc);
3763
3764 hashkit_clone(&new_kit, kit);
3765 test_compare(HASHKIT_SUCCESS, hashkit_set_custom_function(&new_kit, hash_md5_test_function, NULL));
3766
3767 memcached_set_hashkit(memc, &new_kit);
3768
3769 /*
3770 Verify Setting the hash.
3771 */
3772 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3773 {
3774 uint32_t hash_val;
3775
3776 hash_val= hashkit_digest(kit, *ptr, strlen(*ptr));
3777 test_compare_got(md5_values[x], hash_val, *ptr);
3778 }
3779
3780
3781 /*
3782 Now check memcached_st.
3783 */
3784 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3785 {
3786 uint32_t hash_val;
3787
3788 hash_val= memcached_generate_hash(memc, *ptr, strlen(*ptr));
3789 test_compare_got(md5_hosts[x], hash_val, *ptr);
3790 }
3791
3792 test_compare(HASHKIT_SUCCESS, hashkit_set_custom_function(&new_kit, hash_crc_test_function, NULL));
3793
3794 memcached_set_hashkit(memc, &new_kit);
3795
3796 /*
3797 Verify Setting the hash.
3798 */
3799 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3800 {
3801 uint32_t hash_val;
3802
3803 hash_val= hashkit_digest(kit, *ptr, strlen(*ptr));
3804 test_true(crc_values[x] == hash_val);
3805 }
3806
3807 for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++)
3808 {
3809 uint32_t hash_val;
3810
3811 hash_val= memcached_generate_hash(memc, *ptr, strlen(*ptr));
3812 test_compare(crc_hosts[x], hash_val);
3813 }
3814
3815 memcached_free(memc);
3816
3817 return TEST_SUCCESS;
3818 }
3819
3820 /*
3821 Test case adapted from John Gorman <johngorman2@gmail.com>
3822
3823 We are testing the error condition when we connect to a server via memcached_get()
3824 but find that the server is not available.
3825 */
3826 test_return_t memcached_get_MEMCACHED_ERRNO(memcached_st *)
3827 {
3828 size_t len;
3829 uint32_t flags;
3830 memcached_return rc;
3831
3832 // Create a handle.
3833 memcached_st *tl_memc_h= memcached(test_literal_param("--server=localhost:9898 --server=localhost:9899")); // This server should not exist
3834
3835 // See if memcached is reachable.
3836 char *value= memcached_get(tl_memc_h,
3837 test_literal_param(__func__),
3838 &len, &flags, &rc);
3839
3840 test_false(value);
3841 test_zero(len);
3842 test_true(memcached_failed(rc));
3843
3844 memcached_free(tl_memc_h);
3845
3846 return TEST_SUCCESS;
3847 }
3848
3849 /*
3850 We connect to a server which exists, but search for a key that does not exist.
3851 */
3852 test_return_t memcached_get_MEMCACHED_NOTFOUND(memcached_st *memc)
3853 {
3854 size_t len;
3855 uint32_t flags;
3856 memcached_return rc;
3857
3858 // See if memcached is reachable.
3859 char *value= memcached_get(memc,
3860 test_literal_param(__func__),
3861 &len, &flags, &rc);
3862
3863 test_false(value);
3864 test_zero(len);
3865 test_compare(MEMCACHED_NOTFOUND, rc);
3866
3867 return TEST_SUCCESS;
3868 }
3869
3870 /*
3871 Test case adapted from John Gorman <johngorman2@gmail.com>
3872
3873 We are testing the error condition when we connect to a server via memcached_get_by_key()
3874 but find that the server is not available.
3875 */
3876 test_return_t memcached_get_by_key_MEMCACHED_ERRNO(memcached_st *)
3877 {
3878 size_t len;
3879 uint32_t flags;
3880 memcached_return rc;
3881
3882 // Create a handle.
3883 memcached_st *tl_memc_h= memcached_create(NULL);
3884 memcached_server_st *servers= memcached_servers_parse("localhost:9898,localhost:9899"); // This server should not exist
3885 memcached_server_push(tl_memc_h, servers);
3886 memcached_server_list_free(servers);
3887
3888 // See if memcached is reachable.
3889 char *value= memcached_get_by_key(tl_memc_h,
3890 test_literal_param(__func__), // Key
3891 test_literal_param(__func__), // Value
3892 &len, &flags, &rc);
3893
3894 test_false(value);
3895 test_zero(len);
3896 test_true(memcached_failed(rc));
3897
3898 memcached_free(tl_memc_h);
3899
3900 return TEST_SUCCESS;
3901 }
3902
3903 /*
3904 We connect to a server which exists, but search for a key that does not exist.
3905 */
3906 test_return_t memcached_get_by_key_MEMCACHED_NOTFOUND(memcached_st *memc)
3907 {
3908 size_t len;
3909 uint32_t flags;
3910 memcached_return rc;
3911
3912 // See if memcached is reachable.
3913 char *value= memcached_get_by_key(memc,
3914 test_literal_param(__func__), // Key
3915 test_literal_param(__func__), // Value
3916 &len, &flags, &rc);
3917
3918 test_false(value);
3919 test_zero(len);
3920 test_compare(MEMCACHED_NOTFOUND, rc);
3921
3922 return TEST_SUCCESS;
3923 }
3924
3925 test_return_t regression_bug_434484(memcached_st *memc)
3926 {
3927 test_skip(TEST_SUCCESS, pre_binary(memc));
3928
3929 test_compare(MEMCACHED_NOTSTORED,
3930 memcached_append(memc,
3931 test_literal_param(__func__), // Key
3932 test_literal_param(__func__), // Value
3933 0, 0));
3934
3935 libtest::vchar_t data;
3936 data.resize(2048 * 1024);
3937 test_compare(MEMCACHED_E2BIG,
3938 memcached_set(memc,
3939 test_literal_param(__func__), // Key
3940 &data[0], data.size(), 0, 0));
3941
3942 return TEST_SUCCESS;
3943 }
3944
3945 test_return_t regression_bug_434843(memcached_st *original_memc)
3946 {
3947 test_skip(TEST_SUCCESS, pre_binary(original_memc));
3948
3949 memcached_return_t rc;
3950 size_t counter= 0;
3951 memcached_execute_fn callbacks[]= { &callback_counter };
3952
3953 /*
3954 * I only want to hit only _one_ server so I know the number of requests I'm
3955 * sending in the pipleine to the server. Let's try to do a multiget of
3956 * 1024 (that should satisfy most users don't you think?). Future versions
3957 * will include a mget_execute function call if you need a higher number.
3958 */
3959 memcached_st *memc= create_single_instance_memcached(original_memc, "--BINARY-PROTOCOL");
3960
3961 keys_st keys(1024);
3962
3963 /*
3964 * Run two times.. the first time we should have 100% cache miss,
3965 * and the second time we should have 100% cache hits
3966 */
3967 for (ptrdiff_t y= 0; y < 2; y++)
3968 {
3969 test_compare(MEMCACHED_SUCCESS,
3970 memcached_mget(memc, keys.keys_ptr(), keys.lengths_ptr(), keys.size()));
3971
3972 // One the first run we should get a NOT_FOUND, but on the second some data
3973 // should be returned.
3974 test_compare(y ? MEMCACHED_SUCCESS : MEMCACHED_NOTFOUND,
3975 memcached_fetch_execute(memc, callbacks, (void *)&counter, 1));
3976
3977 if (y == 0)
3978 {
3979 /* The first iteration should give me a 100% cache miss. verify that*/
3980 char blob[1024]= { 0 };
3981
3982 test_false(counter);
3983
3984 for (size_t x= 0; x < keys.size(); ++x)
3985 {
3986 rc= memcached_add(memc,
3987 keys.key_at(x), keys.length_at(x),
3988 blob, sizeof(blob), 0, 0);
3989 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
3990 }
3991 }
3992 else
3993 {
3994 /* Verify that we received all of the key/value pairs */
3995 test_compare(counter, keys.size());
3996 }
3997 }
3998
3999 memcached_free(memc);
4000
4001 return TEST_SUCCESS;
4002 }
4003
4004 test_return_t regression_bug_434843_buffered(memcached_st *memc)
4005 {
4006 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, true));
4007
4008 return regression_bug_434843(memc);
4009 }
4010
4011 test_return_t regression_bug_421108(memcached_st *memc)
4012 {
4013 memcached_return_t rc;
4014 memcached_stat_st *memc_stat= memcached_stat(memc, NULL, &rc);
4015 test_compare(MEMCACHED_SUCCESS, rc);
4016
4017 char *bytes_str= memcached_stat_get_value(memc, memc_stat, "bytes", &rc);
4018 test_compare(MEMCACHED_SUCCESS, rc);
4019 test_true(bytes_str);
4020 char *bytes_read_str= memcached_stat_get_value(memc, memc_stat,
4021 "bytes_read", &rc);
4022 test_compare(MEMCACHED_SUCCESS, rc);
4023 test_true(bytes_read_str);
4024
4025 char *bytes_written_str= memcached_stat_get_value(memc, memc_stat,
4026 "bytes_written", &rc);
4027 test_compare(MEMCACHED_SUCCESS, rc);
4028 test_true(bytes_written_str);
4029
4030 unsigned long long bytes= strtoull(bytes_str, 0, 10);
4031 unsigned long long bytes_read= strtoull(bytes_read_str, 0, 10);
4032 unsigned long long bytes_written= strtoull(bytes_written_str, 0, 10);
4033
4034 test_true(bytes != bytes_read);
4035 test_true(bytes != bytes_written);
4036
4037 /* Release allocated resources */
4038 free(bytes_str);
4039 free(bytes_read_str);
4040 free(bytes_written_str);
4041 memcached_stat_free(NULL, memc_stat);
4042
4043 return TEST_SUCCESS;
4044 }
4045
4046 /*
4047 * The test case isn't obvious so I should probably document why
4048 * it works the way it does. Bug 442914 was caused by a bug
4049 * in the logic in memcached_purge (it did not handle the case
4050 * where the number of bytes sent was equal to the watermark).
4051 * In this test case, create messages so that we hit that case
4052 * and then disable noreply mode and issue a new command to
4053 * verify that it isn't stuck. If we change the format for the
4054 * delete command or the watermarks, we need to update this
4055 * test....
4056 */
4057 test_return_t regression_bug_442914(memcached_st *original_memc)
4058 {
4059 test_skip(original_memc->servers[0].type, MEMCACHED_CONNECTION_TCP);
4060
4061 memcached_st* memc= create_single_instance_memcached(original_memc, "--NOREPLY --TCP-NODELAY");
4062
4063 for (uint32_t x= 0; x < 250; ++x)
4064 {
4065 char key[250];
4066 size_t len= (size_t)snprintf(key, sizeof(key), "%0250u", x);
4067 memcached_return_t rc= memcached_delete(memc, key, len, 0);
4068 char error_buffer[2048]= { 0 };
4069 snprintf(error_buffer, sizeof(error_buffer), "%s key: %s", memcached_last_error_message(memc), key);
4070 test_true_got(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED, error_buffer);
4071 }
4072
4073 // Delete, and then delete again to look for not found
4074 {
4075 char key[250];
4076 size_t len= snprintf(key, sizeof(key), "%037u", 251U);
4077 memcached_return_t rc= memcached_delete(memc, key, len, 0);
4078 test_true(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED);
4079
4080 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, false));
4081 test_compare(MEMCACHED_NOTFOUND, memcached_delete(memc, key, len, 0));
4082 }
4083
4084 memcached_free(memc);
4085
4086 return TEST_SUCCESS;
4087 }
4088
4089 test_return_t regression_bug_447342(memcached_st *memc)
4090 {
4091 if (memcached_server_count(memc) < 3 or pre_replication(memc) != TEST_SUCCESS)
4092 {
4093 return TEST_SKIPPED;
4094 }
4095
4096 test_compare(MEMCACHED_SUCCESS,
4097 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 2));
4098
4099 keys_st keys(100);
4100
4101 for (size_t x= 0; x < keys.size(); ++x)
4102 {
4103 test_compare(MEMCACHED_SUCCESS,
4104 memcached_set(memc,
4105 keys.key_at(x), keys.length_at(x), // Keys
4106 keys.key_at(x), keys.length_at(x), // Values
4107 0, 0));
4108 }
4109
4110 /*
4111 ** We are using the quiet commands to store the replicas, so we need
4112 ** to ensure that all of them are processed before we can continue.
4113 ** In the test we go directly from storing the object to trying to
4114 ** receive the object from all of the different servers, so we
4115 ** could end up in a race condition (the memcached server hasn't yet
4116 ** processed the quiet command from the replication set when it process
4117 ** the request from the other client (created by the clone)). As a
4118 ** workaround for that we call memcached_quit to send the quit command
4119 ** to the server and wait for the response ;-) If you use the test code
4120 ** as an example for your own code, please note that you shouldn't need
4121 ** to do this ;-)
4122 */
4123 memcached_quit(memc);
4124
4125 /* Verify that all messages are stored, and we didn't stuff too much
4126 * into the servers
4127 */
4128 test_compare(MEMCACHED_SUCCESS,
4129 memcached_mget(memc,
4130 keys.keys_ptr(), keys.lengths_ptr(), keys.size()));
4131
4132 unsigned int counter= 0;
4133 memcached_execute_fn callbacks[]= { &callback_counter };
4134 test_compare(MEMCACHED_SUCCESS,
4135 memcached_fetch_execute(memc, callbacks, (void *)&counter, 1));
4136
4137 /* Verify that we received all of the key/value pairs */
4138 test_compare(counter, keys.size());
4139
4140 memcached_quit(memc);
4141 /*
4142 * Don't do the following in your code. I am abusing the internal details
4143 * within the library, and this is not a supported interface.
4144 * This is to verify correct behavior in the library. Fake that two servers
4145 * are dead..
4146 */
4147 memcached_server_instance_st instance_one= memcached_server_instance_by_position(memc, 0);
4148 memcached_server_instance_st instance_two= memcached_server_instance_by_position(memc, 2);
4149 in_port_t port0= instance_one->port();
4150 in_port_t port2= instance_two->port();
4151
4152 ((memcached_server_write_instance_st)instance_one)->port(0);
4153 ((memcached_server_write_instance_st)instance_two)->port(0);
4154
4155 test_compare(MEMCACHED_SUCCESS,
4156 memcached_mget(memc,
4157 keys.keys_ptr(), keys.lengths_ptr(), keys.size()));
4158
4159 counter= 0;
4160 test_compare(MEMCACHED_SUCCESS,
4161 memcached_fetch_execute(memc, callbacks, (void *)&counter, 1));
4162 test_compare(counter, keys.size());
4163
4164 /* restore the memc handle */
4165 ((memcached_server_write_instance_st)instance_one)->port(port0);
4166 ((memcached_server_write_instance_st)instance_two)->port(port2);
4167
4168 memcached_quit(memc);
4169
4170 /* Remove half of the objects */
4171 for (size_t x= 0; x < keys.size(); ++x)
4172 {
4173 if (x & 1)
4174 {
4175 test_compare(MEMCACHED_SUCCESS,
4176 memcached_delete(memc, keys.key_at(x), keys.length_at(x), 0));
4177 }
4178 }
4179
4180 memcached_quit(memc);
4181 ((memcached_server_write_instance_st)instance_one)->port(0);
4182 ((memcached_server_write_instance_st)instance_two)->port(0);
4183
4184 /* now retry the command, this time we should have cache misses */
4185 test_compare(MEMCACHED_SUCCESS,
4186 memcached_mget(memc,
4187 keys.keys_ptr(), keys.lengths_ptr(), keys.size()));
4188
4189 counter= 0;
4190 test_compare(MEMCACHED_SUCCESS,
4191 memcached_fetch_execute(memc, callbacks, (void *)&counter, 1));
4192 test_compare(counter, (unsigned int)(keys.size() >> 1));
4193
4194 /* restore the memc handle */
4195 ((memcached_server_write_instance_st)instance_one)->port(port0);
4196 ((memcached_server_write_instance_st)instance_two)->port(port2);
4197
4198 return TEST_SUCCESS;
4199 }
4200
4201 test_return_t regression_bug_463297(memcached_st *memc)
4202 {
4203 test_compare(MEMCACHED_INVALID_ARGUMENTS, memcached_delete(memc, "foo", 3, 1));
4204
4205 // Since we blocked timed delete, this test is no longer valid.
4206 #if 0
4207 memcached_st *memc_clone= memcached_clone(NULL, memc);
4208 test_true(memc_clone);
4209 test_true(memcached_version(memc_clone) == MEMCACHED_SUCCESS);
4210
4211 memcached_server_instance_st instance=
4212 memcached_server_instance_by_position(memc_clone, 0);
4213
4214 if (instance->major_version > 1 ||
4215 (instance->major_version == 1 &&
4216 instance->minor_version > 2))
4217 {
4218 /* Binary protocol doesn't support deferred delete */
4219 memcached_st *bin_clone= memcached_clone(NULL, memc);
4220 test_true(bin_clone);
4221 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(bin_clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1));
4222 test_compare(MEMCACHED_INVALID_ARGUMENTS, memcached_delete(bin_clone, "foo", 3, 1));
4223 memcached_free(bin_clone);
4224
4225 memcached_quit(memc_clone);
4226
4227 /* If we know the server version, deferred delete should fail
4228 * with invalid arguments */
4229 test_compare(MEMCACHED_INVALID_ARGUMENTS, memcached_delete(memc_clone, "foo", 3, 1));
4230
4231 /* If we don't know the server version, we should get a protocol error */
4232 memcached_return_t rc= memcached_delete(memc, "foo", 3, 1);
4233
4234 /* but there is a bug in some of the memcached servers (1.4) that treats
4235 * the counter as noreply so it doesn't send the proper error message
4236 */
4237 test_true_got(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR || rc == MEMCACHED_INVALID_ARGUMENTS, memcached_strerror(NULL, rc));
4238
4239 /* And buffered mode should be disabled and we should get protocol error */
4240 test_true(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1) == MEMCACHED_SUCCESS);
4241 rc= memcached_delete(memc, "foo", 3, 1);
4242 test_true_got(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR || rc == MEMCACHED_INVALID_ARGUMENTS, memcached_strerror(NULL, rc));
4243
4244 /* Same goes for noreply... */
4245 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1));
4246 rc= memcached_delete(memc, "foo", 3, 1);
4247 test_true_got(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR || rc == MEMCACHED_INVALID_ARGUMENTS, memcached_strerror(NULL, rc));
4248
4249 /* but a normal request should go through (and be buffered) */
4250 test_compare(MEMCACHED_BUFFERED, (rc= memcached_delete(memc, "foo", 3, 0)));
4251 test_compare(MEMCACHED_SUCCESS, memcached_flush_buffers(memc));
4252
4253 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 0));
4254 /* unbuffered noreply should be success */
4255 test_compare(MEMCACHED_SUCCESS, memcached_delete(memc, "foo", 3, 0));
4256 /* unbuffered with reply should be not found... */
4257 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 0));
4258 test_compare(MEMCACHED_NOTFOUND, memcached_delete(memc, "foo", 3, 0));
4259 }
4260
4261 memcached_free(memc_clone);
4262 #endif
4263
4264 return TEST_SUCCESS;
4265 }
4266
4267
4268 /* Test memcached_server_get_last_disconnect
4269 * For a working server set, shall be NULL
4270 * For a set of non existing server, shall not be NULL
4271 */
4272 test_return_t test_get_last_disconnect(memcached_st *memc)
4273 {
4274 memcached_return_t rc;
4275 memcached_server_instance_st disconnected_server;
4276
4277 /* With the working set of server */
4278 const char *key= "marmotte";
4279 const char *value= "milka";
4280
4281 memcached_reset_last_disconnected_server(memc);
4282 test_false(memc->last_disconnected_server);
4283 rc= memcached_set(memc, key, strlen(key),
4284 value, strlen(value),
4285 (time_t)0, (uint32_t)0);
4286 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
4287
4288 disconnected_server = memcached_server_get_last_disconnect(memc);
4289 test_false(disconnected_server);
4290
4291 /* With a non existing server */
4292 memcached_st *mine;
4293 memcached_server_st *servers;
4294
4295 const char *server_list= "localhost:9";
4296
4297 servers= memcached_servers_parse(server_list);
4298 test_true(servers);
4299 mine= memcached_create(NULL);
4300 rc= memcached_server_push(mine, servers);
4301 test_compare(MEMCACHED_SUCCESS, rc);
4302 memcached_server_list_free(servers);
4303 test_true(mine);
4304
4305 rc= memcached_set(mine, key, strlen(key),
4306 value, strlen(value),
4307 (time_t)0, (uint32_t)0);
4308 test_true(memcached_failed(rc));
4309
4310 disconnected_server= memcached_server_get_last_disconnect(mine);
4311 test_true_got(disconnected_server, memcached_strerror(mine, rc));
4312 test_compare(in_port_t(9), memcached_server_port(disconnected_server));
4313 test_false(strncmp(memcached_server_name(disconnected_server),"localhost",9));
4314
4315 memcached_quit(mine);
4316 memcached_free(mine);
4317
4318 return TEST_SUCCESS;
4319 }
4320
4321 test_return_t test_multiple_get_last_disconnect(memcached_st *)
4322 {
4323 const char *server_string= "--server=localhost:8888 --server=localhost:8889 --server=localhost:8890 --server=localhost:8891 --server=localhost:8892";
4324 char buffer[BUFSIZ];
4325
4326 test_compare(MEMCACHED_SUCCESS,
4327 libmemcached_check_configuration(server_string, strlen(server_string), buffer, sizeof(buffer)));
4328
4329 memcached_st *memc= memcached(server_string, strlen(server_string));
4330 test_true(memc);
4331
4332 // We will just use the error strings as our keys
4333 uint32_t counter= 100;
4334 while (--counter)
4335 {
4336 for (int x= int(MEMCACHED_SUCCESS); x < int(MEMCACHED_MAXIMUM_RETURN); ++x)
4337 {
4338 const char *msg= memcached_strerror(memc, memcached_return_t(x));
4339 memcached_return_t ret= memcached_set(memc, msg, strlen(msg), NULL, 0, (time_t)0, (uint32_t)0);
4340 test_true_got((ret == MEMCACHED_CONNECTION_FAILURE or ret == MEMCACHED_SERVER_TEMPORARILY_DISABLED), memcached_last_error_message(memc));
4341
4342 memcached_server_instance_st disconnected_server= memcached_server_get_last_disconnect(memc);
4343 test_true(disconnected_server);
4344 test_strcmp("localhost", memcached_server_name(disconnected_server));
4345 test_true(memcached_server_port(disconnected_server) >= 8888 and memcached_server_port(disconnected_server) <= 8892);
4346
4347 if (random() % 2)
4348 {
4349 memcached_reset_last_disconnected_server(memc);
4350 }
4351 }
4352 }
4353
4354 memcached_free(memc);
4355
4356 return TEST_SUCCESS;
4357 }
4358
4359 test_return_t test_verbosity(memcached_st *memc)
4360 {
4361 memcached_verbosity(memc, 3);
4362
4363 return TEST_SUCCESS;
4364 }
4365
4366
4367 static memcached_return_t stat_printer(memcached_server_instance_st server,
4368 const char *key, size_t key_length,
4369 const char *value, size_t value_length,
4370 void *context)
4371 {
4372 (void)server;
4373 (void)context;
4374 (void)key;
4375 (void)key_length;
4376 (void)value;
4377 (void)value_length;
4378
4379 return MEMCACHED_SUCCESS;
4380 }
4381
4382 test_return_t memcached_stat_execute_test(memcached_st *memc)
4383 {
4384 memcached_return_t rc= memcached_stat_execute(memc, NULL, stat_printer, NULL);
4385 test_compare(MEMCACHED_SUCCESS, rc);
4386
4387 test_compare(MEMCACHED_SUCCESS,
4388 memcached_stat_execute(memc, "slabs", stat_printer, NULL));
4389
4390 test_compare(MEMCACHED_SUCCESS,
4391 memcached_stat_execute(memc, "items", stat_printer, NULL));
4392
4393 test_compare(MEMCACHED_SUCCESS,
4394 memcached_stat_execute(memc, "sizes", stat_printer, NULL));
4395
4396 return TEST_SUCCESS;
4397 }
4398
4399 /*
4400 * This test ensures that the failure counter isn't incremented during
4401 * normal termination of the memcached instance.
4402 */
4403 test_return_t wrong_failure_counter_test(memcached_st *original_memc)
4404 {
4405 memcached_st* memc= create_single_instance_memcached(original_memc, NULL);
4406
4407 /* Ensure that we are connected to the server by setting a value */
4408 memcached_return_t rc= memcached_set(memc,
4409 test_literal_param(__func__), // Key
4410 test_literal_param(__func__), // Value
4411 time_t(0), uint32_t(0));
4412 test_true(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED);
4413
4414
4415 memcached_server_instance_st instance= memcached_server_instance_by_position(memc, 0);
4416
4417 /* The test is to see that the memcached_quit doesn't increase the
4418 * the server failure conter, so let's ensure that it is zero
4419 * before sending quit
4420 */
4421 ((memcached_server_write_instance_st)instance)->server_failure_counter= 0;
4422
4423 memcached_quit(memc);
4424
4425 /* Verify that it memcached_quit didn't increment the failure counter
4426 * Please note that this isn't bullet proof, because an error could
4427 * occur...
4428 */
4429 test_zero(instance->server_failure_counter);
4430
4431 memcached_free(memc);
4432
4433 return TEST_SUCCESS;
4434 }
4435
4436 /*
4437 * This tests ensures expected disconnections (for some behavior changes
4438 * for instance) do not wrongly increase failure counter
4439 */
4440 test_return_t wrong_failure_counter_two_test(memcached_st *memc)
4441 {
4442 /* Set value to force connection to the server */
4443 const char *key= "marmotte";
4444 const char *value= "milka";
4445
4446 test_compare_hint(MEMCACHED_SUCCESS,
4447 memcached_set(memc, key, strlen(key),
4448 value, strlen(value),
4449 (time_t)0, (uint32_t)0),
4450 memcached_last_error_message(memc));
4451
4452
4453 /* put failure limit to 1 */
4454 test_compare(MEMCACHED_SUCCESS,
4455 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, true));
4456
4457 /* Put a retry timeout to effectively activate failure_limit effect */
4458 test_compare(MEMCACHED_SUCCESS,
4459 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, true));
4460
4461 /* change behavior that triggers memcached_quit()*/
4462 test_compare(MEMCACHED_SUCCESS,
4463 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, true));
4464
4465
4466 /* Check if we still are connected */
4467 uint32_t flags;
4468 size_t string_length;
4469 memcached_return rc;
4470 char *string= memcached_get(memc, key, strlen(key),
4471 &string_length, &flags, &rc);
4472
4473 test_compare_got(MEMCACHED_SUCCESS, rc, memcached_strerror(NULL, rc));
4474 test_true(string);
4475 free(string);
4476
4477 return TEST_SUCCESS;
4478 }
4479
4480 test_return_t regression_996813_TEST(memcached_st *)
4481 {
4482 memcached_st* memc= memcached_create(NULL);
4483
4484 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA));
4485 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 1));
4486 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 1));
4487 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1));
4488 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, 1));
4489 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT, 300));
4490 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 30));
4491
4492 // We will never connect to these servers
4493 in_port_t base_port= 11211;
4494 for (size_t x= 0; x < 17; x++)
4495 {
4496 test_compare(MEMCACHED_SUCCESS, memcached_server_add(memc, "10.2.3.4", base_port +x));
4497 }
4498 test_compare(6U, memcached_generate_hash(memc, test_literal_param("SZ6hu0SHweFmpwpc0w2R")));
4499 test_compare(1U, memcached_generate_hash(memc, test_literal_param("SQCK9eiCf53YxHWnYA.o")));
4500 test_compare(9U, memcached_generate_hash(memc, test_literal_param("SUSDkGXuuZC9t9VhMwa.")));
4501 test_compare(0U, memcached_generate_hash(memc, test_literal_param("SnnqnJARfaCNT679iAF_")));
4502
4503 memcached_free(memc);
4504
4505 return TEST_SUCCESS;
4506 }
4507
4508
4509 /*
4510 * Test that ensures mget_execute does not end into recursive calls that finally fails
4511 */
4512 test_return_t regression_bug_490486(memcached_st *original_memc)
4513 {
4514
4515 #ifdef __APPLE__
4516 return TEST_SKIPPED; // My MAC can't handle this test
4517 #endif
4518
4519 test_skip(TEST_SUCCESS, pre_binary(original_memc));
4520
4521 /*
4522 * I only want to hit _one_ server so I know the number of requests I'm
4523 * sending in the pipeline.
4524 */
4525 memcached_st *memc= create_single_instance_memcached(original_memc, "--BINARY-PROTOCOL --POLL-TIMEOUT=1000 --REMOVE-FAILED-SERVERS=1 --RETRY-TIMEOUT=3600");
4526 test_true(memc);
4527
4528 keys_st keys(20480);
4529
4530 /* First add all of the items.. */
4531 char blob[1024]= { 0 };
4532 for (size_t x= 0; x < keys.size(); ++x)
4533 {
4534 memcached_return rc= memcached_set(memc,
4535 keys.key_at(x), keys.length_at(x),
4536 blob, sizeof(blob), 0, 0);
4537 test_true(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED); // MEMCACHED_TIMEOUT <-- hash been observed on OSX
4538 }
4539
4540 {
4541
4542 /* Try to get all of them with a large multiget */
4543 size_t counter= 0;
4544 memcached_execute_function callbacks[]= { &callback_counter };
4545 memcached_return_t rc= memcached_mget_execute(memc,
4546 keys.keys_ptr(), keys.lengths_ptr(), keys.size(),
4547 callbacks, &counter, 1);
4548 test_compare(MEMCACHED_SUCCESS, rc);
4549
4550 char* the_value= NULL;
4551 char the_key[MEMCACHED_MAX_KEY];
4552 size_t the_key_length;
4553 size_t the_value_length;
4554 uint32_t the_flags;
4555
4556 do {
4557 the_value= memcached_fetch(memc, the_key, &the_key_length, &the_value_length, &the_flags, &rc);
4558
4559 if ((the_value!= NULL) && (rc == MEMCACHED_SUCCESS))
4560 {
4561 ++counter;
4562 free(the_value);
4563 }
4564
4565 } while ( (the_value!= NULL) && (rc == MEMCACHED_SUCCESS));
4566
4567
4568 test_compare(MEMCACHED_END, rc);
4569
4570 /* Verify that we got all of the items */
4571 test_compare(counter, keys.size());
4572 }
4573
4574 memcached_free(memc);
4575
4576 return TEST_SUCCESS;
4577 }
4578
4579 test_return_t regression_1021819_TEST(memcached_st *original)
4580 {
4581 memcached_st *memc= memcached_clone(NULL, original);
4582 test_true(memc);
4583
4584 test_compare(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SND_TIMEOUT, 2000000), MEMCACHED_SUCCESS);
4585 test_compare(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RCV_TIMEOUT, 3000000), MEMCACHED_SUCCESS);
4586
4587 memcached_return_t rc;
4588
4589 memcached_get(memc,
4590 test_literal_param(__func__),
4591 NULL, NULL, &rc);
4592
4593 test_compare(rc, MEMCACHED_NOTFOUND);
4594
4595 memcached_free(memc);
4596
4597 return TEST_SUCCESS;
4598 }
4599
4600 test_return_t regression_bug_583031(memcached_st *)
4601 {
4602 memcached_st *memc= memcached_create(NULL);
4603 test_true(memc);
4604 test_compare(MEMCACHED_SUCCESS, memcached_server_add(memc, "10.2.3.4", 11211));
4605
4606 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT, 1000);
4607 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 1000);
4608 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SND_TIMEOUT, 1000);
4609 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RCV_TIMEOUT, 1000);
4610 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, 1000);
4611 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, 3);
4612
4613 memcached_return_t rc;
4614 size_t length;
4615 uint32_t flags;
4616
4617 const char *value= memcached_get(memc, "dsf", 3, &length, &flags, &rc);
4618 test_false(value);
4619 test_zero(length);
4620
4621 test_compare_got(MEMCACHED_TIMEOUT, rc, memcached_last_error_message(memc));
4622
4623 memcached_free(memc);
4624
4625 return TEST_SUCCESS;
4626 }
4627
4628 test_return_t regression_bug_581030(memcached_st *)
4629 {
4630 #ifndef DEBUG
4631 memcached_stat_st *local_stat= memcached_stat(NULL, NULL, NULL);
4632 test_false(local_stat);
4633
4634 memcached_stat_free(NULL, NULL);
4635 #endif
4636
4637 return TEST_SUCCESS;
4638 }
4639
4640 #define regression_bug_655423_COUNT 6000
4641 test_return_t regression_bug_655423(memcached_st *memc)
4642 {
4643 memcached_st *clone= memcached_clone(NULL, memc);
4644 memc= NULL; // Just to make sure it is not used
4645 test_true(clone);
4646 char payload[100];
4647
4648 #ifdef __APPLE__
4649 return TEST_SKIPPED;
4650 #endif
4651
4652 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1));
4653 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(clone, MEMCACHED_BEHAVIOR_SUPPORT_CAS, 1));
4654 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(clone, MEMCACHED_BEHAVIOR_TCP_NODELAY, 1));
4655 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(clone, MEMCACHED_BEHAVIOR_IO_KEY_PREFETCH, 1));
4656
4657 memset(payload, int('x'), sizeof(payload));
4658
4659 keys_st keys(regression_bug_655423_COUNT);
4660
4661 for (size_t x= 0; x < keys.size(); x++)
4662 {
4663 test_compare(MEMCACHED_SUCCESS, memcached_set(clone,
4664 keys.key_at(x),
4665 keys.length_at(x),
4666 payload, sizeof(payload), 0, 0));
4667 }
4668
4669 for (size_t x= 0; x < keys.size(); x++)
4670 {
4671 size_t value_length;
4672 memcached_return_t rc;
4673 char *value= memcached_get(clone,
4674 keys.key_at(x),
4675 keys.length_at(x),
4676 &value_length, NULL, &rc);
4677
4678 if (rc == MEMCACHED_NOTFOUND)
4679 {
4680 test_false(value);
4681 test_zero(value_length);
4682 continue;
4683 }
4684
4685 test_compare(MEMCACHED_SUCCESS, rc);
4686 test_true(value);
4687 test_compare(100LLU, value_length);
4688 free(value);
4689 }
4690
4691 test_compare(MEMCACHED_SUCCESS,
4692 memcached_mget(clone,
4693 keys.keys_ptr(), keys.lengths_ptr(),
4694 keys.size()));
4695
4696 uint32_t count= 0;
4697 memcached_result_st *result= NULL;
4698 while ((result= memcached_fetch_result(clone, result, NULL)))
4699 {
4700 test_compare(size_t(100), memcached_result_length(result));
4701 count++;
4702 }
4703
4704 test_true(count > 100); // If we don't get back atleast this, something is up
4705
4706 memcached_free(clone);
4707
4708 return TEST_SUCCESS;
4709 }
4710
4711 /*
4712 * Test that ensures that buffered set to not trigger problems during io_flush
4713 */
4714 #define regression_bug_490520_COUNT 200480
4715 test_return_t regression_bug_490520(memcached_st *original_memc)
4716 {
4717 memcached_st* memc= create_single_instance_memcached(original_memc, NULL);
4718
4719 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK,1);
4720 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS,1);
4721 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, 1000);
4722 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT,1);
4723 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 3600);
4724
4725 /* First add all of the items.. */
4726 char blob[3333] = {0};
4727 for (uint32_t x= 0; x < regression_bug_490520_COUNT; ++x)
4728 {
4729 char key[251];
4730 int key_length= snprintf(key, sizeof(key), "0200%u", x);
4731
4732 memcached_return rc= memcached_set(memc, key, key_length, blob, sizeof(blob), 0, 0);
4733 test_true_got(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED, memcached_last_error_message(memc));
4734 }
4735
4736 memcached_free(memc);
4737
4738 return TEST_SUCCESS;
4739 }
4740
4741 test_return_t regression_1009493_TEST(memcached_st*)
4742 {
4743 memcached_st* memc= memcached_create(NULL);
4744 test_true(memc);
4745 test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_KETAMA, true));
4746
4747 memcached_st* clone= memcached_clone(NULL, memc);
4748 test_true(clone);
4749
4750 test_compare(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED),
4751 memcached_behavior_get(clone, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED));
4752
4753 memcached_free(memc);
4754 memcached_free(clone);
4755
4756 return TEST_SUCCESS;
4757 }
4758
4759 test_return_t regression_994772_TEST(memcached_st* memc)
4760 {
4761 test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1));
4762
4763 test_compare(MEMCACHED_SUCCESS,
4764 memcached_set(memc,
4765 test_literal_param(__func__), // Key
4766 test_literal_param(__func__), // Value
4767 time_t(0), uint32_t(0)));
4768
4769 const char *keys[] = { __func__ };
4770 size_t key_length[]= { strlen(__func__) };
4771 test_compare(MEMCACHED_SUCCESS,
4772 memcached_mget(memc, keys, key_length, 1));
4773
4774 memcached_return_t rc;
4775 memcached_result_st *results= memcached_fetch_result(memc, NULL, &rc);
4776 test_true(results);
4777 test_compare(MEMCACHED_SUCCESS, rc);
4778
4779 test_strcmp(__func__, memcached_result_value(results));
4780 uint64_t cas_value= memcached_result_cas(results);
4781 test_true(cas_value);
4782
4783 char* take_value= memcached_result_take_value(results);
4784 test_strcmp(__func__, take_value);
4785 free(take_value);
4786
4787 memcached_result_free(results);
4788
4789 // Bad cas value, sanity check
4790 test_true(cas_value != 9999);
4791 test_compare(MEMCACHED_END,
4792 memcached_cas(memc,
4793 test_literal_param(__func__), // Key
4794 test_literal_param(__FILE__), // Value
4795 time_t(0), uint32_t(0), 9999));
4796
4797 test_compare(MEMCACHED_SUCCESS, memcached_set(memc,
4798 "different", strlen("different"), // Key
4799 test_literal_param(__FILE__), // Value
4800 time_t(0), uint32_t(0)));
4801
4802 return TEST_SUCCESS;
4803 }
4804
4805 test_return_t regression_bug_854604(memcached_st *)
4806 {
4807 char buffer[1024];
4808
4809 test_compare(MEMCACHED_INVALID_ARGUMENTS, libmemcached_check_configuration(0, 0, buffer, 0));
4810
4811 test_compare(MEMCACHED_PARSE_ERROR, libmemcached_check_configuration(test_literal_param("syntax error"), buffer, 0));
4812
4813 test_compare(MEMCACHED_PARSE_ERROR, libmemcached_check_configuration(test_literal_param("syntax error"), buffer, 1));
4814 test_compare(buffer[0], 0);
4815
4816 test_compare(MEMCACHED_PARSE_ERROR, libmemcached_check_configuration(test_literal_param("syntax error"), buffer, 10));
4817 test_true(strlen(buffer));
4818
4819 test_compare(MEMCACHED_PARSE_ERROR, libmemcached_check_configuration(test_literal_param("syntax error"), buffer, sizeof(buffer)));
4820 test_true(strlen(buffer));
4821
4822 return TEST_SUCCESS;
4823 }
4824
4825 static void die_message(memcached_st* mc, memcached_return error, const char* what, uint32_t it)
4826 {
4827 fprintf(stderr, "Iteration #%u: ", it);
4828
4829 if (error == MEMCACHED_ERRNO)
4830 {
4831 fprintf(stderr, "system error %d from %s: %s\n",
4832 errno, what, strerror(errno));
4833 }
4834 else
4835 {
4836 fprintf(stderr, "error %d from %s: %s\n", error, what,
4837 memcached_strerror(mc, error));
4838 }
4839 }
4840
4841 #define TEST_CONSTANT_CREATION 200
4842
4843 test_return_t regression_bug_(memcached_st *memc)
4844 {
4845 const char *remote_server;
4846 (void)memc;
4847
4848 if (! (remote_server= getenv("LIBMEMCACHED_REMOTE_SERVER")))
4849 {
4850 return TEST_SKIPPED;
4851 }
4852
4853 for (uint32_t x= 0; x < TEST_CONSTANT_CREATION; x++)
4854 {
4855 memcached_st* mc= memcached_create(NULL);
4856 memcached_return rc;
4857
4858 rc= memcached_behavior_set(mc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
4859 if (rc != MEMCACHED_SUCCESS)
4860 {
4861 die_message(mc, rc, "memcached_behavior_set", x);
4862 }
4863
4864 rc= memcached_behavior_set(mc, MEMCACHED_BEHAVIOR_CACHE_LOOKUPS, 1);
4865 if (rc != MEMCACHED_SUCCESS)
4866 {
4867 die_message(mc, rc, "memcached_behavior_set", x);
4868 }
4869
4870 rc= memcached_server_add(mc, remote_server, 0);
4871 if (rc != MEMCACHED_SUCCESS)
4872 {
4873 die_message(mc, rc, "memcached_server_add", x);
4874 }
4875
4876 const char *set_key= "akey";
4877 const size_t set_key_len= strlen(set_key);
4878 const char *set_value= "a value";
4879 const size_t set_value_len= strlen(set_value);
4880
4881 if (rc == MEMCACHED_SUCCESS)
4882 {
4883 if (x > 0)
4884 {
4885 size_t get_value_len;
4886 char *get_value;
4887 uint32_t get_value_flags;
4888
4889 get_value= memcached_get(mc, set_key, set_key_len, &get_value_len,
4890 &get_value_flags, &rc);
4891 if (rc != MEMCACHED_SUCCESS)
4892 {
4893 die_message(mc, rc, "memcached_get", x);
4894 }
4895 else
4896 {
4897
4898 if (x != 0 &&
4899 (get_value_len != set_value_len
4900 || 0!=strncmp(get_value, set_value, get_value_len)))
4901 {
4902 fprintf(stderr, "Values don't match?\n");
4903 rc= MEMCACHED_FAILURE;
4904 }
4905 free(get_value);
4906 }
4907 }
4908
4909 rc= memcached_set(mc,
4910 set_key, set_key_len,
4911 set_value, set_value_len,
4912 0, /* time */
4913 0 /* flags */
4914 );
4915 if (rc != MEMCACHED_SUCCESS)
4916 {
4917 die_message(mc, rc, "memcached_set", x);
4918 }
4919 }
4920
4921 memcached_quit(mc);
4922 memcached_free(mc);
4923
4924 if (rc != MEMCACHED_SUCCESS)
4925 {
4926 break;
4927 }
4928 }
4929
4930 return TEST_SUCCESS;
4931 }
4932
4933 test_return_t kill_HUP_TEST(memcached_st *original_memc)
4934 {
4935 memcached_st *memc= create_single_instance_memcached(original_memc, 0);
4936 test_true(memc);
4937
4938 memcached_server_instance_st instance= memcached_server_instance_by_position(memc, 0);
4939
4940 pid_t pid;
4941 test_true((pid= libmemcached_util_getpid(memcached_server_name(instance),
4942 memcached_server_port(instance), NULL)) > -1);
4943
4944
4945 test_compare(MEMCACHED_SUCCESS,
4946 memcached_set(memc,
4947 test_literal_param(__func__), // Keys
4948 test_literal_param(__func__), // Values
4949 0, 0));
4950 test_true_got(kill(pid, SIGHUP) == 0, strerror(errno));
4951
4952 test_compare(MEMCACHED_CONNECTION_FAILURE,
4953 memcached_set(memc,
4954 test_literal_param(__func__), // Keys
4955 test_literal_param(__func__), // Values
4956 0, 0));
4957
4958 memcached_free(memc);
4959
4960 return TEST_SUCCESS;
4961 }