[kvdb][testcase] improve the kvdb testcase for GC

This commit is contained in:
朱天龙 (Armink) 2023-04-29 23:52:00 +08:00
parent 63fe2961c4
commit aa3a194527

View File

@ -20,39 +20,46 @@
#define TEST_TS_PART_NAME "fdb_kvdb1"
#define TEST_KV_BLOB_NAME "kv_blob_test"
#define TEST_KV_NAME "kv_test"
#define TEST_KV_VALUE_LEN 1300 /* only save 3 KVs in a 4096 sector */
#define TEST_KV_NUM 4
#define TEST_KVDB_SECTOR_SIZE 4096
#if defined(RT_USING_UTEST) && defined(FDB_USING_KVDB)
static struct fdb_default_kv_node default_kv_set[] = {
{"iap_need_copy_app", "0"},
{"iap_need_crc32_check", "0"},
{"iap_copy_app_size", "0"},
{"stop_in_bootloader", "0"},
struct test_kv{
char name[32];
uint8_t value[TEST_KV_VALUE_LEN];
uint32_t addr;
uint32_t saved_data_size;
bool is_changed;
};
static struct fdb_kvdb test_kvdb;
static void test_fdb_kvdb_init(void)
{
if (access("/fdb_kvdb1", 0) < 0)
if (access(TEST_TS_PART_NAME, 0) < 0)
{
mkdir("/fdb_kvdb1", 0);
mkdir(TEST_TS_PART_NAME, 0);
}
struct fdb_default_kv default_kv;
#ifndef FDB_USING_FAL_MODE
uint32_t sec_size = 4096, db_size = sec_size * 16;
uint32_t sec_size = TEST_KVDB_SECTOR_SIZE, db_size = sec_size * 4;
rt_bool_t file_mode = true;
#endif
default_kv.kvs = default_kv_set;
default_kv.num = sizeof(default_kv_set) / sizeof(default_kv_set[0]);
#endif
#ifndef FDB_USING_FAL_MODE
fdb_kvdb_control(&(test_kvdb), FDB_KVDB_CTRL_SET_SEC_SIZE, &sec_size);
fdb_kvdb_control(&(test_kvdb), FDB_KVDB_CTRL_SET_FILE_MODE, &file_mode);
fdb_kvdb_control(&(test_kvdb), FDB_KVDB_CTRL_SET_MAX_SIZE, &db_size);
#endif
uassert_true(fdb_kvdb_init(&test_kvdb, "test_kv", "fdb_kvdb1", &default_kv, NULL) == FDB_NO_ERR);
#endif
uassert_true(fdb_kvdb_init(&test_kvdb, "test_kv", TEST_TS_PART_NAME, NULL, NULL) == FDB_NO_ERR);
}
static void test_fdb_kvdb_init_check(void)
{
/* check the oldest address */
uassert_true(RT_ALIGN_DOWN(test_kvdb.parent.oldest_addr, TEST_KVDB_SECTOR_SIZE) == TEST_KVDB_SECTOR_SIZE * 0);
}
static void test_fdb_create_kv_blob(void)
@ -174,6 +181,332 @@ static void test_fdb_del_kv(void)
read_value = fdb_kv_get(&test_kvdb, TEST_KV_NAME);
uassert_null(read_value);
{
/* check the oldest address is already right when kvdb reinit */
extern void test_fdb_kvdb_deinit(void);
test_fdb_kvdb_deinit();
test_fdb_kvdb_init();
uassert_true(RT_ALIGN_DOWN(test_kvdb.parent.oldest_addr, TEST_KVDB_SECTOR_SIZE) == TEST_KVDB_SECTOR_SIZE * 0);
}
}
static int iter_all_kv(fdb_kvdb_t db, struct test_kv *kv_tbl)
{
struct fdb_kv_iterator iterator;
fdb_kv_t cur_kv;
size_t data_size = 0;
int index = 0;
struct fdb_blob fdb_blob;
fdb_kv_iterator_init(db, &iterator);
while (fdb_kv_iterate(db, &iterator) == RT_TRUE)
{
/* get data len */
cur_kv = &(iterator.curr_kv);
data_size = (size_t)cur_kv->value_len;
rt_strncpy(kv_tbl[index].name, cur_kv->name, 32);
kv_tbl[index].saved_data_size = data_size;
kv_tbl[index].addr = cur_kv->addr.start;
/* read data */
fdb_blob_read((fdb_db_t)db, fdb_kv_to_blob(cur_kv, fdb_blob_make(&fdb_blob, &kv_tbl[index].value, data_size)));
uassert_true(kv_tbl[index].saved_data_size <= TEST_KV_VALUE_LEN);
index++;
}
uassert_true(index == TEST_KV_NUM);
return index;
}
static void test_fdb_by_kvs(struct test_kv *kv_tbl, size_t len)
{
struct fdb_blob blob_obj, * blob = &blob_obj;
static struct test_kv saved_kv_tbl[TEST_KV_NUM] = { 0 };
for (int i = 0; i < len; i++)
{
if (kv_tbl[i].is_changed)
{
fdb_kv_set_blob(&test_kvdb, kv_tbl[i].name, fdb_blob_make(blob, kv_tbl[i].value, TEST_KV_VALUE_LEN));
}
}
iter_all_kv(&test_kvdb, saved_kv_tbl);
for (int i = 0; i < len; i++)
{
uassert_str_equal(saved_kv_tbl[i].name, kv_tbl[i].name);
uassert_str_equal(saved_kv_tbl[i].value, kv_tbl[i].value);
uassert_true(RT_ALIGN_DOWN(saved_kv_tbl[i].addr, TEST_KVDB_SECTOR_SIZE) == TEST_KVDB_SECTOR_SIZE * kv_tbl[i].addr);
}
}
static void test_fdb_gc(void)
{
fdb_kv_set_default(&test_kvdb);
{
/*
* prepare1: add 4 KVs
*
* +---------------------------------------------------------+
* | sector0 | sector1 | sector2 | sector3 |
* | using | using | empty | empty |
* +---------------------------------------------------------+
* | | | | |
* | kv0 | kv3 | | |
* | new | new | | |
* +----------------------------+ | |
* | | | | |
* | kv1 | | | |
* | new | | | |
* +--------------+ | | |
* | | | | |
* | kv2 | | | |
* | new | | | |
* +--------------+ | | |
* | | | | |
* +---------------------------------------------------------+
*/
struct test_kv kv_tbl[TEST_KV_NUM] = {
{"kv0", "0", 0, 0, 1},
{"kv1", "1", 0, 0, 1},
{"kv2", "2", 0, 0, 1},
{"kv3", "3", 1, 0, 1},
};
test_fdb_by_kvs(kv_tbl, sizeof(kv_tbl)/sizeof(kv_tbl[0]));
uassert_true(RT_ALIGN_DOWN(test_kvdb.parent.oldest_addr, TEST_KVDB_SECTOR_SIZE) == TEST_KVDB_SECTOR_SIZE * 0);
}
{
/*
* prepare2: change kv0 and kv3
*
* +--------------+-------------+--------------+-------------+
* | sector0 | sector1 | sector2 | sector3 |
* | using | using | empty | empty |
* +---------------------------------------------------------+
* | | | | |
* | kv0 | kv3 | | |
* | delete | delete | | |
* +----------------------------+ | |
* | | | | |
* | kv1 | kv0 | | |
* | new | new | | |
* +----------------------------+ | |
* | | | | |
* | kv2 | kv3 | | |
* | new | new | | |
* +----------------------------+ | |
* | | | | |
* +--------------+-------------+--------------+-------------+
*/
struct test_kv kv_tbl[TEST_KV_NUM] = {
{"kv1", "1", 0, 0, 0},
{"kv2", "2", 0, 0, 0},
{"kv0", "00", 1, 0, 1},
{"kv3", "33", 1, 0, 1},
};
test_fdb_by_kvs(kv_tbl, sizeof(kv_tbl) / sizeof(kv_tbl[0]));
uassert_true(RT_ALIGN_DOWN(test_kvdb.parent.oldest_addr, TEST_KVDB_SECTOR_SIZE) == TEST_KVDB_SECTOR_SIZE * 0);
}
{
/*
* change kv0, kv1, kv2 and kv3, trigger GC
*
* step1: change kv0, kv1 and kv2
* +--------------+-------------+--------------+-------------+
* | sector0 | sector1 | sector2 | sector3 |
* | using | using | using | empty |
* +---------------------------------------------------------+
* | | | | |
* | kv0 | kv3 | kv0 | |
* | delete | delete | new | |
* +-------------------------------------------+ |
* | | | | |
* | kv1 | kv0 | kv1 | |
* | delete | delete | new | |
* +-------------------------------------------+ |
* | | | | |
* | kv2 | kv3 | kv2 | |
* | delete | new | new | |
* +-------------------------------------------+ |
* | | | | |
* +--------------+-------------+--------------+-------------+
*
* step2.1: change kv3, start GC, only GC 1 sector on FlashDB V1.2
*
* +--------------+-------------+--------------+-------------+
* | sector0 | sector1 | sector2 | sector3 |
* | empty | using | using | empty |
* +---------------------------------------------------------+
* | | | | |
* | | kv3 | kv0 | |
* | | delete | new | |
* | +----------------------------+ |
* | | | | |
* | | kv0 | kv1 | |
* | | delete | new | |
* | +----------------------------+ |
* | | | | |
* | | kv3 | kv2 | |
* | | new | new | |
* | +----------------------------+ |
* | | | | |
* +--------------+-------------+--------------+-------------+
*
* step2.2: change kv3
*
* +--------------+-------------+--------------+-------------+
* | sector0 | sector1 | sector2 | sector3 |
* | empty | using | using | using |
* +---------------------------------------------------------+
* | | | | |
* | | kv3 | kv0 | kv3 |
* | | delete | new | new |
* | +------------------------------------------+
* | | | | |
* | | kv0 | kv1 | |
* | | delete | new | |
* | +----------------------------+ |
* | | | | |
* | | kv3 | kv2 | |
* | | delete | new | |
* | +----------------------------+ |
* | | | | |
* +--------------+-------------+--------------+-------------+
*
*/
struct test_kv kv_tbl[TEST_KV_NUM] = {
{"kv0", "000", 2, 0, 1},
{"kv1", "111", 2, 0, 1},
{"kv2", "222", 2, 0, 1},
{"kv3", "333", 3, 0, 1},
};
test_fdb_by_kvs(kv_tbl, sizeof(kv_tbl) / sizeof(kv_tbl[0]));
uassert_true(RT_ALIGN_DOWN(test_kvdb.parent.oldest_addr, TEST_KVDB_SECTOR_SIZE) == TEST_KVDB_SECTOR_SIZE * 1);
}
{
/*
* change kv0, kv1, kv2 and kv3, trigger GC
*
* change kv0 and kv1
* +--------------+-------------+--------------+-------------+
* | sector0 | sector1 | sector2 | sector3 |
* | empty | using | using | using |
* +---------------------------------------------------------+
* | | | | |
* | | kv3 | kv0 | kv3 |
* | | delete | delete | new |
* | +------------------------------------------+
* | | | | |
* | | kv0 | kv1 | kv0 |
* | | delete | delete | new |
* | +------------------------------------------+
* | | | | |
* | | kv3 | kv2 | kv1 |
* | | delete | new | new |
* | +------------------------------------------+
* | | | | |
* +--------------+-------------+--------------+-------------+
*
* step2.1: change kv2, start GC, only GC 1 sector on FlashDB V1.2
*
* +--------------+-------------+--------------+-------------+
* | sector0 | sector1 | sector2 | sector3 |
* | empty | empty | using | using |
* +---------------------------------------------------------+
* | | | | |
* | | | kv0 | kv3 |
* | | | delete | new |
* | | +----------------------------+
* | | | | |
* | | | kv1 | kv0 |
* | | | delete | new |
* | | +----------------------------+
* | | | | |
* | | | kv2 | kv1 |
* | | | new | new |
* | | +----------------------------+
* | | | | |
* +--------------+-------------+--------------+-------------+
*
* step2.2: change kv2
*
* +--------------+-------------+--------------+-------------+
* | sector0 | sector1 | sector2 | sector3 |
* | uings | empty | using | using |
* +---------------------------------------------------------+
* | | | | |
* | kv2 | | kv0 | kv3 |
* | new | | delete | new |
* +--------------+ +----------------------------+
* | | | | |
* | | | kv1 | kv0 |
* | | | delete | new |
* | | +----------------------------+
* | | | | |
* | | | kv2 | kv1 |
* | | | delete | new |
* | | +----------------------------+
* | | | | |
* +--------------+-------------+--------------+-------------+
*
* step3: change kv3
*
* +--------------+-------------+--------------+-------------+
* | sector0 | sector1 | sector2 | sector3 |
* | using | empty | using | using |
* +---------------------------------------------------------+
* | | | | |
* | kv2 | | kv0 | kv3 |
* | new | | delete | delete |
* +--------------+ +----------------------------+
* | | | | |
* | kv3 | | kv1 | kv0 |
* | new | | delete | new |
* +--------------+ +----------------------------+
* | | | | |
* | | | kv2 | kv1 |
* | | | delete | new |
* | | +----------------------------+
* | | | | |
* +--------------+-------------+--------------+-------------+
*/
struct test_kv kv_tbl[TEST_KV_NUM] = {
{"kv0", "0000", 3, 0, 1},
{"kv1", "1111", 3, 0, 1},
{"kv2", "2222", 0, 0, 1},
{"kv3", "3333", 0, 0, 1},
};
test_fdb_by_kvs(kv_tbl, sizeof(kv_tbl) / sizeof(kv_tbl[0]));
uassert_true(RT_ALIGN_DOWN(test_kvdb.parent.oldest_addr, TEST_KVDB_SECTOR_SIZE) == TEST_KVDB_SECTOR_SIZE * 2);
}
{
/* check the oldest address is already right when kvdb reinit */
extern void test_fdb_kvdb_deinit(void);
test_fdb_kvdb_deinit();
test_fdb_kvdb_init();
uassert_true(RT_ALIGN_DOWN(test_kvdb.parent.oldest_addr, TEST_KVDB_SECTOR_SIZE) == TEST_KVDB_SECTOR_SIZE * 2);
}
}
static void test_fdb_kvdb_set_default(void)
{
uassert_true(fdb_kv_set_default(&test_kvdb) == FDB_NO_ERR);
}
static void test_fdb_kvdb_deinit(void)
@ -188,20 +521,29 @@ static rt_err_t utest_tc_init(void)
static rt_err_t utest_tc_cleanup(void)
{
if (test_kvdb.parent.init_ok)
{
fdb_kv_set_default(&test_kvdb);
fdb_kvdb_deinit(&test_kvdb);
}
return RT_EOK;
}
static void testcase(void)
{
UTEST_UNIT_RUN(test_fdb_kvdb_init);
UTEST_UNIT_RUN(test_fdb_kvdb_init_check);
UTEST_UNIT_RUN(test_fdb_create_kv_blob);
UTEST_UNIT_RUN(test_fdb_change_kv_blob);
UTEST_UNIT_RUN(test_fdb_del_kv_blob);
UTEST_UNIT_RUN(test_fdb_create_kv);
UTEST_UNIT_RUN(test_fdb_change_kv);
UTEST_UNIT_RUN(test_fdb_del_kv);
UTEST_UNIT_RUN(test_fdb_gc);
UTEST_UNIT_RUN(test_fdb_kvdb_set_default);
UTEST_UNIT_RUN(test_fdb_kvdb_deinit);
}
UTEST_TC_EXPORT(testcase, "packages.tools.flashdb.kvdb", utest_tc_init, utest_tc_cleanup, 20);
UTEST_TC_EXPORT(testcase, "packages.system.flashdb.kvdb", utest_tc_init, utest_tc_cleanup, 20);
#endif /* defined(RT_USING_UTEST) && defined(FDB_USING_KVDB) */