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