Migrate kvstore.c unit tests to new test framework. (#446)
This PR migrates all tests related to kvstore into new test framework as part of the parent issue https://github.com/valkey-io/valkey/issues/428. --------- Signed-off-by: Karthick Ariyaratnam <karthyuom@gmail.com> Signed-off-by: Madelyn Olson <madelyneolson@gmail.com> Co-authored-by: Madelyn Olson <madelyneolson@gmail.com>
This commit is contained in:
parent
1aca85e3de
commit
4e944cedee
147
src/kvstore.c
147
src/kvstore.c
@ -865,150 +865,3 @@ int kvstoreDictDelete(kvstore *kvs, int didx, const void *key) {
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef SERVER_TEST
|
||||
#include <stdio.h>
|
||||
#include "testhelp.h"
|
||||
|
||||
#define TEST(name) printf("test — %s\n", name);
|
||||
|
||||
uint64_t hashTestCallback(const void *key) {
|
||||
return dictGenHashFunction((unsigned char*)key, strlen((char*)key));
|
||||
}
|
||||
|
||||
void freeTestCallback(dict *d, void *val) {
|
||||
UNUSED(d);
|
||||
zfree(val);
|
||||
}
|
||||
|
||||
dictType KvstoreDictTestType = {
|
||||
hashTestCallback,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
freeTestCallback,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
char *stringFromInt(int value) {
|
||||
char buf[32];
|
||||
int len;
|
||||
char *s;
|
||||
|
||||
len = snprintf(buf, sizeof(buf), "%d",value);
|
||||
s = zmalloc(len+1);
|
||||
memcpy(s, buf, len);
|
||||
s[len] = '\0';
|
||||
return s;
|
||||
}
|
||||
|
||||
/* ./valkey-server test kvstore */
|
||||
int kvstoreTest(int argc, char **argv, int flags) {
|
||||
UNUSED(argc);
|
||||
UNUSED(argv);
|
||||
UNUSED(flags);
|
||||
|
||||
int i;
|
||||
void *key;
|
||||
dictEntry *de;
|
||||
kvstoreIterator *kvs_it;
|
||||
kvstoreDictIterator *kvs_di;
|
||||
|
||||
int didx = 0;
|
||||
int curr_slot = 0;
|
||||
kvstore *kvs1 = kvstoreCreate(&KvstoreDictTestType, 0, KVSTORE_ALLOCATE_DICTS_ON_DEMAND);
|
||||
kvstore *kvs2 = kvstoreCreate(&KvstoreDictTestType, 0, KVSTORE_ALLOCATE_DICTS_ON_DEMAND | KVSTORE_FREE_EMPTY_DICTS);
|
||||
|
||||
TEST("Add 16 keys") {
|
||||
for (i = 0; i < 16; i++) {
|
||||
de = kvstoreDictAddRaw(kvs1, didx, stringFromInt(i), NULL);
|
||||
assert(de != NULL);
|
||||
de = kvstoreDictAddRaw(kvs2, didx, stringFromInt(i), NULL);
|
||||
assert(de != NULL);
|
||||
}
|
||||
assert(kvstoreDictSize(kvs1, didx) == 16);
|
||||
assert(kvstoreSize(kvs1) == 16);
|
||||
assert(kvstoreDictSize(kvs2, didx) == 16);
|
||||
assert(kvstoreSize(kvs2) == 16);
|
||||
}
|
||||
|
||||
TEST("kvstoreIterator case 1: removing all keys does not delete the empty dict") {
|
||||
kvs_it = kvstoreIteratorInit(kvs1);
|
||||
while((de = kvstoreIteratorNext(kvs_it)) != NULL) {
|
||||
curr_slot = kvstoreIteratorGetCurrentDictIndex(kvs_it);
|
||||
key = dictGetKey(de);
|
||||
assert(kvstoreDictDelete(kvs1, curr_slot, key) == DICT_OK);
|
||||
}
|
||||
kvstoreIteratorRelease(kvs_it);
|
||||
|
||||
dict *d = kvstoreGetDict(kvs1, didx);
|
||||
assert(d != NULL);
|
||||
assert(kvstoreDictSize(kvs1, didx) == 0);
|
||||
assert(kvstoreSize(kvs1) == 0);
|
||||
}
|
||||
|
||||
TEST("kvstoreIterator case 2: removing all keys will delete the empty dict") {
|
||||
kvs_it = kvstoreIteratorInit(kvs2);
|
||||
while((de = kvstoreIteratorNext(kvs_it)) != NULL) {
|
||||
curr_slot = kvstoreIteratorGetCurrentDictIndex(kvs_it);
|
||||
key = dictGetKey(de);
|
||||
assert(kvstoreDictDelete(kvs2, curr_slot, key) == DICT_OK);
|
||||
}
|
||||
kvstoreIteratorRelease(kvs_it);
|
||||
|
||||
/* Make sure the dict was removed from the rehashing list. */
|
||||
while (kvstoreIncrementallyRehash(kvs2, 1000)) {}
|
||||
|
||||
dict *d = kvstoreGetDict(kvs2, didx);
|
||||
assert(d == NULL);
|
||||
assert(kvstoreDictSize(kvs2, didx) == 0);
|
||||
assert(kvstoreSize(kvs2) == 0);
|
||||
}
|
||||
|
||||
TEST("Add 16 keys again") {
|
||||
for (i = 0; i < 16; i++) {
|
||||
de = kvstoreDictAddRaw(kvs1, didx, stringFromInt(i), NULL);
|
||||
assert(de != NULL);
|
||||
de = kvstoreDictAddRaw(kvs2, didx, stringFromInt(i), NULL);
|
||||
assert(de != NULL);
|
||||
}
|
||||
assert(kvstoreDictSize(kvs1, didx) == 16);
|
||||
assert(kvstoreSize(kvs1) == 16);
|
||||
assert(kvstoreDictSize(kvs2, didx) == 16);
|
||||
assert(kvstoreSize(kvs2) == 16);
|
||||
}
|
||||
|
||||
TEST("kvstoreDictIterator case 1: removing all keys does not delete the empty dict") {
|
||||
kvs_di = kvstoreGetDictSafeIterator(kvs1, didx);
|
||||
while((de = kvstoreDictIteratorNext(kvs_di)) != NULL) {
|
||||
key = dictGetKey(de);
|
||||
assert(kvstoreDictDelete(kvs1, didx, key) == DICT_OK);
|
||||
}
|
||||
kvstoreReleaseDictIterator(kvs_di);
|
||||
|
||||
dict *d = kvstoreGetDict(kvs1, didx);
|
||||
assert(d != NULL);
|
||||
assert(kvstoreDictSize(kvs1, didx) == 0);
|
||||
assert(kvstoreSize(kvs1) == 0);
|
||||
}
|
||||
|
||||
TEST("kvstoreDictIterator case 2: removing all keys will delete the empty dict") {
|
||||
kvs_di = kvstoreGetDictSafeIterator(kvs2, didx);
|
||||
while((de = kvstoreDictIteratorNext(kvs_di)) != NULL) {
|
||||
key = dictGetKey(de);
|
||||
assert(kvstoreDictDelete(kvs2, didx, key) == DICT_OK);
|
||||
}
|
||||
kvstoreReleaseDictIterator(kvs_di);
|
||||
|
||||
dict *d = kvstoreGetDict(kvs2, didx);
|
||||
assert(d == NULL);
|
||||
assert(kvstoreDictSize(kvs2, didx) == 0);
|
||||
assert(kvstoreSize(kvs2) == 0);
|
||||
}
|
||||
|
||||
kvstoreRelease(kvs1);
|
||||
kvstoreRelease(kvs2);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
@ -72,8 +72,4 @@ dictEntry *kvstoreDictTwoPhaseUnlinkFind(kvstore *kvs, int didx, const void *key
|
||||
void kvstoreDictTwoPhaseUnlinkFree(kvstore *kvs, int didx, dictEntry *he, dictEntry **plink, int table_index);
|
||||
int kvstoreDictDelete(kvstore *kvs, int didx, const void *key);
|
||||
|
||||
#ifdef SERVER_TEST
|
||||
int kvstoreTest(int argc, char *argv[], int flags);
|
||||
#endif
|
||||
|
||||
#endif /* DICTARRAY_H_ */
|
||||
|
@ -6911,7 +6911,6 @@ struct serverTest {
|
||||
{"sds", sdsTest},
|
||||
{"dict", dictTest},
|
||||
{"listpack", listpackTest},
|
||||
{"kvstore", kvstoreTest},
|
||||
};
|
||||
serverTestProc *getTestProcByName(const char *name) {
|
||||
int numtests = sizeof(serverTests)/sizeof(struct serverTest);
|
||||
|
@ -16,6 +16,11 @@ int test_intsetUpgradeFromint16Toint64(int argc, char **argv, int flags);
|
||||
int test_intsetUpgradeFromint32Toint64(int argc, char **argv, int flags);
|
||||
int test_intsetStressLookups(int argc, char **argv, int flags);
|
||||
int test_intsetStressAddDelete(int argc, char **argv, int flags);
|
||||
int test_kvstoreAdd16Keys(int argc, char **argv, int flags);
|
||||
int test_kvstoreIteratorRemoveAllKeysNoDeleteEmptyDict(int argc, char **argv, int flags);
|
||||
int test_kvstoreIteratorRemoveAllKeysDeleteEmptyDict(int argc, char **argv, int flags);
|
||||
int test_kvstoreDictIteratorRemoveAllKeysNoDeleteEmptyDict(int argc, char **argv, int flags);
|
||||
int test_kvstoreDictIteratorRemoveAllKeysDeleteEmptyDict(int argc, char **argv, int flags);
|
||||
int test_string2ll(int argc, char **argv, int flags);
|
||||
int test_string2l(int argc, char **argv, int flags);
|
||||
int test_ll2string(int argc, char **argv, int flags);
|
||||
@ -26,6 +31,7 @@ int test_reclaimFilePageCache(int argc, char **argv, int flags);
|
||||
unitTest __test_crc64_c[] = {{"test_crc64", test_crc64}, {NULL, NULL}};
|
||||
unitTest __test_crc64combine_c[] = {{"test_crc64combine", test_crc64combine}, {NULL, NULL}};
|
||||
unitTest __test_intset_c[] = {{"test_intsetValueEncodings", test_intsetValueEncodings}, {"test_intsetBasicAdding", test_intsetBasicAdding}, {"test_intsetLargeNumberRandomAdd", test_intsetLargeNumberRandomAdd}, {"test_intsetUpgradeFromint16Toint32", test_intsetUpgradeFromint16Toint32}, {"test_intsetUpgradeFromint16Toint64", test_intsetUpgradeFromint16Toint64}, {"test_intsetUpgradeFromint32Toint64", test_intsetUpgradeFromint32Toint64}, {"test_intsetStressLookups", test_intsetStressLookups}, {"test_intsetStressAddDelete", test_intsetStressAddDelete}, {NULL, NULL}};
|
||||
unitTest __test_kvstore_c[] = {{"test_kvstoreAdd16Keys", test_kvstoreAdd16Keys}, {"test_kvstoreIteratorRemoveAllKeysNoDeleteEmptyDict", test_kvstoreIteratorRemoveAllKeysNoDeleteEmptyDict}, {"test_kvstoreIteratorRemoveAllKeysDeleteEmptyDict", test_kvstoreIteratorRemoveAllKeysDeleteEmptyDict}, {"test_kvstoreDictIteratorRemoveAllKeysNoDeleteEmptyDict", test_kvstoreDictIteratorRemoveAllKeysNoDeleteEmptyDict}, {"test_kvstoreDictIteratorRemoveAllKeysDeleteEmptyDict", test_kvstoreDictIteratorRemoveAllKeysDeleteEmptyDict}, {NULL, NULL}};
|
||||
unitTest __test_util_c[] = {{"test_string2ll", test_string2ll}, {"test_string2l", test_string2l}, {"test_ll2string", test_ll2string}, {"test_ld2string", test_ld2string}, {"test_fixedpoint_d2string", test_fixedpoint_d2string}, {"test_reclaimFilePageCache", test_reclaimFilePageCache}, {NULL, NULL}};
|
||||
|
||||
struct unitTestSuite {
|
||||
@ -35,5 +41,6 @@ struct unitTestSuite {
|
||||
{"test_crc64.c", __test_crc64_c},
|
||||
{"test_crc64combine.c", __test_crc64combine_c},
|
||||
{"test_intset.c", __test_intset_c},
|
||||
{"test_kvstore.c", __test_kvstore_c},
|
||||
{"test_util.c", __test_util_c},
|
||||
};
|
||||
|
205
src/unit/test_kvstore.c
Normal file
205
src/unit/test_kvstore.c
Normal file
@ -0,0 +1,205 @@
|
||||
#include "../kvstore.c"
|
||||
#undef UNUSED
|
||||
#include "test_help.h"
|
||||
|
||||
uint64_t hashTestCallback(const void *key) {
|
||||
return dictGenHashFunction((unsigned char*)key, strlen((char*)key));
|
||||
}
|
||||
|
||||
void freeTestCallback(dict *d, void *val) {
|
||||
UNUSED(d);
|
||||
zfree(val);
|
||||
}
|
||||
|
||||
dictType KvstoreDictTestType = {
|
||||
hashTestCallback,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
freeTestCallback,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
char *stringFromInt(int value) {
|
||||
char buf[32];
|
||||
int len;
|
||||
char *s;
|
||||
|
||||
len = snprintf(buf, sizeof(buf), "%d",value);
|
||||
s = zmalloc(len+1);
|
||||
memcpy(s, buf, len);
|
||||
s[len] = '\0';
|
||||
return s;
|
||||
}
|
||||
|
||||
int test_kvstoreAdd16Keys(int argc, char **argv, int flags) {
|
||||
UNUSED(argc);
|
||||
UNUSED(argv);
|
||||
UNUSED(flags);
|
||||
|
||||
int i;
|
||||
dictEntry *de;
|
||||
|
||||
int didx = 0;
|
||||
kvstore *kvs1 = kvstoreCreate(&KvstoreDictTestType, 0, KVSTORE_ALLOCATE_DICTS_ON_DEMAND);
|
||||
kvstore *kvs2 = kvstoreCreate(&KvstoreDictTestType, 0, KVSTORE_ALLOCATE_DICTS_ON_DEMAND | KVSTORE_FREE_EMPTY_DICTS);
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
de = kvstoreDictAddRaw(kvs1, didx, stringFromInt(i), NULL);
|
||||
TEST_ASSERT(de != NULL);
|
||||
de = kvstoreDictAddRaw(kvs2, didx, stringFromInt(i), NULL);
|
||||
TEST_ASSERT(de != NULL);
|
||||
}
|
||||
TEST_ASSERT(kvstoreDictSize(kvs1, didx) == 16);
|
||||
TEST_ASSERT(kvstoreSize(kvs1) == 16);
|
||||
TEST_ASSERT(kvstoreDictSize(kvs2, didx) == 16);
|
||||
TEST_ASSERT(kvstoreSize(kvs2) == 16);
|
||||
|
||||
kvstoreRelease(kvs1);
|
||||
kvstoreRelease(kvs2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_kvstoreIteratorRemoveAllKeysNoDeleteEmptyDict(int argc, char **argv, int flags) {
|
||||
UNUSED(argc);
|
||||
UNUSED(argv);
|
||||
UNUSED(flags);
|
||||
|
||||
int i;
|
||||
void *key;
|
||||
dictEntry *de;
|
||||
kvstoreIterator *kvs_it;
|
||||
|
||||
int didx = 0;
|
||||
int curr_slot = 0;
|
||||
kvstore *kvs1 = kvstoreCreate(&KvstoreDictTestType, 0, KVSTORE_ALLOCATE_DICTS_ON_DEMAND);
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
de = kvstoreDictAddRaw(kvs1, didx, stringFromInt(i), NULL);
|
||||
TEST_ASSERT(de != NULL);
|
||||
}
|
||||
|
||||
kvs_it = kvstoreIteratorInit(kvs1);
|
||||
while((de = kvstoreIteratorNext(kvs_it)) != NULL) {
|
||||
curr_slot = kvstoreIteratorGetCurrentDictIndex(kvs_it);
|
||||
key = dictGetKey(de);
|
||||
TEST_ASSERT(kvstoreDictDelete(kvs1, curr_slot, key) == DICT_OK);
|
||||
}
|
||||
kvstoreIteratorRelease(kvs_it);
|
||||
|
||||
dict *d = kvstoreGetDict(kvs1, didx);
|
||||
TEST_ASSERT(d != NULL);
|
||||
TEST_ASSERT(kvstoreDictSize(kvs1, didx) == 0);
|
||||
TEST_ASSERT(kvstoreSize(kvs1) == 0);
|
||||
|
||||
kvstoreRelease(kvs1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_kvstoreIteratorRemoveAllKeysDeleteEmptyDict(int argc, char **argv, int flags) {
|
||||
UNUSED(argc);
|
||||
UNUSED(argv);
|
||||
UNUSED(flags);
|
||||
|
||||
int i;
|
||||
void *key;
|
||||
dictEntry *de;
|
||||
kvstoreIterator *kvs_it;
|
||||
|
||||
int didx = 0;
|
||||
int curr_slot = 0;
|
||||
kvstore *kvs2 = kvstoreCreate(&KvstoreDictTestType, 0, KVSTORE_ALLOCATE_DICTS_ON_DEMAND | KVSTORE_FREE_EMPTY_DICTS);
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
de = kvstoreDictAddRaw(kvs2, didx, stringFromInt(i), NULL);
|
||||
TEST_ASSERT(de != NULL);
|
||||
}
|
||||
|
||||
kvs_it = kvstoreIteratorInit(kvs2);
|
||||
while((de = kvstoreIteratorNext(kvs_it)) != NULL) {
|
||||
curr_slot = kvstoreIteratorGetCurrentDictIndex(kvs_it);
|
||||
key = dictGetKey(de);
|
||||
TEST_ASSERT(kvstoreDictDelete(kvs2, curr_slot, key) == DICT_OK);
|
||||
}
|
||||
kvstoreIteratorRelease(kvs_it);
|
||||
|
||||
/* Make sure the dict was removed from the rehashing list. */
|
||||
while (kvstoreIncrementallyRehash(kvs2, 1000)) {}
|
||||
|
||||
dict *d = kvstoreGetDict(kvs2, didx);
|
||||
TEST_ASSERT(d == NULL);
|
||||
TEST_ASSERT(kvstoreDictSize(kvs2, didx) == 0);
|
||||
TEST_ASSERT(kvstoreSize(kvs2) == 0);
|
||||
|
||||
kvstoreRelease(kvs2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_kvstoreDictIteratorRemoveAllKeysNoDeleteEmptyDict(int argc, char **argv, int flags) {
|
||||
UNUSED(argc);
|
||||
UNUSED(argv);
|
||||
UNUSED(flags);
|
||||
|
||||
int i;
|
||||
void *key;
|
||||
dictEntry *de;
|
||||
kvstoreDictIterator *kvs_di;
|
||||
|
||||
int didx = 0;
|
||||
kvstore *kvs1 = kvstoreCreate(&KvstoreDictTestType, 0, KVSTORE_ALLOCATE_DICTS_ON_DEMAND);
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
de = kvstoreDictAddRaw(kvs1, didx, stringFromInt(i), NULL);
|
||||
TEST_ASSERT(de != NULL);
|
||||
}
|
||||
|
||||
kvs_di = kvstoreGetDictSafeIterator(kvs1, didx);
|
||||
while((de = kvstoreDictIteratorNext(kvs_di)) != NULL) {
|
||||
key = dictGetKey(de);
|
||||
TEST_ASSERT(kvstoreDictDelete(kvs1, didx, key) == DICT_OK);
|
||||
}
|
||||
kvstoreReleaseDictIterator(kvs_di);
|
||||
|
||||
dict *d = kvstoreGetDict(kvs1, didx);
|
||||
TEST_ASSERT(d != NULL);
|
||||
TEST_ASSERT(kvstoreDictSize(kvs1, didx) == 0);
|
||||
TEST_ASSERT(kvstoreSize(kvs1) == 0);
|
||||
|
||||
kvstoreRelease(kvs1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_kvstoreDictIteratorRemoveAllKeysDeleteEmptyDict(int argc, char **argv, int flags) {
|
||||
UNUSED(argc);
|
||||
UNUSED(argv);
|
||||
UNUSED(flags);
|
||||
|
||||
int i;
|
||||
void *key;
|
||||
dictEntry *de;
|
||||
kvstoreDictIterator *kvs_di;
|
||||
|
||||
int didx = 0;
|
||||
kvstore *kvs2 = kvstoreCreate(&KvstoreDictTestType, 0, KVSTORE_ALLOCATE_DICTS_ON_DEMAND | KVSTORE_FREE_EMPTY_DICTS);
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
de = kvstoreDictAddRaw(kvs2, didx, stringFromInt(i), NULL);
|
||||
TEST_ASSERT(de != NULL);
|
||||
}
|
||||
|
||||
kvs_di = kvstoreGetDictSafeIterator(kvs2, didx);
|
||||
while((de = kvstoreDictIteratorNext(kvs_di)) != NULL) {
|
||||
key = dictGetKey(de);
|
||||
TEST_ASSERT(kvstoreDictDelete(kvs2, didx, key) == DICT_OK);
|
||||
}
|
||||
kvstoreReleaseDictIterator(kvs_di);
|
||||
|
||||
dict *d = kvstoreGetDict(kvs2, didx);
|
||||
TEST_ASSERT(d == NULL);
|
||||
TEST_ASSERT(kvstoreDictSize(kvs2, didx) == 0);
|
||||
TEST_ASSERT(kvstoreSize(kvs2) == 0);
|
||||
|
||||
kvstoreRelease(kvs2);
|
||||
return 0;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user