Sequoia
Loading...
Searching...
No Matches
TestLogger.hpp
Go to the documentation of this file.
1
2// Copyright Oliver J. Rosten 2019. //
3// Distributed under the GNU GENERAL PUBLIC LICENSE, Version 3.0. //
4// (See accompanying file LICENSE.md or copy at //
5// https://www.gnu.org/licenses/gpl-3.0.en.html) //
7
8#pragma once
9
25#include "sequoia/TestFramework/TestMode.hpp"
26
27#include <chrono>
28#include <filesystem>
29
30namespace sequoia::testing
31{
36 {
37 std::filesystem::path recovery_file{};
38 std::filesystem::path dump_file{};
39 };
40
42 {
43 failure_output
44 failure_messages,
45 diagnostics_output,
46 caught_exception_messages;
47
48 uncaught_exception_info exception_info{};
49
50 std::size_t
51 failures{},
52 top_level_failures{},
53 performance_failures{},
54 critical_failures{},
55 top_level_checks{},
56 deep_checks{},
57 performance_checks{};
58 };
59
66 class sentinel_base;
67
75 {
76 friend sentinel_base;
77 public:
78 test_logger_base(const test_logger_base&) = delete;
79 test_logger_base& operator=(const test_logger_base&) = delete;
80
81 [[nodiscard]]
82 const test_results& results() const noexcept { return m_Results; }
83
84 void reset_results() noexcept { m_Results = {}; }
85
86 [[nodiscard]]
87 const active_recovery_files& recovery() const noexcept { return m_Recovery; }
88
89 void recovery(active_recovery_files paths) { m_Recovery = std::move(paths); }
90
91 [[nodiscard]]
92 std::string_view top_level_message() const noexcept
93 {
94 return !m_SentinelDepth.empty() ? std::string_view{m_SentinelDepth.front().message} : "";
95 }
96
97 [[nodiscard]]
98 const uncaught_exception_info& exceptions_detected_by_sentinel() const noexcept
99 {
100 return m_Results.exception_info;
101 }
102 protected:
103 test_logger_base() = default;
104
105 explicit test_logger_base(active_recovery_files recovery)
106 : m_Recovery{std::move(recovery)}
107 {}
108
109 test_logger_base(test_logger_base&&) noexcept = default;
110 test_logger_base& operator=(test_logger_base&&) noexcept = default;
111 private:
112 struct level_message
113 {
114 explicit level_message(std::string_view m)
115 : message{m}
116 {}
117
118 std::string message;
119 bool written{};
120 };
121
122 enum class is_critical{yes, no};
123
124 test_results m_Results;
125 std::vector<level_message> m_SentinelDepth;
126 active_recovery_files m_Recovery{};
127
128 [[nodiscard]]
129 std::size_t depth() const noexcept { return m_SentinelDepth.size(); }
130
131 void log_check() noexcept { ++m_Results.deep_checks; }
132
133 void log_top_level_check() noexcept { ++m_Results.top_level_checks; }
134
135 void log_performance_check() noexcept
136 {
137 log_check();
138 ++m_Results.performance_checks;
139 }
140
141 void failure_message(test_mode mode, std::string_view message, is_critical isCritical);
142
143 void log_failure(test_mode mode, std::string_view message)
144 {
145 ++m_Results.failures;
146 failure_message(mode, message, is_critical::no);
147 }
148
149 void log_performance_failure(test_mode mode, std::string_view message)
150 {
151 ++m_Results.performance_failures;
152 log_failure(mode, message);
153 }
154
155 void log_critical_failure(test_mode mode, std::string_view message);
156
157 void log_top_level_failure(test_mode mode, std::string message);
158
159 void log_caught_exception_message(std::string_view message);
160
161 void append_to_diagnostics_output(std::string message);
162
163 void increment_depth(std::string_view message);
164
165 void decrement_depth();
166
167 void end_message(test_mode mode, is_critical isCritical);
168
169 [[nodiscard]]
170 failure_output& output_channel(test_mode mode, is_critical isCritical) noexcept;
171
172 failure_output& add_to_output(failure_output& output, std::string_view message);
173 };
174
181 template<test_mode Mode>
183 {
184 public:
185 constexpr static test_mode mode{Mode};
186
187 test_logger() = default;
188
189 explicit test_logger(active_recovery_files recoveryFiles)
190 : test_logger_base{recoveryFiles}
191 {}
192
193 test_logger(const test_logger&) = delete;
194 test_logger(test_logger&&) noexcept = default;
195
196 test_logger& operator=(const test_logger&) = delete;
197 test_logger& operator=(test_logger&&) noexcept = default;
198
199 };
200
201
203 {
204 public:
205 sentinel_base(const sentinel_base&) = delete;
206 sentinel_base& operator=(const sentinel_base&) = delete;
207
208 void log_performance_check() { get().log_performance_check(); }
209
210 void log_check() { get().log_check(); }
211
212 void log_failure(std::string_view message) { get().log_failure(m_Mode, message); }
213
214 void log_performance_failure(std::string_view message) { get().log_performance_failure(m_Mode, message); }
215
216 void log_critical_failure(std::string_view message) { get().log_critical_failure(m_Mode, message); }
217
218 void log_caught_exception_message(std::string_view message) { get().log_caught_exception_message(message); }
219
220 [[nodiscard]]
221 bool critical_failure_detected() const noexcept { return get().results().critical_failures != m_PriorCriticalFailures; }
222
223 [[nodiscard]]
224 bool failure_detected() const noexcept { return get().results().failures != m_PriorFailures; }
225
226 [[nodiscard]]
227 bool checks_registered() const noexcept { return get().results().deep_checks != m_PriorDeepChecks; }
228 protected:
229
230 sentinel_base(test_logger_base& logger, test_mode mode, std::string message);
231
233
234 sentinel_base(sentinel_base&&) noexcept = default;
235 sentinel_base& operator=(sentinel_base&&) noexcept = default;
236 private:
237 [[nodiscard]]
238 test_logger_base& get() noexcept { return *m_pLogger; }
239
240 [[nodiscard]]
241 const test_logger_base& get() const noexcept { return *m_pLogger; }
242
243 test_logger_base* m_pLogger;
244 test_mode m_Mode;
245 std::string m_Message;
246 std::size_t
247 m_PriorFailures{},
248 m_PriorCriticalFailures{},
249 m_PriorDeepChecks{};
250 };
251
275 template<test_mode Mode>
276 class [[nodiscard]] sentinel : public sentinel_base
277 {
278 public:
279 constexpr static test_mode mode{Mode};
280
281 sentinel(test_logger<Mode>& logger, std::string message)
282 : sentinel_base{logger, Mode, std::move(message)}
283 {}
284
285 sentinel(const sentinel&) = delete;
286 sentinel(sentinel&&) noexcept = default;
287
288 sentinel& operator=(const sentinel&) = delete;
289 sentinel& operator=(sentinel&&) noexcept = default;
290
291 };
292
299 {
300 public:
301 using duration = std::chrono::steady_clock::duration;
302
303 log_summary() = default;
304
305 explicit log_summary(std::string_view name);
306
307 template<test_mode Mode>
308 log_summary(std::string_view name, const test_logger<Mode>& logger, const duration delta)
309 : log_summary(name, logger, Mode, delta)
310 {}
311
312 void clear() noexcept;
313
314 [[nodiscard]]
315 std::size_t standard_top_level_checks() const noexcept { return m_StandardTopLevelChecks; }
316
317 [[nodiscard]]
318 std::size_t standard_deep_checks() const noexcept { return m_StandardDeepChecks; }
319
320 [[nodiscard]]
321 std::size_t standard_performance_checks() const noexcept { return m_StandardPerformanceChecks; }
322
323 [[nodiscard]]
324 std::size_t false_positive_checks() const noexcept { return m_FalsePositiveChecks; }
325
326 [[nodiscard]]
327 std::size_t false_positive_performance_checks() const noexcept { return m_FalsePositivePerformanceChecks; }
328
329 [[nodiscard]]
330 std::size_t false_negative_checks() const noexcept { return m_FalseNegativeChecks; }
331
332 [[nodiscard]]
333 std::size_t false_negative_performance_checks() const noexcept { return m_FalseNegativePerformanceChecks; }
334
335 [[nodiscard]]
336 std::size_t standard_deep_failures() const noexcept { return m_StandardDeepFailures; }
337
338 [[nodiscard]]
339 std::size_t standard_top_level_failures() const noexcept { return m_StandardTopLevelFailures; }
340
341 [[nodiscard]]
342 std::size_t standard_performance_failures() const noexcept { return m_StandardPerformanceFailures; }
343
344 [[nodiscard]]
345 std::size_t false_positive_failures() const noexcept { return m_FalsePositiveFailures; }
346
347 [[nodiscard]]
348 std::size_t false_positive_performance_failures() const noexcept { return m_FalsePositivePerformanceFailures; }
349
350 [[nodiscard]]
351 std::size_t false_negative_failures() const noexcept { return m_FalseNegativeFailures; }
352
353 [[nodiscard]]
354 std::size_t false_negative_performance_failures() const noexcept { return m_FalseNegativePerformanceFailures; }
355
356 [[nodiscard]]
357 std::size_t critical_failures() const noexcept { return m_CriticalFailures; }
358
359 [[nodiscard]]
360 std::size_t soft_failures() const noexcept;
361
362 [[nodiscard]]
363 const std::string& diagnostics_output() const noexcept { return m_DiagnosticsOutput; }
364
365 void diagnostics_output(std::string output)
366 {
367 m_DiagnosticsOutput = std::move(output);
368 }
369
370 [[nodiscard]]
371 const std::string& caught_exceptions_output() const noexcept { return m_CaughtExceptionMessages; }
372
373 [[nodiscard]]
374 duration execution_time() const noexcept { return m_Duration; }
375
376 void execution_time(const duration delta) { m_Duration = delta; }
377
378 log_summary& operator+=(const log_summary& rhs);
379
380 [[nodiscard]]
381 const std::string& name() const noexcept { return m_Name; }
382
383 [[nodiscard]]
384 const std::string& failure_messages() const noexcept { return m_FailureMessages; }
385
386 friend log_summary operator+(const log_summary& lhs, const log_summary& rhs);
387 private:
388 std::string
389 m_Name,
390 m_FailureMessages,
391 m_DiagnosticsOutput,
392 m_CaughtExceptionMessages;
393
394 std::size_t
395 m_StandardTopLevelChecks{},
396 m_StandardDeepChecks{},
397 m_StandardPerformanceChecks{},
398 m_FalsePositiveChecks{},
399 m_FalseNegativeChecks{},
400 m_FalsePositivePerformanceChecks{},
401 m_FalseNegativePerformanceChecks{},
402 m_StandardTopLevelFailures{},
403 m_StandardDeepFailures{},
404 m_StandardPerformanceFailures{},
405 m_FalsePositiveFailures{},
406 m_FalseNegativeFailures{},
407 m_FalsePositivePerformanceFailures{},
408 m_FalseNegativePerformanceFailures{},
409 m_CriticalFailures{};
410
411 int m_ExceptionsInFlight{};
412
413 duration m_Duration{};
414
415 log_summary(std::string_view name, const test_logger_base& logger, test_mode mode, const duration delta);
416 };
417}
Utilities for recording information from test failures.
A collection of functions for formatting test output.
std::string failure_message(is_final_message_t, T, T)
To prevent implicit conversions to bool.
Definition: Output.hpp:146
Traits which are sufficiently general to appear in the sequoia namespace.
Summaries data generated by the logger, for the purposes of reporting.
Definition: TestLogger.hpp:299
Definition: TestLogger.hpp:203
Definition: TestLogger.hpp:277
Definition: TestLogger.hpp:75
Definition: TestLogger.hpp:183
Holds paths to files where recovery information will be written if the path is not empty.
Definition: TestLogger.hpp:36
Definition: TestLogger.hpp:42
Definition: CoreInfrastructure.hpp:99