From 0bb5aa23187d57a6770dd039c77a77bf3d940ce0 Mon Sep 17 00:00:00 2001 From: Jeremy Rifkin <51220084+jeremy-rifkin@users.noreply.github.com> Date: Sun, 18 Aug 2024 11:41:38 -0500 Subject: [PATCH] Add a basic test for traced exception objects --- test/CMakeLists.txt | 1 + test/unit/traced_exception.cpp | 68 ++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 test/unit/traced_exception.cpp diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 6136004..114e807 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -84,6 +84,7 @@ if(NOT CPPTRACE_SKIP_UNIT) unit/object_trace.cpp unit/stacktrace.cpp unit/from_current.cpp + unit/traced_exception.cpp ) target_compile_features(unittest PRIVATE cxx_std_20) target_link_libraries(unittest PRIVATE ${target_name} GTest::gtest_main GTest::gmock_main) diff --git a/test/unit/traced_exception.cpp b/test/unit/traced_exception.cpp new file mode 100644 index 0000000..dee67c2 --- /dev/null +++ b/test/unit/traced_exception.cpp @@ -0,0 +1,68 @@ +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +using namespace std::literals; + + +// NOTE: returning something and then return stacktrace_traced_object_3(line_numbers) * 2; later helps prevent the call from +// being optimized to a jmp +CPPTRACE_FORCE_NO_INLINE int stacktrace_traced_object_3(std::vector& line_numbers) { + line_numbers.insert(line_numbers.begin(), __LINE__ + 1); + throw cpptrace::runtime_error("foobar"); +} + +CPPTRACE_FORCE_NO_INLINE int stacktrace_traced_object_2(std::vector& line_numbers) { + line_numbers.insert(line_numbers.begin(), __LINE__ + 1); + return stacktrace_traced_object_3(line_numbers) * 2; +} + +CPPTRACE_FORCE_NO_INLINE int stacktrace_traced_object_1(std::vector& line_numbers) { + line_numbers.insert(line_numbers.begin(), __LINE__ + 1); + return stacktrace_traced_object_2(line_numbers) * 2; +} + +TEST(TracedException, Basic) { + std::vector line_numbers; + try { + line_numbers.insert(line_numbers.begin(), __LINE__ + 1); + stacktrace_traced_object_1(line_numbers); + } catch(cpptrace::exception& e) { + EXPECT_EQ(e.message(), "foobar"sv); + const auto& trace = e.trace(); + ASSERT_GE(trace.frames.size(), 4); + size_t i = 0; + ASSERT_LT(i, trace.frames.size()); + ASSERT_LT(i, line_numbers.size()); + EXPECT_THAT(trace.frames[i].filename, testing::EndsWith("traced_exception.cpp")); + EXPECT_EQ(trace.frames[i].line.value(), line_numbers[i]); + EXPECT_THAT(trace.frames[i].symbol, testing::HasSubstr("stacktrace_traced_object_3")); + i++; + ASSERT_LT(i, trace.frames.size()); + ASSERT_LT(i, line_numbers.size()); + EXPECT_THAT(trace.frames[i].filename, testing::EndsWith("traced_exception.cpp")); + EXPECT_EQ(trace.frames[i].line.value(), line_numbers[i]); + EXPECT_THAT(trace.frames[i].symbol, testing::HasSubstr("stacktrace_traced_object_2")); + i++; + ASSERT_LT(i, trace.frames.size()); + ASSERT_LT(i, line_numbers.size()); + EXPECT_THAT(trace.frames[i].filename, testing::EndsWith("traced_exception.cpp")); + EXPECT_EQ(trace.frames[i].line.value(), line_numbers[i]); + EXPECT_THAT(trace.frames[i].symbol, testing::HasSubstr("stacktrace_traced_object_1")); + i++; + ASSERT_LT(i, trace.frames.size()); + ASSERT_LT(i, line_numbers.size()); + EXPECT_THAT(trace.frames[i].filename, testing::EndsWith("traced_exception.cpp")); + EXPECT_EQ(trace.frames[i].line.value(), line_numbers[i]); + EXPECT_THAT(trace.frames[i].symbol, testing::HasSubstr("TracedException_Basic_Test::TestBody")); + } +}