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 "pw_assert/assert.h"
18 #include "pw_unit_test/framework.h"
19
20 namespace pw::unit_test {
21 namespace {
22
23 time_t kFakeTimeSinceEpoch = 12345;
24
TEST(TestRecordFunctionality,SingleTestRun)25 TEST(TestRecordFunctionality, SingleTestRun) {
26 TestRecordEventHandler test_record_event_handler(kFakeTimeSinceEpoch);
27
28 // Initialize test cases to be run
29 TestCase test_case{"suite1", "test1", "dir1/test_file.cc"};
30 TestResult test_result = TestResult::kSuccess;
31 RunTestsSummary run_tests_summary = {1, 0, 0, 0};
32
33 // Simulate test run
34 test_record_event_handler.TestCaseStart(test_case);
35 test_record_event_handler.TestCaseEnd(test_case, test_result);
36 test_record_event_handler.RunAllTestsEnd(run_tests_summary);
37
38 std::string actual = test_record_event_handler.GetTestRecordJsonString(300);
39 std::string expected =
40 R"({"tests": {"dir1": {"test_file.cc": {"suite1":)"
41 R"( {"test1": {"expected": "PASS", "actual": "PASS"}}}}},)"
42 R"( "version": 3, "interrupted": false, "seconds_since_epoch": 12345,)"
43 R"( "num_failures_by_type": {"PASS": 1, "FAIL": 0, "SKIP": 0}})";
44 ASSERT_EQ(actual, expected);
45
46 std::string failed_results_actual =
47 test_record_event_handler.GetTestRecordJsonString(300, true);
48
49 std::string failed_results_expected =
50 R"({"tests": {}, "version": 3, "interrupted": false,)"
51 R"( "seconds_since_epoch": 12345, "num_failures_by_type": {"PASS": 1,)"
52 R"( "FAIL": 0, "SKIP": 0}})";
53 ASSERT_EQ(failed_results_actual, failed_results_expected);
54 }
55
TEST(TestRecordFunctionality,MultipleTestsRun)56 TEST(TestRecordFunctionality, MultipleTestsRun) {
57 TestRecordEventHandler test_record_event_handler(kFakeTimeSinceEpoch);
58
59 // Initialize test cases to be run
60 TestCase test_case1{"suite1", "test1", "dir1/test_file.cc"};
61 TestResult test_result1 = TestResult::kSuccess;
62 TestCase test_case2{"suite2", "test2", "dir1/test_file.cc"};
63 TestResult test_result2 = TestResult::kFailure;
64 TestCase test_case3{"suite3", "test3", "dir1/dir2/test_file.cc"};
65 TestResult test_result3 = TestResult::kSuccess;
66 RunTestsSummary run_tests_summary = {2, 1, 0, 0};
67
68 // Simulate test run
69 test_record_event_handler.TestCaseStart(test_case1);
70 test_record_event_handler.TestCaseEnd(test_case1, test_result1);
71 test_record_event_handler.TestCaseStart(test_case2);
72 test_record_event_handler.TestCaseEnd(test_case2, test_result2);
73 test_record_event_handler.TestCaseStart(test_case3);
74 test_record_event_handler.TestCaseEnd(test_case3, test_result3);
75 test_record_event_handler.RunAllTestsEnd(run_tests_summary);
76
77 std::string actual = test_record_event_handler.GetTestRecordJsonString(400);
78
79 std::string expected =
80 R"({"tests": {"dir1": {"dir2": {"test_file.cc": {"suite3": {"test3":)"
81 R"( {"expected": "PASS", "actual": "PASS"}}}}, "test_file.cc":)"
82 R"( {"suite2": {"test2": {"expected": "PASS", "actual": "FAIL"}},)"
83 R"( "suite1": {"test1": {"expected": "PASS", "actual": "PASS"}}}}},)"
84 R"( "version": 3, "interrupted": false, "seconds_since_epoch": 12345,)"
85 R"( "num_failures_by_type": {"PASS": 2, "FAIL": 1, "SKIP": 0}})";
86 ASSERT_EQ(actual, expected);
87
88 std::string failed_results_actual =
89 test_record_event_handler.GetTestRecordJsonString(400, true);
90
91 std::string failed_results_expected =
92 R"({"tests": {"dir1": {"test_file.cc": {"suite2": {"test2": {"expected":)"
93 R"( "PASS", "actual": "FAIL"}}}}}, "version": 3, "interrupted": false,)"
94 R"( "seconds_since_epoch": 12345, "num_failures_by_type": {"PASS": 2,)"
95 R"( "FAIL": 1, "SKIP": 0}})";
96 ASSERT_EQ(failed_results_actual, failed_results_expected);
97 }
98
TEST(TestRecordFunctionality,JsonBufferTooSmall)99 TEST(TestRecordFunctionality, JsonBufferTooSmall) {
100 TestRecordEventHandler test_record_event_handler(kFakeTimeSinceEpoch);
101
102 // Initialize test cases to be run
103 TestCase test_case{"suite1", "test1", "dir1/test_file.cc"};
104 TestResult test_result = TestResult::kSuccess;
105 RunTestsSummary run_tests_summary = {1, 0, 0, 0};
106
107 // Simulate test run
108 test_record_event_handler.TestCaseStart(test_case);
109 test_record_event_handler.TestCaseEnd(test_case, test_result);
110 test_record_event_handler.RunAllTestsEnd(run_tests_summary);
111 EXPECT_DEATH_IF_SUPPORTED(
112 test_record_event_handler.GetTestRecordJsonString(10),
113 "Test record json buffer is not big enough, please increase size.");
114 }
115
TEST(TestRecordFunctionality,HandleSkipMacro)116 TEST(TestRecordFunctionality, HandleSkipMacro) {
117 TestRecordEventHandler test_record_event_handler(kFakeTimeSinceEpoch);
118
119 // Initialize test cases to be run
120 TestCase test_case{"suite1", "test1", "dir1/test_file.cc"};
121 TestResult test_result = TestResult::kSkipped;
122 TestExpectation skip_expectation = {
123 pw::unit_test::json_impl::kSkipMacroIndicator,
124 pw::unit_test::json_impl::kSkipMacroIndicator,
125 0,
126 true};
127 RunTestsSummary run_tests_summary = {0, 0, 1, 0};
128
129 // Simulate test run
130 test_record_event_handler.TestCaseStart(test_case);
131 test_record_event_handler.TestCaseExpect(test_case, skip_expectation);
132 test_record_event_handler.TestCaseEnd(test_case, test_result);
133 test_record_event_handler.RunAllTestsEnd(run_tests_summary);
134
135 std::string actual = test_record_event_handler.GetTestRecordJsonString(300);
136 std::string expected =
137 R"({"tests": {"dir1": {"test_file.cc": {"suite1":)"
138 R"( {"test1": {"expected": "SKIP", "actual": "SKIP"}}}}},)"
139 R"( "version": 3, "interrupted": false, "seconds_since_epoch": 12345,)"
140 R"( "num_failures_by_type": {"PASS": 0, "FAIL": 0, "SKIP": 1}})";
141 ASSERT_EQ(actual, expected);
142
143 std::string failed_results_actual =
144 test_record_event_handler.GetTestRecordJsonString(300, true);
145
146 std::string failed_results_expected =
147 R"({"tests": {}, "version": 3, "interrupted": false,)"
148 R"( "seconds_since_epoch": 12345, "num_failures_by_type": {"PASS": 0,)"
149 R"( "FAIL": 0, "SKIP": 1}})";
150 ASSERT_EQ(failed_results_actual, failed_results_expected);
151 }
152
TEST(TestRecordFunctionality,DuplicateTest)153 TEST(TestRecordFunctionality, DuplicateTest) {
154 TestRecordEventHandler test_record_event_handler(kFakeTimeSinceEpoch);
155
156 // Initialize test cases to be run
157 TestCase test_case1{"suite1", "test1", "dir1/test_file.cc"};
158 TestResult test_result1 = TestResult::kSuccess;
159 TestCase test_case2{"suite1", "test1", "dir1/test_file.cc"};
160 TestResult test_result2 = TestResult::kFailure;
161 RunTestsSummary run_tests_summary = {0, 1, 0, 0};
162
163 // Simulate test run
164 test_record_event_handler.TestCaseStart(test_case1);
165 test_record_event_handler.TestCaseEnd(test_case1, test_result1);
166 test_record_event_handler.TestCaseStart(test_case2);
167 test_record_event_handler.TestCaseEnd(test_case2, test_result2);
168 test_record_event_handler.RunAllTestsEnd(run_tests_summary);
169
170 std::string actual = test_record_event_handler.GetTestRecordJsonString(300);
171
172 std::string expected =
173 R"({"tests": {"dir1": {"test_file.cc": {"suite1":)"
174 R"( {"test1": {"expected": "PASS", "actual": "FAIL"}}}}},)"
175 R"( "version": 3, "interrupted": false, "seconds_since_epoch": 12345,)"
176 R"( "num_failures_by_type": {"PASS": 0, "FAIL": 1, "SKIP": 0}})";
177 ASSERT_EQ(actual, expected);
178
179 std::string failed_results_actual =
180 test_record_event_handler.GetTestRecordJsonString(300, true);
181
182 std::string failed_results_expected =
183 R"({"tests": {"dir1": {"test_file.cc": {"suite1":)"
184 R"( {"test1": {"expected": "PASS", "actual": "FAIL"}}}}},)"
185 R"( "version": 3, "interrupted": false, "seconds_since_epoch": 12345,)"
186 R"( "num_failures_by_type": {"PASS": 0, "FAIL": 1, "SKIP": 0}})";
187 ASSERT_EQ(failed_results_actual, failed_results_expected);
188 }
189
190 } // namespace
191 } // namespace pw::unit_test