1 // Copyright 2020 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 // The Pigweed unit test framework requires C++17 to use its full functionality.
16 #pragma once
17 
18 // IWYU pragma: private, include "pw_unit_test/framework.h"
19 
20 #if defined(GTEST_TEST)
21 #error \
22     "GTEST_TEST is already defined. Make sure googletest headers are not " \
23        "included when using the pw_unit_test light backend."
24 #endif  // GTEST_TEST
25 
26 #include <cstddef>
27 #include <cstdint>
28 #include <cstring>
29 #include <new>
30 #include <string_view>
31 
32 #include "pw_bytes/alignment.h"
33 #include "pw_polyfill/standard.h"
34 #include "pw_preprocessor/compiler.h"
35 #include "pw_preprocessor/util.h"
36 #include "pw_span/span.h"
37 #include "pw_status/status.h"
38 #include "pw_string/string_builder.h"
39 #include "pw_unit_test/config.h"
40 #include "pw_unit_test/event_handler.h"
41 
42 /// @def GTEST_TEST
43 /// Alias for `TEST`.
44 #define GTEST_TEST(test_suite_name, test_name)                           \
45   _PW_TEST_SUITE_NAMES_MUST_BE_UNIQUE(void /* TEST */, test_suite_name); \
46   _PW_TEST(test_suite_name, test_name, ::pw::unit_test::internal::Test)
47 
48 /// @def TEST
49 /// Defines a test given the suite name and test case name.
50 ///
51 /// If `TEST` is conflicting with other code, set `GTEST_DONT_DEFINE_TEST` to
52 /// 1 and use `GTEST_TEST` instead.
53 ///
54 /// @param[in] test_suite_name The name of the test suite or collection of
55 /// tests.
56 /// @param[in] test_name The name of the test case.
57 #if !(defined(GTEST_DONT_DEFINE_TEST) && GTEST_DONT_DEFINE_TEST)
58 #define TEST(test_suite_name, test_name) GTEST_TEST(test_suite_name, test_name)
59 #endif  // !GTEST_DONT_DEFINE_TEST
60 
61 /// @def TEST_F
62 /// Defines a test case using a test fixture.
63 ///
64 /// @param[in] test_fixture The name of the test fixture class to use.
65 /// @param[in] test_name The name of the test case.
66 #define TEST_F(test_fixture, test_name)                                \
67   _PW_TEST_SUITE_NAMES_MUST_BE_UNIQUE(int /* TEST_F */, test_fixture); \
68   _PW_TEST(test_fixture, test_name, test_fixture)
69 
70 /// @def FRIEND_TEST
71 /// Defines a test case from a test suite as a friend class of an implementation
72 /// class.
73 ///
74 /// @warning Use of `FRIEND_TEST` is discouraged, because it induces coupling
75 /// between testing and implementation code. Consider this a last resort only.
76 ///
77 /// @param[in] test_suite_name The name of the test suite to befriend.
78 /// @param[in] test_name The name of the test case to befriend.
79 #define FRIEND_TEST(test_suite_name, test_name) \
80   friend class test_suite_name##_##test_name##_Test
81 
82 /// @def EXPECT_TRUE
83 /// Verifies that @p expr evaluates to true.
84 ///
85 /// @param[in] expr The expression to evaluate.
86 #define EXPECT_TRUE(expr) _PW_TEST_EXPECT(_PW_TEST_BOOL(expr, true))
87 
88 /// @def EXPECT_FALSE
89 /// Verifies that @p expr evaluates to false.
90 ///
91 /// @param[in] expr The expression to evaluate.
92 #define EXPECT_FALSE(expr) _PW_TEST_EXPECT(_PW_TEST_BOOL(expr, false))
93 
94 /// @def EXPECT_EQ
95 /// Verifies that `lhs == rhs`.
96 ///
97 /// Does pointer equality on pointers. If used on two C strings, `EXPECT_EQ`
98 /// tests if they are in the same memory location, not if they have the same
99 /// value. Use `EXPECT_STREQ` to compare C strings (e.g. `const char*`) by
100 /// value.
101 ///
102 /// When comparing a pointer to `NULL` use `EXPECT_EQ(ptr, nullptr)` instead of
103 /// `EXPECT_EQ(ptr, NULL)`.
104 ///
105 /// @param[in] lhs The left side of the equality comparison.
106 /// @param[in] rhs The right side of the equality comparison.
107 #define EXPECT_EQ(lhs, rhs) _PW_TEST_EXPECT(_PW_TEST_OP(lhs, rhs, ==))
108 
109 /// @def EXPECT_NE
110 /// Verifies that `lhs != rhs`.
111 ///
112 /// Does pointer equality on pointers. If used on two C strings, it tests if
113 /// they are in different memory locations, not if they have different values.
114 /// Use `EXPECT_STRNE` to compare C strings (e.g. `const char*`) by value.
115 ///
116 /// When comparing a pointer to `NULL`, use `EXPECT_NE(ptr, nullptr)` instead
117 /// of `EXPECT_NE(ptr, NULL)`.
118 
119 /// @param[in] lhs The left side of the inequality comparison.
120 /// @param[in] rhs The right side of the inequality comparison.
121 #define EXPECT_NE(lhs, rhs) _PW_TEST_EXPECT(_PW_TEST_OP(lhs, rhs, !=))
122 
123 /// @def EXPECT_GT
124 /// Verifies that `lhs > rhs`.
125 ///
126 /// @param[in] lhs The left side of the comparison.
127 /// @param[in] rhs The right side of the comparison.
128 #define EXPECT_GT(lhs, rhs) _PW_TEST_EXPECT(_PW_TEST_OP(lhs, rhs, >))
129 
130 /// @def EXPECT_GE
131 /// Verifies that `lhs >= rhs`.
132 ///
133 /// @param[in] lhs The left side of the comparison.
134 /// @param[in] rhs The right side of the comparison.
135 #define EXPECT_GE(lhs, rhs) _PW_TEST_EXPECT(_PW_TEST_OP(lhs, rhs, >=))
136 
137 /// @def EXPECT_LT
138 /// Verifies that `lhs < rhs`.
139 ///
140 /// @param[in] lhs The left side of the comparison.
141 /// @param[in] rhs The right side of the comparison.
142 #define EXPECT_LT(lhs, rhs) _PW_TEST_EXPECT(_PW_TEST_OP(lhs, rhs, <))
143 
144 /// @def EXPECT_LE
145 /// Verifies that `lhs <= rhs`.
146 ///
147 /// @param[in] lhs The left side of the comparison.
148 /// @param[in] rhs The right side of the comparison.
149 #define EXPECT_LE(lhs, rhs) _PW_TEST_EXPECT(_PW_TEST_OP(lhs, rhs, <=))
150 
151 /// @def EXPECT_NEAR
152 /// Verifies that the difference between `lhs` and `rhs` does not exceed the
153 /// absolute error bound `epsilon`.
154 ///
155 /// @param[in] lhs The left side of the comparison.
156 /// @param[in] rhs The right side of the comparison.
157 /// @param[in] epsilon The maximum difference between `lhs` and `rhs`.
158 #define EXPECT_NEAR(lhs, rhs, epsilon) \
159   _PW_TEST_EXPECT(_PW_TEST_NEAR(lhs, rhs, epsilon))
160 
161 /// @def EXPECT_FLOAT_EQ
162 /// Verifies that the two float values `rhs` and `lhs` are approximately
163 /// equal, to within 4 units in the last place (ULPs) from each other.
164 ///
165 /// @param[in] lhs The left side of the equality comparison.
166 /// @param[in] rhs The right side of the equality comparison.
167 #define EXPECT_FLOAT_EQ(lhs, rhs) \
168   _PW_TEST_EXPECT(                \
169       _PW_TEST_NEAR(lhs, rhs, 4 * std::numeric_limits<float>::epsilon()))
170 
171 /// @def EXPECT_DOUBLE_EQ
172 /// Verifies that the two double values `rhs` and `lhs` are approximately
173 /// equal, to within 4 units in the last place (ULPs) from each other.
174 ///
175 /// @param[in] lhs The left side of the equality comparison.
176 /// @param[in] rhs The right side of the equality comparison.
177 #define EXPECT_DOUBLE_EQ(lhs, rhs) \
178   _PW_TEST_EXPECT(                 \
179       _PW_TEST_NEAR(lhs, rhs, 4 * std::numeric_limits<double>::epsilon()))
180 
181 /// @def EXPECT_STREQ
182 /// Verifies that the two C strings `lhs` and `rhs` have the same contents.
183 ///
184 /// @param[in] lhs The left side of the equality comparison.
185 /// @param[] rhs The right side of the equality comparison.
186 #define EXPECT_STREQ(lhs, rhs) _PW_TEST_EXPECT(_PW_TEST_C_STR(lhs, rhs, ==))
187 
188 /// @def EXPECT_STRNE
189 /// Verifies that the two C strings `lhs` and `rhs` have different content.
190 ///
191 /// @param[in] lhs The left side of the inequality comparison.
192 /// @param[in] rhs The right side of the inequality comparison.
193 #define EXPECT_STRNE(lhs, rhs) _PW_TEST_EXPECT(_PW_TEST_C_STR(lhs, rhs, !=))
194 
195 /// @def ASSERT_TRUE
196 /// See `EXPECT_TRUE`.
197 #define ASSERT_TRUE(expr) _PW_TEST_ASSERT(_PW_TEST_BOOL(expr, true))
198 
199 /// @def ASSERT_FALSE
200 /// See `EXPECT_FALSE`.
201 #define ASSERT_FALSE(expr) _PW_TEST_ASSERT(_PW_TEST_BOOL(expr, false))
202 
203 /// @def ASSERT_EQ
204 /// See `EXPECT_EQ`.
205 #define ASSERT_EQ(lhs, rhs) _PW_TEST_ASSERT(_PW_TEST_OP(lhs, rhs, ==))
206 
207 /// @def ASSERT_NE
208 /// See `EXPECT_NE`.
209 #define ASSERT_NE(lhs, rhs) _PW_TEST_ASSERT(_PW_TEST_OP(lhs, rhs, !=))
210 
211 /// @def ASSERT_GT
212 /// See `EXPECT_GT`.
213 #define ASSERT_GT(lhs, rhs) _PW_TEST_ASSERT(_PW_TEST_OP(lhs, rhs, >))
214 
215 /// @def ASSERT_GE
216 /// See `EXPECT_GE`.
217 #define ASSERT_GE(lhs, rhs) _PW_TEST_ASSERT(_PW_TEST_OP(lhs, rhs, >=))
218 
219 /// @def ASSERT_LT
220 /// See `EXPECT_LT`.
221 #define ASSERT_LT(lhs, rhs) _PW_TEST_ASSERT(_PW_TEST_OP(lhs, rhs, <))
222 
223 /// @def ASSERT_LE
224 /// See `EXPECT_LE`.
225 #define ASSERT_LE(lhs, rhs) _PW_TEST_ASSERT(_PW_TEST_OP(lhs, rhs, <=))
226 
227 /// @def ASSERT_NEAR
228 /// See `EXPECT_NEAR`.
229 #define ASSERT_NEAR(lhs, rhs, epsilon) \
230   _PW_TEST_ASSERT(_PW_TEST_NEAR(lhs, rhs, epsilon))
231 
232 /// @def ASSERT_FLOAT_EQ
233 /// See `EXPECT_FLOAT_EQ`.
234 #define ASSERT_FLOAT_EQ(lhs, rhs) \
235   _PW_TEST_ASSERT(                \
236       _PW_TEST_NEAR(lhs, rhs, 4 * std::numeric_limits<float>::epsilon()))
237 
238 /// @def ASSERT_DOUBLE_EQ
239 /// See `EXPECT_DOUBLE_EQ`.
240 #define ASSERT_DOUBLE_EQ(lhs, rhs) \
241   _PW_TEST_ASSERT(                 \
242       _PW_TEST_NEAR(lhs, rhs, 4 * std::numeric_limits<double>::epsilon()))
243 
244 /// @def ASSERT_STREQ
245 /// See `EXPECT_STREQ`.
246 #define ASSERT_STREQ(lhs, rhs) _PW_TEST_ASSERT(_PW_TEST_C_STR(lhs, rhs, ==))
247 
248 /// @def ASSERT_STRNE
249 /// See `EXPECT_STRNE`.
250 #define ASSERT_STRNE(lhs, rhs) _PW_TEST_ASSERT(_PW_TEST_C_STR(lhs, rhs, !=))
251 
252 /// @def ADD_FAILURE
253 /// Generates a non-fatal failure with a generic message.
254 #define ADD_FAILURE()                                                      \
255   ::pw::unit_test::internal::ReturnHelper() =                              \
256       ::pw::unit_test::internal::Framework::Get().CurrentTestExpectSimple( \
257           "(line is not executed)", "(line was executed)", __LINE__, false)
258 
259 /// @def GTEST_FAIL
260 ///
261 /// Alias of `FAIL`.
262 #define GTEST_FAIL() return ADD_FAILURE()
263 
264 /// @def GTEST_SKIP
265 /// Skips test at runtime. Skips are neither successful nor failed. They
266 /// abort the current function.
267 #define GTEST_SKIP()                                                      \
268   return ::pw::unit_test::internal::ReturnHelper() =                      \
269              ::pw::unit_test::internal::Framework::Get().CurrentTestSkip( \
270                  __LINE__)
271 
272 /// @def FAIL
273 /// Generates a fatal failure with a generic message.
274 ///
275 /// If this generic name is clashing with other code, set
276 /// `GTEST_DONT_DEFINE_FAIL` to 1 and use `GTEST_FAIL` instead.
277 #if !(defined(GTEST_DONT_DEFINE_FAIL) && GTEST_DONT_DEFINE_FAIL)
278 #define FAIL() GTEST_FAIL()
279 #endif  // !GTEST_DONT_DEFINE_FAIL
280 
281 /// @def GTEST_SUCCEED
282 ///
283 /// Alias of `SUCCEED`.
284 #define GTEST_SUCCEED()                                                \
285   ::pw::unit_test::internal::Framework::Get().CurrentTestExpectSimple( \
286       "(success)", "(success)", __LINE__, true)
287 
288 /// @def SUCCEED
289 ///
290 /// Generates success with a generic message.
291 ///
292 /// If this generic name is conflicting with other code, set
293 /// `GTEST_DONT_DEFINE_SUCCEED` to 1 and use `GTEST_SUCCEED` instead.
294 #if !(defined(GTEST_DONT_DEFINE_SUCCEED) && GTEST_DONT_DEFINE_SUCCEED)
295 #define SUCCEED() GTEST_SUCCEED()
296 #endif  // !GTEST_DONT_DEFINE_SUCCEED
297 
298 /// The `pw_unit_test` framework entrypoint. Runs every registered test case
299 /// and dispatches the results through the event handler.
300 ///
301 /// @pre An event handler has been registered before calling `RUN_ALL_TESTS`.
302 ///
303 /// @returns A status of 0 if all tests passed, or non-zero if there were any
304 /// failures. This is compatible with GoogleTest.
305 int RUN_ALL_TESTS();
306 
307 /// @def GTEST_HAS_DEATH_TEST
308 /// Death tests are not supported. The `*_DEATH_IF_SUPPORTED` macros do nothing.
309 #define GTEST_HAS_DEATH_TEST 0
310 
311 /// @def EXPECT_DEATH_IF_SUPPORTED
312 /// See `GTEST_HAS_DEATH_TEST`.
313 #define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \
314   if (0) {                                          \
315     static_cast<void>(statement);                   \
316     static_cast<void>(regex);                       \
317   }                                                 \
318   static_assert(true, "Macros must be terminated with a semicolon")
319 
320 /// @def ASSERT_DEATH_IF_SUPPORTED
321 /// See `GTEST_HAS_DEATH_TEST`.
322 #define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \
323   EXPECT_DEATH_IF_SUPPORTED(statement, regex)
324 
325 namespace pw {
326 namespace string {
327 
328 // This function is used to print unknown types that are used in EXPECT or
329 // ASSERT statements in tests.
330 //
331 // You can add support for displaying custom types by defining a ToString
332 // template specialization. For example:
333 //
334 //   namespace pw {
335 //
336 //   template <>
337 //   StatusWithSize ToString<MyType>(const MyType& value,
338 //                                   span<char> buffer) {
339 //     return string::Format("<MyType|%d>", value.id);
340 //   }
341 //
342 //   }  // namespace pw
343 //
344 // See the documentation in pw_string/string_builder.h for more information.
345 template <typename T>
UnknownTypeToString(const T & value,span<char> buffer)346 StatusWithSize UnknownTypeToString(const T& value, span<char> buffer) {
347   StringBuilder sb(buffer);
348   sb << '<' << sizeof(value) << "-byte object at 0x" << &value;
349 
350   // How many bytes of the object to print.
351   //
352   // WARNING: Printing the contents of an object may be undefined behavior!
353   // Accessing uninitialized memory is undefined behavior, and objects
354   // sometimes contain uninitialized regions, such as padding bytes or
355   // unallocated storage (e.g. std::optional). kPrintMaybeUninitializedBytes
356   // MUST stay at 0, except when changed locally to help with debugging.
357   constexpr size_t kPrintMaybeUnintializedBytes = 0;
358 
359   constexpr size_t kBytesToPrint =
360       std::min(sizeof(value), kPrintMaybeUnintializedBytes);
361 
362   if (kBytesToPrint != 0u) {
363     sb << " |";
364 
365     // reinterpret_cast to std::byte is permitted by C++'s type aliasing
366     // rules.
367     const std::byte* bytes = reinterpret_cast<const std::byte*>(&value);
368 
369     for (size_t i = 0; i < kBytesToPrint; ++i) {
370       sb << ' ' << bytes[i];
371     }
372 
373     // If there's just one more byte, output it. Otherwise, output ellipsis.
374     if (sizeof(value) == kBytesToPrint + 1) {
375       sb << ' ' << bytes[sizeof(value) - 1];
376     } else if (sizeof(value) > kBytesToPrint) {
377       sb << " …";
378     }
379   }
380 
381   sb << '>';
382   return sb.status_with_size();
383 }
384 
385 }  // namespace string
386 
387 namespace unit_test {
388 namespace internal {
389 
390 class Test;
391 class TestInfo;
392 
393 // Types of SetUpTestSuite() and TearDownTestSuite() functions.
394 using SetUpTestSuiteFunc = void (*)();
395 using TearDownTestSuiteFunc = void (*)();
396 
397 // Used to tag arguments to EXPECT_STREQ/EXPECT_STRNE so they are treated like
398 // C strings rather than pointers.
399 struct CStringArg {
400   const char* const c_str;
401 };
402 
MaxPaddingNeededToRaiseAlignment(size_t current_align,size_t new_align)403 constexpr size_t MaxPaddingNeededToRaiseAlignment(size_t current_align,
404                                                   size_t new_align) {
405   if (new_align < current_align) {
406     return 0;
407   }
408   return new_align - current_align;
409 }
410 
411 // GoogleTest supports stream-style messages, but pw_unit_test does not. This
412 // class accepts and ignores C++ <<-style logs.
413 class FailureMessageAdapter {
414  public:
415   constexpr FailureMessageAdapter() = default;
416 
417   template <typename T>
418   constexpr const FailureMessageAdapter& operator<<(const T&) const {
419     return *this;
420   }
421 };
422 
423 // Used to ignore a stream-style message in an assert, which returns. This
424 // uses a similar approach as upstream GoogleTest, but drops any messages.
425 class ReturnHelper {
426  public:
427   constexpr ReturnHelper() = default;
428 
429   // Return void so that assigning to ReturnHelper converts the log expression
430   // to void without blocking the stream-style log with a closing parenthesis.
431   // NOLINTNEXTLINE(misc-unconventional-assign-operator)
432   constexpr void operator=(const FailureMessageAdapter&) const {}
433 };
434 
435 // Singleton test framework class responsible for managing and running test
436 // cases. This implementation is internal to Pigweed test; free functions
437 // wrapping its functionality are exposed as the public interface.
438 class Framework {
439  public:
Framework()440   constexpr Framework()
441       : current_test_(nullptr),
442         current_result_(TestResult::kSuccess),
443         run_tests_summary_{.passed_tests = 0,
444                            .failed_tests = 0,
445                            .skipped_tests = 0,
446                            .disabled_tests = 0},
447         exit_status_(0),
448         event_handler_(nullptr),
449         memory_pool_() {}
450 
Get()451   static Framework& Get() { return framework_; }
452 
453   // Registers a single test case with the framework. The framework owns the
454   // registered unit test. Called during static initialization.
455   void RegisterTest(TestInfo* test) const;
456 
457   // Sets the handler to which the framework dispatches test events. During a
458   // test run, the framework owns the event handler.
RegisterEventHandler(EventHandler * event_handler)459   inline void RegisterEventHandler(EventHandler* event_handler) {
460     event_handler_ = event_handler;
461   }
462 
463   // Runs all registered test cases, returning a status of 0 if all succeeded
464   // or nonzero if there were any failures. Test events that occur during the
465   // run are sent to the registered event handler, if any.
466   int RunAllTests();
467 
468   // Only run test suites whose names are included in the provided list during
469   // the next test run. This is C++17 only; older versions of C++ will run all
470   // non-disabled tests.
SetTestSuitesToRun(span<std::string_view> test_suites)471   void SetTestSuitesToRun(span<std::string_view> test_suites) {
472     test_suites_to_run_ = test_suites;
473   }
474 
475   bool ShouldRunTest(const TestInfo& test_info) const;
476 
477   // Whether the current test is skipped.
IsSkipped()478   bool IsSkipped() const { return current_result_ == TestResult::kSkipped; }
479 
480   // Whether the current test has failed.
HasFailure()481   bool HasFailure() const { return current_result_ == TestResult::kFailure; }
482 
483   // Constructs an instance of a unit test class and runs the test.
484   //
485   // Tests are constructed within a static memory pool at run time instead of
486   // being statically allocated to avoid blowing up the size of the test
487   // binary in cases where users have large test fixtures (e.g. containing
488   // buffers) reused many times. Instead, only a small, fixed-size TestInfo
489   // struct is statically allocated per test case, with a run() function that
490   // references this method instantiated for its test class.
491   template <typename TestInstance>
CreateAndRunTest(const TestInfo & test_info)492   static void CreateAndRunTest(const TestInfo& test_info) {
493     static_assert(
494         sizeof(TestInstance) +
495                 MaxPaddingNeededToRaiseAlignment(
496                     alignof(decltype(memory_pool_)), alignof(TestInstance)) <=
497             sizeof(memory_pool_),
498         "The test memory pool is too small for this test. Either increase "
499         "PW_UNIT_TEST_CONFIG_MEMORY_POOL_SIZE or decrease the size of your "
500         "test fixture.");
501 
502     Framework& framework = Get();
503     framework.StartTest(test_info);
504 
505     // Reset the memory pool to a marker value to help detect use of
506     // uninitialized memory.
507     std::memset(&framework.memory_pool_, 0xa5, sizeof(framework.memory_pool_));
508 
509     framework.SetUpTestSuiteIfNeeded(TestInstance::SetUpTestSuite);
510 
511     // Construct the test object within the static memory pool. The StartTest
512     // function has already been called by the TestInfo at this point.
513     void* aligned_pool =
514         AlignUp(&framework.memory_pool_, alignof(TestInstance));
515     TestInstance* test_instance = new (aligned_pool) TestInstance();
516     test_instance->PigweedTestRun();
517 
518     // Manually call the destructor as it is not called automatically for
519     // objects constructed using placement new.
520     test_instance->~TestInstance();
521 
522     framework.TearDownTestSuiteIfNeeded(TestInstance::TearDownTestSuite);
523 
524     framework.EndCurrentTest();
525   }
526 
527   template <typename Expectation, typename Lhs, typename Rhs, typename Epsilon>
CurrentTestExpect(Expectation expectation,const Lhs & lhs,const Rhs & rhs,const Epsilon & epsilon,const char * expression,int line)528   [[nodiscard]] bool CurrentTestExpect(Expectation expectation,
529                                        const Lhs& lhs,
530                                        const Rhs& rhs,
531                                        const Epsilon& epsilon,
532                                        const char* expression,
533                                        int line) {
534     // Size of the buffer into which to write the string with the evaluated
535     // version of the arguments. This buffer is allocated on the unit test's
536     // stack, so it shouldn't be too large.
537     // TODO(hepler): Make this configurable.
538     [[maybe_unused]] constexpr size_t kExpectationBufferSizeBytes = 192;
539 
540     const bool success = expectation(lhs, rhs, epsilon);
541     if (!success) {
542       CurrentTestExpectSimple(
543           expression,
544           MakeString<kExpectationBufferSizeBytes>(ConvertForPrint(lhs),
545                                                   " within ",
546                                                   ConvertForPrint(epsilon),
547                                                   " of ",
548                                                   ConvertForPrint(rhs))
549               .c_str(),
550           line,
551           success);
552     }
553     return success;
554   }
555 
556   // Runs an expectation function for the currently active test case.
557   template <typename Expectation, typename Lhs, typename Rhs>
CurrentTestExpect(Expectation expectation,const Lhs & lhs,const Rhs & rhs,const char * expectation_string,const char * expression,int line)558   bool CurrentTestExpect(Expectation expectation,
559                          const Lhs& lhs,
560                          const Rhs& rhs,
561                          [[maybe_unused]] const char* expectation_string,
562                          const char* expression,
563                          int line) {
564     // Size of the buffer into which to write the string with the evaluated
565     // version of the arguments. This buffer is allocated on the unit test's
566     // stack, so it shouldn't be too large.
567     // TODO(hepler): Make this configurable.
568     [[maybe_unused]] constexpr size_t kExpectationBufferSizeBytes = 192;
569 
570     const bool success = expectation(lhs, rhs);
571     if (!success) {
572       CurrentTestExpectSimple(
573           expression,
574           MakeString<kExpectationBufferSizeBytes>(ConvertForPrint(lhs),
575                                                   ' ',
576                                                   expectation_string,
577                                                   ' ',
578                                                   ConvertForPrint(rhs))
579               .c_str(),
580           line,
581           success);
582     }
583     return success;
584   }
585 
586   // Skips the current test and dispatches an event for it.
587   ::pw::unit_test::internal::FailureMessageAdapter CurrentTestSkip(int line);
588 
589   // Dispatches an event indicating the result of an expectation.
590   ::pw::unit_test::internal::FailureMessageAdapter CurrentTestExpectSimple(
591       const char* expression,
592       const char* evaluated_expression,
593       int line,
594       bool success);
595 
596  private:
597   // Convert char* to void* so that they are printed as pointers instead of
598   // strings in EXPECT_EQ and other macros. EXPECT_STREQ wraps its pointers in
599   // a CStringArg so its pointers are treated like C strings.
ConvertForPrint(const char * str)600   static constexpr const void* ConvertForPrint(const char* str) { return str; }
601 
ConvertForPrint(char * str)602   static constexpr const void* ConvertForPrint(char* str) { return str; }
603 
ConvertForPrint(CStringArg value)604   static constexpr const char* ConvertForPrint(CStringArg value) {
605     return value.c_str;
606   }
607 
608   template <typename T>
ConvertForPrint(T && value)609   static constexpr T ConvertForPrint(T&& value) {
610     return std::forward<T>(value);
611   }
612 
613   // If current_test_ will be first of its suite, call set_up_ts
614   void SetUpTestSuiteIfNeeded(SetUpTestSuiteFunc set_up_ts) const;
615 
616   // If current_test_ was the last of its suite, call tear_down_ts
617   void TearDownTestSuiteIfNeeded(TearDownTestSuiteFunc tear_down_ts) const;
618 
619   // Sets current_test_ and dispatches an event indicating that a test
620   // started.
621   void StartTest(const TestInfo& test);
622 
623   // Dispatches event indicating that a test finished and clears
624   // current_test_.
625   void EndCurrentTest();
626 
627   // Singleton instance of the framework class.
628   static Framework framework_;
629 
630   // Linked list of all registered test cases. This is static as it tests are
631   // registered using static initialization.
632   static TestInfo* tests_;
633 
634   // The current test case which is running.
635   const TestInfo* current_test_;
636 
637   // Overall result of the current test case (pass/fail/skip).
638   TestResult current_result_;
639 
640   // Overall result of the ongoing test run, which covers multiple tests.
641   RunTestsSummary run_tests_summary_;
642 
643   // Program exit status returned by RunAllTests for GoogleTest compatibility.
644   int exit_status_;
645 
646   // Handler to which to dispatch test events.
647   EventHandler* event_handler_;
648 
649   span<std::string_view> test_suites_to_run_;
650 
651   alignas(std::max_align_t) std::byte memory_pool_[config::kMemoryPoolSize];
652 };
653 
654 // Information about a single test case, including a pointer to a function
655 // which constructs and runs the test class. These are statically allocated
656 // instead of the test classes, as test classes can be very large.
657 class TestInfo {
658  public:
TestInfo(const char * const test_suite_name,const char * const test_name,const char * const file_name,void (* run_func)(const TestInfo &))659   TestInfo(const char* const test_suite_name,
660            const char* const test_name,
661            const char* const file_name,
662            void (*run_func)(const TestInfo&))
663       : test_case_{
664         .suite_name = test_suite_name,
665         .test_name = test_name,
666         .file_name = file_name,
667        }, run_(run_func) {
668     Framework::Get().RegisterTest(this);
669   }
670 
671   // The name of the suite to which the test case belongs, the name of the
672   // test case itself, and the path to the file in which the test case is
673   // located.
test_case()674   const TestCase& test_case() const { return test_case_; }
675 
676   bool enabled() const;
677 
run()678   void run() const { run_(*this); }
679 
next()680   TestInfo* next() const { return next_; }
set_next(TestInfo * next)681   void set_next(TestInfo* next) { next_ = next; }
682 
683  private:
684   TestCase test_case_;
685 
686   // Function which runs the test case. Refers to Framework::CreateAndRunTest
687   // instantiated for the test case's class.
688   void (*run_)(const TestInfo&);
689 
690   // TestInfo structs are registered with the test framework and stored as a
691   // linked list.
692   TestInfo* next_ = nullptr;
693 };
694 
695 // Base class for all test cases or custom test fixtures.
696 // Every unit test created using the TEST or TEST_F macro defines a class that
697 // inherits from this (or a subclass of this).
698 //
699 // For example, given the following test definition:
700 //
701 //   TEST(MyTest, SaysHello) {
702 //     ASSERT_STREQ(SayHello(), "Hello, world!");
703 //   }
704 //
705 // A new class is defined for the test, e.g. MyTest_SaysHello_Test. This class
706 // inherits from the Test class and implements its PigweedTestBody function
707 // with the block provided to the TEST macro.
708 class Test {
709  public:
710   Test(const Test&) = delete;
711   Test& operator=(const Test&) = delete;
712 
713   virtual ~Test() = default;
714 
SetUpTestSuite()715   static void SetUpTestSuite() {}
TearDownTestSuite()716   static void TearDownTestSuite() {}
717 
HasFailure()718   static bool HasFailure() { return Framework::Get().HasFailure(); }
719 
720   // Runs the unit test.
PigweedTestRun()721   void PigweedTestRun() {
722     SetUp();
723     // TODO(deymo): Skip the test body if there's a fatal error in SetUp().
724     if (!Framework::Get().IsSkipped()) {
725       PigweedTestBody();
726     }
727     TearDown();
728   }
729 
730  protected:
731   Test() = default;
732 
733   // Called immediately before executing the test body.
734   //
735   // Setup and cleanup can typically be done in the test fixture's constructor
736   // and destructor, but there are cases where SetUp/TearDown must be used
737   // instead. See the Google Test documentation for more information.
SetUp()738   virtual void SetUp() {}
739 
740   // Called immediately after executing the test body.
TearDown()741   virtual void TearDown() {}
742 
743  private:
744   friend class internal::Framework;
745 
746   // The user-provided body of the test case. Populated by the TEST macro.
747   virtual void PigweedTestBody() = 0;
748 };
749 
750 // Checks that a test suite name is valid.
HasNoUnderscores(const char * suite)751 constexpr bool HasNoUnderscores(const char* suite) {
752   const char* disabled_prefix = "DISABLED_";
753 
754   for (; *suite != '\0'; ++suite) {
755     if (*suite == *disabled_prefix) {
756       disabled_prefix += 1;
757     } else {
758       disabled_prefix = "";
759       if (*suite == '_') {
760         return false;
761       }
762     }
763   }
764   return true;
765 }
766 
767 }  // namespace internal
768 
SetTestSuitesToRun(span<std::string_view> test_suites)769 inline void SetTestSuitesToRun(span<std::string_view> test_suites) {
770   internal::Framework::Get().SetTestSuitesToRun(test_suites);
771 }
772 
773 }  // namespace unit_test
774 }  // namespace pw
775 
RUN_ALL_TESTS()776 inline int RUN_ALL_TESTS() {
777   return ::pw::unit_test::internal::Framework::Get().RunAllTests();
778 }
779 
780 #define _PW_TEST(test_suite_name, test_name, parent_class)                     \
781   static_assert(sizeof(#test_suite_name) > 1,                                  \
782                 "The test suite name must not be empty");                      \
783   static_assert(::pw::unit_test::internal::HasNoUnderscores(#test_suite_name), \
784                 "The test suite name (" #test_suite_name                       \
785                 ") cannot contain underscores");                               \
786   static_assert(sizeof(#test_name) > 1, "The test name must not be empty");    \
787                                                                                \
788   _PW_TEST_CLASS(test_suite_name,                                              \
789                  test_name,                                                    \
790                  test_suite_name##_##test_name##_Test,                         \
791                  parent_class)
792 
793 #define _PW_TEST_CLASS(suite, name, class_name, parent_class)               \
794   class class_name final : public parent_class {                            \
795    private:                                                                 \
796     void PigweedTestBody() override;                                        \
797   };                                                                        \
798                                                                             \
799   extern "C" {                                                              \
800                                                                             \
801   /* Silence ASAN to avoid errors in the initialization order checker */    \
802   /* caused by the intentional use of dynamic initializers which modify */  \
803   /* other globals */                                                       \
804   PW_NO_SANITIZE("address")                                                 \
805   /* Declare the TestInfo as non-const since const variables do not work */ \
806   /* with the PW_UNIT_TEST_LINK_FILE_CONTAINING_TEST macro. */              \
807   /* NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables) */  \
808   ::pw::unit_test::internal::TestInfo _pw_unit_test_Info_##suite##_##name(  \
809       #suite,                                                               \
810       #name,                                                                \
811       __FILE__,                                                             \
812       ::pw::unit_test::internal::Framework::CreateAndRunTest<class_name>);  \
813                                                                             \
814   } /* extern "C" */                                                        \
815                                                                             \
816   void class_name::PigweedTestBody()
817 
818 #define _PW_TEST_ASSERT(expectation)                 \
819   if (!(expectation))                                \
820   return ::pw::unit_test::internal::ReturnHelper() = \
821              ::pw::unit_test::internal::FailureMessageAdapter()
822 
823 #define _PW_TEST_EXPECT(expectation) \
824   if (!(expectation))                \
825   ::pw::unit_test::internal::FailureMessageAdapter()
826 
827 #define _PW_TEST_BOOL(expr, value)                                   \
828   ::pw::unit_test::internal::Framework::Get().CurrentTestExpect(     \
829       [](bool _pw_lhs, bool _pw_rhs) { return _pw_lhs == _pw_rhs; }, \
830       static_cast<bool>(expr),                                       \
831       value,                                                         \
832       "is",                                                          \
833       #expr " is " #value,                                           \
834       __LINE__)
835 
836 #define _PW_TEST_OP(lhs, rhs, op)                                \
837   ::pw::unit_test::internal::Framework::Get().CurrentTestExpect( \
838       [](const auto& _pw_lhs, const auto& _pw_rhs) {             \
839         return _pw_lhs op _pw_rhs;                               \
840       },                                                         \
841       (lhs),                                                     \
842       (rhs),                                                     \
843       #op,                                                       \
844       #lhs " " #op " " #rhs,                                     \
845       __LINE__)
846 
847 #define _PW_TEST_NEAR(lhs, rhs, epsilon)                                      \
848   ::pw::unit_test::internal::Framework::Get().CurrentTestExpect(              \
849       [](const auto& _pw_lhs, const auto& _pw_rhs, const auto& _pw_epsilon) { \
850         return std::abs(_pw_lhs - _pw_rhs) <= _pw_epsilon;                    \
851       },                                                                      \
852       (lhs),                                                                  \
853       (rhs),                                                                  \
854       (epsilon),                                                              \
855       #lhs " within " #epsilon " of " #rhs,                                   \
856       __LINE__)
857 
858 #define _PW_TEST_C_STR(lhs, rhs, op)                             \
859   ::pw::unit_test::internal::Framework::Get().CurrentTestExpect( \
860       [](const auto& _pw_lhs, const auto& _pw_rhs) {             \
861         auto cmp = [](const char* l, const char* r) -> int {     \
862           if (!l || !r) {                                        \
863             return l != r;                                       \
864           }                                                      \
865           return std::strcmp(l, r);                              \
866         };                                                       \
867         return cmp(_pw_lhs.c_str, _pw_rhs.c_str) op 0;           \
868       },                                                         \
869       ::pw::unit_test::internal::CStringArg{lhs},                \
870       ::pw::unit_test::internal::CStringArg{rhs},                \
871       #op,                                                       \
872       #lhs " " #op " " #rhs,                                     \
873       __LINE__)
874 
875 // Checks that test suite names between TEST and TEST_F declarations are unique.
876 // This works by declaring a function named for the test suite. The function
877 // takes no arguments but is declared with different return types in the TEST
878 // and TEST_F macros. If a TEST and TEST_F use the same test suite name, the
879 // function declarations conflict, resulting in a compilation error.
880 //
881 // This catches most conflicts, but a runtime check is ultimately needed since
882 // tests may be declared in different translation units.
883 #if !defined(__clang__) && !defined(__GNUC___) && __GNUC__ <= 8
884 // For some reason GCC8 is unable to ignore -Wredundant-decls here.
885 #define _PW_TEST_SUITE_NAMES_MUST_BE_UNIQUE(return_type, test_suite)
886 #else  // All other compilers.
887 #define _PW_TEST_SUITE_NAMES_MUST_BE_UNIQUE(return_type, test_suite)           \
888   PW_MODIFY_DIAGNOSTICS_PUSH();                                                \
889   PW_MODIFY_DIAGNOSTIC(ignored, "-Wredundant-decls");                          \
890   extern "C" return_type /* use extern "C" to escape namespacing */            \
891       PwUnitTestSuiteNamesMustBeUniqueBetweenTESTandTEST_F_##test_suite(void); \
892   PW_MODIFY_DIAGNOSTICS_POP()
893 #endif  // GCC8 or older.
894 
895 namespace testing {
896 
897 // Alias Test as ::testing::Test for GoogleTest compatibility.
898 using Test = ::pw::unit_test::internal::Test;
899 
900 // Provide a no-op init routine for GoogleTest compatibility.
InitGoogleTest(int *,char **)901 inline void InitGoogleTest(int*, char**) {}
902 
903 }  // namespace testing
904