From 5f1053cf173ccef8207d12d63031fe16257b62bd Mon Sep 17 00:00:00 2001 From: Drew Galbraith Date: Thu, 11 Jan 2024 16:42:43 -0800 Subject: [PATCH] [Glacier] Add Vector tests with memory check. --- lib/glacier/test/CMakeLists.txt | 2 + lib/glacier/test/container/vector.cpp | 110 +++++++++++++++++++++++++- scripts/test.sh | 2 +- 3 files changed, 112 insertions(+), 2 deletions(-) diff --git a/lib/glacier/test/CMakeLists.txt b/lib/glacier/test/CMakeLists.txt index f34214a..1396d3b 100644 --- a/lib/glacier/test/CMakeLists.txt +++ b/lib/glacier/test/CMakeLists.txt @@ -1,4 +1,6 @@ find_package(Catch2 3 REQUIRED) +find_program(MEMORYCHECK_COMMAND valgrind) +set(MEMORYCHECK_COMMAND_OPTIONS "--trace-children=yes --leak-check=full") add_subdirectory(container) diff --git a/lib/glacier/test/container/vector.cpp b/lib/glacier/test/container/vector.cpp index 872d63f..fc281d6 100644 --- a/lib/glacier/test/container/vector.cpp +++ b/lib/glacier/test/container/vector.cpp @@ -4,7 +4,115 @@ using namespace glcr; -TEST_CASE("Build Vector", "[vector]") { +TEST_CASE("Empty Vector", "[vector]") { Vector v; REQUIRE(v.size() == 0); + REQUIRE(v.empty()); +} + +TEST_CASE("Push/Pop Vector", "[vector]") { + Vector v; + v.PushBack(42); + REQUIRE(v.size() == 1); + REQUIRE(v.capacity() >= 1); + v.PushBack(33); + REQUIRE(v.size() == 2); + REQUIRE(v.capacity() >= 2); + + REQUIRE(v.at(0) == 42); + REQUIRE(v[0] == 42); + REQUIRE(v.at(1) == 33); + REQUIRE(v[1] == 33); + + REQUIRE(v.PopBack() == 33); + REQUIRE(v.size() == 1); + REQUIRE(v.PopBack() == 42); + REQUIRE(v.size() == 0); +} + +class ConstructRecorder { + public: + static uint64_t construct_cnt; + static uint64_t copy_cnt; + static uint64_t move_cnt; + ConstructRecorder() { construct_cnt++; } + ConstructRecorder(const ConstructRecorder&) { copy_cnt++; } + ConstructRecorder& operator=(const ConstructRecorder&) { + copy_cnt++; + return *this; + } + + ConstructRecorder(ConstructRecorder&&) { move_cnt++; } + ConstructRecorder& operator=(ConstructRecorder&&) { + move_cnt++; + return *this; + } + + static void Reset() { + construct_cnt = 0; + copy_cnt = 0; + move_cnt = 0; + } + + private: + uint64_t dummy_data = 0; +}; + +uint64_t ConstructRecorder::construct_cnt = 0; +uint64_t ConstructRecorder::copy_cnt = 0; +uint64_t ConstructRecorder::move_cnt = 0; + +TEST_CASE("Data-Type Construction", "[vector]") { + ConstructRecorder::Reset(); + Vector v; + + SECTION("Copy Insert") { + ConstructRecorder obj; + v.PushBack(obj); + // This is overfitted on the implementation which also default constructs + // the held objects when allocating a new backing array. + REQUIRE(ConstructRecorder::construct_cnt == 2); + REQUIRE(ConstructRecorder::copy_cnt == 1); + REQUIRE(ConstructRecorder::move_cnt == 0); + } + + SECTION("Move Insert") { + ConstructRecorder obj; + v.PushBack(glcr::Move(obj)); + // This is overfitted on the implementation which also default constructs + // the held objects when allocating a new backing array. + REQUIRE(ConstructRecorder::construct_cnt == 2); + REQUIRE(ConstructRecorder::copy_cnt == 0); + REQUIRE(ConstructRecorder::move_cnt == 1); + } + + SECTION("RValue Insert") { + v.PushBack({}); + // This is overfitted on the implementation which also default constructs + // the held objects when allocating a new backing array. + REQUIRE(ConstructRecorder::construct_cnt == 2); + REQUIRE(ConstructRecorder::copy_cnt == 0); + REQUIRE(ConstructRecorder::move_cnt == 1); + } + + SECTION("Emplace Insert") { + v.EmplaceBack(); + // This is overfitted on the implementation which also default constructs + // the held objects when allocating a new backing array. + REQUIRE(ConstructRecorder::construct_cnt == 2); + REQUIRE(ConstructRecorder::copy_cnt == 0); + REQUIRE(ConstructRecorder::move_cnt == 1); + } + + SECTION("PopBack Move") { + v.EmplaceBack(); + ConstructRecorder obj = v.PopBack(); + + // This is overfitted on the implementation which also default constructs + // the held objects when allocating a new backing array. + REQUIRE(ConstructRecorder::construct_cnt == 2); + REQUIRE(ConstructRecorder::copy_cnt == 0); + // 1 from emplace, 1 from pop. (No additional regular constructions). + REQUIRE(ConstructRecorder::move_cnt == 2); + } } diff --git a/scripts/test.sh b/scripts/test.sh index 45b0185..54a894e 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -8,7 +8,7 @@ pushd "$DIR/.." cmake -B test-bin/ -G Ninja -D enable_testing=on pushd test-bin/ ninja build_test -ctest --output-on-failure +ctest --output-on-failure -T memcheck popd popd