From 10888b487251657eca0ced8754a535cc73c6b9dd Mon Sep 17 00:00:00 2001 From: Kyle Isom Date: Sat, 21 Oct 2023 17:40:01 -0700 Subject: [PATCH] tests: all tests now use SimpleSuite. - Also continuing doc updates. --- CMakeLists.txt | 4 +- include/scmp/estimation.h | 4 +- include/scmp/estimation/Madgwick.h | 2 + include/scmp/geom/Coord2D.h | 2 + test/buffer.cc | 107 +++++++++++---- test/coord2d.cc | 4 +- test/dictionary.cc | 181 ++++++++++++++----------- test/flags.cc | 31 ++++- test/tlv.cc | 207 +++++++++++++++++------------ 9 files changed, 348 insertions(+), 194 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8f8113d..6f83114 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -113,7 +113,6 @@ endmacro() generate_test(buffer) generate_test(tlv) generate_test(dictionary) -generate_test(flags) generate_test(stringutil) # math and physics @@ -124,6 +123,9 @@ generate_test(orientation) generate_test(quaternion) generate_test(vector) +add_executable(flags-demo test/flags.cc) +target_link_libraries(flags-demo ${PROJECT_NAME}) + # test tooling generate_test(simple_suite_example) diff --git a/include/scmp/estimation.h b/include/scmp/estimation.h index c4ecddc..92c95e8 100644 --- a/include/scmp/estimation.h +++ b/include/scmp/estimation.h @@ -2,7 +2,9 @@ /// \file include/scmp/estimation.h /// \author K. Isom /// \date 2023-10-20 -/// \brief +/// \brief Estimate position and orientation. +/// +/// \section COPYRIGHT /// /// Copyright 2023 K. Isom /// diff --git a/include/scmp/estimation/Madgwick.h b/include/scmp/estimation/Madgwick.h index 480a888..3e6494b 100644 --- a/include/scmp/estimation/Madgwick.h +++ b/include/scmp/estimation/Madgwick.h @@ -6,6 +6,8 @@ /// /// See https://courses.cs.washington.edu/courses/cse466/14au/labs/l4/madgwick_internal_report.pdf. /// +/// \section COPYRIGHT +/// /// Copyright 2019 K. Isom /// /// Permission to use, copy, modify, and/or distribute this software for diff --git a/include/scmp/geom/Coord2D.h b/include/scmp/geom/Coord2D.h index 35565f2..7714388 100755 --- a/include/scmp/geom/Coord2D.h +++ b/include/scmp/geom/Coord2D.h @@ -4,6 +4,8 @@ /// \date 2017-06-05 /// \brief 2D point and polar coordinate systems. /// +/// \section COPYRIGHT +/// /// Copyright 2017 K. Isom /// /// Permission to use, copy, modify, and/or distribute this software for diff --git a/test/buffer.cc b/test/buffer.cc index 5383ec6..c51ab4e 100644 --- a/test/buffer.cc +++ b/test/buffer.cc @@ -1,59 +1,108 @@ -#include +/// +/// \file test/buffer.cc +/// \author K.Isom +/// \date 2017-06-05 +/// \brief Unit tests on the scsl::Buffer class. +/// +/// \section COPYRIGHT +/// +/// Copyright 2023 K. Isom +/// +/// Permission to use, copy, modify, and/or distribute this software for +/// any purpose with or without fee is hereby granted, provided that +/// the above copyright notice and this permission notice appear in all /// copies. +/// +/// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +/// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +/// WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +/// AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +/// DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA +/// OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +/// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +/// PERFORMANCE OF THIS SOFTWARE. +/// + #include #include +#include +#include +#include + + using namespace scsl; -int -main(int argc, char *argv[]) +bool +bufferTest() { - (void) argc; - (void) argv; - Buffer buffer("hlo, world"); Buffer helloWorld("hello, world!"); Buffer goodbyeWorld("goodbye, world"); Buffer goodbyeCruelWorld("goodbye, cruel world"); - std::cout << buffer << "\n"; - buffer.Insert(1, (uint8_t *) "el", 2); - buffer.Append('!'); - assert(buffer == helloWorld); + SCTEST_CHECK_EQ(buffer.Length(), 12); - std::cout << buffer << "\n"; + buffer.Append('!'); + SCTEST_CHECK_EQ(buffer, helloWorld); buffer.Remove(buffer.Length() - 1); - std::cout << buffer << "\n"; + SCTEST_CHECK_EQ(buffer.Length(), 12); + buffer.Remove(0, 5); - std::cout << buffer << "\n"; buffer.Insert(0, 'g'); - std::cout << buffer << "\n"; buffer.Insert(1, (uint8_t *) "oodbye", 6); - std::cout << buffer << "\n"; - assert(buffer == goodbyeWorld); + SCTEST_CHECK_EQ(buffer, goodbyeWorld); + buffer.Insert(9, (uint8_t *)"cruel ", 6); - - std::cout << buffer << "\n"; - buffer.HexDump(std::cout); - buffer.Reclaim(); - buffer.Append("and now for something completely different..."); + SCTEST_CHECK_EQ(buffer.Length(), 0); + SCTEST_CHECK_EQ(buffer.Capacity(), 0); - std::cout << buffer.Contents() << "\n"; - std::cout << "Length: " << buffer.Length() << ", capacity " << buffer.Capacity() << "\n"; + buffer.Append("and now for something completely different..."); buffer.Resize(128); - std::cout << "Length: " << buffer.Length() << ", capacity " << buffer.Capacity() << "\n"; + SCTEST_CHECK_EQ(buffer.Capacity(), 128); buffer.Trim(); - std::cout << "Length: " << buffer.Length() << ", capacity " << buffer.Capacity() << "\n"; + SCTEST_CHECK_EQ(buffer.Capacity(), 64); Buffer buffer2("and now for something completely different..."); - assert(buffer == buffer2); + SCTEST_CHECK_EQ(buffer, buffer2); buffer2.Remove(buffer2.Length()-3, 3); - std::cout << buffer << "\n"; - assert(buffer != buffer2); + SCTEST_CHECK_NE(buffer, buffer2); - return 0; + return true; +} + + +int +main(int argc, char *argv[]) +{ + auto noReport = false; + auto quiet = false; + auto flags = new scsl::Flags("test_buffer", + "This test validates the Buffer class."); + flags->Register("-n", false, "don't print the report"); + flags->Register("-q", false, "suppress test output"); + + auto parsed = flags->Parse(argc, argv); + if (parsed != scsl::Flags::ParseStatus::OK) { + std::cerr << "Failed to parse flags: " + << scsl::Flags::ParseStatusToString(parsed) << "\n"; + } + + sctest::SimpleSuite suite; + flags->GetBool("-n", noReport); + flags->GetBool("-q", quiet); + if (quiet) { + suite.Silence(); + } + + suite.AddTest("bufferTest", bufferTest); + + delete flags; + auto result = suite.Run(); + if (!noReport) { std::cout << suite.GetReport() << "\n"; } + return result ? 0 : 1; } diff --git a/test/coord2d.cc b/test/coord2d.cc index 00773fb..b744906 100755 --- a/test/coord2d.cc +++ b/test/coord2d.cc @@ -1,9 +1,11 @@ /// -/// \file tset/coord2d.cc +/// \file test/coord2d.cc /// \author K.Isom /// \date 2017-06-05 /// \brief Unit tests on 2D geometry code. /// +/// \section COPYRIGHT +/// /// Copyright 2017 K. Isom /// /// Permission to use, copy, modify, and/or distribute this software for diff --git a/test/dictionary.cc b/test/dictionary.cc index 983ad16..8101420 100644 --- a/test/dictionary.cc +++ b/test/dictionary.cc @@ -1,8 +1,35 @@ +/// +/// \file test/dictionary.cc +/// \author K.Isom +/// \date 2023-10-05 +/// \brief Unit tests on the scsl::Dictionary class. +/// +/// \section COPYRIGHT +/// +/// Copyright 2023 K. Isom +/// +/// Permission to use, copy, modify, and/or distribute this software for +/// any purpose with or without fee is hereby granted, provided that +/// the above copyright notice and this permission notice appear in all /// copies. +/// +/// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +/// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +/// WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +/// AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +/// DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA +/// OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +/// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +/// PERFORMANCE OF THIS SOFTWARE. +/// + #include #include #include -#include +#include +#include +#include + #include "test_fixtures.h" @@ -10,17 +37,17 @@ using namespace scsl; using namespace sctest; -constexpr char TEST_KVSTR1[] = "foo"; +constexpr char TEST_KVSTR1[] = "foo"; constexpr uint8_t TEST_KVSTRLEN1 = 3; -constexpr char TEST_KVSTR2[] = "baz"; +constexpr char TEST_KVSTR2[] = "baz"; constexpr uint8_t TEST_KVSTRLEN2 = 3; -constexpr char TEST_KVSTR3[] = "quux"; +constexpr char TEST_KVSTR3[] = "quux"; constexpr uint8_t TEST_KVSTRLEN3 = 4; -constexpr char TEST_KVSTR4[] = "spam"; +constexpr char TEST_KVSTR4[] = "spam"; constexpr uint8_t TEST_KVSTRLEN4 = 4; -constexpr char TEST_KVSTR5[] = "xyzzx"; +constexpr char TEST_KVSTR5[] = "xyzzx"; constexpr uint8_t TEST_KVSTRLEN5 = 5; -constexpr char TEST_KVSTR6[] = "corvid"; +constexpr char TEST_KVSTR6[] = "corvid"; constexpr uint8_t TEST_KVSTRLEN6 = 6; @@ -28,82 +55,86 @@ static bool testSetKV(Dictionary &pb, const char *k, uint8_t kl, const char *v, uint8_t vl) { - bool ok; - std::cout << "test Set " << k << "->" << v << "\n"; - ok = pb.Set(k, kl, v, vl) == 0; - std::cout << "\tSet complete\n"; - return ok; + return pb.Set(k, kl, v, vl) == 0; +} + +bool +dictionaryTest() +{ + Arena arena; + TLV::Record value; + TLV::Record expect; + + if (arena.Create(ARENA_FILE, ARENA_SIZE) == -1) { + abort(); + } + + TLV::SetRecord(expect, DICTIONARY_TAG_VAL, TEST_KVSTRLEN3, TEST_KVSTR3); + + Dictionary dict(arena); + SCTEST_CHECK_FALSE(dict.Contains(TEST_KVSTR2, TEST_KVSTRLEN2)); + SCTEST_CHECK(testSetKV(dict, TEST_KVSTR1, TEST_KVSTRLEN1, TEST_KVSTR3, + TEST_KVSTRLEN3)); + + SCTEST_CHECK(testSetKV(dict, TEST_KVSTR2, TEST_KVSTRLEN2, TEST_KVSTR3, + TEST_KVSTRLEN3)); + + SCTEST_CHECK(dict.Contains(TEST_KVSTR2, TEST_KVSTRLEN2)); + SCTEST_CHECK(testSetKV(dict, TEST_KVSTR4, TEST_KVSTRLEN4, TEST_KVSTR5, + TEST_KVSTRLEN5)); + + SCTEST_CHECK(dict.Lookup(TEST_KVSTR2, TEST_KVSTRLEN2, value)); + + SCTEST_CHECK(cmpRecord(value, expect)); + + + SCTEST_CHECK(testSetKV(dict, TEST_KVSTR2, TEST_KVSTRLEN2, TEST_KVSTR6, + TEST_KVSTRLEN6)); + + TLV::SetRecord(expect, DICTIONARY_TAG_VAL, TEST_KVSTRLEN6, TEST_KVSTR6); + SCTEST_CHECK(dict.Lookup(TEST_KVSTR2, TEST_KVSTRLEN2, value)); + + SCTEST_CHECK(cmpRecord(value, expect)); + + SCTEST_CHECK(testSetKV(dict, TEST_KVSTR3, TEST_KVSTRLEN3, TEST_KVSTR5, + TEST_KVSTRLEN5)); + + TLV::SetRecord(expect, DICTIONARY_TAG_VAL, TEST_KVSTRLEN5, TEST_KVSTR5); + SCTEST_CHECK(dict.Lookup(TEST_KVSTR4, TEST_KVSTRLEN4, value)); + SCTEST_CHECK(cmpRecord(value, expect)); + + arena.Clear(); + return true; } int -main(int argc, const char *argv[]) +main(int argc, char *argv[]) { - (void) argc; - (void) argv; + auto noReport = false; + auto quiet = false; + auto flags = new scsl::Flags("test_dictionary", + "This test validates the Dictionary class."); + flags->Register("-n", false, "don't print the report"); + flags->Register("-q", false, "suppress test output"); - Arena arena; - TLV::Record value; - TLV::Record expect; - - std::cout << "TESTPROG: " << argv[0] << "\n"; - -#if defined(__linux__) - if (arena.Create(ARENA_FILE, ARENA_SIZE) == -1) { - abort(); + auto parsed = flags->Parse(argc, argv); + if (parsed != scsl::Flags::ParseStatus::OK) { + std::cerr << "Failed to parse flags: " + << scsl::Flags::ParseStatusToString(parsed) << "\n"; } -#else - if (arena.SetAlloc(ARENA_SIZE) == -1) { - abort(); + + sctest::SimpleSuite suite; + flags->GetBool("-n", noReport); + flags->GetBool("-q", quiet); + if (quiet) { + suite.Silence(); } -#endif - std::cout << arena << "\n"; - TLV::SetRecord(expect, DICTIONARY_TAG_VAL, TEST_KVSTRLEN3, TEST_KVSTR3); - Dictionary dict(arena); - Assert(!dict.Contains(TEST_KVSTR2, TEST_KVSTRLEN2)); + suite.AddTest("dictionaryTest", dictionaryTest); - Assert(testSetKV(dict, TEST_KVSTR1, TEST_KVSTRLEN1, TEST_KVSTR3, - TEST_KVSTRLEN3)); - std::cout << dict; - Assert(testSetKV(dict, TEST_KVSTR2, TEST_KVSTRLEN2, TEST_KVSTR3, - TEST_KVSTRLEN3)); - std::cout << dict; - Assert(dict.Contains(TEST_KVSTR2, TEST_KVSTRLEN2)); - Assert(testSetKV(dict, TEST_KVSTR4, TEST_KVSTRLEN4, TEST_KVSTR5, - TEST_KVSTRLEN5)); - std::cout << dict; - Assert(dict.Lookup(TEST_KVSTR2, TEST_KVSTRLEN2, value)); - - Assert(cmpRecord(value, expect)); - - std::cout << "test overwriting key" << "\n"; - Assert(testSetKV(dict, TEST_KVSTR2, TEST_KVSTRLEN2, TEST_KVSTR6, - TEST_KVSTRLEN6)); - std::cout << dict; - TLV::SetRecord(expect, DICTIONARY_TAG_VAL, TEST_KVSTRLEN6, TEST_KVSTR6); - std::cout << "\tlookup" << "\n"; - Assert(dict.Lookup(TEST_KVSTR2, TEST_KVSTRLEN2, value)); - std::cout << "\tcompare records" << "\n"; - Assert(cmpRecord(value, expect)); - - std::cout << "\tadd new key to dictionary" << "\n"; - Assert(testSetKV(dict, TEST_KVSTR3, TEST_KVSTRLEN3, TEST_KVSTR5, - TEST_KVSTRLEN5)); - std::cout << dict; - - TLV::SetRecord(expect, DICTIONARY_TAG_VAL, TEST_KVSTRLEN5, TEST_KVSTR5); - Assert(dict.Lookup(TEST_KVSTR4, TEST_KVSTRLEN4, value)); - Assert(cmpRecord(value, expect)); - - std::cout << "OK" << "\n"; - - // Dump the generated arena for inspection later. -#if defined(__linux__) -#else - dict.DumpToFile(ARENA_FILE); -#endif - - arena.Clear(); - std::cout << dict; + delete flags; + auto result = suite.Run(); + if (!noReport) { std::cout << suite.GetReport() << "\n"; } + return result ? 0 : 1; } diff --git a/test/flags.cc b/test/flags.cc index a360393..f0b1b03 100644 --- a/test/flags.cc +++ b/test/flags.cc @@ -1,7 +1,30 @@ -// -// Created by kyle on 10/15/23. -// - +/// +/// \file test/flags.cc +/// \author K.Isom +/// \date 2017-06-05 +/// \brief Demonstration of the scsl::Flags class. +/// +/// \note This isn't a test program, and won't be run as part of a +/// normal ctest run. It's meant to show how flags work in +/// practice. +/// +/// \section COPYRIGHT +/// +/// Copyright 2017 K. Isom +/// +/// Permission to use, copy, modify, and/or distribute this software for +/// any purpose with or without fee is hereby granted, provided that +/// the above copyright notice and this permission notice appear in all /// copies. +/// +/// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +/// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +/// WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +/// AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +/// DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA +/// OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +/// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +/// PERFORMANCE OF THIS SOFTWARE. +/// #include #include diff --git a/test/tlv.cc b/test/tlv.cc index 5672233..520ece7 100644 --- a/test/tlv.cc +++ b/test/tlv.cc @@ -1,130 +1,171 @@ -#include -#include +/// +/// \file test/tlv.cc +/// \author K. Isom +/// \date 2023-10-05 +/// \brief Unit tests for the TLV namespace. +/// +/// simple_suite_example demonstrates the usage of the SimpleSuite test class +/// and serves to unit test the unit tester (qui custodiet ipsos custodes)? +/// +/// \section COPYRIGHT +/// +/// Copyright 2023 K. Isom +/// +/// Permission to use, copy, modify, and/or distribute this software for +/// any purpose with or without fee is hereby granted, provided that the +/// above copyright notice and this permission notice appear in all copies. +/// +/// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +/// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +/// WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR +/// BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES +/// OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +/// WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +/// ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +/// SOFTWARE. +/// + #include #include #include +#include #include -#include +#include +#include #include "test_fixtures.h" + using namespace scsl; static uint8_t arenaBuffer[ARENA_SIZE]; -void -tlvTestSuite(Arena &backend) +bool +runTLVTest(Arena &backend) { - TLV::Record rec1, rec2, rec3, rec4; - uint8_t *cursor = nullptr; + TLV::Record rec1, rec2, rec3, rec4; + uint8_t *cursor = nullptr; - std::cout << "\tSetting first three records." << "\n"; TLV::SetRecord(rec1, 1, TEST_STRLEN1, TEST_STR1); TLV::SetRecord(rec2, 2, TEST_STRLEN2, TEST_STR2); TLV::SetRecord(rec3, 1, TEST_STRLEN4, TEST_STR4); rec4.Tag = 1; - std::cout << "\twriting new rec1" << "\n"; cursor = TLV::WriteToMemory(backend, cursor, rec1); - sctest::Assert(cursor != nullptr, - "cursor should not be NULL after writing rec1"); - std::cout << "\twriting new rec2" << "\n"; + SCTEST_CHECK_NE(cursor, nullptr); + cursor = TLV::WriteToMemory(backend, cursor, rec2); - sctest::Assert(cursor != nullptr, - "cursor should not be NULL after writing rec2"); - std::cout << "\twriting new rec3" << "\n"; + SCTEST_CHECK_NE(cursor, nullptr); + cursor = TLV::WriteToMemory(backend, cursor, rec3); - sctest::Assert(cursor != nullptr); - cursor = nullptr; + SCTEST_CHECK_NE(cursor, nullptr); + // the cursor should point At the next record, // and rec4 should contain the same data as rec1. - std::cout << "\tFindTag 1" << "\n"; - cursor = TLV::FindTag(backend, cursor, rec4); - sctest::Assert(cursor != nullptr, "cursor should not be null"); - sctest::Assert(cursor != backend.Start()); - sctest::Assert(cmpRecord(rec1, rec4)); + cursor = TLV::FindTag(backend, nullptr, rec4); + SCTEST_CHECK_NE(cursor, nullptr); + SCTEST_CHECK_NE(cursor, backend.Start()); + SCTEST_CHECK(cmpRecord(rec1, rec4)); - std::cout << "\tFindTag 2" << "\n"; cursor = TLV::FindTag(backend, cursor, rec4); - sctest::Assert(cursor != nullptr, - "cursor should not be null after reading last record"); - sctest::Assert(cmpRecord(rec3, rec4), "rec3 != rec4"); + SCTEST_CHECK_NE(cursor, nullptr); + SCTEST_CHECK(cmpRecord(rec3, rec4)); - std::cout << "\tSetRecord 1\n"; TLV::SetRecord(rec4, 3, TEST_STRLEN3, TEST_STR3); - sctest::Assert(TLV::WriteToMemory(backend, nullptr, rec4)); + SCTEST_CHECK(TLV::WriteToMemory(backend, nullptr, rec4)); - std::cout << "FindTag 3\n"; rec4.Tag = 2; cursor = TLV::FindTag(backend, nullptr, rec4); - sctest::Assert(cursor != nullptr); + SCTEST_CHECK_NE(cursor, nullptr); - std::cout << "DeleteRecord\n"; TLV::DeleteRecord(backend, cursor); - sctest::Assert(cursor[0] == 3); -} + SCTEST_CHECK_EQ(cursor[0], 3); + rec4.Tag = 3; + cursor = nullptr; -bool -runSuite(Arena &backend, const char *label) -{ - std::exception exc; - - std::cout << backend << "\n"; - std::cout << "running test suite " << label << ": "; - try { - tlvTestSuite(backend); - } catch (std::exception &exc){ - std::cout << "FAILED: " << exc.what() << "\n"; - return false; - } - std::cout << "OK" << "\n"; - - std::cout << "\tdestroying arena: "; - backend.Destroy(); - - std::cout << "OK" << "\n"; return true; } -int -main(int argc, const char *argv[]) +bool +tlvTestSuite(ArenaType arenaType) { - (void)argc; (void)argv; + Arena backend; - Arena arenaStatic; - Arena arenaMem; - - std::cout << "TESTPROG: " << argv[0] << "\n"; - - if (-1 == arenaStatic.SetStatic(arenaBuffer, ARENA_SIZE)) { - abort(); - } else if (!runSuite(arenaStatic, "arenaStatic")) { - abort(); - } - arenaStatic.Clear(); - - Arena arenaFile; - auto status = arenaFile.Create(ARENA_FILE, ARENA_SIZE); - - if (status != 0) { - std::cerr << "Create failed with error " << status << "\n"; - abort(); - } else if (!runSuite(arenaFile, "arenaFile")) { - abort(); + switch (arenaType) { + case ArenaType::Static: + if (backend.SetStatic(arenaBuffer, ARENA_SIZE) != 0) { + std::cerr << "[!] failed to set up statically-allocated arena\n"; + return false; + } + break; + case ArenaType::Alloc: + if (backend.SetAlloc(ARENA_SIZE) != 0) { + std::cerr << "[!] failed to set up dynamically-allocated arena\n"; + return false; + } + break; + case ArenaType::MemoryMapped: + if (backend.Create(ARENA_FILE, ARENA_SIZE)) { + std::cerr << "[!] failed to set up memory-mapped arena\n"; + return false; + } + break; + default: + std::cerr << "[!] " << static_cast(arenaType) << " is invalid for this test.\n"; + return false; } - if (-1 == arenaMem.SetAlloc(ARENA_SIZE)) { - abort(); - } else if (!runSuite(arenaMem, "arenaMem")) { - abort(); + auto result = runTLVTest(backend); + if (!result) { + std::cerr << "[!] suite failed with " << backend << "\n"; } - arenaMem.Clear(); - - std::cout << "OK" << "\n"; - return 0; + backend.Destroy(); + return result; +} + +std::function +buildTestSuite(ArenaType arenaType) +{ + return [arenaType](){ + return tlvTestSuite(arenaType); + }; +} + + +int +main(int argc, char *argv[]) +{ + auto noReport = false; + auto quiet = false; + auto flags = new scsl::Flags("test_tlv", + "This test validates various TLV-related components in scsl."); + flags->Register("-n", false, "don't print the report"); + flags->Register("-q", false, "suppress test output"); + + auto parsed = flags->Parse(argc, argv); + if (parsed != scsl::Flags::ParseStatus::OK) { + std::cerr << "Failed to parse flags: " + << scsl::Flags::ParseStatusToString(parsed) << "\n"; + } + + sctest::SimpleSuite suite; + flags->GetBool("-n", noReport); + flags->GetBool("-q", quiet); + if (quiet) { + suite.Silence(); + } + + suite.AddTest("ArenaStatic", buildTestSuite(ArenaType::Static)); + suite.AddTest("ArenaAlloc", buildTestSuite(ArenaType::Alloc)); + suite.AddTest("ArenaFile", buildTestSuite(ArenaType::MemoryMapped)); + + delete flags; + auto result = suite.Run(); + if (!noReport) { std::cout << suite.GetReport() << "\n"; } + return result ? 0 : 1; }