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