From: myoungwon oh Date: Thu, 15 Sep 2022 08:59:22 +0000 (+0900) Subject: test/crimson/seastore: add allocator tests X-Git-Tag: v18.1.0~794^2~4 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=b302322cabada9af77d5d63521408b2fea8e7b62;p=ceph-ci.git test/crimson/seastore: add allocator tests Signed-off-by: Myoungwon Oh --- diff --git a/src/test/crimson/seastore/CMakeLists.txt b/src/test/crimson/seastore/CMakeLists.txt index 7da1352be05..1f6ddb778d0 100644 --- a/src/test/crimson/seastore/CMakeLists.txt +++ b/src/test/crimson/seastore/CMakeLists.txt @@ -113,4 +113,14 @@ target_link_libraries( crimson-seastore aio) +add_executable(unittest-seastore-extent-allocator + test_extent_allocator.cc) +add_ceph_test(unittest-seastore-extent-allocator + unittest-seastore-extent-allocator --memory 256M --smp 1) +target_link_libraries( + unittest-seastore-extent-allocator + crimson::gtest + crimson-seastore + aio) + add_subdirectory(onode_tree) diff --git a/src/test/crimson/seastore/test_extent_allocator.cc b/src/test/crimson/seastore/test_extent_allocator.cc new file mode 100644 index 00000000000..6bda4825741 --- /dev/null +++ b/src/test/crimson/seastore/test_extent_allocator.cc @@ -0,0 +1,181 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#include + +#include + +#include "test/crimson/gtest_seastar.h" +#include "crimson/os/seastore/random_block_manager.h" +#include "crimson/os/seastore/random_block_manager/extent_allocator.h" +#include "crimson/os/seastore/random_block_manager/avlallocator.h" +#include "include/interval_set.h" + + +using namespace crimson; +using namespace crimson::os; +using namespace crimson::os::seastore; + +namespace { + [[maybe_unused]] seastar::logger& logger() { + return crimson::get_logger(ceph_subsys_test); + } +} + +struct allocator_test_t : + public seastar_test_suite_t, + ::testing::WithParamInterface { + std::random_device rd; + std::mt19937 gen; + ExtentAllocatorRef allocator; + + allocator_test_t() + : gen(rd()) {} + + seastar::future<> set_up_fut() final { + std::string a_type = GetParam(); + if (a_type == "avl") { + allocator.reset(new AvlAllocator); + return seastar::now(); + } + ceph_assert(0 == "no support"); + } + seastar::future<> tear_down_fut() final { + if (allocator) { + allocator->close(); + } + return seastar::now(); + } + void init_alloc(uint64_t block_size, uint64_t total_size) { + assert(allocator); + allocator->init(0, total_size, block_size); + } + void close() { + assert(allocator); + allocator->close(); + } + auto allocate(size_t size) { + return allocator->alloc_extent(size); + } + void free(uint64_t start, uint64_t length) { + allocator->free_extent(start, length); + } + rbm_abs_addr get_random_addr(size_t block_size, size_t capacity) { + return block_size * + std::uniform_int_distribution<>(0, (capacity / block_size) - 1)(gen); + } +}; + +TEST_P(allocator_test_t, test_alloc_init) +{ + init_alloc(4096, 4096 * 64); + ASSERT_EQ((4096 * 64), allocator->get_available_size()); + close(); + init_alloc(8192, 8192 * 32); + allocate(8192); + ASSERT_EQ(8192 * 32 - 8192, allocator->get_available_size()); + close(); + init_alloc(4096, 4096 * 128); + allocate(8192); + ASSERT_EQ(4096 * 128 - 8192, allocator->get_available_size()); +} + +TEST_P(allocator_test_t, test_init_alloc_free) +{ + uint64_t block_size = 4096; + uint64_t capacity = 4 * 1024 * block_size; + + { + init_alloc(block_size, capacity); + + auto free_length = allocator->get_available_size(); + allocate(allocator->get_max_alloc_size()); + ASSERT_EQ(free_length - allocator->get_max_alloc_size(), + allocator->get_available_size()); + + free(0, allocator->get_max_alloc_size()); + ASSERT_EQ(free_length, allocator->get_available_size()); + } +} + +TEST_P(allocator_test_t, test_alloc_failure) +{ + uint64_t block_size = 8192; + uint64_t capacity = 1024 * block_size; + + { + init_alloc(block_size, capacity); + allocator->mark_extent_used(0, block_size * 256); + allocator->mark_extent_used(block_size * 512, block_size * 256); + + auto result = allocate(block_size * 512); + ASSERT_EQ(false, result.has_value()); + + free(0, block_size * 256); + allocator->mark_extent_used(0, block_size * 512); + + result = allocate(block_size * 512); + ASSERT_EQ(false, result.has_value()); + } +} + +TEST_P(allocator_test_t, test_random_alloc_verify) +{ + uint64_t block_size = 4096; + uint64_t capacity = 64 * 1024 * block_size; + uint64_t avail = capacity; + interval_set alloc_map; + init_alloc(block_size, capacity); + + { + for (int i = 0; i < 256; i++) { + auto addr = get_random_addr(block_size, capacity); + auto size = get_random_addr(block_size, capacity) % (4 << 20); + if (addr + size > capacity || size == 0 || + alloc_map.intersects(addr, size) ) continue; + allocator->mark_extent_used(addr, size); + alloc_map.insert(addr, size); + avail -= size; + } + ASSERT_EQ(avail, allocator->get_available_size()); + + for (auto p : alloc_map) { + free(p.first, p.second); + avail += p.second; + alloc_map.erase(p.first, p.second); + ASSERT_EQ(avail, allocator->get_available_size()); + } + ASSERT_EQ(capacity, allocator->get_available_size()); + + for (int i = 0; i < 100; i++) { + auto addr = get_random_addr(block_size, capacity); + auto size = get_random_addr(block_size, capacity) % (4 << 20); + if (addr + size > capacity || size == 0 || + alloc_map.intersects(addr, size) ) continue; + allocator->mark_extent_used(addr, size); + alloc_map.insert(addr, size); + avail -= size; + } + + for (int i = 0; i < 50; i++) { + free((*alloc_map.begin()).first, (*alloc_map.begin()).second); + avail += (*alloc_map.begin()).second; + alloc_map.erase((*alloc_map.begin()).first, (*alloc_map.begin()).second); + ASSERT_EQ(avail, allocator->get_available_size()); + + auto addr = get_random_addr(block_size, capacity); + auto size = get_random_addr(block_size, capacity) % (4 << 20); + if (addr + size > capacity || size == 0 || + alloc_map.intersects(addr, size) ) continue; + allocator->mark_extent_used(addr, size); + alloc_map.insert(addr, size); + avail -= size; + } + ASSERT_EQ(avail, allocator->get_available_size()); + } +} + +INSTANTIATE_TEST_SUITE_P( + allocator_test, + allocator_test_t, + ::testing::Values("avl"));