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 : #if CHIP_HAVE_CONFIG_H
30 : #include <crypto/CryptoBuildConfig.h>
31 : #endif
32 : #if CHIP_CRYPTO_PSA
33 : #include <psa/crypto.h>
34 : #endif
35 :
36 : using namespace chip;
37 : using namespace pw::unit_test;
38 :
39 : namespace {
40 :
41 : bool gQuiet = false;
42 :
43 : #define kOptQuiet 'q'
44 :
45 : ArgParser::OptionDef gProgramCustomOptionDefs[] = {
46 : { "quiet", ArgParser::kNoArgument, kOptQuiet },
47 : {},
48 : };
49 :
50 : const char gProgramCustomOptionHelp[] = " --quiet\n"
51 : " Output only failures and assertion errors.\n"
52 : "\n";
53 :
54 386 : bool HandleCustomOption(const char * aProgram, ArgParser::OptionSet * aOptions, int aIdentifier, const char * aName,
55 : const char * aValue)
56 : {
57 386 : switch (aIdentifier)
58 : {
59 386 : case kOptQuiet:
60 386 : gQuiet = true;
61 386 : break;
62 0 : default:
63 0 : ArgParser::PrintArgError("%s: INTERNAL ERROR: Unhandled option: %s\n", aProgram, aName);
64 0 : return false;
65 : }
66 :
67 386 : return true;
68 : }
69 :
70 : ArgParser::OptionSet gProgramCustomOptions = { HandleCustomOption, gProgramCustomOptionDefs, "GENERAL OPTIONS",
71 : gProgramCustomOptionHelp };
72 :
73 : class ChipLogHandler : public pw::unit_test::EventHandler
74 : {
75 : public:
76 386 : ChipLogHandler(bool quiet) : mQuiet(quiet) {}
77 :
78 0 : void TestProgramStart(const ProgramSummary & program_summary) override
79 : {
80 0 : VerifyOrReturn(!mQuiet);
81 0 : printf("[==========] Running %d tests from %d test suite%s.\n", program_summary.tests_to_run, program_summary.test_suites,
82 0 : program_summary.test_suites > 1 ? "s" : "");
83 : }
84 :
85 0 : void EnvironmentsSetUpEnd() override
86 : {
87 0 : VerifyOrReturn(!mQuiet);
88 0 : printf("[----------] Global test environments setup.\n");
89 : }
90 :
91 0 : void TestSuiteStart(const TestSuite & test_suite) override
92 : {
93 0 : VerifyOrReturn(!mQuiet);
94 0 : printf("[----------] %d tests from %s.\n", test_suite.test_to_run_count, test_suite.name);
95 : }
96 :
97 0 : void TestSuiteEnd(const TestSuite & test_suite) override
98 : {
99 0 : VerifyOrReturn(!mQuiet);
100 0 : printf("[----------] %d tests from %s.\n", test_suite.test_to_run_count, test_suite.name);
101 : }
102 :
103 : /// Called after environment teardown for each iteration of tests ends.
104 0 : void EnvironmentsTearDownEnd() override
105 : {
106 0 : VerifyOrReturn(!mQuiet);
107 0 : printf("[----------] Global test environments tear-down.\n");
108 : }
109 :
110 : /// Called after all test activities have ended.
111 0 : void TestProgramEnd(const ProgramSummary & program_summary) override
112 : {
113 0 : VerifyOrReturn(!mQuiet);
114 0 : printf("[==========] %d / %d tests from %d test suite%s ran.\n",
115 0 : program_summary.tests_to_run - program_summary.tests_summary.skipped_tests -
116 0 : program_summary.tests_summary.disabled_tests,
117 0 : program_summary.tests_to_run, program_summary.test_suites, program_summary.test_suites > 1 ? "s" : "");
118 0 : printf("[ PASSED ] %d test(s).\n", program_summary.tests_summary.passed_tests);
119 :
120 0 : if (program_summary.tests_summary.skipped_tests || program_summary.tests_summary.disabled_tests)
121 : {
122 0 : printf("[ DISABLED ] %d test(s).\n",
123 0 : program_summary.tests_summary.skipped_tests + program_summary.tests_summary.disabled_tests);
124 : }
125 :
126 0 : if (program_summary.tests_summary.failed_tests)
127 : {
128 0 : printf("[ FAILED ] %d test(s).\n", program_summary.tests_summary.failed_tests);
129 : }
130 : }
131 :
132 : /// Called before all tests are run.
133 386 : void RunAllTestsStart() override
134 : {
135 386 : VerifyOrReturn(!mQuiet);
136 0 : printf("[==========] Running all tests.\n");
137 : }
138 :
139 : /// Called after all tests are run.
140 386 : void RunAllTestsEnd(const RunTestsSummary & run_tests_summary) override
141 : {
142 386 : VerifyOrReturn(!mQuiet);
143 0 : printf("[==========] Done running all tests.\n");
144 0 : printf("[ PASSED ] %d test(s).\n", run_tests_summary.passed_tests);
145 :
146 0 : if (run_tests_summary.skipped_tests)
147 : {
148 0 : printf("[ DISABLED ] %d test(s).\n", run_tests_summary.skipped_tests);
149 : }
150 0 : if (run_tests_summary.failed_tests)
151 : {
152 0 : printf("[ FAILED ] %d test(s).\n", run_tests_summary.failed_tests);
153 : }
154 : }
155 :
156 3486 : void TestCaseStart(const TestCase & test_case) override
157 : {
158 3486 : VerifyOrReturn(!mQuiet);
159 0 : printf("[ RUN ] %s.%s\n", test_case.suite_name, test_case.test_name);
160 : }
161 :
162 3486 : void TestCaseEnd(const TestCase & test_case, TestResult result) override
163 : {
164 3486 : switch (result)
165 : {
166 3477 : case TestResult::kSuccess:
167 3477 : if (!mQuiet)
168 : {
169 0 : printf("[ OK ] %s.%s\n", test_case.suite_name, test_case.test_name);
170 : }
171 3477 : break;
172 0 : case TestResult::kFailure:
173 0 : printf("[ FAILED ] %s.%s\n", test_case.suite_name, test_case.test_name);
174 0 : break;
175 9 : case TestResult::kSkipped:
176 9 : if (!mQuiet)
177 : {
178 0 : printf("[ DISABLED ] %s.%s\n", test_case.suite_name, test_case.test_name);
179 : }
180 9 : break;
181 : }
182 3486 : }
183 :
184 : /// Called when a disabled test case is encountered.
185 0 : void TestCaseDisabled(const TestCase & test) override
186 : {
187 0 : VerifyOrReturn(!mQuiet);
188 0 : printf("Skipping disabled test %s.%s\n", test.suite_name, test.test_name);
189 : }
190 :
191 : /// Called after each expect or assert statement within a test case with the
192 : /// result.
193 10 : void TestCaseExpect(const TestCase & test_case, const TestExpectation & expectation) override
194 : {
195 10 : VerifyOrReturn(!expectation.success);
196 :
197 0 : printf("%s:%d: Failure\n", expectation.file_name, expectation.line_number);
198 0 : printf(" Expected: %s\n", expectation.expression);
199 0 : printf(" Actual: %s\n", expectation.evaluated_expression);
200 : }
201 :
202 : private:
203 : bool mQuiet;
204 : };
205 :
206 : } // namespace
207 :
208 386 : int main(int argc, char ** argv)
209 : {
210 772 : SuccessOrDie(Platform::MemoryInit());
211 :
212 : #if CHIP_CRYPTO_PSA
213 : // Catch-all for tests that use crypto without InitChipStack() (which is where
214 : // the POSIX platform manager initializes PSA). Idempotent.
215 : VerifyOrDie(psa_crypto_init() == PSA_SUCCESS);
216 : #endif
217 :
218 386 : ArgParser::HelpOptions helpOptions(argv[0], "Usage: unit_test_main [options]", "1.0");
219 386 : ArgParser::OptionSet * allOptions[] = { &helpOptions, &gProgramCustomOptions, nullptr };
220 :
221 386 : if (!ArgParser::ParseArgs(argv[0], argc, argv, allOptions))
222 : {
223 0 : return 1;
224 : }
225 :
226 : // Make the binary compatible with pw_unit_test:googletest. Has no effect
227 : // when using pw_unit_test:light.
228 386 : testing::InitGoogleTest(&argc, argv);
229 :
230 386 : if (gQuiet)
231 : {
232 : // Extra quiet - we keep errors since those likely help debug failures, however
233 : // the rest are hidden.
234 386 : Logging::SetLogFilter(Logging::kLogCategory_Error);
235 : }
236 :
237 386 : ChipLogHandler handler(gQuiet);
238 :
239 386 : pw::unit_test::RegisterEventHandler(&handler);
240 386 : return RUN_ALL_TESTS();
241 386 : }
|