diff --git a/src/util/Assert.cpp b/src/util/Assert.cpp new file mode 100644 index 00000000..73abc4c6 --- /dev/null +++ b/src/util/Assert.cpp @@ -0,0 +1,67 @@ +//------------------------------------------------------------------------------ +/* + This file is part of clio: https://github.com/XRPLF/clio + Copyright (c) 2025, the clio developers. + + Permission to use, copy, modify, and 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 "util/Assert.hpp" + +#include "util/log/Logger.hpp" + +#include + +#include +#include +#include +#include + +namespace util::impl { + +OnAssert::ActionType OnAssert::action; + +void +OnAssert::call(std::string_view message) +{ + if (not OnAssert::action) { + resetAction(); + } + OnAssert::action(message); +} + +void +OnAssert::setAction(ActionType newAction) +{ + OnAssert::action = std::move(newAction); +} + +void +OnAssert::resetAction() +{ + OnAssert::action = [](std::string_view m) { OnAssert::defaultAction(m); }; +} + +void +OnAssert::defaultAction(std::string_view message) +{ + if (LogService::enabled()) { + LOG(LogService::fatal()) << message; + } else { + std::cerr << message; + } + std::exit(EXIT_FAILURE); // std::abort does not flush gcovr output and causes uncovered lines +} + +} // namespace util::impl diff --git a/src/util/Assert.hpp b/src/util/Assert.hpp index ad19ea6f..50382985 100644 --- a/src/util/Assert.hpp +++ b/src/util/Assert.hpp @@ -20,9 +20,11 @@ #pragma once #include "util/SourceLocation.hpp" -#include "util/log/Logger.hpp" #include + +#include +#include #ifndef CLIO_WITHOUT_STACKTRACE #include #include @@ -31,9 +33,30 @@ #include #include -#include -namespace util { +namespace util::impl { + +class OnAssert { +public: + using ActionType = std::function; + +private: + static ActionType action; + +public: + static void + call(std::string_view message); + + static void + setAction(ActionType newAction); + + static void + resetAction(); + +private: + static void + defaultAction(std::string_view message); +}; /** * @brief Assert that a condition is true @@ -75,16 +98,12 @@ assertImpl( fmt::format(format, std::forward(args)...) ); #endif - if (boost::log::core::get()->get_logging_enabled()) { - LOG(LogService::fatal()) << resultMessage; - } else { - std::cerr << resultMessage; - } - std::exit(EXIT_FAILURE); // std::abort does not flush gcovr output and causes uncovered lines + + OnAssert::call(resultMessage); } } -} // namespace util +} // namespace util::impl #define ASSERT(condition, ...) \ - util::assertImpl(CURRENT_SRC_LOCATION, #condition, static_cast(condition), __VA_ARGS__) + util::impl::assertImpl(CURRENT_SRC_LOCATION, #condition, static_cast(condition), __VA_ARGS__) diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt index ee988124..51d44765 100644 --- a/src/util/CMakeLists.txt +++ b/src/util/CMakeLists.txt @@ -2,7 +2,8 @@ add_library(clio_util) target_sources( clio_util - PRIVATE build/Build.cpp + PRIVATE Assert.cpp + build/Build.cpp config/Config.cpp CoroutineGroup.cpp log/Logger.cpp diff --git a/src/util/async/AnyOperation.hpp b/src/util/async/AnyOperation.hpp index 2835d8b5..3c0ee171 100644 --- a/src/util/async/AnyOperation.hpp +++ b/src/util/async/AnyOperation.hpp @@ -77,7 +77,7 @@ public: * Used to cancel the timer for scheduled operations and request the operation to be stopped as soon as possible */ void - abort() noexcept + abort() { operation_.abort(); } diff --git a/src/util/log/Logger.cpp b/src/util/log/Logger.cpp index 2e4815a8..3fcad094 100644 --- a/src/util/log/Logger.cpp +++ b/src/util/log/Logger.cpp @@ -199,6 +199,12 @@ LogService::init(config::ClioConfigDefinition const& config) return {}; } +bool +LogService::enabled() +{ + return boost::log::core::get()->get_logging_enabled(); +} + Logger::Pump Logger::trace(SourceLocationType const& loc) const { diff --git a/src/util/log/Logger.hpp b/src/util/log/Logger.hpp index eb6ddcae..6390b47d 100644 --- a/src/util/log/Logger.hpp +++ b/src/util/log/Logger.hpp @@ -367,6 +367,14 @@ public: { return alertLog.warn(loc); } + + /** + * @brief Whether the LogService is enabled or not + * + * @return true if the LogService is enabled, false otherwise + */ + [[nodiscard]] static bool + enabled(); }; }; // namespace util diff --git a/tests/common/CMakeLists.txt b/tests/common/CMakeLists.txt index e0c57718..ed174da1 100644 --- a/tests/common/CMakeLists.txt +++ b/tests/common/CMakeLists.txt @@ -2,7 +2,8 @@ add_library(clio_testing_common) target_sources( clio_testing_common - PRIVATE util/AssignRandomPort.cpp + PRIVATE util/MockAssert.cpp + util/AssignRandomPort.cpp util/CallWithTimeout.cpp util/StringUtils.cpp util/TestHttpClient.cpp diff --git a/tests/common/util/MockAssert.cpp b/tests/common/util/MockAssert.cpp new file mode 100644 index 00000000..055096f9 --- /dev/null +++ b/tests/common/util/MockAssert.cpp @@ -0,0 +1,45 @@ +//------------------------------------------------------------------------------ +/* + This file is part of clio: https://github.com/XRPLF/clio + Copyright (c) 2025, the clio developers. + + Permission to use, copy, modify, and 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 "util/MockAssert.hpp" + +#include "util/Assert.hpp" + +#include +#include + +namespace common::util { + +WithMockAssert::WithMockAssert() +{ + ::util::impl::OnAssert::setAction([](std::string_view m) { WithMockAssert::throwOnAssert(m); }); +} + +WithMockAssert::~WithMockAssert() +{ + ::util::impl::OnAssert::resetAction(); +} + +void +WithMockAssert::throwOnAssert(std::string_view m) +{ + throw MockAssertException{.message = std::string{m}}; +} + +} // namespace common::util diff --git a/tests/common/util/MockAssert.hpp b/tests/common/util/MockAssert.hpp new file mode 100644 index 00000000..0a174114 --- /dev/null +++ b/tests/common/util/MockAssert.hpp @@ -0,0 +1,59 @@ +//------------------------------------------------------------------------------ +/* + This file is part of clio: https://github.com/XRPLF/clio + Copyright (c) 2025, the clio developers. + + Permission to use, copy, modify, and 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. +*/ +//============================================================================== + +#pragma once + +#include +#include + +#include +#include + +namespace common::util { + +class WithMockAssert : virtual public testing::Test { +public: + struct MockAssertException { + std::string message; + }; + + WithMockAssert(); + ~WithMockAssert() override; + +private: + static void + throwOnAssert(std::string_view m); +}; + +} // namespace common::util + +#define EXPECT_CLIO_ASSERT_FAIL(statement) EXPECT_THROW(statement, MockAssertException) + +#define EXPECT_CLIO_ASSERT_FAIL_WITH_MESSAGE(statement, message_regex) \ + EXPECT_THROW( \ + { \ + try { \ + statement; \ + } catch (common::util::WithMockAssert::MockAssertException const& e) { \ + EXPECT_THAT(e.message, testing::ContainsRegex(message_regex)); \ + throw; \ + } \ + }, \ + common::util::WithMockAssert::MockAssertException \ + ) diff --git a/tests/unit/data/AmendmentCenterTests.cpp b/tests/unit/data/AmendmentCenterTests.cpp index 0a732b2d..2ea254fc 100644 --- a/tests/unit/data/AmendmentCenterTests.cpp +++ b/tests/unit/data/AmendmentCenterTests.cpp @@ -20,6 +20,7 @@ #include "data/AmendmentCenter.hpp" #include "data/Types.hpp" #include "util/AsioContextTestFixture.hpp" +#include "util/MockAssert.hpp" #include "util/MockBackendTestFixture.hpp" #include "util/MockPrometheus.hpp" #include "util/TestObject.hpp" @@ -149,12 +150,12 @@ TEST(AmendmentTest, GenerateAmendmentId) ); } -struct AmendmentCenterDeathTest : AmendmentCenterTest {}; +struct AmendmentCenterAssertTest : common::util::WithMockAssert, AmendmentCenterTest {}; -TEST_F(AmendmentCenterDeathTest, GetInvalidAmendmentAsserts) +TEST_F(AmendmentCenterAssertTest, GetInvalidAmendmentAsserts) { - EXPECT_DEATH({ [[maybe_unused]] auto _ = amendmentCenter.getAmendment("invalidAmendmentKey"); }, ".*"); - EXPECT_DEATH({ [[maybe_unused]] auto _ = amendmentCenter["invalidAmendmentKey"]; }, ".*"); + EXPECT_CLIO_ASSERT_FAIL({ [[maybe_unused]] auto _ = amendmentCenter.getAmendment("invalidAmendmentKey"); }); + EXPECT_CLIO_ASSERT_FAIL({ [[maybe_unused]] auto _ = amendmentCenter["invalidAmendmentKey"]; }); } struct AmendmentKeyTest : testing::Test {}; diff --git a/tests/unit/etlng/ExtractionTests.cpp b/tests/unit/etlng/ExtractionTests.cpp index 012145bc..9d50784b 100644 --- a/tests/unit/etlng/ExtractionTests.cpp +++ b/tests/unit/etlng/ExtractionTests.cpp @@ -24,6 +24,7 @@ #include "etlng/impl/Extraction.hpp" #include "util/BinaryTestObject.hpp" #include "util/LoggerFixtures.hpp" +#include "util/MockAssert.hpp" #include "util/TestObject.hpp" #include @@ -359,21 +360,17 @@ TEST_F(ExtractionNgTests, SuccessorsWithNoNeighborsIncluded) ASSERT_FALSE(res.has_value()); } -struct ExtractionDeathTest : NoLoggerFixture {}; +struct ExtractionAssertTest : common::util::WithMockAssert, NoLoggerFixture {}; -TEST_F(ExtractionDeathTest, InvalidModTypeAsserts) +TEST_F(ExtractionAssertTest, InvalidModTypeAsserts) { using namespace etlng::impl; - EXPECT_DEATH( - { - [[maybe_unused]] auto _ = extractModType( - PBModType:: - RawLedgerObject_ModificationType_RawLedgerObject_ModificationType_INT_MIN_SENTINEL_DO_NOT_USE_ - ); - }, - ".*" - ); + EXPECT_CLIO_ASSERT_FAIL({ + [[maybe_unused]] auto _ = extractModType( + PBModType::RawLedgerObject_ModificationType_RawLedgerObject_ModificationType_INT_MIN_SENTINEL_DO_NOT_USE_ + ); + }); } struct MockFetcher : etl::LedgerFetcherInterface { diff --git a/tests/unit/etlng/LoadingTests.cpp b/tests/unit/etlng/LoadingTests.cpp index 5f14513b..452c1bf8 100644 --- a/tests/unit/etlng/LoadingTests.cpp +++ b/tests/unit/etlng/LoadingTests.cpp @@ -24,6 +24,7 @@ #include "etlng/impl/Loading.hpp" #include "rpc/RPCHelpers.hpp" #include "util/BinaryTestObject.hpp" +#include "util/MockAssert.hpp" #include "util/MockBackendTestFixture.hpp" #include "util/MockETLServiceTestFixture.hpp" #include "util/MockPrometheus.hpp" @@ -71,7 +72,7 @@ protected: Loader loader_{backend_, mockLedgerFetcherPtr_, mockRegistryPtr_, mockAmendmentBlockHandlerPtr_}; }; -struct LoadingDeathTest : LoadingTests {}; +struct LoadingAssertTest : common::util::WithMockAssert, LoadingTests {}; auto createTestData() @@ -146,7 +147,7 @@ TEST_F(LoadingTests, OnInitialLoadGotMoreObjectsWithoutKey) loader_.onInitialLoadGotMoreObjects(kSEQ, data.objects, lastKey); } -TEST_F(LoadingDeathTest, LoadInitialLedgerHasDataInDB) +TEST_F(LoadingAssertTest, LoadInitialLedgerHasDataInDB) { auto const data = createTestData(); auto const range = LedgerRange{.minSequence = kSEQ - 1, .maxSequence = kSEQ}; @@ -156,5 +157,5 @@ TEST_F(LoadingDeathTest, LoadInitialLedgerHasDataInDB) testing::Mock::AllowLeak(&*backend_); ON_CALL(*backend_, hardFetchLedgerRange(testing::_)).WillByDefault(testing::Return(range)); - EXPECT_DEATH({ [[maybe_unused]] auto unused = loader_.loadInitialLedger(data); }, ".*"); + EXPECT_CLIO_ASSERT_FAIL({ [[maybe_unused]] auto unused = loader_.loadInitialLedger(data); }); } diff --git a/tests/unit/migration/MigrationInspectorFactoryTests.cpp b/tests/unit/migration/MigrationInspectorFactoryTests.cpp index 9c91a8ac..23352d2e 100644 --- a/tests/unit/migration/MigrationInspectorFactoryTests.cpp +++ b/tests/unit/migration/MigrationInspectorFactoryTests.cpp @@ -19,6 +19,7 @@ #include "data/Types.hpp" #include "migration/MigrationInspectorFactory.hpp" +#include "util/MockAssert.hpp" #include "util/MockBackendTestFixture.hpp" #include "util/MockPrometheus.hpp" #include "util/newconfig/ConfigDefinition.hpp" @@ -32,18 +33,18 @@ using namespace testing; -struct MigrationInspectorFactoryTests : public util::prometheus::WithPrometheus, public MockBackendTest { +struct MigrationInspectorFactoryTests : util::prometheus::WithPrometheus, + common::util::WithMockAssert, + MockBackendTest { protected: util::config::ClioConfigDefinition const readerConfig_ = util::config::ClioConfigDefinition{ {"read_only", util::config::ConfigValue{util::config::ConfigType::Boolean}.defaultValue(true)} }; }; -struct MigrationInspectorFactoryTestsDeathTest : public MigrationInspectorFactoryTests {}; - -TEST_F(MigrationInspectorFactoryTestsDeathTest, NullBackend) +TEST_F(MigrationInspectorFactoryTests, NullBackend) { - EXPECT_DEATH(migration::makeMigrationInspector(readerConfig_, nullptr), ".*"); + EXPECT_CLIO_ASSERT_FAIL(migration::makeMigrationInspector(readerConfig_, nullptr)); } TEST_F(MigrationInspectorFactoryTests, NotInitMigrationTableIfReader) diff --git a/tests/unit/migration/cassandra/FullTableScannerTests.cpp b/tests/unit/migration/cassandra/FullTableScannerTests.cpp index f45ab6d4..f4b0a669 100644 --- a/tests/unit/migration/cassandra/FullTableScannerTests.cpp +++ b/tests/unit/migration/cassandra/FullTableScannerTests.cpp @@ -19,6 +19,7 @@ #include "migration/cassandra/impl/FullTableScanner.hpp" #include "util/LoggerFixtures.hpp" +#include "util/MockAssert.hpp" #include #include @@ -51,30 +52,32 @@ struct TestScannerAdaper { }; } // namespace -struct FullTableScannerTests : public NoLoggerFixture {}; +struct FullTableScannerAssertTest : common::util::WithMockAssert {}; -TEST_F(FullTableScannerTests, workerNumZero) +TEST_F(FullTableScannerAssertTest, workerNumZero) { testing::MockFunction mockCallback; - EXPECT_DEATH( + EXPECT_CLIO_ASSERT_FAIL_WITH_MESSAGE( migration::cassandra::impl::FullTableScanner( {.ctxThreadsNum = 1, .jobsNum = 0, .cursorsPerJob = 100}, TestScannerAdaper(mockCallback) ), - "jobsNum for full table scanner must be greater than 0" + ".*jobsNum for full table scanner must be greater than 0" ); } -TEST_F(FullTableScannerTests, cursorsPerWorkerZero) +TEST_F(FullTableScannerAssertTest, cursorsPerWorkerZero) { testing::MockFunction mockCallback; - EXPECT_DEATH( + EXPECT_CLIO_ASSERT_FAIL_WITH_MESSAGE( migration::cassandra::impl::FullTableScanner( {.ctxThreadsNum = 1, .jobsNum = 1, .cursorsPerJob = 0}, TestScannerAdaper(mockCallback) ), - "cursorsPerJob for full table scanner must be greater than 0" + ".*cursorsPerJob for full table scanner must be greater than 0" ); } +struct FullTableScannerTests : NoLoggerFixture {}; + TEST_F(FullTableScannerTests, SingleThreadCtx) { testing::MockFunction mockCallback; diff --git a/tests/unit/rpc/handlers/AllHandlerTests.cpp b/tests/unit/rpc/handlers/AllHandlerTests.cpp index cf82e91b..1b5bfc43 100644 --- a/tests/unit/rpc/handlers/AllHandlerTests.cpp +++ b/tests/unit/rpc/handlers/AllHandlerTests.cpp @@ -50,6 +50,7 @@ #include "util/Assert.hpp" #include "util/HandlerBaseTestFixture.hpp" #include "util/MockAmendmentCenter.hpp" +#include "util/MockAssert.hpp" #include "util/MockCounters.hpp" #include "util/MockCountersFixture.hpp" #include "util/MockETLService.hpp" @@ -113,11 +114,12 @@ using AnyHandlerType = Types< TransactionEntryHandler>; template -struct AllHandlersDeathTest : HandlerBaseTest, - MockLoadBalancerTest, - MockCountersTest, - testing::WithParamInterface { - AllHandlersDeathTest() : handler_{initHandler()} +struct AllHandlersAssertTest : common::util::WithMockAssert, + HandlerBaseTest, + MockLoadBalancerTest, + MockCountersTest, + testing::WithParamInterface { + AllHandlersAssertTest() : handler_{initHandler()} { ASSERT(mockAmendmentCenterPtr_.amendmentCenterMock != nullptr, "mockAmendmentCenterPtr is not initialized."); ASSERT( @@ -244,9 +246,9 @@ createInput() return input; } -TYPED_TEST_CASE(AllHandlersDeathTest, AnyHandlerType); +TYPED_TEST_CASE(AllHandlersAssertTest, AnyHandlerType); -TYPED_TEST(AllHandlersDeathTest, NoRangeAvailable) +TYPED_TEST(AllHandlersAssertTest, NoRangeAvailable) { // doesn't work without 'this' this->runSpawn( @@ -256,7 +258,7 @@ TYPED_TEST(AllHandlersDeathTest, NoRangeAvailable) auto const input = createInput(); auto const context = Context{yield, this->session_}; - EXPECT_DEATH( + EXPECT_CLIO_ASSERT_FAIL_WITH_MESSAGE( { [[maybe_unused]] auto unused = handler.process(input, context); }, "Assertion .* failed at .*" ); }, diff --git a/tests/unit/util/AssertTests.cpp b/tests/unit/util/AssertTests.cpp index 60d4d986..e85e4882 100644 --- a/tests/unit/util/AssertTests.cpp +++ b/tests/unit/util/AssertTests.cpp @@ -18,15 +18,18 @@ //============================================================================== #include "util/Assert.hpp" +#include "util/MockAssert.hpp" #include -TEST(AssertTests, assertTrue) +struct AssertTest : common::util::WithMockAssert {}; + +TEST_F(AssertTest, assertTrue) { EXPECT_NO_THROW(ASSERT(true, "Should not fail")); } -TEST(AssertDeathTest, assertFalse) +TEST_F(AssertTest, assertFalse) { - EXPECT_DEATH({ ASSERT(false, "failure"); }, ".*"); + EXPECT_CLIO_ASSERT_FAIL({ ASSERT(false, "failure"); }); } diff --git a/tests/unit/util/SignalsHandlerTests.cpp b/tests/unit/util/SignalsHandlerTests.cpp index 3001a880..8288c179 100644 --- a/tests/unit/util/SignalsHandlerTests.cpp +++ b/tests/unit/util/SignalsHandlerTests.cpp @@ -18,6 +18,7 @@ //============================================================================== #include "util/LoggerFixtures.hpp" +#include "util/MockAssert.hpp" #include "util/SignalsHandler.hpp" #include "util/newconfig/ConfigDefinition.hpp" #include "util/newconfig/ConfigValue.hpp" @@ -64,7 +65,9 @@ protected: bool testCanBeFinished_{false}; }; -TEST(SignalsHandlerDeathTest, CantCreateTwoSignalsHandlers) +struct SignalsHandlerAssertTest : common::util::WithMockAssert {}; + +TEST_F(SignalsHandlerAssertTest, CantCreateTwoSignalsHandlers) { auto makeHandler = []() { return SignalsHandler{ @@ -72,7 +75,7 @@ TEST(SignalsHandlerDeathTest, CantCreateTwoSignalsHandlers) }; }; auto const handler = makeHandler(); - EXPECT_DEATH({ makeHandler(); }, ".*"); + EXPECT_CLIO_ASSERT_FAIL({ makeHandler(); }); } struct SignalsHandlerTests : SignalsHandlerTestsBase { diff --git a/tests/unit/util/async/AnyOperationTests.cpp b/tests/unit/util/async/AnyOperationTests.cpp index 87451d74..06f9157e 100644 --- a/tests/unit/util/async/AnyOperationTests.cpp +++ b/tests/unit/util/async/AnyOperationTests.cpp @@ -17,6 +17,7 @@ */ //============================================================================== +#include "util/MockAssert.hpp" #include "util/MockOperation.hpp" #include "util/async/AnyOperation.hpp" #include "util/async/Error.hpp" @@ -32,7 +33,7 @@ using namespace util::async; using namespace ::testing; -struct AnyOperationTests : Test { +struct AnyOperationTests : virtual Test { using OperationType = MockOperation>; using StoppableOperationType = MockStoppableOperation>; using ScheduledOperationType = MockScheduledOperation>; @@ -49,7 +50,6 @@ struct AnyOperationTests : Test { AnyOperation scheduledVoidOp{impl::ErasedOperation(static_cast(mockScheduledOp))}; AnyOperation repeatingOp{impl::ErasedOperation(static_cast(mockRepeatingOp))}; }; -using AnyOperationDeathTest = AnyOperationTests; TEST_F(AnyOperationTests, Move) { @@ -134,12 +134,14 @@ TEST_F(AnyOperationTests, RepeatingOpInvokeCallPropagated) repeatingOp.invoke(); } -TEST_F(AnyOperationDeathTest, CallAbortOnNonStoppableOrCancellableOperation) +struct AnyOperationAssertTest : common::util::WithMockAssert, AnyOperationTests {}; + +TEST_F(AnyOperationAssertTest, CallAbortOnNonStoppableOrCancellableOperation) { - EXPECT_DEATH(voidOp.abort(), ".*"); + EXPECT_CLIO_ASSERT_FAIL(voidOp.abort()); } -TEST_F(AnyOperationDeathTest, CallInvokeOnNonForceInvocableOperation) +TEST_F(AnyOperationAssertTest, CallInvokeOnNonForceInvocableOperation) { - EXPECT_DEATH(voidOp.invoke(), ".*"); + EXPECT_CLIO_ASSERT_FAIL(voidOp.invoke()); } diff --git a/tests/unit/util/async/AnyStopTokenTests.cpp b/tests/unit/util/async/AnyStopTokenTests.cpp index 4767b2de..9c6b31d9 100644 --- a/tests/unit/util/async/AnyStopTokenTests.cpp +++ b/tests/unit/util/async/AnyStopTokenTests.cpp @@ -17,6 +17,7 @@ */ //============================================================================== +#include "util/MockAssert.hpp" #include "util/async/AnyStopToken.hpp" #include @@ -38,7 +39,6 @@ struct FakeStopToken { } // namespace struct AnyStopTokenTests : public TestWithParam {}; -using AnyStopTokenDeathTest = AnyStopTokenTests; INSTANTIATE_TEST_CASE_P(AnyStopTokenGroup, AnyStopTokenTests, ValuesIn({true, false}), [](auto const& info) { return info.param ? "true" : "false"; @@ -61,9 +61,11 @@ TEST_P(AnyStopTokenTests, IsStopRequestedCallPropagated) EXPECT_EQ(stopToken, flag); } -TEST_F(AnyStopTokenDeathTest, ConversionToYieldContextAssertsIfUnsupported) +struct AnyStopTokenAssertTest : common::util::WithMockAssert {}; + +TEST_F(AnyStopTokenAssertTest, ConversionToYieldContextAssertsIfUnsupported) { - EXPECT_DEATH( - [[maybe_unused]] auto unused = static_cast(AnyStopToken{FakeStopToken{}}), ".*" + EXPECT_CLIO_ASSERT_FAIL( + [[maybe_unused]] auto unused = static_cast(AnyStopToken{FakeStopToken{}}) ); } diff --git a/tests/unit/util/newconfig/ArrayTests.cpp b/tests/unit/util/newconfig/ArrayTests.cpp index 76f99ec8..66e6d4ef 100644 --- a/tests/unit/util/newconfig/ArrayTests.cpp +++ b/tests/unit/util/newconfig/ArrayTests.cpp @@ -17,6 +17,7 @@ */ //============================================================================== +#include "util/MockAssert.hpp" #include "util/newconfig/Array.hpp" #include "util/newconfig/ConfigConstraints.hpp" #include "util/newconfig/ConfigValue.hpp" @@ -38,9 +39,11 @@ TEST(ArrayTest, prefix) EXPECT_EQ(Array::prefix("foo.bar.[].baz"), "foo.bar.[]"); } -TEST(ArrayDeathTest, prefix) +struct ArrayAssertTest : common::util::WithMockAssert {}; + +TEST_F(ArrayAssertTest, prefix) { - EXPECT_DEATH(Array::prefix("foo.bar"), ".*"); + EXPECT_CLIO_ASSERT_FAIL(Array::prefix("foo.bar")); } TEST(ArrayTest, addSingleValue) diff --git a/tests/unit/util/newconfig/ArrayViewTests.cpp b/tests/unit/util/newconfig/ArrayViewTests.cpp index 057101c4..6464b0b9 100644 --- a/tests/unit/util/newconfig/ArrayViewTests.cpp +++ b/tests/unit/util/newconfig/ArrayViewTests.cpp @@ -17,6 +17,7 @@ */ //============================================================================== +#include "util/MockAssert.hpp" #include "util/newconfig/ArrayView.hpp" #include "util/newconfig/ConfigDefinition.hpp" #include "util/newconfig/ConfigFileJson.hpp" @@ -33,7 +34,7 @@ using namespace util::config; -struct ArrayViewTest : testing::Test { +struct ArrayViewTest : virtual testing::Test { ArrayViewTest() { ConfigFileJson const jsonFileObj{boost::json::parse(kJSON_DATA).as_object()}; @@ -147,31 +148,31 @@ TEST_F(ArrayViewTest, IterateObject) EXPECT_EQ(it, arr.end()); } -struct ArrayViewDeathTest : ArrayViewTest {}; +struct ArrayViewAssertTest : common::util::WithMockAssert, ArrayViewTest {}; -TEST_F(ArrayViewDeathTest, AccessArrayOutOfBounce) +TEST_F(ArrayViewAssertTest, AccessArrayOutOfBounce) { // dies because higher only has 1 object (trying to access 2nd element) - EXPECT_DEATH({ [[maybe_unused]] auto _ = configData.getArray("higher").objectAt(1); }, ".*"); + EXPECT_CLIO_ASSERT_FAIL({ [[maybe_unused]] auto _ = configData.getArray("higher").objectAt(1); }); } -TEST_F(ArrayViewDeathTest, AccessIndexOfWrongType) +TEST_F(ArrayViewAssertTest, AccessIndexOfWrongType) { auto const& arrVals2 = configData.getArray("array.[].sub2"); auto const& tempVal = arrVals2.valueAt(0); // dies as value is not of type int - EXPECT_DEATH({ [[maybe_unused]] auto _ = tempVal.asIntType(); }, ".*"); + EXPECT_CLIO_ASSERT_FAIL({ [[maybe_unused]] auto _ = tempVal.asIntType(); }); } -TEST_F(ArrayViewDeathTest, GetValueWhenItIsObject) +TEST_F(ArrayViewAssertTest, GetValueWhenItIsObject) { ArrayView const arr = configData.getArray("higher"); - EXPECT_DEATH({ [[maybe_unused]] auto _ = arr.begin(); }, ".*"); + EXPECT_CLIO_ASSERT_FAIL({ [[maybe_unused]] auto _ = arr.begin(); }); } -TEST_F(ArrayViewDeathTest, GetObjectWhenItIsValue) +TEST_F(ArrayViewAssertTest, GetObjectWhenItIsValue) { ArrayView const dosguardWhitelist = configData.getArray("dosguard.whitelist"); - EXPECT_DEATH({ [[maybe_unused]] auto _ = dosguardWhitelist.begin(); }, ".*"); + EXPECT_CLIO_ASSERT_FAIL({ [[maybe_unused]] auto _ = dosguardWhitelist.begin(); }); } diff --git a/tests/unit/util/newconfig/ClioConfigDefinitionTests.cpp b/tests/unit/util/newconfig/ClioConfigDefinitionTests.cpp index 5a55a9ec..987ed6ad 100644 --- a/tests/unit/util/newconfig/ClioConfigDefinitionTests.cpp +++ b/tests/unit/util/newconfig/ClioConfigDefinitionTests.cpp @@ -18,6 +18,7 @@ //============================================================================== #include "util/LoggerFixtures.hpp" +#include "util/MockAssert.hpp" #include "util/newconfig/Array.hpp" #include "util/newconfig/ArrayView.hpp" #include "util/newconfig/ConfigDefinition.hpp" @@ -45,7 +46,7 @@ using namespace util::config; -struct NewConfigTest : testing::Test { +struct NewConfigTest : virtual testing::Test { ClioConfigDefinition const configData = generateConfig(); }; @@ -129,41 +130,41 @@ TEST_F(NewConfigTest, CheckAllKeys) EXPECT_EQ(expected, actual); } -struct NewConfigDeathTest : NewConfigTest {}; +struct NewConfigAssertTest : common::util::WithMockAssert, NewConfigTest {}; -TEST_F(NewConfigDeathTest, GetNonExistentKeys) +TEST_F(NewConfigAssertTest, GetNonExistentKeys) { - EXPECT_DEATH({ [[maybe_unused]] auto unused = configData.getValueView("head."); }, ".*"); - EXPECT_DEATH({ [[maybe_unused]] auto unused = configData.getValueView("asdf"); }, ".*"); + EXPECT_CLIO_ASSERT_FAIL({ [[maybe_unused]] auto unused = configData.getValueView("head."); }); + EXPECT_CLIO_ASSERT_FAIL({ [[maybe_unused]] auto unused = configData.getValueView("asdf"); }); } -TEST_F(NewConfigDeathTest, GetValueButIsArray) +TEST_F(NewConfigAssertTest, GetValueButIsArray) { - EXPECT_DEATH({ [[maybe_unused]] auto unused = configData.getValueView("dosguard.whitelist"); }, ".*"); - EXPECT_DEATH({ [[maybe_unused]] auto unused = configData.getValueView("dosguard.whitelist.[]"); }, ".*"); + EXPECT_CLIO_ASSERT_FAIL({ [[maybe_unused]] auto unused = configData.getValueView("dosguard.whitelist"); }); + EXPECT_CLIO_ASSERT_FAIL({ [[maybe_unused]] auto unused = configData.getValueView("dosguard.whitelist.[]"); }); } -TEST_F(NewConfigDeathTest, GetNonExistentObjectKey) +TEST_F(NewConfigAssertTest, GetNonExistentObjectKey) { ASSERT_FALSE(configData.contains("head")); - EXPECT_DEATH({ [[maybe_unused]] auto unused = configData.getObject("head"); }, ".*"); - EXPECT_DEATH({ [[maybe_unused]] auto unused = configData.getObject("doesNotExist"); }, ".*"); + EXPECT_CLIO_ASSERT_FAIL({ [[maybe_unused]] auto unused = configData.getObject("head"); }); + EXPECT_CLIO_ASSERT_FAIL({ [[maybe_unused]] auto unused = configData.getObject("doesNotExist"); }); } -TEST_F(NewConfigDeathTest, GetObjectButIsArray) +TEST_F(NewConfigAssertTest, GetObjectButIsArray) { - EXPECT_DEATH({ [[maybe_unused]] auto unused = configData.getObject("array"); }, ".*"); - EXPECT_DEATH({ [[maybe_unused]] auto unused = configData.getObject("array", 2); }, ".*"); + EXPECT_CLIO_ASSERT_FAIL({ [[maybe_unused]] auto unused = configData.getObject("array"); }); + EXPECT_CLIO_ASSERT_FAIL({ [[maybe_unused]] auto unused = configData.getObject("array", 2); }); } -TEST_F(NewConfigDeathTest, GetArrayButIsValue) +TEST_F(NewConfigAssertTest, GetArrayButIsValue) { - EXPECT_DEATH({ [[maybe_unused]] auto unused = configData.getArray("header.text1"); }, ".*"); + EXPECT_CLIO_ASSERT_FAIL({ [[maybe_unused]] auto unused = configData.getArray("header.text1"); }); } -TEST_F(NewConfigDeathTest, GetNonExistentArrayKey) +TEST_F(NewConfigAssertTest, GetNonExistentArrayKey) { - EXPECT_DEATH({ [[maybe_unused]] auto unused = configData.getArray("asdf"); }, ".*"); + EXPECT_CLIO_ASSERT_FAIL({ [[maybe_unused]] auto unused = configData.getArray("asdf"); }); } TEST(ConfigDescription, GetValues) @@ -178,12 +179,14 @@ TEST(ConfigDescription, GetValues) EXPECT_EQ(definition.get("prometheus.enabled"), "Enable or disable Prometheus metrics."); } -TEST(ConfigDescriptionAssertDeathTest, NonExistingKeyTest) +struct ConfigDescriptionAssertTest : common::util::WithMockAssert {}; + +TEST_F(ConfigDescriptionAssertTest, NonExistingKeyTest) { ClioConfigDescription const definition{}; - EXPECT_DEATH({ [[maybe_unused]] auto a = definition.get("data"); }, ".*"); - EXPECT_DEATH({ [[maybe_unused]] auto a = definition.get("etl_sources.[]"); }, ".*"); + EXPECT_CLIO_ASSERT_FAIL({ [[maybe_unused]] auto a = definition.get("data"); }); + EXPECT_CLIO_ASSERT_FAIL({ [[maybe_unused]] auto a = definition.get("etl_sources.[]"); }); } /** @brief Testing override the default values with the ones in Json */ diff --git a/tests/unit/util/newconfig/ConfigFileJsonTests.cpp b/tests/unit/util/newconfig/ConfigFileJsonTests.cpp index ea7830bc..d95a436b 100644 --- a/tests/unit/util/newconfig/ConfigFileJsonTests.cpp +++ b/tests/unit/util/newconfig/ConfigFileJsonTests.cpp @@ -18,6 +18,7 @@ //============================================================================== #include "util/LoggerFixtures.hpp" +#include "util/MockAssert.hpp" #include "util/NameGenerator.hpp" #include "util/OverloadSet.hpp" #include "util/TmpFile.hpp" @@ -338,30 +339,30 @@ TEST_F(ConfigFileJsonTest, getValue) EXPECT_FALSE(jsonFileObj.containsKey("object.int")); } -struct ConfigFileJsonDeathTest : ConfigFileJsonTest {}; +struct ConfigFileJsonAssertTest : common::util::WithMockAssert, ConfigFileJsonTest {}; -TEST_F(ConfigFileJsonDeathTest, getValueInvalidKey) +TEST_F(ConfigFileJsonAssertTest, getValueInvalidKey) { auto const jsonFileObj = ConfigFileJson{boost::json::parse("{}").as_object()}; - EXPECT_DEATH([[maybe_unused]] auto a = jsonFileObj.getValue("some_key"), ".*"); + EXPECT_CLIO_ASSERT_FAIL([[maybe_unused]] auto a = jsonFileObj.getValue("some_key")); } -TEST_F(ConfigFileJsonDeathTest, getValueOfArray) +TEST_F(ConfigFileJsonAssertTest, getValueOfArray) { auto const jsonStr = R"json({ "array": [1, 2, 3] })json"; auto const jsonFileObj = ConfigFileJson{boost::json::parse(jsonStr).as_object()}; - EXPECT_DEATH([[maybe_unused]] auto a = jsonFileObj.getValue("array"), ".*"); + EXPECT_CLIO_ASSERT_FAIL([[maybe_unused]] auto a = jsonFileObj.getValue("array")); } -TEST_F(ConfigFileJsonDeathTest, nullIsNotSupported) +TEST_F(ConfigFileJsonAssertTest, nullIsNotSupported) { auto const jsonStr = R"json({ "null": null })json"; auto const jsonFileObj = ConfigFileJson{boost::json::parse(jsonStr).as_object()}; - EXPECT_DEATH([[maybe_unused]] auto a = jsonFileObj.getValue("null"), ".*"); + EXPECT_CLIO_ASSERT_FAIL([[maybe_unused]] auto a = jsonFileObj.getValue("null")); } TEST_F(ConfigFileJsonTest, getArray) @@ -444,19 +445,19 @@ TEST_F(ConfigFileJsonTest, getArrayOptionalInArray) EXPECT_EQ(std::get(bools.at(1).value()), true); } -TEST_F(ConfigFileJsonDeathTest, getArrayInvalidKey) +TEST_F(ConfigFileJsonAssertTest, getArrayInvalidKey) { auto const jsonFileObj = ConfigFileJson{boost::json::parse("{}").as_object()}; - EXPECT_DEATH([[maybe_unused]] auto a = jsonFileObj.getArray("some_key"), ".*"); + EXPECT_CLIO_ASSERT_FAIL([[maybe_unused]] auto a = jsonFileObj.getArray("some_key")); } -TEST_F(ConfigFileJsonDeathTest, getArrayNotArray) +TEST_F(ConfigFileJsonAssertTest, getArrayNotArray) { auto const jsonStr = R"json({ "int": 42 })json"; auto const jsonFileObj = ConfigFileJson{boost::json::parse(jsonStr).as_object()}; - EXPECT_DEATH([[maybe_unused]] auto a = jsonFileObj.getArray("int"), ".*"); + EXPECT_CLIO_ASSERT_FAIL([[maybe_unused]] auto a = jsonFileObj.getArray("int")); } TEST_F(ConfigFileJsonTest, containsKey) diff --git a/tests/unit/util/newconfig/ConfigValueTests.cpp b/tests/unit/util/newconfig/ConfigValueTests.cpp index 468ba746..ecd54956 100644 --- a/tests/unit/util/newconfig/ConfigValueTests.cpp +++ b/tests/unit/util/newconfig/ConfigValueTests.cpp @@ -18,6 +18,7 @@ //============================================================================== #include "util/LoggerFixtures.hpp" +#include "util/MockAssert.hpp" #include "util/newconfig/ConfigConstraints.hpp" #include "util/newconfig/ConfigValue.hpp" #include "util/newconfig/Error.hpp" @@ -34,8 +35,7 @@ using namespace util::config; -struct ConfigValueTest : NoLoggerFixture {}; -struct ConfigValueDeathTest : ConfigValueTest {}; +struct ConfigValueTest : common::util::WithMockAssert, NoLoggerFixture {}; TEST_F(ConfigValueTest, construct) { @@ -69,9 +69,9 @@ TEST_F(ConfigValueTest, defaultValueWithDescription) EXPECT_EQ(cv.type(), ConfigType::String); } -TEST_F(ConfigValueDeathTest, invalidDefaultValue) +TEST_F(ConfigValueTest, invalidDefaultValue) { - EXPECT_DEATH({ [[maybe_unused]] auto const a = ConfigValue{ConfigType::String}.defaultValue(33); }, ".*"); + EXPECT_CLIO_ASSERT_FAIL({ [[maybe_unused]] auto const a = ConfigValue{ConfigType::String}.defaultValue(33); }); } TEST_F(ConfigValueTest, setValueWrongType) @@ -128,19 +128,13 @@ TEST_F(ConfigValueConstraintTest, defaultValueWithConstraint) EXPECT_EQ(cv.getValue(), Value{123}); } -struct ConfigValueConstraintDeathTest : ConfigValueConstraintTest {}; - -TEST_F(ConfigValueConstraintDeathTest, defaultValueWithConstraintCheckError) +TEST_F(ConfigValueConstraintTest, defaultValueWithConstraintCheckError) { - EXPECT_DEATH( - { - EXPECT_CALL(constraint, checkTypeImpl).WillOnce(testing::Return(std::nullopt)); - EXPECT_CALL(constraint, checkValueImpl).WillOnce(testing::Return(Error{"value error"})); - [[maybe_unused]] auto const cv = - ConfigValue{ConfigType::Integer}.defaultValue(123).withConstraint(constraint); - }, - ".*" - ); + EXPECT_CLIO_ASSERT_FAIL({ + EXPECT_CALL(constraint, checkTypeImpl).WillOnce(testing::Return(std::nullopt)); + EXPECT_CALL(constraint, checkValueImpl).WillOnce(testing::Return(Error{"value error"})); + [[maybe_unused]] auto const cv = ConfigValue{ConfigType::Integer}.defaultValue(123).withConstraint(constraint); + }); } // A test for each constraint so it's easy to change in the future @@ -259,11 +253,11 @@ struct ConstraintTestBundle { Constraint const& constraint; }; -struct ConstraintDeathTest : testing::TestWithParam {}; +struct ConstraintAssertTest : common::util::WithMockAssert, testing::WithParamInterface {}; INSTANTIATE_TEST_SUITE_P( EachConstraints, - ConstraintDeathTest, + ConstraintAssertTest, testing::Values( ConstraintTestBundle{"logTagConstraint", gValidateLogTag}, ConstraintTestBundle{"portConstraint", gValidatePort}, @@ -281,43 +275,28 @@ INSTANTIATE_TEST_SUITE_P( [](testing::TestParamInfo const& info) { return info.param.name; } ); -TEST_P(ConstraintDeathTest, TestEachConstraint) +TEST_P(ConstraintAssertTest, TestEachConstraint) { - EXPECT_DEATH( - { - [[maybe_unused]] auto const a = - ConfigValue{ConfigType::Boolean}.defaultValue(true).withConstraint(GetParam().constraint); - }, - ".*" - ); + EXPECT_CLIO_ASSERT_FAIL({ + [[maybe_unused]] auto const a = + ConfigValue{ConfigType::Boolean}.defaultValue(true).withConstraint(GetParam().constraint); + }); } -TEST(ConstraintDeathTest, SetInvalidValueTypeStringAndBool) +TEST_F(ConstraintAssertTest, SetInvalidValueTypeStringAndBool) { - EXPECT_DEATH( - { - [[maybe_unused]] auto a = - ConfigValue{ConfigType::String}.defaultValue(33).withConstraint(gValidateLoadMode); - }, - ".*" - ); - EXPECT_DEATH({ [[maybe_unused]] auto a = ConfigValue{ConfigType::Boolean}.defaultValue(-66); }, ".*"); + EXPECT_CLIO_ASSERT_FAIL({ + [[maybe_unused]] auto a = ConfigValue{ConfigType::String}.defaultValue(33).withConstraint(gValidateLoadMode); + }); + EXPECT_CLIO_ASSERT_FAIL({ [[maybe_unused]] auto a = ConfigValue{ConfigType::Boolean}.defaultValue(-66); }); } -TEST(ConstraintDeathTest, OutOfBounceIntegerConstraint) +TEST_F(ConstraintAssertTest, OutOfBounceIntegerConstraint) { - EXPECT_DEATH( - { - [[maybe_unused]] auto a = - ConfigValue{ConfigType::Integer}.defaultValue(999999).withConstraint(gValidateUint16); - }, - ".*" - ); - EXPECT_DEATH( - { - [[maybe_unused]] auto a = - ConfigValue{ConfigType::Integer}.defaultValue(-66).withConstraint(gValidateUint32); - }, - ".*" - ); + EXPECT_CLIO_ASSERT_FAIL({ + [[maybe_unused]] auto a = ConfigValue{ConfigType::Integer}.defaultValue(999999).withConstraint(gValidateUint16); + }); + EXPECT_CLIO_ASSERT_FAIL({ + [[maybe_unused]] auto a = ConfigValue{ConfigType::Integer}.defaultValue(-66).withConstraint(gValidateUint32); + }); } diff --git a/tests/unit/util/newconfig/JsonFileTests.cpp b/tests/unit/util/newconfig/JsonFileTests.cpp deleted file mode 100644 index 94bde312..00000000 --- a/tests/unit/util/newconfig/JsonFileTests.cpp +++ /dev/null @@ -1,98 +0,0 @@ -//------------------------------------------------------------------------------ -/* - This file is part of clio: https://github.com/XRPLF/clio - Copyright (c) 2024, the clio developers. - - Permission to use, copy, modify, and 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 "util/TmpFile.hpp" -#include "util/newconfig/ConfigFileJson.hpp" -#include "util/newconfig/FakeConfigData.hpp" - -#include - -#include -#include -#include -#include -#include - -struct JsonFromTempFile : testing::Test { - JsonFromTempFile() : jsonFileObj{util::config::ConfigFileJson::makeConfigFileJson(TmpFile(kJSON_DATA).path).value()} - { - } - - ConfigFileJson jsonFileObj; -}; - -TEST_F(JsonFromTempFile, validateKeys) -{ - EXPECT_TRUE(jsonFileObj.containsKey("header.text1")); - EXPECT_TRUE(jsonFileObj.containsKey("header.sub.sub2Value")); - EXPECT_TRUE(jsonFileObj.containsKey("dosguard.port")); - EXPECT_FALSE(jsonFileObj.containsKey("idk")); - EXPECT_FALSE(jsonFileObj.containsKey("optional.withNoDefault")); -} - -TEST_F(JsonFromTempFile, validateValues) -{ - EXPECT_EQ(std::get(jsonFileObj.getValue("header.text1")), "value"); - EXPECT_EQ(std::get(jsonFileObj.getValue("header.sub.sub2Value")), "TSM"); - EXPECT_EQ(std::get(jsonFileObj.getValue("dosguard.port")), 44444); -} - -TEST_F(JsonFromTempFile, validateArrayValue) -{ - // validate array.[].sub matches expected values - EXPECT_TRUE(jsonFileObj.containsKey("array.[].sub")); - auto const arrSub = jsonFileObj.getArray("array.[].sub"); - EXPECT_EQ(arrSub.size(), 3); - - std::vector expectedArrSubVal{111.11, 4321.55, 5555.44}; - std::vector actualArrSubVal{}; - - for (auto it = arrSub.begin(); it != arrSub.end(); ++it) { - ASSERT_TRUE(std::holds_alternative(*it)); - actualArrSubVal.emplace_back(std::get(*it)); - } - EXPECT_TRUE(std::ranges::equal(expectedArrSubVal, actualArrSubVal)); - - // validate array.[].sub2 matches expected values - EXPECT_TRUE(jsonFileObj.containsKey("array.[].sub2")); - auto const arrSub2 = jsonFileObj.getArray("array.[].sub2"); - EXPECT_EQ(arrSub2.size(), 3); - std::vector expectedArrSub2Val{"subCategory", "temporary", "london"}; - std::vector actualArrSub2Val{}; - - for (auto it = arrSub2.begin(); it != arrSub2.end(); ++it) { - ASSERT_TRUE(std::holds_alternative(*it)); - actualArrSub2Val.emplace_back(std::get(*it)); - } - EXPECT_TRUE(std::ranges::equal(expectedArrSub2Val, actualArrSub2Val)); - - EXPECT_TRUE(jsonFileObj.containsKey("dosguard.whitelist.[]")); - auto const whitelistArr = jsonFileObj.getArray("dosguard.whitelist.[]"); - EXPECT_EQ(whitelistArr.size(), 2); - EXPECT_EQ("125.5.5.1", std::get(whitelistArr.at(0))); - EXPECT_EQ("204.2.2.1", std::get(whitelistArr.at(1))); -} - -struct ConfigValueJsonGetArrayDeathTest : JsonFromTempFile {}; - -TEST_F(ConfigValueJsonGetArrayDeathTest, invalidGetValues) -{ - // not possible for json value to call a value that doesn't exist - EXPECT_DEATH([[maybe_unused]] auto a = jsonFileObj.getArray("header.text1"), ".*"); -} diff --git a/tests/unit/util/newconfig/ObjectViewTests.cpp b/tests/unit/util/newconfig/ObjectViewTests.cpp index 488bbf63..d9a740bc 100644 --- a/tests/unit/util/newconfig/ObjectViewTests.cpp +++ b/tests/unit/util/newconfig/ObjectViewTests.cpp @@ -17,6 +17,7 @@ */ //============================================================================== +#include "util/MockAssert.hpp" #include "util/newconfig/ArrayView.hpp" #include "util/newconfig/ConfigDefinition.hpp" #include "util/newconfig/ConfigFileJson.hpp" @@ -31,7 +32,7 @@ using namespace util::config; -struct ObjectViewTest : testing::Test { +struct ObjectViewTest : virtual testing::Test { ObjectViewTest() { ConfigFileJson const jsonFileObj{boost::json::parse(kJSON_DATA).as_object()}; @@ -124,27 +125,29 @@ TEST_F(ObjectViewTest, getArrayInObject) EXPECT_EQ("204.2.2.1", arr.valueAt(1).asString()); } -struct ObjectViewDeathTest : ObjectViewTest {}; +struct ObjectViewAssertTest : common::util::WithMockAssert, ObjectViewTest {}; -TEST_F(ObjectViewDeathTest, KeyDoesNotExist) +TEST_F(ObjectViewAssertTest, KeyDoesNotExist) { - EXPECT_DEATH({ [[maybe_unused]] auto _ = configData.getObject("head"); }, ".*"); + EXPECT_CLIO_ASSERT_FAIL({ [[maybe_unused]] auto _ = configData.getObject("head"); }); } -TEST_F(ObjectViewDeathTest, KeyIsValueView) +TEST_F(ObjectViewAssertTest, KeyIsValueView) { - EXPECT_DEATH({ [[maybe_unused]] auto _ = configData.getObject("header.text1"); }, ".*"); - EXPECT_DEATH({ [[maybe_unused]] auto _ = configData.getArray("header"); }, ".*"); + EXPECT_CLIO_ASSERT_FAIL({ [[maybe_unused]] auto _ = configData.getObject("header.text1"); }); + EXPECT_CLIO_ASSERT_FAIL({ [[maybe_unused]] auto _ = configData.getArray("header"); }); } -TEST_F(ObjectViewDeathTest, KeyisArrayView) +TEST_F(ObjectViewAssertTest, KeyisArrayView) { // dies because only 1 object in higher.[].low - EXPECT_DEATH({ [[maybe_unused]] auto _ = configData.getObject("higher.[].low", 1); }, ".*"); + EXPECT_CLIO_ASSERT_FAIL({ [[maybe_unused]] auto _ = configData.getObject("higher.[].low", 1); }); } -TEST_F(ObjectViewDeathTest, KeyisNotOptional) +TEST_F(ObjectViewAssertTest, KeyisNotOptional) { // dies because not an optional - EXPECT_DEATH({ [[maybe_unused]] auto _ = configData.getObject("header").maybeValue("text1"); }, ".*"); + EXPECT_CLIO_ASSERT_FAIL({ + [[maybe_unused]] auto _ = configData.getObject("header").maybeValue("text1"); + }); } diff --git a/tests/unit/util/newconfig/ValueViewTests.cpp b/tests/unit/util/newconfig/ValueViewTests.cpp index 6c7055ff..41a899f5 100644 --- a/tests/unit/util/newconfig/ValueViewTests.cpp +++ b/tests/unit/util/newconfig/ValueViewTests.cpp @@ -17,6 +17,7 @@ */ //============================================================================== +#include "util/MockAssert.hpp" #include "util/newconfig/ConfigConstraints.hpp" #include "util/newconfig/ConfigDefinition.hpp" #include "util/newconfig/ConfigValue.hpp" @@ -32,7 +33,7 @@ using namespace util::config; -struct ValueViewTest : testing::Test { +struct ValueViewTest : virtual testing::Test { ClioConfigDefinition const configData = generateConfig(); }; @@ -106,20 +107,20 @@ TEST_F(ValueViewTest, OptionalValues) EXPECT_EQ(vv4.asOptional(), "hello"); } -struct ValueDeathTest : ValueViewTest {}; +struct ValueViewAssertTest : common::util::WithMockAssert, ValueViewTest {}; -TEST_F(ValueDeathTest, WrongTypes) +TEST_F(ValueViewAssertTest, WrongTypes) { auto const vv = configData.getValueView("header.port"); - EXPECT_DEATH({ [[maybe_unused]] auto unused = vv.asBool(); }, ".*"); - EXPECT_DEATH({ [[maybe_unused]] auto unused = vv.asString(); }, ".*"); + EXPECT_CLIO_ASSERT_FAIL({ [[maybe_unused]] auto unused = vv.asBool(); }); + EXPECT_CLIO_ASSERT_FAIL({ [[maybe_unused]] auto unused = vv.asString(); }); auto const cv = ConfigValue{ConfigType::Integer}.defaultValue(-5); auto const vv2 = ValueView(cv); - EXPECT_DEATH({ [[maybe_unused]] auto unused = vv2.asIntType(); }, ".*"); + EXPECT_CLIO_ASSERT_FAIL({ [[maybe_unused]] auto unused = vv2.asIntType(); }); auto const cv2 = ConfigValue{ConfigType::String}.defaultValue("asdf"); auto const vv3 = ValueView(cv2); - EXPECT_DEATH({ [[maybe_unused]] auto unused = vv3.asDouble(); }, ".*"); - EXPECT_DEATH({ [[maybe_unused]] auto unused = vv3.asFloat(); }, ".*"); + EXPECT_CLIO_ASSERT_FAIL({ [[maybe_unused]] auto unused = vv3.asDouble(); }); + EXPECT_CLIO_ASSERT_FAIL({ [[maybe_unused]] auto unused = vv3.asFloat(); }); } diff --git a/tests/unit/util/prometheus/CounterTests.cpp b/tests/unit/util/prometheus/CounterTests.cpp index 3affd357..eb1bda3f 100644 --- a/tests/unit/util/prometheus/CounterTests.cpp +++ b/tests/unit/util/prometheus/CounterTests.cpp @@ -17,6 +17,7 @@ */ //============================================================================== +#include "util/MockAssert.hpp" #include "util/prometheus/Counter.hpp" #include "util/prometheus/OStream.hpp" @@ -30,7 +31,7 @@ using namespace util::prometheus; -struct AnyCounterTests : ::testing::Test { +struct AnyCounterTests : virtual ::testing::Test { struct MockCounterImpl { using ValueType = std::uint64_t; MOCK_METHOD(void, add, (ValueType)); @@ -89,18 +90,15 @@ TEST_F(AnyCounterTests, value) EXPECT_EQ(counter.value(), 42); } -struct AnyCounterDeathTest : AnyCounterTests {}; +struct AnyCounterAssertTest : common::util::WithMockAssert, AnyCounterTests {}; -TEST_F(AnyCounterDeathTest, setLowerValue) +TEST_F(AnyCounterAssertTest, setLowerValue) { testing::Mock::AllowLeak(&mockCounterImpl); - EXPECT_DEATH( - { - EXPECT_CALL(mockCounterImpl, value()).WillOnce(::testing::Return(50)); - counter.set(42); - }, - ".*" - ); + EXPECT_CLIO_ASSERT_FAIL({ + EXPECT_CALL(mockCounterImpl, value()).WillOnce(::testing::Return(50)); + counter.set(42); + }); } struct CounterIntTests : ::testing::Test { diff --git a/tests/unit/util/prometheus/MetricBuilderTests.cpp b/tests/unit/util/prometheus/MetricBuilderTests.cpp index f35b678f..01b83b37 100644 --- a/tests/unit/util/prometheus/MetricBuilderTests.cpp +++ b/tests/unit/util/prometheus/MetricBuilderTests.cpp @@ -17,6 +17,7 @@ */ //============================================================================== +#include "util/MockAssert.hpp" #include "util/prometheus/Counter.hpp" #include "util/prometheus/Gauge.hpp" #include "util/prometheus/Histogram.hpp" @@ -32,7 +33,9 @@ using namespace util::prometheus; -TEST(MetricBuilderDeathTest, build) +struct MetricBuilderAssertTest : common::util::WithMockAssert {}; + +TEST_F(MetricBuilderAssertTest, build) { std::string const name = "name"; std::string const labelsString = "{label1=\"value1\"}"; @@ -80,5 +83,5 @@ TEST(MetricBuilderDeathTest, build) EXPECT_EQ(metric->labelsString(), labelsString); } } - EXPECT_DEATH({ builder(name, labelsString, MetricType::Summary, std::vector{}); }, ""); + EXPECT_CLIO_ASSERT_FAIL({ builder(name, labelsString, MetricType::Summary, std::vector{}); }); } diff --git a/tests/unit/web/ng/ResponseTests.cpp b/tests/unit/web/ng/ResponseTests.cpp index 9ee8d044..f9a1a0e6 100644 --- a/tests/unit/web/ng/ResponseTests.cpp +++ b/tests/unit/web/ng/ResponseTests.cpp @@ -17,6 +17,7 @@ */ //============================================================================== +#include "util/MockAssert.hpp" #include "util/Taggable.hpp" #include "util/build/Build.hpp" #include "util/newconfig/ConfigDefinition.hpp" @@ -45,21 +46,21 @@ using namespace web::ng; namespace http = boost::beast::http; using namespace util::config; -struct ResponseDeathTest : testing::Test {}; +struct ResponseAssertTest : common::util::WithMockAssert {}; -TEST_F(ResponseDeathTest, intoHttpResponseWithoutHttpData) +TEST_F(ResponseAssertTest, intoHttpResponseWithoutHttpData) { Request::HttpHeaders const headers{}; Request const request{"some message", headers}; Response response{boost::beast::http::status::ok, "message", request}; - EXPECT_DEATH(std::move(response).intoHttpResponse(), ""); + EXPECT_CLIO_ASSERT_FAIL(std::move(response).intoHttpResponse()); } -TEST_F(ResponseDeathTest, asConstBufferWithHttpData) +TEST_F(ResponseAssertTest, asConstBufferWithHttpData) { Request const request{http::request{http::verb::get, "/", 11}}; Response const response{boost::beast::http::status::ok, "message", request}; - EXPECT_DEATH(response.asWsResponse(), ""); + EXPECT_CLIO_ASSERT_FAIL(response.asWsResponse()); } struct ResponseTest : testing::Test {