1 // Copyright 2024 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14
15 #include "pw_unit_test/test_record_event_handler.h"
16
17 #include <string>
18
19 #include "pw_assert/assert.h"
20 #include "pw_unit_test/framework.h"
21
22 namespace pw::unit_test {
23 namespace {
24
25 time_t kFakeTimeSinceEpoch = 12345;
26
TEST(TestRecordFunctionality,SingleTestRun)27 TEST(TestRecordFunctionality, SingleTestRun) {
28 TestRecordEventHandler test_record_event_handler(kFakeTimeSinceEpoch);
29
30 // Initialize test cases to be run
31 TestCase test_case{"suite1", "test1", "dir1/test_file.cc"};
32 TestResult test_result = TestResult::kSuccess;
33 RunTestsSummary run_tests_summary = {1, 0, 0, 0};
34
35 // Simulate test run
36 test_record_event_handler.TestCaseStart(test_case);
37 test_record_event_handler.TestCaseEnd(test_case, test_result);
38 test_record_event_handler.RunAllTestsEnd(run_tests_summary);
39
40 std::string actual = test_record_event_handler.GetTestRecordJsonString(300);
41 std::string expected =
42 R"({"tests": {"dir1": {"test_file.cc": {"suite1":)"
43 R"( {"test1": {"expected": "PASS", "actual": "PASS"}}}}},)"
44 R"( "version": 3, "interrupted": false, "seconds_since_epoch": 12345,)"
45 R"( "num_failures_by_type": {"PASS": 1, "FAIL": 0, "SKIP": 0}})";
46 ASSERT_EQ(actual, expected);
47
48 std::string failed_results_actual =
49 test_record_event_handler.GetTestRecordJsonString(300, true);
50
51 std::string failed_results_expected =
52 R"({"tests": {}, "version": 3, "interrupted": false,)"
53 R"( "seconds_since_epoch": 12345, "num_failures_by_type": {"PASS": 1,)"
54 R"( "FAIL": 0, "SKIP": 0}})";
55 ASSERT_EQ(failed_results_actual, failed_results_expected);
56 }
57
TEST(TestRecordFunctionality,MultipleTestsRun)58 TEST(TestRecordFunctionality, MultipleTestsRun) {
59 TestRecordEventHandler test_record_event_handler(kFakeTimeSinceEpoch);
60
61 // Initialize test cases to be run
62 TestCase test_case1{"suite1", "test1", "dir1/test_file.cc"};
63 TestResult test_result1 = TestResult::kSuccess;
64 TestCase test_case2{"suite2", "test2", "dir1/test_file.cc"};
65 TestResult test_result2 = TestResult::kFailure;
66 TestCase test_case3{"suite3", "test3", "dir1/dir2/test_file.cc"};
67 TestResult test_result3 = TestResult::kSuccess;
68 RunTestsSummary run_tests_summary = {2, 1, 0, 0};
69
70 // Simulate test run
71 test_record_event_handler.TestCaseStart(test_case1);
72 test_record_event_handler.TestCaseEnd(test_case1, test_result1);
73 test_record_event_handler.TestCaseStart(test_case2);
74 test_record_event_handler.TestCaseEnd(test_case2, test_result2);
75 test_record_event_handler.TestCaseStart(test_case3);
76 test_record_event_handler.TestCaseEnd(test_case3, test_result3);
77 test_record_event_handler.RunAllTestsEnd(run_tests_summary);
78
79 std::string actual = test_record_event_handler.GetTestRecordJsonString(400);
80
81 std::string expected =
82 R"({"tests": {"dir1": {"dir2": {"test_file.cc": {"suite3": {"test3":)"
83 R"( {"expected": "PASS", "actual": "PASS"}}}}, "test_file.cc":)"
84 R"( {"suite2": {"test2": {"expected": "PASS", "actual": "FAIL"}},)"
85 R"( "suite1": {"test1": {"expected": "PASS", "actual": "PASS"}}}}},)"
86 R"( "version": 3, "interrupted": false, "seconds_since_epoch": 12345,)"
87 R"( "num_failures_by_type": {"PASS": 2, "FAIL": 1, "SKIP": 0}})";
88 ASSERT_EQ(actual, expected);
89
90 std::string failed_results_actual =
91 test_record_event_handler.GetTestRecordJsonString(400, true);
92
93 std::string failed_results_expected =
94 R"({"tests": {"dir1": {"test_file.cc": {"suite2": {"test2": {"expected":)"
95 R"( "PASS", "actual": "FAIL"}}}}}, "version": 3, "interrupted": false,)"
96 R"( "seconds_since_epoch": 12345, "num_failures_by_type": {"PASS": 2,)"
97 R"( "FAIL": 1, "SKIP": 0}})";
98 ASSERT_EQ(failed_results_actual, failed_results_expected);
99 }
100
TEST(TestRecordFunctionality,JsonBufferTooSmall)101 TEST(TestRecordFunctionality, JsonBufferTooSmall) {
102 TestRecordEventHandler test_record_event_handler(kFakeTimeSinceEpoch);
103
104 // Initialize test cases to be run
105 TestCase test_case{"suite1", "test1", "dir1/test_file.cc"};
106 TestResult test_result = TestResult::kSuccess;
107 RunTestsSummary run_tests_summary = {1, 0, 0, 0};
108
109 // Simulate test run
110 test_record_event_handler.TestCaseStart(test_case);
111 test_record_event_handler.TestCaseEnd(test_case, test_result);
112 test_record_event_handler.RunAllTestsEnd(run_tests_summary);
113 EXPECT_DEATH_IF_SUPPORTED(
114 test_record_event_handler.GetTestRecordJsonString(10),
115 "Test record json buffer is not big enough, please increase size.");
116 }
117
TEST(TestRecordFunctionality,HandleSkipMacro)118 TEST(TestRecordFunctionality, HandleSkipMacro) {
119 TestRecordEventHandler test_record_event_handler(kFakeTimeSinceEpoch);
120
121 // Initialize test cases to be run
122 TestCase test_case{"suite1", "test1", "dir1/test_file.cc"};
123 TestResult test_result = TestResult::kSkipped;
124 TestExpectation skip_expectation = {
125 pw::unit_test::json_impl::kSkipMacroIndicator,
126 pw::unit_test::json_impl::kSkipMacroIndicator,
127 0,
128 true};
129 RunTestsSummary run_tests_summary = {0, 0, 1, 0};
130
131 // Simulate test run
132 test_record_event_handler.TestCaseStart(test_case);
133 test_record_event_handler.TestCaseExpect(test_case, skip_expectation);
134 test_record_event_handler.TestCaseEnd(test_case, test_result);
135 test_record_event_handler.RunAllTestsEnd(run_tests_summary);
136
137 std::string actual = test_record_event_handler.GetTestRecordJsonString(300);
138 std::string expected =
139 R"({"tests": {"dir1": {"test_file.cc": {"suite1":)"
140 R"( {"test1": {"expected": "SKIP", "actual": "SKIP"}}}}},)"
141 R"( "version": 3, "interrupted": false, "seconds_since_epoch": 12345,)"
142 R"( "num_failures_by_type": {"PASS": 0, "FAIL": 0, "SKIP": 1}})";
143 ASSERT_EQ(actual, expected);
144
145 std::string failed_results_actual =
146 test_record_event_handler.GetTestRecordJsonString(300, true);
147
148 std::string failed_results_expected =
149 R"({"tests": {}, "version": 3, "interrupted": false,)"
150 R"( "seconds_since_epoch": 12345, "num_failures_by_type": {"PASS": 0,)"
151 R"( "FAIL": 0, "SKIP": 1}})";
152 ASSERT_EQ(failed_results_actual, failed_results_expected);
153 }
154
TEST(TestRecordFunctionality,DuplicateTest)155 TEST(TestRecordFunctionality, DuplicateTest) {
156 TestRecordEventHandler test_record_event_handler(kFakeTimeSinceEpoch);
157
158 // Initialize test cases to be run
159 TestCase test_case1{"suite1", "test1", "dir1/test_file.cc"};
160 TestResult test_result1 = TestResult::kSuccess;
161 TestCase test_case2{"suite1", "test1", "dir1/test_file.cc"};
162 TestResult test_result2 = TestResult::kFailure;
163 RunTestsSummary run_tests_summary = {0, 1, 0, 0};
164
165 // Simulate test run
166 test_record_event_handler.TestCaseStart(test_case1);
167 test_record_event_handler.TestCaseEnd(test_case1, test_result1);
168 test_record_event_handler.TestCaseStart(test_case2);
169 test_record_event_handler.TestCaseEnd(test_case2, test_result2);
170 test_record_event_handler.RunAllTestsEnd(run_tests_summary);
171
172 std::string actual = test_record_event_handler.GetTestRecordJsonString(300);
173
174 std::string expected =
175 R"({"tests": {"dir1": {"test_file.cc": {"suite1":)"
176 R"( {"test1": {"expected": "PASS", "actual": "FAIL"}}}}},)"
177 R"( "version": 3, "interrupted": false, "seconds_since_epoch": 12345,)"
178 R"( "num_failures_by_type": {"PASS": 0, "FAIL": 1, "SKIP": 0}})";
179 ASSERT_EQ(actual, expected);
180
181 std::string failed_results_actual =
182 test_record_event_handler.GetTestRecordJsonString(300, true);
183
184 std::string failed_results_expected =
185 R"({"tests": {"dir1": {"test_file.cc": {"suite1":)"
186 R"( {"test1": {"expected": "PASS", "actual": "FAIL"}}}}},)"
187 R"( "version": 3, "interrupted": false, "seconds_since_epoch": 12345,)"
188 R"( "num_failures_by_type": {"PASS": 0, "FAIL": 1, "SKIP": 0}})";
189 ASSERT_EQ(failed_results_actual, failed_results_expected);
190 }
191
192 } // namespace
193 } // namespace pw::unit_test
194