| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | //====================================================================================================================== | ||
| 2 | //! @file | ||
| 3 | /* | ||
| 4 | TTS - Tiny Test System | ||
| 5 | Copyright : TTS Contributors & Maintainers | ||
| 6 | SPDX-License-Identifier: BSL-1.0 | ||
| 7 | */ | ||
| 8 | //====================================================================================================================== | ||
| 9 | #pragma once | ||
| 10 | |||
| 11 | #include <tts/engine/deps.hpp> | ||
| 12 | #include <tts/tools/clock.hpp> | ||
| 13 | #include <tts/tools/options.hpp> | ||
| 14 | #include <tts/tools/output.hpp> | ||
| 15 | |||
| 16 | //====================================================================================================================== | ||
| 17 | // Test environment | ||
| 18 | //====================================================================================================================== | ||
| 19 | namespace tts::_ | ||
| 20 | { | ||
| 21 | struct env | ||
| 22 | { | ||
| 23 | 1601612 | void pass() | |
| 24 | { | ||
| 25 | 1601612 | test_count++; | |
| 26 | 1601612 | success_count++; | |
| 27 | 1601612 | } | |
| 28 | 55 | void fail() | |
| 29 | { | ||
| 30 | 55 | test_count++; | |
| 31 | 55 | failure_count++; | |
| 32 | 55 | } | |
| 33 | ✗ | void fatal() | |
| 34 | { | ||
| 35 | ✗ | test_count++; | |
| 36 | ✗ | failure_count++; | |
| 37 | ✗ | fatal_count++; | |
| 38 | ✗ | } | |
| 39 | 8 | void invalid() | |
| 40 | { | ||
| 41 | 8 | test_count++; | |
| 42 | 8 | invalid_count++; | |
| 43 | 8 | } | |
| 44 | 32 | void unexpected() | |
| 45 | { | ||
| 46 | 32 | unexpected_count++; | |
| 47 | 32 | } | |
| 48 | |||
| 49 | 99 | int report(counter fails, counter invalids) const | |
| 50 | { | ||
| 51 |
2/2✓ Branch 0 taken 67 times.
✓ Branch 1 taken 32 times.
|
99 | auto test_txt = test_count > 1 ? "s" : ""; |
| 52 |
2/2✓ Branch 0 taken 58 times.
✓ Branch 1 taken 41 times.
|
99 | auto pass_txt = success_count > 1 ? "es" : ""; |
| 53 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 93 times.
|
99 | auto fail_txt = failure_count > 1 ? "s" : ""; |
| 54 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 97 times.
|
99 | auto inv_txt = invalid_count > 1 ? "s" : ""; |
| 55 | |||
| 56 | 99 | auto& out = ::tts::output(); | |
| 57 | |||
| 58 | // Also cleans up a color colorized_sink left dangling by -q, not just "Results:". | ||
| 59 |
1/1✓ Branch 1 taken 99 times.
|
99 | out.suite_finished(failure_count, invalid_count); |
| 60 | |||
| 61 |
1/1✓ Branch 1 taken 99 times.
|
99 | ::tts::_::separator(); |
| 62 |
1/1✓ Branch 1 taken 99 times.
|
99 | out.write("Results: %llu test%s ", test_count, test_txt); |
| 63 |
2/2✓ Branch 0 taken 86 times.
✓ Branch 1 taken 13 times.
|
99 | if(success_count != 0) |
| 64 | { | ||
| 65 |
1/1✓ Branch 1 taken 86 times.
|
86 | out.suite_metric(::tts::outcome::success, success_count, test_count); |
| 66 | 86 | out.write("- %llu/%llu (%2.2f%%) success%s ", | |
| 67 | 86 | success_count, | |
| 68 | 86 | test_count, | |
| 69 |
1/1✓ Branch 1 taken 86 times.
|
86 | 100.f * static_cast<float>(success_count) / static_cast<float>(test_count), |
| 70 | pass_txt); | ||
| 71 | } | ||
| 72 |
2/2✓ Branch 0 taken 19 times.
✓ Branch 1 taken 80 times.
|
99 | if(failure_count != 0) |
| 73 | { | ||
| 74 |
1/1✓ Branch 1 taken 19 times.
|
19 | out.suite_metric(::tts::outcome::failure, failure_count, test_count); |
| 75 | 19 | out.write("- %llu/%llu (%2.2f%%) failure%s ", | |
| 76 | 19 | failure_count, | |
| 77 | 19 | test_count, | |
| 78 |
1/1✓ Branch 1 taken 19 times.
|
19 | 100.f * static_cast<float>(failure_count) / static_cast<float>(test_count), |
| 79 | fail_txt); | ||
| 80 | } | ||
| 81 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 91 times.
|
99 | if(invalid_count != 0) |
| 82 | { | ||
| 83 |
1/1✓ Branch 1 taken 8 times.
|
8 | out.suite_metric(::tts::outcome::invalid, invalid_count, test_count); |
| 84 | 8 | out.write("- %llu/%llu (%2.2f%%) invalid%s ", | |
| 85 | 8 | invalid_count, | |
| 86 | 8 | test_count, | |
| 87 |
1/1✓ Branch 1 taken 8 times.
|
8 | 100.f * static_cast<float>(invalid_count) / static_cast<float>(test_count), |
| 88 | inv_txt); | ||
| 89 | } | ||
| 90 | |||
| 91 |
1/1✓ Branch 2 taken 99 times.
|
99 | out.writeln(); |
| 92 | |||
| 93 | 3 | double avg_duration_ns = | |
| 94 |
2/2✓ Branch 0 taken 96 times.
✓ Branch 1 taken 3 times.
|
99 | test_count ? static_cast<double>(total_duration_ns) / static_cast<double>(test_count) : 0.0; |
| 95 | 99 | out.writeln("Total Time: %s - %s/test", | |
| 96 |
1/1✓ Branch 2 taken 99 times.
|
99 | ::tts::_::format_duration(static_cast<double>(total_duration_ns)).data(), |
| 97 |
2/2✓ Branch 1 taken 99 times.
✓ Branch 5 taken 99 times.
|
198 | ::tts::_::format_duration(avg_duration_ns).data()); |
| 98 | |||
| 99 | // A shard landing on zero tests is expected, not a bug - behaves like --allow-empty here. | ||
| 100 |
8/8✓ Branch 0 taken 3 times.
✓ Branch 1 taken 96 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 1 times.
✓ Branch 8 taken 1 times.
✓ Branch 9 taken 1 times.
✓ Branch 10 taken 1 times.
✓ Branch 11 taken 98 times.
|
99 | if(test_count == 0 && !::tts::arguments()("--allow-empty") && !::tts::arguments()("--shard")) |
| 101 | 1 | return 1; | |
| 102 | |||
| 103 | // No explicit fails/invalids: unexpected_count alone decides pass/fail. | ||
| 104 |
4/4✓ Branch 0 taken 83 times.
✓ Branch 1 taken 15 times.
✓ Branch 2 taken 82 times.
✓ Branch 3 taken 1 times.
|
98 | if(!fails && !invalids) return unexpected_count == 0 ? 0 : 1; |
| 105 |
3/4✓ Branch 0 taken 15 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 15 times.
|
16 | else return (failure_count == fails && invalid_count == invalids) ? 0 : 1; |
| 106 | } | ||
| 107 | |||
| 108 | counter test_count = 0; | ||
| 109 | counter success_count = 0; | ||
| 110 | counter failure_count = 0; | ||
| 111 | counter fatal_count = 0; | ||
| 112 | counter invalid_count = 0; | ||
| 113 | counter unexpected_count = 0; | ||
| 114 | nanoseconds total_duration_ns = 0; | ||
| 115 | bool fail_status = false; | ||
| 116 | }; | ||
| 117 | } | ||
| 118 | |||
| 119 | namespace tts | ||
| 120 | { | ||
| 121 | inline _::env global_runtime = {}; | ||
| 122 | inline bool fatal_error_status = false; | ||
| 123 | inline bool global_logger_status = false; | ||
| 124 | |||
| 125 | //==================================================================================================================== | ||
| 126 | /** | ||
| 127 | @brief Test reporting customization point | ||
| 128 | @ingroup customization-points | ||
| 129 | |||
| 130 | Aggregates test results and validate the whole test suite with respect to expect numbers of | ||
| 131 | failures and invalids. | ||
| 132 | |||
| 133 | @param fails Number of expected failures. | ||
| 134 | @param invalids Number of expected invalid tests. | ||
| 135 | |||
| 136 | @return 0 if all tests passed and 1 otherwise. | ||
| 137 | **/ | ||
| 138 | //==================================================================================================================== | ||
| 139 | 95 | inline int report(counter fails, counter invalids) | |
| 140 | { | ||
| 141 | 95 | return global_runtime.report(fails, invalids); | |
| 142 | } | ||
| 143 | } | ||
| 144 |