From e3f902d6e302c6efad94a1040b6bc81c0780d612 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Sat, 23 Aug 2025 14:26:11 +0100 Subject: [PATCH] Unit test for SmallObjectAllocator --- test/unit/meson.build | 1 + test/unit/small_object_allocator_test.cpp | 75 +++++++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 test/unit/small_object_allocator_test.cpp diff --git a/test/unit/meson.build b/test/unit/meson.build index 5086fca..9fa0534 100644 --- a/test/unit/meson.build +++ b/test/unit/meson.build @@ -11,6 +11,7 @@ unit_test_prog = executable(meson.project_name(), 'tiger_test.cpp', 'infix_iterator.cpp', 'tree_iterator_test.cpp', + 'small_object_allocator_test.cpp', install: false, dependencies: [sprout_dep, catch2_dep], include_directories: [public_incl], diff --git a/test/unit/small_object_allocator_test.cpp b/test/unit/small_object_allocator_test.cpp new file mode 100644 index 0000000..a7258ab --- /dev/null +++ b/test/unit/small_object_allocator_test.cpp @@ -0,0 +1,75 @@ +/* Copyright 2016-2024 Michele Santullo + * This file is part of "duckhandy". + * + * "duckhandy" is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * "duckhandy" is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with "duckhandy". If not, see . + */ + +#include "catch2/catch_test_macros.hpp" +#include "duckhandy/small_object_allocator.hpp" +#include + +namespace { +static const void* g_alloc_last{nullptr}; +static std::size_t g_alloc_count{0}; + +template +struct TestAlloc { + std::unique_ptr operator()() { + auto ret = std::make_unique(); + g_alloc_last = ret.get(); + ++g_alloc_count; + return ret; + } +}; +} //unnamed namespace + +TEST_CASE("Check SmallObjectAllocator", "[SmallObjectAllocator][containers][memory][allocators]") { + dhandy::SmallObjectAllocator soa; + CHECK(g_alloc_last == nullptr); + CHECK(g_alloc_count == 0u); + + int* const int01 = soa.allocate(sizeof(int)); + const void* old_block = g_alloc_last; + REQUIRE(int01 != nullptr); + CHECK(g_alloc_last != nullptr); + CHECK(g_alloc_count == 1); + + int* const int02 = soa.allocate(sizeof(int)); + REQUIRE(int02 != nullptr); + CHECK(int01 != int02); + CHECK(g_alloc_last == old_block); + CHECK(g_alloc_count == 1); + + int* prev_int = int02; + for (std::size_t z = 2; z < dhandy::SmallObjectAllocator::objects_per_block; ++z) { + int* const new_int = soa.allocate(sizeof(int)); + REQUIRE(new_int != nullptr); + CHECK(new_int != int01); + CHECK(new_int != prev_int); + prev_int = new_int; + CHECK(g_alloc_last == old_block); + CHECK(g_alloc_count == 1); + CHECK(reinterpret_cast(new_int) % alignof(int) == 0); + } + + int* const int03 = soa.allocate(sizeof(int)); + REQUIRE(int03 != nullptr); + CHECK(int03 != int02); + CHECK(int03 != int01); + CHECK(g_alloc_last != old_block); + old_block = g_alloc_last; + CHECK(g_alloc_count == 2); + + soa.deallocate(int02, sizeof(int)); +}