test_backtrace.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#include "crucible/process.hpp" #include "crucible/testing.hpp" #include <algorithm> namespace crucible::process::test_backtrace { #ifdef CRUCIBLE_UNIX auto detailed_snapshot_inner_function() -> void { auto const result { process::backtrace::take_detailed_snapshot() }; EXPECT_FAILURE(result); auto const &error { result.get_failure() }; EXPECT_EQ(error.format(), "crucible::core::fallible::Error { my_variant: crucible::process::result::MissingDebugInformation {} }"); } #endif // CRUCIBLE_UNIX #ifdef CRUCIBLE_WINDOWS auto detailed_snapshot_inner_function() -> void { std::string const file_std_string { __FILE__ }; auto const result { process::backtrace::take_detailed_snapshot() }; int const line { __LINE__ }; EXPECT_SUCCESS(result); auto const &snapshot { result.get_success() }; EXPECT(!snapshot.empty()); auto const &frame_1 { snapshot.at(1) }; EXPECT_EQ(frame_1.get_function(), "crucible::process::backtrace::take_detailed_snapshot()"); auto const &frame_2 { snapshot.at(2) }; EXPECT_EQ(frame_2.get_function(), "crucible::process::test_backtrace::detailed_snapshot_inner_function()"); EXPECT_EQ(frame_2.get_file(), file_std_string); EXPECT_EQ(frame_2.get_line(), line); std::string const root_std_string { CRUCIBLE_ROOT }; auto const root_index { file_std_string.find(root_std_string) }; auto const relative_file { root_index == 0 ? file_std_string.substr(root_std_string.size() + 1) : file_std_string }; EXPECT_EQ(frame_2.describe(), "crucible::process::test_backtrace::detailed_snapshot_inner_function() at " + relative_file + ":" + std::to_string(line)); EXPECT_EQ(frame_2.format(), "crucible::process::backtrace::DetailedStackFrame { my_function: std::string { \"crucible::process::test_backtrace::detailed_snapshot_inner_function()\" }, my_file: std::string { \"" + file_std_string + "\" }, my_line: " + std::to_string(line) + " }"); } #endif // CRUCIBLE_WINDOWS auto simple_snapshot_inner_function() -> void { auto const result { process::backtrace::take_simple_snapshot() }; EXPECT_SUCCESS(result); auto const &snapshot { result.get_success() }; EXPECT(!snapshot.empty()); { auto const predicate { [](process::backtrace::SimpleStackFrame const &frame) -> bool { return frame.get_function().find("crucible::process::backtrace::take_simple_snapshot") != std::string::npos; } }; auto const iterator { std::find_if(snapshot.begin(), snapshot.end(), predicate) }; EXPECT_NE(iterator, snapshot.end()); } { auto const predicate { [](process::backtrace::SimpleStackFrame const &frame) -> bool { return frame.get_function().find("crucible::process::test_backtrace::simple_snapshot_inner_function") != std::string::npos; } }; auto const iterator { std::find_if(snapshot.begin(), snapshot.end(), predicate) }; EXPECT_NE(iterator, snapshot.end()); auto const &frame_2 { *iterator }; auto const actual_describe { frame_2.describe() }; auto const expected_describe { "crucible::process::test_backtrace::simple_snapshot_inner_function" }; EXPECT_NE(actual_describe.find(expected_describe), std::string::npos); auto const actual_format { frame_2.format() }; auto const expected_format_head { "crucible::process::backtrace::SimpleStackFrame { " }; auto const expected_format_function { "crucible::process::test_backtrace::simple_snapshot_inner_function" }; EXPECT_NE(actual_format.find(expected_format_head), std::string::npos); EXPECT_NE(actual_format.find(expected_format_function), std::string::npos); } } SCENARIO(backtrace, take_detailed_snapshot) { detailed_snapshot_inner_function(); } SCENARIO(backtrace, take_simple_snapshot) { simple_snapshot_inner_function(); } }