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