Line data Source code
1 : /*
2 : * Copyright (c) 2026 Project CHIP Authors
3 : *
4 : * Licensed under the Apache License, Version 2.0 (the "License");
5 : * you may not use this file except in compliance with the License.
6 : * You may obtain a copy of the License at
7 : *
8 : * http://www.apache.org/licenses/LICENSE-2.0
9 : *
10 : * Unless required by applicable law or agreed to in writing, software
11 : * distributed under the License is distributed on an "AS IS" BASIS,
12 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 : * See the License for the specific language governing permissions and
14 : * limitations under the License.
15 : */
16 :
17 : #include <string_view>
18 :
19 : #include <lib/support/CHIPArgParser.hpp>
20 : #include <lib/support/CHIPMem.h>
21 : #include <lib/support/CHIPPlatformMemory.h>
22 : #include <lib/support/logging/CHIPLogging.h>
23 :
24 : #include "lib/support/logging/Constants.h"
25 : #include "lib/support/logging/TextOnlyLogging.h"
26 : #include "pw_unit_test/event_handler.h"
27 : #include "pw_unit_test/framework.h"
28 :
29 : using namespace chip;
30 : using namespace pw::unit_test;
31 :
32 : namespace {
33 :
34 : bool gQuiet = false;
35 :
36 : #define kOptQuiet 'q'
37 :
38 : ArgParser::OptionDef gProgramCustomOptionDefs[] = {
39 : { "quiet", ArgParser::kNoArgument, kOptQuiet },
40 : {},
41 : };
42 :
43 : const char gProgramCustomOptionHelp[] = " --quiet\n"
44 : " Output only failures and assertion errors.\n"
45 : "\n";
46 :
47 365 : bool HandleCustomOption(const char * aProgram, ArgParser::OptionSet * aOptions, int aIdentifier, const char * aName,
48 : const char * aValue)
49 : {
50 365 : switch (aIdentifier)
51 : {
52 365 : case kOptQuiet:
53 365 : gQuiet = true;
54 365 : break;
55 0 : default:
56 0 : ArgParser::PrintArgError("%s: INTERNAL ERROR: Unhandled option: %s\n", aProgram, aName);
57 0 : return false;
58 : }
59 :
60 365 : return true;
61 : }
62 :
63 : ArgParser::OptionSet gProgramCustomOptions = { HandleCustomOption, gProgramCustomOptionDefs, "GENERAL OPTIONS",
64 : gProgramCustomOptionHelp };
65 :
66 : class ChipLogHandler : public pw::unit_test::EventHandler
67 : {
68 : public:
69 365 : ChipLogHandler(bool quiet) : mQuiet(quiet) {}
70 :
71 0 : void TestProgramStart(const ProgramSummary & program_summary) override
72 : {
73 0 : VerifyOrReturn(!mQuiet);
74 0 : printf("[==========] Running %d tests from %d test suite%s.\n", program_summary.tests_to_run, program_summary.test_suites,
75 0 : program_summary.test_suites > 1 ? "s" : "");
76 : }
77 :
78 0 : void EnvironmentsSetUpEnd() override
79 : {
80 0 : VerifyOrReturn(!mQuiet);
81 0 : printf("[----------] Global test environments setup.\n");
82 : }
83 :
84 0 : void TestSuiteStart(const TestSuite & test_suite) override
85 : {
86 0 : VerifyOrReturn(!mQuiet);
87 0 : printf("[----------] %d tests from %s.\n", test_suite.test_to_run_count, test_suite.name);
88 : }
89 :
90 0 : void TestSuiteEnd(const TestSuite & test_suite) override
91 : {
92 0 : VerifyOrReturn(!mQuiet);
93 0 : printf("[----------] %d tests from %s.\n", test_suite.test_to_run_count, test_suite.name);
94 : }
95 :
96 : /// Called after environment teardown for each iteration of tests ends.
97 0 : void EnvironmentsTearDownEnd() override
98 : {
99 0 : VerifyOrReturn(!mQuiet);
100 0 : printf("[----------] Global test environments tear-down.\n");
101 : }
102 :
103 : /// Called after all test activities have ended.
104 0 : void TestProgramEnd(const ProgramSummary & program_summary) override
105 : {
106 0 : VerifyOrReturn(!mQuiet);
107 0 : printf("[==========] %d / %d tests from %d test suite%s ran.\n",
108 0 : program_summary.tests_to_run - program_summary.tests_summary.skipped_tests -
109 0 : program_summary.tests_summary.disabled_tests,
110 0 : program_summary.tests_to_run, program_summary.test_suites, program_summary.test_suites > 1 ? "s" : "");
111 0 : printf("[ PASSED ] %d test(s).\n", program_summary.tests_summary.passed_tests);
112 :
113 0 : if (program_summary.tests_summary.skipped_tests || program_summary.tests_summary.disabled_tests)
114 : {
115 0 : printf("[ DISABLED ] %d test(s).\n",
116 0 : program_summary.tests_summary.skipped_tests + program_summary.tests_summary.disabled_tests);
117 : }
118 :
119 0 : if (program_summary.tests_summary.failed_tests)
120 : {
121 0 : printf("[ FAILED ] %d test(s).\n", program_summary.tests_summary.failed_tests);
122 : }
123 : }
124 :
125 : /// Called before all tests are run.
126 365 : void RunAllTestsStart() override
127 : {
128 365 : VerifyOrReturn(!mQuiet);
129 0 : printf("[==========] Running all tests.\n");
130 : }
131 :
132 : /// Called after all tests are run.
133 365 : void RunAllTestsEnd(const RunTestsSummary & run_tests_summary) override
134 : {
135 365 : VerifyOrReturn(!mQuiet);
136 0 : printf("[==========] Done running all tests.\n");
137 0 : printf("[ PASSED ] %d test(s).\n", run_tests_summary.passed_tests);
138 :
139 0 : if (run_tests_summary.skipped_tests)
140 : {
141 0 : printf("[ DISABLED ] %d test(s).\n", run_tests_summary.skipped_tests);
142 : }
143 0 : if (run_tests_summary.failed_tests)
144 : {
145 0 : printf("[ FAILED ] %d test(s).\n", run_tests_summary.failed_tests);
146 : }
147 : }
148 :
149 3045 : void TestCaseStart(const TestCase & test_case) override
150 : {
151 3045 : VerifyOrReturn(!mQuiet);
152 0 : printf("[ RUN ] %s.%s\n", test_case.suite_name, test_case.test_name);
153 : }
154 :
155 3045 : void TestCaseEnd(const TestCase & test_case, TestResult result) override
156 : {
157 3045 : switch (result)
158 : {
159 3041 : case TestResult::kSuccess:
160 3041 : if (!mQuiet)
161 : {
162 0 : printf("[ OK ] %s.%s\n", test_case.suite_name, test_case.test_name);
163 : }
164 3041 : break;
165 0 : case TestResult::kFailure:
166 0 : printf("[ FAILED ] %s.%s\n", test_case.suite_name, test_case.test_name);
167 0 : break;
168 4 : case TestResult::kSkipped:
169 4 : if (!mQuiet)
170 : {
171 0 : printf("[ DISABLED ] %s.%s\n", test_case.suite_name, test_case.test_name);
172 : }
173 4 : break;
174 : }
175 3045 : }
176 :
177 : /// Called when a disabled test case is encountered.
178 0 : void TestCaseDisabled(const TestCase & test) override
179 : {
180 0 : VerifyOrReturn(!mQuiet);
181 0 : printf("Skipping disabled test %s.%s\n", test.suite_name, test.test_name);
182 : }
183 :
184 : /// Called after each expect or assert statement within a test case with the
185 : /// result.
186 5 : void TestCaseExpect(const TestCase & test_case, const TestExpectation & expectation) override
187 : {
188 5 : VerifyOrReturn(!expectation.success);
189 :
190 0 : printf("%s:%d: Failure\n", expectation.file_name, expectation.line_number);
191 0 : printf(" Expected: %s\n", expectation.expression);
192 0 : printf(" Actual: %s\n", expectation.evaluated_expression);
193 : }
194 :
195 : private:
196 : bool mQuiet;
197 : };
198 :
199 : } // namespace
200 :
201 365 : int main(int argc, char ** argv)
202 : {
203 730 : SuccessOrDie(Platform::MemoryInit());
204 :
205 365 : ArgParser::HelpOptions helpOptions(argv[0], "Usage: unit_test_main [options]", "1.0");
206 365 : ArgParser::OptionSet * allOptions[] = { &helpOptions, &gProgramCustomOptions, nullptr };
207 :
208 365 : if (!ArgParser::ParseArgs(argv[0], argc, argv, allOptions))
209 : {
210 0 : return 1;
211 : }
212 :
213 : // Make the binary compatible with pw_unit_test:googletest. Has no effect
214 : // when using pw_unit_test:light.
215 365 : testing::InitGoogleTest(&argc, argv);
216 :
217 365 : if (gQuiet)
218 : {
219 : // Extra quiet - we keep errors since those likely help debug failures, however
220 : // the rest are hidden.
221 365 : Logging::SetLogFilter(Logging::kLogCategory_Error);
222 : }
223 :
224 365 : ChipLogHandler handler(gQuiet);
225 :
226 365 : pw::unit_test::RegisterEventHandler(&handler);
227 365 : return RUN_ALL_TESTS();
228 365 : }
|