9 #include "basic_engine_testsuite.h"
42 while (nfeats-- > 0) {
54 item *test_item = NULL;
56 assert(h1->
allocate(h, NULL, &test_item, key, strlen(key), 1,1,1) == ENGINE_SUCCESS);
57 assert(test_item != NULL);
68 assert(h1->
allocate(h, NULL, &it, key,
69 strlen(key), 1, 1, 0) == ENGINE_SUCCESS);
74 for (
int ii = 0; ii < 10; ++ii) {
76 assert(h1->
store(h, NULL, it, &cas, OPERATION_SET,0) == ENGINE_SUCCESS);
77 assert(cas != prev_cas);
89 assert(h1->
allocate(h, NULL, &it, key,
90 strlen(key), 1, 1, 0) == ENGINE_SUCCESS);
93 for (
int ii = 0; ii < 10; ++ii) {
94 ENGINE_ERROR_CODE
ret = h1->
store(h, NULL, it, &cas, OPERATION_ADD, 0);
96 assert(ret == ENGINE_SUCCESS);
99 assert(ret == ENGINE_NOT_STORED);
112 assert(set_test(h, h1) == SUCCESS);
114 assert(h1->
allocate(h, NULL, &it, key,
115 strlen(key),
sizeof(
int), 1, 0) == ENGINE_SUCCESS);
122 for (
int ii = 0; ii < 10; ++ii) {
124 *(
int*)(item_info.value[0].iov_base) = ii;
125 assert(h1->
store(h, NULL, it, &cas, OPERATION_REPLACE,0) == ENGINE_SUCCESS);
126 assert(cas != prev_cas);
130 assert(h1->
get(h, NULL, &it, key, strlen(key), 0) == ENGINE_SUCCESS);
132 assert(item_info.value[0].iov_len ==
sizeof(
int));
133 assert(*(
int*)(item_info.value[0].iov_base) == 9);
147 assert(h1->
allocate(h, NULL, &it, key,
148 strlen(key), 5, 1, 0) == ENGINE_SUCCESS);
149 item_info item_info = { .nvalue = 1 };
151 memcpy(item_info.value[0].iov_base,
"HELLO", 5);
152 assert(h1->
store(h, NULL, it, &cas, OPERATION_SET, 0) == ENGINE_SUCCESS);
154 assert(h1->
allocate(h, NULL, &it, key,
155 strlen(key), 6, 1, 0) == ENGINE_SUCCESS);
156 item_info.nvalue = 1;
158 memcpy(item_info.value[0].iov_base,
" WORLD", 6);
159 assert(h1->
store(h, NULL, it, &cas, OPERATION_APPEND, 0) == ENGINE_SUCCESS);
162 assert(h1->
get(h, NULL, &it, key, strlen(key), 0) == ENGINE_SUCCESS);
164 assert(item_info.value[0].iov_len == 11);
165 assert(memcmp(item_info.value[0].iov_base,
"HELLO WORLD", 11) == 0);
179 assert(h1->
allocate(h, NULL, &it, key,
180 strlen(key), 5, 1, 0) == ENGINE_SUCCESS);
181 item_info item_info = { .nvalue = 1 };
183 memcpy(item_info.value[0].iov_base,
"HELLO", 5);
184 assert(h1->
store(h, NULL, it, &cas, OPERATION_SET, 0) == ENGINE_SUCCESS);
186 assert(h1->
allocate(h, NULL, &it, key,
187 strlen(key), 6, 1, 0) == ENGINE_SUCCESS);
188 item_info.nvalue = 1;
190 memcpy(item_info.value[0].iov_base,
" WORLD", 6);
191 assert(h1->
store(h, NULL, it, &cas, OPERATION_PREPEND, 0) == ENGINE_SUCCESS);
194 assert(h1->
get(h, NULL, &it, key, strlen(key), 0) == ENGINE_SUCCESS);
196 assert(item_info.value[0].iov_len == 11);
197 assert(memcmp(item_info.value[0].iov_base,
" WORLDHELLO", 11) == 0);
208 item *test_item = NULL;
211 assert(h1->
allocate(h, NULL, &test_item, key, strlen(key), 1,1,1) == ENGINE_SUCCESS);
212 assert(h1->
store(h, NULL, test_item, &cas, OPERATION_SET,0) == ENGINE_SUCCESS);
223 item *test_item = NULL;
224 item *test_item_get = NULL;
225 void *key =
"get_test_key";
227 assert(h1->
allocate(h, NULL, &test_item, key, strlen(key), 1,0, 0) == ENGINE_SUCCESS);
228 assert(h1->
store(h, NULL, test_item, &cas, OPERATION_SET,0) == ENGINE_SUCCESS);
229 assert(h1->
get(h,NULL,&test_item_get,key,strlen(key),0) == ENGINE_SUCCESS);
231 h1->
release(h,NULL,test_item_get);
236 item *test_item = NULL;
237 item *test_item_get = NULL;
238 void *key =
"get_test_key";
240 assert(h1->
allocate(h, NULL, &test_item, key, strlen(key), 1, 0, 10) == ENGINE_SUCCESS);
241 assert(h1->
store(h, NULL, test_item, &cas, OPERATION_SET, 0) == ENGINE_SUCCESS);
243 assert(h1->
get(h,NULL,&test_item_get,key,strlen(key),0) == ENGINE_KEY_ENOENT);
254 item *test_item = NULL;
255 void *key =
"release_test_key";
257 assert(h1->
allocate(h, NULL, &test_item, key, strlen(key), 1, 0, 0) == ENGINE_SUCCESS);
258 assert(h1->
store(h, NULL, test_item, &cas, OPERATION_SET,0) == ENGINE_SUCCESS);
259 h1->
release(h, NULL, test_item);
268 item *test_item = NULL;
269 void *key =
"remove_test_key";
271 assert(h1->
allocate(h, NULL, &test_item, key, strlen(key), 1,0, 0) == ENGINE_SUCCESS);
272 assert(h1->
store(h, NULL, test_item, &cas, OPERATION_SET,0) == ENGINE_SUCCESS);
273 assert(h1->
remove(h, NULL, key, strlen(key), cas, 0) == ENGINE_SUCCESS);
274 item *check_item = test_item;
275 assert(h1->
get(h, NULL, &check_item, key, strlen(key), 0) == ENGINE_KEY_ENOENT);
276 assert(check_item == NULL);
277 h1->
release(h, NULL, test_item);
286 item *test_item = NULL;
287 void *key =
"incr_test_key";
290 assert(h1->
allocate(h, NULL, &test_item, key, strlen(key), 1, 0, 0) == ENGINE_SUCCESS);
291 assert(h1->
arithmetic(h, NULL, key, strlen(key),
true,
true, 0, 1,
292 0, &cas, &res, 0 ) == ENGINE_SUCCESS);
294 assert(h1->
arithmetic(h, NULL, key, strlen(key),
true,
false, 1, 0,
295 0, &cas, &res, 0 ) == ENGINE_SUCCESS);
297 h1->
release(h, NULL, test_item);
301 static void *incr_test_main(
void *arg) {
304 void *key =
"incr_test_key";
308 for (
int ii = 0; ii < 1000; ++ii) {
309 assert(h1->
arithmetic(h, NULL, key, strlen(key),
false,
false, 1, 0,
310 0, &cas, &res, 0 ) == ENGINE_SUCCESS);
324 const int max_threads = 1;
326 const int max_threads = 30;
328 pthread_t tid[max_threads];
330 if (max_threads < 2) {
334 item *test_item = NULL;
335 void *key =
"incr_test_key";
338 assert(h1->
allocate(h, NULL, &test_item, key,
339 strlen(key), 1, 0, 0) == ENGINE_SUCCESS);
340 assert(h1->
arithmetic(h, NULL, key, strlen(key),
true,
true, 0, 1,
341 0, &cas, &res, 0 ) == ENGINE_SUCCESS);
342 h1->
release(h, NULL, test_item);
344 for (
int ii = 0; ii < max_threads; ++ii) {
345 assert(pthread_create(&tid[ii], NULL, incr_test_main, h) == 0);
348 for (
int ii = 0; ii < max_threads; ++ii) {
350 assert(pthread_join(tid[ii], &ret) == 0);
362 item *test_item = NULL;
363 void *key =
"decr_test_key";
366 assert(h1->
allocate(h, NULL, &test_item, key, strlen(key), 1,0, 0) == ENGINE_SUCCESS);
367 assert(h1->
arithmetic(h, NULL, key, strlen(key),
false,
true, 0, 1,
368 0, &cas, &res, 0 ) == ENGINE_SUCCESS);
370 assert(h1->
arithmetic(h, NULL, key, strlen(key),
false,
false, 1, 0,
371 0, &cas, &res, 0 ) == ENGINE_SUCCESS);
373 h1->
release(h, NULL, test_item);
382 item *test_item = NULL;
383 void *key =
"flush_test_key";
386 assert(h1->
allocate(h, NULL, &test_item, key, strlen(key), 1, 0, 0) == ENGINE_SUCCESS);
387 assert(h1->
store(h, NULL, test_item, &cas, OPERATION_SET,0) == ENGINE_SUCCESS);
388 assert(h1->
flush(h, NULL, 0) == ENGINE_SUCCESS);
389 item *check_item = test_item;
390 assert(h1->
get(h, NULL, &check_item, key, strlen(key), 0) == ENGINE_KEY_ENOENT);
391 assert(check_item == NULL);
392 h1->
release(h, NULL, test_item);
401 item *test_item = NULL;
402 char *key =
"get_item_info_test_key";
404 const rel_time_t exp = 1;
405 item_info ii = { .nvalue = 1 };
406 assert(h1->
allocate(h, NULL, &test_item, key, strlen(key), 1,0, exp) == ENGINE_SUCCESS);
407 assert(h1->
store(h, NULL, test_item, &cas, OPERATION_SET,0) == ENGINE_SUCCESS);
410 assert(ii.cas == cas);
411 assert(ii.
flags == 0);
412 assert(strcmp(key,ii.
key) == 0);
413 assert(ii.
nkey == strlen(key));
416 h1->
release(h, NULL, test_item);
421 item *test_item = NULL;
422 char *key =
"item_set_cas_test_key";
424 const rel_time_t exp = 1;
425 item_info ii = { .nvalue = 1 };
426 assert(h1->
allocate(h, NULL, &test_item, key, strlen(key), 1,0, exp) == ENGINE_SUCCESS);
427 assert(h1->
store(h, NULL, test_item, &cas, OPERATION_SET,0) == ENGINE_SUCCESS);
428 uint64_t newcas = cas + 1;
431 assert(ii.cas == newcas);
432 h1->
release(h, NULL, test_item);
437 static void eviction_stats_handler(
const char *key,
const uint16_t klen,
438 const char *val,
const uint32_t vlen,
439 const void *cookie) {
440 if (memcmp(key,
"evictions", klen) == 0) {
441 char buffer[vlen + 1];
442 memcpy(buffer, val, vlen);
444 evictions = atoi(buffer);
449 item *test_item = NULL;
450 const char *hot_key =
"hot_key";
452 assert(h1->
allocate(h, NULL, &test_item,
453 hot_key, strlen(hot_key), 4096, 0, 0) == ENGINE_SUCCESS);
454 assert(h1->
store(h, NULL, test_item,
455 &cas, OPERATION_SET,0) == ENGINE_SUCCESS);
456 h1->
release(h, NULL, test_item);
459 for (ii = 0; ii < 250; ++ii) {
460 assert(h1->
get(h, NULL, &test_item,
461 hot_key, strlen(hot_key), 0) == ENGINE_SUCCESS);
462 h1->
release(h, NULL, test_item);
464 size_t keylen = snprintf(key,
sizeof(key),
"lru_test_key_%08d", ii);
465 assert(h1->
allocate(h, NULL, &test_item,
466 key, keylen, 4096, 0, 0) == ENGINE_SUCCESS);
467 assert(h1->
store(h, NULL, test_item,
468 &cas, OPERATION_SET,0) == ENGINE_SUCCESS);
469 h1->
release(h, NULL, test_item);
471 eviction_stats_handler) == ENGINE_SUCCESS);
472 if (evictions == 2) {
478 for (
int jj = 0; jj <= ii; ++jj) {
480 size_t keylen = snprintf(key,
sizeof(key),
"lru_test_key_%08d", jj);
481 if (jj == 0 || jj == 1) {
482 assert(h1->
get(h, NULL, &test_item,
483 key, keylen, 0) == ENGINE_KEY_ENOENT);
485 assert(h1->
get(h, NULL, &test_item,
486 key, keylen, 0) == ENGINE_SUCCESS);
487 assert(test_item != NULL);
488 h1->
release(h, NULL, test_item);
512 static void release_last_response(
void) {
514 last_response = NULL;
517 static bool response_handler(
const void *key, uint16_t keylen,
518 const void *ext, uint8_t extlen,
519 const void *body, uint32_t bodylen,
520 uint8_t datatype, uint16_t status,
521 uint64_t cas,
const void *cookie)
523 assert(last_response == NULL);
524 last_response = malloc(
sizeof(*last_response) + keylen + extlen + bodylen);
525 if (last_response == NULL) {
529 r->response.magic = PROTOCOL_BINARY_RES;
530 r->response.opcode = 0xff;
531 r->response.keylen = htons(keylen);
532 r->response.extlen = extlen;
533 r->response.datatype = PROTOCOL_BINARY_RAW_BYTES;
534 r->response.status = htons(status);
535 r->response.bodylen = htonl(keylen + extlen + bodylen);
536 r->response.opaque = 0xffffff;
537 r->response.cas = cas;
538 char *ptr = (
void*)(r + 1);
539 memcpy(ptr, ext, extlen);
541 memcpy(ptr, key, keylen);
543 memcpy(ptr, body, bodylen);
554 void *key =
"get_test_key";
555 size_t keylen = strlen(key);
560 .magic = PROTOCOL_BINARY_REQ,
561 .opcode = PROTOCOL_BINARY_CMD_TOUCH,
562 .keylen = htons((uint16_t)keylen),
564 .datatype = PROTOCOL_BINARY_RAW_BYTES,
566 .bodylen = htonl(keylen + 4),
567 .opaque = 0xdeadbeef,
571 .expiration = htonl(10)
577 memcpy(r.buffer +
sizeof(r.touch.bytes), key, keylen);
578 ENGINE_ERROR_CODE
ret;
579 ret = h1->
unknown_command(h, NULL, &r.touch.message.header, response_handler);
580 assert(ret == ENGINE_SUCCESS);
581 assert(last_response != NULL);
582 assert(ntohs(last_response->response.status) == PROTOCOL_BINARY_RESPONSE_KEY_ENOENT);
583 assert(last_response->response.keylen == 0);
584 assert(last_response->response.extlen == 0);
585 assert(last_response->response.bodylen == 0);
586 release_last_response();
589 assert(get_test(h, h1) == SUCCESS);
592 ret = h1->
unknown_command(h, NULL, &r.touch.message.header, response_handler);
593 assert(ret == ENGINE_SUCCESS);
594 assert(last_response != NULL);
595 assert(ntohs(last_response->response.status) == PROTOCOL_BINARY_RESPONSE_SUCCESS);
596 assert(last_response->response.keylen == 0);
597 assert(last_response->response.extlen == 0);
598 assert(last_response->response.bodylen == 0);
599 release_last_response();
606 assert(h1->
get(h, NULL, &item, key, keylen, 0) == ENGINE_KEY_ENOENT);
609 r.touch.message.header.request.extlen = 0;
610 r.touch.message.header.request.bodylen = htonl(keylen);
611 ret = h1->
unknown_command(h, NULL, &r.touch.message.header, response_handler);
612 assert(ret == ENGINE_SUCCESS);
613 assert(last_response != NULL);
614 assert(ntohs(last_response->response.status) == PROTOCOL_BINARY_RESPONSE_EINVAL);
615 release_last_response();
618 r.touch.message.header.request.extlen = 4;
619 r.touch.message.header.request.keylen = 0;
620 r.touch.message.header.request.bodylen = htonl(4);
621 ret = h1->
unknown_command(h, NULL, &r.touch.message.header, response_handler);
622 assert(ret == ENGINE_SUCCESS);
623 assert(last_response != NULL);
624 assert(ntohs(last_response->response.status) == PROTOCOL_BINARY_RESPONSE_EINVAL);
625 release_last_response();
636 void *key =
"get_test_key";
637 size_t keylen = strlen(key);
642 .magic = PROTOCOL_BINARY_REQ,
643 .opcode = PROTOCOL_BINARY_CMD_GAT,
644 .keylen = htons((uint16_t)keylen),
646 .datatype = PROTOCOL_BINARY_RAW_BYTES,
648 .bodylen = htonl(keylen + 4),
649 .opaque = 0xdeadbeef,
653 .expiration = htonl(10)
659 memcpy(r.buffer +
sizeof(r.gat.bytes), key, keylen);
660 ENGINE_ERROR_CODE
ret;
661 ret = h1->
unknown_command(h, NULL, &r.gat.message.header, response_handler);
662 assert(ret == ENGINE_SUCCESS);
663 assert(last_response != NULL);
664 assert(ntohs(last_response->response.status) == PROTOCOL_BINARY_RESPONSE_KEY_ENOENT);
665 assert(last_response->response.keylen == 0);
666 assert(last_response->response.extlen == 0);
667 assert(last_response->response.bodylen == 0);
668 release_last_response();
671 assert(get_test(h, h1) == SUCCESS);
674 ret = h1->
unknown_command(h, NULL, &r.gat.message.header, response_handler);
675 assert(ret == ENGINE_SUCCESS);
676 assert(last_response != NULL);
677 assert(ntohs(last_response->response.status) == PROTOCOL_BINARY_RESPONSE_SUCCESS);
678 assert(last_response->response.keylen == 0);
679 assert(last_response->response.extlen == 4);
680 assert(ntohl(last_response->response.bodylen) == 5);
681 release_last_response();
688 assert(h1->
get(h, NULL, &item, key, keylen, 0) == ENGINE_KEY_ENOENT);
691 r.gat.message.header.request.extlen = 0;
692 r.gat.message.header.request.bodylen = htonl(keylen);
693 ret = h1->
unknown_command(h, NULL, &r.gat.message.header, response_handler);
694 assert(ret == ENGINE_SUCCESS);
695 assert(last_response != NULL);
696 assert(ntohs(last_response->response.status) == PROTOCOL_BINARY_RESPONSE_EINVAL);
697 release_last_response();
700 r.gat.message.header.request.extlen = 4;
701 r.gat.message.header.request.keylen = 0;
702 r.gat.message.header.request.bodylen = htonl(4);
703 ret = h1->
unknown_command(h, NULL, &r.gat.message.header, response_handler);
704 assert(ret == ENGINE_SUCCESS);
705 assert(last_response != NULL);
706 assert(ntohs(last_response->response.status) == PROTOCOL_BINARY_RESPONSE_EINVAL);
707 release_last_response();
718 void *key =
"get_test_key";
719 size_t keylen = strlen(key);
724 .magic = PROTOCOL_BINARY_REQ,
725 .opcode = PROTOCOL_BINARY_CMD_GATQ,
726 .keylen = htons((uint16_t)keylen),
728 .datatype = PROTOCOL_BINARY_RAW_BYTES,
730 .bodylen = htonl(keylen + 4),
731 .opaque = 0xdeadbeef,
735 .expiration = htonl(10)
741 memcpy(r.buffer +
sizeof(r.gat.bytes), key, keylen);
742 ENGINE_ERROR_CODE
ret;
743 ret = h1->
unknown_command(h, NULL, &r.gat.message.header, response_handler);
744 assert(ret == ENGINE_SUCCESS);
747 assert(last_response == NULL);
750 assert(get_test(h, h1) == SUCCESS);
753 ret = h1->
unknown_command(h, NULL, &r.gat.message.header, response_handler);
754 assert(ret == ENGINE_SUCCESS);
755 assert(last_response != NULL);
756 assert(ntohs(last_response->response.status) == PROTOCOL_BINARY_RESPONSE_SUCCESS);
757 assert(last_response->response.keylen == 0);
758 assert(last_response->response.extlen == 4);
759 assert(ntohl(last_response->response.bodylen) == 5);
760 release_last_response();
767 assert(h1->
get(h, NULL, &item, key, keylen, 0) == ENGINE_KEY_ENOENT);
770 r.gat.message.header.request.extlen = 0;
771 r.gat.message.header.request.bodylen = htonl(keylen);
772 ret = h1->
unknown_command(h, NULL, &r.gat.message.header, response_handler);
773 assert(ret == ENGINE_SUCCESS);
774 assert(last_response != NULL);
775 assert(ntohs(last_response->response.status) == PROTOCOL_BINARY_RESPONSE_EINVAL);
776 release_last_response();
779 r.gat.message.header.request.extlen = 4;
780 r.gat.message.header.request.keylen = 0;
781 r.gat.message.header.request.bodylen = htonl(4);
782 ret = h1->
unknown_command(h, NULL, &r.gat.message.header, response_handler);
783 assert(ret == ENGINE_SUCCESS);
784 assert(last_response != NULL);
785 assert(ntohs(last_response->response.status) == PROTOCOL_BINARY_RESPONSE_EINVAL);
786 release_last_response();
794 {
"get info test", get_info_test, NULL, NULL, NULL},
795 {
"get info description test", get_info_description_test, NULL, NULL, NULL},
796 {
"get info features test", get_info_features_test, NULL, NULL, NULL},
797 {
"allocate test", allocate_test, NULL, NULL, NULL},
798 {
"set test", set_test, NULL, NULL, NULL},
799 {
"add test", add_test, NULL, NULL, NULL},
800 {
"replace test", replace_test, NULL, NULL, NULL},
801 {
"append test", append_test, NULL, NULL, NULL},
802 {
"prepend test", prepend_test, NULL, NULL, NULL},
803 {
"store test", store_test, NULL, NULL, NULL},
804 {
"get test", get_test, NULL, NULL, NULL},
805 {
"expiry test", expiry_test, NULL, NULL, NULL},
806 {
"remove test", remove_test, NULL, NULL, NULL},
807 {
"release test", release_test, NULL, NULL, NULL},
808 {
"incr test", incr_test, NULL, NULL, NULL},
809 {
"mt incr test", mt_incr_test, NULL, NULL, NULL},
810 {
"decr test", decr_test, NULL, NULL, NULL},
811 {
"flush test", flush_test, NULL, NULL, NULL},
812 {
"get item info test", get_item_info_test, NULL, NULL, NULL},
813 {
"set cas test", item_set_cas_test, NULL, NULL, NULL},
814 {
"LRU test", lru_test, NULL, NULL,
"cache_size=48"},
815 {
"get stats test", get_stats_test, NULL, NULL, NULL},
816 {
"reset stats test", reset_stats_test, NULL, NULL, NULL},
817 {
"get stats struct test", get_stats_struct_test, NULL, NULL, NULL},
818 {
"aggregate stats test", aggregate_stats_test, NULL, NULL, NULL},
819 {
"touch", touch_test, NULL, NULL, NULL},
820 {
"Get And Touch", gat_test, NULL, NULL, NULL},
821 {
"Get And Touch Quiet", gatq_test, NULL, NULL, NULL},
822 {NULL, NULL, NULL, NULL, NULL}