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