From 7b9496986904035d54df46c81ec36c1f07134645 Mon Sep 17 00:00:00 2001 From: Vitaliy Filippov Date: Thu, 17 Jul 2025 12:48:43 +0300 Subject: [PATCH] Add a basic mocked blockstore test --- src/test/CMakeLists.txt | 9 +- src/test/test_blockstore.cpp | 203 +++++++++++++++++------------------ 2 files changed, 102 insertions(+), 110 deletions(-) diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt index a40ca535..bf43839d 100644 --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -64,8 +64,11 @@ target_link_libraries(test_crc32 vitastor_blk ) -## test_blockstore, test_shit -#add_executable(test_blockstore test_blockstore.cpp) -#target_link_libraries(test_blockstore blockstore) +# test_blockstore +add_executable(test_blockstore test_blockstore.cpp) +target_link_libraries(test_blockstore vitastor_blk) +add_test(NAME test_blockstore COMMAND test_blockstore) + +## test_shit #add_executable(test_shit test_shit.cpp osd_peering_pg.cpp) #target_link_libraries(test_shit ${LIBURING_LIBRARIES} m) diff --git a/src/test/test_blockstore.cpp b/src/test/test_blockstore.cpp index 89acb6ec..644c7545 100644 --- a/src/test/test_blockstore.cpp +++ b/src/test/test_blockstore.cpp @@ -2,127 +2,116 @@ // License: VNPL-1.1 (see README.md for details) #include -#include "blockstore.h" -#include "epoll_manager.h" +#include "blockstore_impl.h" int main(int narg, char *args[]) { blockstore_config_t config; - config["meta_device"] = "./test_meta.bin"; - config["journal_device"] = "./test_journal.bin"; config["data_device"] = "./test_data.bin"; - ring_loop_t *ringloop = new ring_loop_t(RINGLOOP_DEFAULT_SIZE); - epoll_manager_t *epmgr = new epoll_manager_t(ringloop); - blockstore_i *bs = blockstore_i::create(config, ringloop, epmgr->tfd); + config["data_device_size"] = "1073741824"; + config["data_device_sect"] = "4096"; + config["meta_offset"] = "0"; + config["journal_offset"] = "16777216"; + config["data_offset"] = "33554432"; + config["disable_data_fsync"] = "1"; + config["immediate_commit"] = "all"; + config["log_level"] = "10"; + config["data_csum_type"] = "crc32c"; + config["csum_block_size"] = "4096"; + disk_mock_t *data_disk = NULL; + ring_loop_mock_t *ringloop = new ring_loop_mock_t(RINGLOOP_DEFAULT_SIZE, [&](io_uring_sqe *sqe) + { + assert(sqe->fd == MOCK_DATA_FD); + bool ok = data_disk->submit(sqe); + assert(ok); + }); + timerfd_manager_t *tfd = new timerfd_manager_t(nullptr); + data_disk = new disk_mock_t(ringloop, 1073741824); + blockstore_impl_t *bs = new blockstore_impl_t(config, ringloop, tfd, true); + + // Wait for blockstore init + while (!bs->is_started()) + ringloop->loop(); + printf("init completed\n"); + + // Write + bool done = false; blockstore_op_t op; - int main_state = 0; uint64_t version = 0; - ring_consumer_t main_cons; + op.opcode = BS_OP_WRITE; + op.oid = { .inode = 1, .stripe = 0 }; + op.version = 1; + op.offset = 16384; + op.len = 4096; + op.buf = (uint8_t*)memalign_or_die(MEM_ALIGNMENT, 128*1024); + memset(op.buf, 0xaa, 4096); op.callback = [&](blockstore_op_t *op) { - printf("op completed %d\n", op->retval); - if (main_state == 1) - main_state = 2; - else if (main_state == 3) - main_state = 4; - else if (main_state == 5) - main_state = 6; - else if (main_state == 7) - main_state = 8; - else if (main_state == 9) - main_state = 10; + printf("op completed code=%lu retval=%d\n", op->opcode, op->retval); + done = true; }; - main_cons.loop = [&]() - { - if (main_state == 0) - { - if (bs->is_started()) - { - printf("init completed\n"); - op.opcode = BS_OP_WRITE; - op.oid = { .inode = 1, .stripe = 0 }; - op.version = 0; - op.offset = 16384; - op.len = 4096; - op.buf = (uint8_t*)memalign(512, 128*1024); - memset(op.buf, 0xaa, 4096); - bs->enqueue_op(&op); - main_state = 1; - } - } - else if (main_state == 2) - { - printf("version %ju written, syncing\n", op.version); - version = op.version; - op.opcode = BS_OP_SYNC; - bs->enqueue_op(&op); - main_state = 3; - } - else if (main_state == 4) - { - printf("stabilizing version %ju\n", version); - op.opcode = BS_OP_STABLE; - op.len = 1; - *((obj_ver_id*)op.buf) = { - .oid = { .inode = 1, .stripe = 0 }, - .version = version, - }; - bs->enqueue_op(&op); - main_state = 5; - } - else if (main_state == 6) - { - printf("stabilizing version %ju\n", version); - op.opcode = BS_OP_STABLE; - op.len = 1; - *((obj_ver_id*)op.buf) = { - .oid = { .inode = 1, .stripe = 0 }, - .version = version, - }; - bs->enqueue_op(&op); - main_state = 7; - } - else if (main_state == 8) - { - printf("reading 0-128K\n"); - op.opcode = BS_OP_READ; - op.oid = { .inode = 1, .stripe = 0 }; - op.version = UINT64_MAX; - op.offset = 0; - op.len = 128*1024; - bs->enqueue_op(&op); - main_state = 9; - } - else if (main_state == 10) - { - void *cmp = memalign(512, 128*1024); - memset(cmp, 0, 128*1024); - memset(cmp+16384, 0xaa, 4096); - int ok = 1; - for (int i = 0; i < 128*1024; i += 4096) - { - if (memcmp(cmp+i, op.buf+i, 4096) != 0) - { - printf("bitmap works incorrectly, bytes %d - %d differ (%02x, should be %02x)\n", i, i+4096, ((uint8_t*)op.buf)[i], ((uint8_t*)cmp)[i]); - ok = 0; - } - } - if (ok) - printf("bitmap works correctly\n"); - free(cmp); - main_state = 11; - } - }; - - ringloop->register_consumer(&main_cons); - while (1) - { + bs->enqueue_op(&op); + while (!done) ringloop->loop(); - ringloop->wait(); + assert(op.retval == op.len); + + // Sync + printf("version %ju written, syncing\n", op.version); + done = false; + version = op.version; + op.opcode = BS_OP_SYNC; + bs->enqueue_op(&op); + while (!done) + ringloop->loop(); + assert(op.retval == 0); + + // Commit + printf("commit version %ju\n", version); + done = false; + op.opcode = BS_OP_STABLE; + op.len = 1; + *((obj_ver_id*)op.buf) = { + .oid = { .inode = 1, .stripe = 0 }, + .version = version, + }; + bs->enqueue_op(&op); + while (!done) + ringloop->loop(); + assert(op.retval == 0); + + // Read + printf("reading 0-128K\n"); + done = false; + op.opcode = BS_OP_READ; + op.oid = { .inode = 1, .stripe = 0 }; + op.version = UINT64_MAX; + op.offset = 0; + op.len = 128*1024; + bs->enqueue_op(&op); + while (!done) + ringloop->loop(); + assert(op.retval == op.len); + uint8_t *cmp = (uint8_t*)memalign_or_die(MEM_ALIGNMENT, 128*1024); + memset(cmp, 0, 128*1024); + memset(cmp+16384, 0xaa, 4096); + if (memcmp(op.buf, cmp, 128*1024) == 0) + printf("read successful\n"); + else + { + printf("read returned incorrect data\n"); + abort(); } + free(cmp); + + free(op.buf); + + // Destroy + while (!bs->is_safe_to_stop()) + ringloop->loop(); delete bs; - delete epmgr; + delete tfd; + delete data_disk; delete ringloop; return 0; }