xref: /aosp_15_r20/external/pigweed/pw_assert/assert_facade_test.cc (revision 61c4878ac05f98d0ceed94b57d316916de578985)
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 // This test directly verifies the facade logic, by leveraging a fake backend
16 // that captures arguments and returns rather than aborting execution.
17 
18 #include "pw_assert_test/fake_backend.h"
19 
20 // This directly includes the assert facade implementation header rather than
21 // going through the backend header indirection mechanism, to prevent the real
22 // assert backend from triggering.
23 //
24 // clang-format off
25 #include "pw_assert/internal/check_impl.h"
26 // clang-format on
27 
28 #include "pw_compilation_testing/negative_compilation.h"
29 #include "pw_result/result.h"
30 #include "pw_status/status.h"
31 #include "pw_status/status_with_size.h"
32 #include "pw_unit_test/framework.h"
33 
34 namespace {
35 
36 #define EXPECT_MESSAGE(expected_assert_message)                        \
37   do {                                                                 \
38     EXPECT_STREQ(pw_captured_assert.message, expected_assert_message); \
39   } while (0)
40 
41 class AssertFailTest : public ::testing::Test {
42  protected:
SetUp()43   void SetUp() override { pw_captured_assert.triggered = 0; }
TearDown()44   void TearDown() override { EXPECT_EQ(pw_captured_assert.triggered, 1); }
45 };
46 
47 class AssertPassTest : public ::testing::Test {
48  protected:
SetUp()49   void SetUp() override { pw_captured_assert.triggered = 0; }
TearDown()50   void TearDown() override { EXPECT_EQ(pw_captured_assert.triggered, 0); }
51 };
52 
53 // PW_CRASH(...)
TEST_F(AssertFailTest,CrashMessageNoArguments)54 TEST_F(AssertFailTest, CrashMessageNoArguments) {
55   PW_CRASH("Goodbye");
56   EXPECT_MESSAGE("Goodbye");
57 }
TEST_F(AssertFailTest,CrashMessageWithArguments)58 TEST_F(AssertFailTest, CrashMessageWithArguments) {
59   PW_CRASH("Goodbye cruel %s", "world");
60   EXPECT_MESSAGE("Goodbye cruel world");
61 }
62 
63 // PW_CHECK(...) - No message
TEST_F(AssertPassTest,CheckNoMessage)64 TEST_F(AssertPassTest, CheckNoMessage) { PW_CHECK(true); }
TEST_F(AssertFailTest,CheckNoMessage)65 TEST_F(AssertFailTest, CheckNoMessage) {
66   PW_CHECK(false);
67   EXPECT_MESSAGE("Check failed: false. ");
68 }
TEST_F(AssertPassTest,CheckNoMessageComplexExpression)69 TEST_F(AssertPassTest, CheckNoMessageComplexExpression) { PW_CHECK(2 == 2); }
TEST_F(AssertFailTest,CheckNoMessageComplexExpression)70 TEST_F(AssertFailTest, CheckNoMessageComplexExpression) {
71   PW_CHECK(1 == 2);
72   EXPECT_MESSAGE("Check failed: 1 == 2. ");
73 }
74 
75 // PW_CHECK(..., msg) - With message; with and without arguments.
TEST_F(AssertPassTest,CheckMessageNoArguments)76 TEST_F(AssertPassTest, CheckMessageNoArguments) { PW_CHECK(true, "Hello"); }
TEST_F(AssertFailTest,CheckMessageNoArguments)77 TEST_F(AssertFailTest, CheckMessageNoArguments) {
78   PW_CHECK(false, "Hello");
79   EXPECT_MESSAGE("Check failed: false. Hello");
80 }
TEST_F(AssertPassTest,CheckMessageWithArguments)81 TEST_F(AssertPassTest, CheckMessageWithArguments) {
82   PW_CHECK(true, "Hello %d", 5);
83 }
TEST_F(AssertFailTest,CheckMessageWithArguments)84 TEST_F(AssertFailTest, CheckMessageWithArguments) {
85   PW_CHECK(false, "Hello %d", 5);
86   EXPECT_MESSAGE("Check failed: false. Hello 5");
87 }
88 
89 // PW_CHECK_INT_*(...)
90 // Binary checks with ints, comparisons: <, <=, =, !=, >, >=.
91 
92 // Test message formatting separate from the triggering.
93 // Only test formatting for the type once.
TEST_F(AssertFailTest,IntLessThanNoMessageNoArguments)94 TEST_F(AssertFailTest, IntLessThanNoMessageNoArguments) {
95   PW_CHECK_INT_LT(5, -2);
96   EXPECT_MESSAGE("Check failed: 5 (=5) < -2 (=-2). ");
97 }
TEST_F(AssertFailTest,IntLessThanMessageNoArguments)98 TEST_F(AssertFailTest, IntLessThanMessageNoArguments) {
99   PW_CHECK_INT_LT(5, -2, "msg");
100   EXPECT_MESSAGE("Check failed: 5 (=5) < -2 (=-2). msg");
101 }
TEST_F(AssertFailTest,IntLessThanMessageArguments)102 TEST_F(AssertFailTest, IntLessThanMessageArguments) {
103   PW_CHECK_INT_LT(5, -2, "msg: %d", 6);
104   EXPECT_MESSAGE("Check failed: 5 (=5) < -2 (=-2). msg: 6");
105 }
106 
107 // Test comparison boundaries.
108 
109 // INT <
TEST_F(AssertPassTest,IntLt1)110 TEST_F(AssertPassTest, IntLt1) { PW_CHECK_INT_LT(-1, 2); }
TEST_F(AssertPassTest,IntLt2)111 TEST_F(AssertPassTest, IntLt2) { PW_CHECK_INT_LT(1, 2); }
TEST_F(AssertFailTest,IntLt3)112 TEST_F(AssertFailTest, IntLt3) { PW_CHECK_INT_LT(-1, -2); }
TEST_F(AssertFailTest,IntLt4)113 TEST_F(AssertFailTest, IntLt4) { PW_CHECK_INT_LT(1, 1); }
114 
115 // INT <=
TEST_F(AssertPassTest,IntLe1)116 TEST_F(AssertPassTest, IntLe1) { PW_CHECK_INT_LE(-1, 2); }
TEST_F(AssertPassTest,IntLe2)117 TEST_F(AssertPassTest, IntLe2) { PW_CHECK_INT_LE(1, 2); }
TEST_F(AssertFailTest,IntLe3)118 TEST_F(AssertFailTest, IntLe3) { PW_CHECK_INT_LE(-1, -2); }
TEST_F(AssertPassTest,IntLe4)119 TEST_F(AssertPassTest, IntLe4) { PW_CHECK_INT_LE(1, 1); }
120 
121 // INT ==
TEST_F(AssertFailTest,IntEq1)122 TEST_F(AssertFailTest, IntEq1) { PW_CHECK_INT_EQ(-1, 2); }
TEST_F(AssertFailTest,IntEq2)123 TEST_F(AssertFailTest, IntEq2) { PW_CHECK_INT_EQ(1, 2); }
TEST_F(AssertFailTest,IntEq3)124 TEST_F(AssertFailTest, IntEq3) { PW_CHECK_INT_EQ(-1, -2); }
TEST_F(AssertPassTest,IntEq4)125 TEST_F(AssertPassTest, IntEq4) { PW_CHECK_INT_EQ(1, 1); }
126 
127 // INT !=
TEST_F(AssertPassTest,IntNe1)128 TEST_F(AssertPassTest, IntNe1) { PW_CHECK_INT_NE(-1, 2); }
TEST_F(AssertPassTest,IntNe2)129 TEST_F(AssertPassTest, IntNe2) { PW_CHECK_INT_NE(1, 2); }
TEST_F(AssertPassTest,IntNe3)130 TEST_F(AssertPassTest, IntNe3) { PW_CHECK_INT_NE(-1, -2); }
TEST_F(AssertFailTest,IntNe4)131 TEST_F(AssertFailTest, IntNe4) { PW_CHECK_INT_NE(1, 1); }
132 
133 // INT >
TEST_F(AssertFailTest,IntGt1)134 TEST_F(AssertFailTest, IntGt1) { PW_CHECK_INT_GT(-1, 2); }
TEST_F(AssertFailTest,IntGt2)135 TEST_F(AssertFailTest, IntGt2) { PW_CHECK_INT_GT(1, 2); }
TEST_F(AssertPassTest,IntGt3)136 TEST_F(AssertPassTest, IntGt3) { PW_CHECK_INT_GT(-1, -2); }
TEST_F(AssertFailTest,IntGt4)137 TEST_F(AssertFailTest, IntGt4) { PW_CHECK_INT_GT(1, 1); }
138 
139 // INT >=
TEST_F(AssertFailTest,IntGe1)140 TEST_F(AssertFailTest, IntGe1) { PW_CHECK_INT_GE(-1, 2); }
TEST_F(AssertFailTest,IntGe2)141 TEST_F(AssertFailTest, IntGe2) { PW_CHECK_INT_GE(1, 2); }
TEST_F(AssertPassTest,IntGe3)142 TEST_F(AssertPassTest, IntGe3) { PW_CHECK_INT_GE(-1, -2); }
TEST_F(AssertPassTest,IntGe4)143 TEST_F(AssertPassTest, IntGe4) { PW_CHECK_INT_GE(1, 1); }
144 
145 // PW_CHECK_UINT_*(...)
146 // Binary checks with uints, comparisons: <, <=, =, !=, >, >=.
147 
148 // Test message formatting separate from the triggering.
149 // Only test formatting for the type once.
TEST_F(AssertFailTest,UintLessThanNoMessageNoArguments)150 TEST_F(AssertFailTest, UintLessThanNoMessageNoArguments) {
151   PW_CHECK_UINT_LT(5, 2);
152   EXPECT_MESSAGE("Check failed: 5 (=5) < 2 (=2). ");
153 }
TEST_F(AssertFailTest,UintLessThanMessageNoArguments)154 TEST_F(AssertFailTest, UintLessThanMessageNoArguments) {
155   PW_CHECK_UINT_LT(5, 2, "msg");
156   EXPECT_MESSAGE("Check failed: 5 (=5) < 2 (=2). msg");
157 }
TEST_F(AssertFailTest,UintLessThanMessageArguments)158 TEST_F(AssertFailTest, UintLessThanMessageArguments) {
159   PW_CHECK_UINT_LT(5, 2, "msg: %d", 6);
160   EXPECT_MESSAGE("Check failed: 5 (=5) < 2 (=2). msg: 6");
161 }
162 
163 // Test comparison boundaries.
164 
165 // UINT <
TEST_F(AssertPassTest,UintLt1)166 TEST_F(AssertPassTest, UintLt1) { PW_CHECK_UINT_LT(1, 2); }
TEST_F(AssertFailTest,UintLt2)167 TEST_F(AssertFailTest, UintLt2) { PW_CHECK_UINT_LT(2, 2); }
TEST_F(AssertFailTest,UintLt3)168 TEST_F(AssertFailTest, UintLt3) { PW_CHECK_UINT_LT(2, 1); }
169 
170 // UINT <=
TEST_F(AssertPassTest,UintLe1)171 TEST_F(AssertPassTest, UintLe1) { PW_CHECK_UINT_LE(1, 2); }
TEST_F(AssertPassTest,UintLe2)172 TEST_F(AssertPassTest, UintLe2) { PW_CHECK_UINT_LE(2, 2); }
TEST_F(AssertFailTest,UintLe3)173 TEST_F(AssertFailTest, UintLe3) { PW_CHECK_UINT_LE(2, 1); }
174 
175 // UINT ==
TEST_F(AssertFailTest,UintEq1)176 TEST_F(AssertFailTest, UintEq1) { PW_CHECK_UINT_EQ(1, 2); }
TEST_F(AssertPassTest,UintEq2)177 TEST_F(AssertPassTest, UintEq2) { PW_CHECK_UINT_EQ(2, 2); }
TEST_F(AssertFailTest,UintEq3)178 TEST_F(AssertFailTest, UintEq3) { PW_CHECK_UINT_EQ(2, 1); }
179 
180 // UINT !=
TEST_F(AssertPassTest,UintNe1)181 TEST_F(AssertPassTest, UintNe1) { PW_CHECK_UINT_NE(1, 2); }
TEST_F(AssertFailTest,UintNe2)182 TEST_F(AssertFailTest, UintNe2) { PW_CHECK_UINT_NE(2, 2); }
TEST_F(AssertPassTest,UintNe3)183 TEST_F(AssertPassTest, UintNe3) { PW_CHECK_UINT_NE(2, 1); }
184 
185 // UINT >
TEST_F(AssertFailTest,UintGt1)186 TEST_F(AssertFailTest, UintGt1) { PW_CHECK_UINT_GT(1, 2); }
TEST_F(AssertFailTest,UintGt2)187 TEST_F(AssertFailTest, UintGt2) { PW_CHECK_UINT_GT(2, 2); }
TEST_F(AssertPassTest,UintGt3)188 TEST_F(AssertPassTest, UintGt3) { PW_CHECK_UINT_GT(2, 1); }
189 
190 // UINT >=
TEST_F(AssertFailTest,UintGe1)191 TEST_F(AssertFailTest, UintGe1) { PW_CHECK_UINT_GE(1, 2); }
TEST_F(AssertPassTest,UintGe2)192 TEST_F(AssertPassTest, UintGe2) { PW_CHECK_UINT_GE(2, 2); }
TEST_F(AssertPassTest,UintGe3)193 TEST_F(AssertPassTest, UintGe3) { PW_CHECK_UINT_GE(2, 1); }
194 
195 // PW_CHECK_PTR_*(...)
196 // Binary checks with uints, comparisons: <, <=, =, !=, >, >=.
197 // Note: The format checks are skipped since they're not portable.
198 
199 // Test comparison boundaries.
200 
201 // PTR <
TEST_F(AssertPassTest,PtrLt1)202 TEST_F(AssertPassTest, PtrLt1) {
203   PW_CHECK_PTR_LT(reinterpret_cast<void*>(0xa), reinterpret_cast<void*>(0xb));
204 }
TEST_F(AssertFailTest,PtrLt2)205 TEST_F(AssertFailTest, PtrLt2) {
206   PW_CHECK_PTR_LT(reinterpret_cast<void*>(0xb), reinterpret_cast<void*>(0xb));
207 }
TEST_F(AssertFailTest,PtrLt3)208 TEST_F(AssertFailTest, PtrLt3) {
209   PW_CHECK_PTR_LT(reinterpret_cast<void*>(0xb), reinterpret_cast<void*>(0xa));
210 }
211 
212 // PTR <=
TEST_F(AssertPassTest,PtrLe1)213 TEST_F(AssertPassTest, PtrLe1) {
214   PW_CHECK_PTR_LE(reinterpret_cast<void*>(0xa), reinterpret_cast<void*>(0xb));
215 }
TEST_F(AssertPassTest,PtrLe2)216 TEST_F(AssertPassTest, PtrLe2) {
217   PW_CHECK_PTR_LE(reinterpret_cast<void*>(0xb), reinterpret_cast<void*>(0xb));
218 }
TEST_F(AssertFailTest,PtrLe3)219 TEST_F(AssertFailTest, PtrLe3) {
220   PW_CHECK_PTR_LE(reinterpret_cast<void*>(0xb), reinterpret_cast<void*>(0xa));
221 }
222 
223 // PTR ==
TEST_F(AssertFailTest,PtrEq1)224 TEST_F(AssertFailTest, PtrEq1) {
225   PW_CHECK_PTR_EQ(reinterpret_cast<void*>(0xa), reinterpret_cast<void*>(0xb));
226 }
TEST_F(AssertPassTest,PtrEq2)227 TEST_F(AssertPassTest, PtrEq2) {
228   PW_CHECK_PTR_EQ(reinterpret_cast<void*>(0xb), reinterpret_cast<void*>(0xb));
229 }
TEST_F(AssertFailTest,PtrEq3)230 TEST_F(AssertFailTest, PtrEq3) {
231   PW_CHECK_PTR_EQ(reinterpret_cast<void*>(0xb), reinterpret_cast<void*>(0xa));
232 }
233 
234 // PTR !=
TEST_F(AssertPassTest,PtrNe1)235 TEST_F(AssertPassTest, PtrNe1) {
236   PW_CHECK_PTR_NE(reinterpret_cast<void*>(0xa), reinterpret_cast<void*>(0xb));
237 }
TEST_F(AssertFailTest,PtrNe2)238 TEST_F(AssertFailTest, PtrNe2) {
239   PW_CHECK_PTR_NE(reinterpret_cast<void*>(0xb), reinterpret_cast<void*>(0xb));
240 }
TEST_F(AssertPassTest,PtrNe3)241 TEST_F(AssertPassTest, PtrNe3) {
242   PW_CHECK_PTR_NE(reinterpret_cast<void*>(0xb), reinterpret_cast<void*>(0xa));
243 }
244 
245 // PTR >
TEST_F(AssertFailTest,PtrGt1)246 TEST_F(AssertFailTest, PtrGt1) {
247   PW_CHECK_PTR_GT(reinterpret_cast<void*>(0xa), reinterpret_cast<void*>(0xb));
248 }
TEST_F(AssertFailTest,PtrGt2)249 TEST_F(AssertFailTest, PtrGt2) {
250   PW_CHECK_PTR_GT(reinterpret_cast<void*>(0xb), reinterpret_cast<void*>(0xb));
251 }
TEST_F(AssertPassTest,PtrGt3)252 TEST_F(AssertPassTest, PtrGt3) {
253   PW_CHECK_PTR_GT(reinterpret_cast<void*>(0xb), reinterpret_cast<void*>(0xa));
254 }
255 
256 // PTR >=
TEST_F(AssertFailTest,PtrGe1)257 TEST_F(AssertFailTest, PtrGe1) {
258   PW_CHECK_PTR_GE(reinterpret_cast<void*>(0xa), reinterpret_cast<void*>(0xb));
259 }
TEST_F(AssertPassTest,PtrGe2)260 TEST_F(AssertPassTest, PtrGe2) {
261   PW_CHECK_PTR_GE(reinterpret_cast<void*>(0xb), reinterpret_cast<void*>(0xb));
262 }
TEST_F(AssertPassTest,PtrGe3)263 TEST_F(AssertPassTest, PtrGe3) {
264   PW_CHECK_PTR_GE(reinterpret_cast<void*>(0xb), reinterpret_cast<void*>(0xa));
265 }
266 
267 // NOTNULL
TEST_F(AssertPassTest,PtrNotNull)268 TEST_F(AssertPassTest, PtrNotNull) {
269   PW_CHECK_NOTNULL(reinterpret_cast<void*>(0xa));
270 }
TEST_F(AssertFailTest,PtrNotNull)271 TEST_F(AssertFailTest, PtrNotNull) {
272   PW_CHECK_NOTNULL(reinterpret_cast<void*>(0x0));
273 }
274 
Function1()275 [[maybe_unused]] void Function1() {}
Function2(int)276 [[maybe_unused]] bool Function2(int) { return false; }
277 
278 // NOTNULL for function poionters
TEST_F(AssertPassTest,FunctionPtrNotNull)279 TEST_F(AssertPassTest, FunctionPtrNotNull) {
280   PW_CHECK_NOTNULL(&Function1);
281   PW_CHECK_NOTNULL(&Function2);
282 }
TEST_F(AssertFailTest,FunctionPtrNotNull)283 TEST_F(AssertFailTest, FunctionPtrNotNull) {
284   void (*const function)() = nullptr;
285   PW_CHECK_NOTNULL(function);
286 }
287 
CompareIntWithString()288 [[maybe_unused]] void CompareIntWithString() {
289 #if PW_NC_TEST(CompareIntWithString)
290   PW_NC_EXPECT("cannot initialize|invalid conversion");
291 
292   PW_CHECK_INT_EQ(123l, "This check message is accidentally compared to 123!");
293 #endif  // PW_NC_TEST
294 }
295 
296 // Note: Due to platform inconsistencies, the below test for the NOTNULL
297 // message doesn't work. Some platforms print NULL formatted as %p as "(nil)",
298 // others "0x0". Leaving this here for reference.
299 //
300 //   TEST_F(AssertFailTest, PtrNotNullDescription) {
301 //     intptr_t intptr = 0;
302 //     PW_CHECK_NOTNULL(intptr);
303 //     EXPECT_MESSAGE("Check failed: intptr (=0x0) != nullptr (=0x0). ");
304 //   }
305 
306 // PW_CHECK_FLOAT_*(...)
307 // Binary checks with floats, comparisons: EXACT_LT, EXACT_LE, NEAR, EXACT_EQ,
308 // EXACT_NE, EXACT_GE, EXACT_GT.
309 
310 // Test message formatting separate from the triggering.
311 // Only test formatting for the type once.
TEST_F(AssertFailTest,FloatLessThanNoMessageNoArguments)312 TEST_F(AssertFailTest, FloatLessThanNoMessageNoArguments) {
313   PW_CHECK_FLOAT_EXACT_LT(5.2, 2.3);
314   EXPECT_MESSAGE("Check failed: 5.2 (=5.200000) < 2.3 (=2.300000). ");
315 }
TEST_F(AssertFailTest,FloatLessThanMessageNoArguments)316 TEST_F(AssertFailTest, FloatLessThanMessageNoArguments) {
317   PW_CHECK_FLOAT_EXACT_LT(5.2, 2.3, "msg");
318   EXPECT_MESSAGE("Check failed: 5.2 (=5.200000) < 2.3 (=2.300000). msg");
319 }
TEST_F(AssertFailTest,FloatLessThanMessageArguments)320 TEST_F(AssertFailTest, FloatLessThanMessageArguments) {
321   PW_CHECK_FLOAT_EXACT_LT(5.2, 2.3, "msg: %d", 6);
322   EXPECT_MESSAGE("Check failed: 5.2 (=5.200000) < 2.3 (=2.300000). msg: 6");
323 }
324 // Check float NEAR both above and below the permitted range.
TEST_F(AssertFailTest,FloatNearAboveNoMessageNoArguments)325 TEST_F(AssertFailTest, FloatNearAboveNoMessageNoArguments) {
326   PW_CHECK_FLOAT_NEAR(5.2, 2.3, 0.1);
327   EXPECT_MESSAGE(
328       "Check failed: 5.2 (=5.200000) <= 2.3 + abs_tolerance (=2.400000). ");
329 }
TEST_F(AssertFailTest,FloatNearAboveMessageNoArguments)330 TEST_F(AssertFailTest, FloatNearAboveMessageNoArguments) {
331   PW_CHECK_FLOAT_NEAR(5.2, 2.3, 0.1, "msg");
332   EXPECT_MESSAGE(
333       "Check failed: 5.2 (=5.200000) <= 2.3 + abs_tolerance (=2.400000). msg");
334 }
TEST_F(AssertFailTest,FloatNearAboveMessageArguments)335 TEST_F(AssertFailTest, FloatNearAboveMessageArguments) {
336   PW_CHECK_FLOAT_NEAR(5.2, 2.3, 0.1, "msg: %d", 6);
337   EXPECT_MESSAGE(
338       "Check failed: 5.2 (=5.200000) <= 2.3 + abs_tolerance (=2.400000). msg: "
339       "6");
340 }
TEST_F(AssertFailTest,FloatNearBelowNoMessageNoArguments)341 TEST_F(AssertFailTest, FloatNearBelowNoMessageNoArguments) {
342   PW_CHECK_FLOAT_NEAR(1.2, 2.3, 0.1);
343   EXPECT_MESSAGE(
344       "Check failed: 1.2 (=1.200000) >= 2.3 - abs_tolerance (=2.200000). ");
345 }
TEST_F(AssertFailTest,FloatNearBelowMessageNoArguments)346 TEST_F(AssertFailTest, FloatNearBelowMessageNoArguments) {
347   PW_CHECK_FLOAT_NEAR(1.2, 2.3, 0.1, "msg");
348   EXPECT_MESSAGE(
349       "Check failed: 1.2 (=1.200000) >= 2.3 - abs_tolerance (=2.200000). msg");
350 }
TEST_F(AssertFailTest,FloatNearBelowMessageArguments)351 TEST_F(AssertFailTest, FloatNearBelowMessageArguments) {
352   PW_CHECK_FLOAT_NEAR(1.2, 2.3, 0.1, "msg: %d", 6);
353   EXPECT_MESSAGE(
354       "Check failed: 1.2 (=1.200000) >= 2.3 - abs_tolerance (=2.200000). msg: "
355       "6");
356 }
357 // Test comparison boundaries.
358 // Note: The below example numbers all round to integer 1, to detect accidental
359 // integer conversions in the asserts.
360 
361 // FLOAT <
TEST_F(AssertPassTest,FloatLt1)362 TEST_F(AssertPassTest, FloatLt1) { PW_CHECK_FLOAT_EXACT_LT(1.1, 1.2); }
TEST_F(AssertFailTest,FloatLt2)363 TEST_F(AssertFailTest, FloatLt2) { PW_CHECK_FLOAT_EXACT_LT(1.2, 1.2); }
TEST_F(AssertFailTest,FloatLt3)364 TEST_F(AssertFailTest, FloatLt3) { PW_CHECK_FLOAT_EXACT_LT(1.2, 1.1); }
365 
366 // FLOAT <=
TEST_F(AssertPassTest,FloatLe1)367 TEST_F(AssertPassTest, FloatLe1) { PW_CHECK_FLOAT_EXACT_LE(1.1, 1.2); }
TEST_F(AssertPassTest,FloatLe2)368 TEST_F(AssertPassTest, FloatLe2) { PW_CHECK_FLOAT_EXACT_LE(1.2, 1.2); }
TEST_F(AssertFailTest,FloatLe3)369 TEST_F(AssertFailTest, FloatLe3) { PW_CHECK_FLOAT_EXACT_LE(1.2, 1.1); }
370 
371 // FLOAT ~= based on absolute error.
TEST_F(AssertFailTest,FloatNearAbs1)372 TEST_F(AssertFailTest, FloatNearAbs1) { PW_CHECK_FLOAT_NEAR(1.09, 1.2, 0.1); }
TEST_F(AssertPassTest,FloatNearAbs2)373 TEST_F(AssertPassTest, FloatNearAbs2) { PW_CHECK_FLOAT_NEAR(1.1, 1.2, 0.1); }
TEST_F(AssertPassTest,FloatNearAbs3)374 TEST_F(AssertPassTest, FloatNearAbs3) { PW_CHECK_FLOAT_NEAR(1.2, 1.2, 0.1); }
TEST_F(AssertPassTest,FloatNearAbs4)375 TEST_F(AssertPassTest, FloatNearAbs4) { PW_CHECK_FLOAT_NEAR(1.2, 1.1, 0.1); }
TEST_F(AssertFailTest,FloatNearAbs5)376 TEST_F(AssertFailTest, FloatNearAbs5) { PW_CHECK_FLOAT_NEAR(1.21, 1.1, 0.1); }
377 // Make sure the abs_tolerance is asserted to be >= 0.
TEST_F(AssertFailTest,FloatNearAbs6)378 TEST_F(AssertFailTest, FloatNearAbs6) { PW_CHECK_FLOAT_NEAR(1.2, 1.2, -0.1); }
TEST_F(AssertPassTest,FloatNearAbs7)379 TEST_F(AssertPassTest, FloatNearAbs7) { PW_CHECK_FLOAT_NEAR(1.2, 1.2, 0.0); }
380 
381 // FLOAT ==
TEST_F(AssertFailTest,FloatEq1)382 TEST_F(AssertFailTest, FloatEq1) { PW_CHECK_FLOAT_EXACT_EQ(1.1, 1.2); }
TEST_F(AssertPassTest,FloatEq2)383 TEST_F(AssertPassTest, FloatEq2) { PW_CHECK_FLOAT_EXACT_EQ(1.2, 1.2); }
TEST_F(AssertFailTest,FloatEq3)384 TEST_F(AssertFailTest, FloatEq3) { PW_CHECK_FLOAT_EXACT_EQ(1.2, 1.1); }
385 
386 // FLOAT !=
TEST_F(AssertPassTest,FloatNe1)387 TEST_F(AssertPassTest, FloatNe1) { PW_CHECK_FLOAT_EXACT_NE(1.1, 1.2); }
TEST_F(AssertFailTest,FloatNe2)388 TEST_F(AssertFailTest, FloatNe2) { PW_CHECK_FLOAT_EXACT_NE(1.2, 1.2); }
TEST_F(AssertPassTest,FloatNe3)389 TEST_F(AssertPassTest, FloatNe3) { PW_CHECK_FLOAT_EXACT_NE(1.2, 1.1); }
390 
391 // FLOAT >
TEST_F(AssertFailTest,FloatGt1)392 TEST_F(AssertFailTest, FloatGt1) { PW_CHECK_FLOAT_EXACT_GT(1.1, 1.2); }
TEST_F(AssertFailTest,FloatGt2)393 TEST_F(AssertFailTest, FloatGt2) { PW_CHECK_FLOAT_EXACT_GT(1.2, 1.2); }
TEST_F(AssertPassTest,FloatGt3)394 TEST_F(AssertPassTest, FloatGt3) { PW_CHECK_FLOAT_EXACT_GT(1.2, 1.1); }
395 
396 // FLOAT >=
TEST_F(AssertFailTest,FloatGe1)397 TEST_F(AssertFailTest, FloatGe1) { PW_CHECK_FLOAT_EXACT_GE(1.1, 1.2); }
TEST_F(AssertPassTest,FloatGe2)398 TEST_F(AssertPassTest, FloatGe2) { PW_CHECK_FLOAT_EXACT_GE(1.2, 1.2); }
TEST_F(AssertPassTest,FloatGe3)399 TEST_F(AssertPassTest, FloatGe3) { PW_CHECK_FLOAT_EXACT_GE(1.2, 1.1); }
400 
401 // Nested comma handling.
Add3(int a,int b,int c)402 static int Add3(int a, int b, int c) { return a + b + c; }
403 
TEST_F(AssertFailTest,CommaHandlingLeftSide)404 TEST_F(AssertFailTest, CommaHandlingLeftSide) {
405   PW_CHECK_INT_EQ(Add3(1, 2, 3), 4);
406   EXPECT_MESSAGE("Check failed: Add3(1, 2, 3) (=6) == 4 (=4). ");
407 }
TEST_F(AssertFailTest,CommaHandlingRightSide)408 TEST_F(AssertFailTest, CommaHandlingRightSide) {
409   PW_CHECK_INT_EQ(4, Add3(1, 2, 3));
410   EXPECT_MESSAGE("Check failed: 4 (=4) == Add3(1, 2, 3) (=6). ");
411 }
412 
413 // Verify that the CHECK_*(x,y) macros only evaluate their arguments once.
414 struct MultiEvaluateTestContext {
IncrementAndReturnZero__anonb5aec29a0111::MultiEvaluateTestContext415   int IncrementAndReturnZero() {
416     counter += 1;
417     return 0;
418   }
419   int counter = 0;
420 };
421 
TEST(AssertPass,CheckSingleSideEffectingCall)422 TEST(AssertPass, CheckSingleSideEffectingCall) {
423   MultiEvaluateTestContext ctx;
424   PW_CHECK(ctx.IncrementAndReturnZero() == 0);
425   EXPECT_EQ(ctx.counter, 1);
426 }
TEST(AssertFail,CheckSingleSideEffectingCall)427 TEST(AssertFail, CheckSingleSideEffectingCall) {
428   MultiEvaluateTestContext ctx;
429   PW_CHECK(ctx.IncrementAndReturnZero() == 1);
430   EXPECT_EQ(ctx.counter, 1);
431 }
TEST(AssertPass,BinaryOpSingleSideEffectingCall)432 TEST(AssertPass, BinaryOpSingleSideEffectingCall) {
433   MultiEvaluateTestContext ctx;
434   PW_CHECK_INT_EQ(0, ctx.IncrementAndReturnZero());
435   EXPECT_EQ(ctx.counter, 1);
436 }
TEST(AssertPass,BinaryOpTwoSideEffectingCalls)437 TEST(AssertPass, BinaryOpTwoSideEffectingCalls) {
438   MultiEvaluateTestContext ctx;
439   PW_CHECK_INT_EQ(ctx.IncrementAndReturnZero(), ctx.IncrementAndReturnZero());
440   EXPECT_EQ(ctx.counter, 2);
441 }
TEST(AssertFail,BinaryOpSingleSideEffectingCall)442 TEST(AssertFail, BinaryOpSingleSideEffectingCall) {
443   MultiEvaluateTestContext ctx;
444   PW_CHECK_INT_EQ(12314, ctx.IncrementAndReturnZero());
445   EXPECT_EQ(ctx.counter, 1);
446 }
TEST(AssertFail,BinaryOpTwoSideEffectingCalls)447 TEST(AssertFail, BinaryOpTwoSideEffectingCalls) {
448   MultiEvaluateTestContext ctx;
449   PW_CHECK_INT_EQ(ctx.IncrementAndReturnZero() + 10,
450                   ctx.IncrementAndReturnZero());
451   EXPECT_EQ(ctx.counter, 2);
452 }
TEST(AssertPass,CheckOkSingleSideEffectingCall)453 TEST(AssertPass, CheckOkSingleSideEffectingCall) {
454   MultiEvaluateTestContext ctx;
455   PW_CHECK_OK(ctx.IncrementAndReturnZero() ? pw::OkStatus() : pw::OkStatus());
456   EXPECT_EQ(ctx.counter, 1);
457 }
TEST(AssertFail,CheckOkSingleSideEffectingCall)458 TEST(AssertFail, CheckOkSingleSideEffectingCall) {
459   MultiEvaluateTestContext ctx;
460   PW_CHECK_OK(ctx.IncrementAndReturnZero() ? pw::Status::NotFound()
461                                            : pw::Status::NotFound());
462   EXPECT_EQ(ctx.counter, 1);
463 }
464 
465 // Verify side effects of debug checks work as expected.
466 // Only check a couple of cases, since the logic is all the same.
467 
468 // When DCHECKs are enabled, they behave the same as normal checks.
469 // When DCHECKs are disabled, they should not trip, and their arguments
470 // shouldn't be evaluated.
471 constexpr int kExpectedSideEffects = PW_ASSERT_ENABLE_DEBUG;
472 
TEST(AssertPass,DCheckEnabledSingleSideEffectingCall)473 TEST(AssertPass, DCheckEnabledSingleSideEffectingCall) {
474   MultiEvaluateTestContext ctx;
475   PW_DCHECK(ctx.IncrementAndReturnZero() == 0);
476   EXPECT_EQ(ctx.counter, kExpectedSideEffects);
477 }
TEST(AssertFail,DCheckEnabledSingleSideEffectingCall)478 TEST(AssertFail, DCheckEnabledSingleSideEffectingCall) {
479   MultiEvaluateTestContext ctx;
480   PW_DCHECK(ctx.IncrementAndReturnZero() == 1);
481   EXPECT_EQ(ctx.counter, kExpectedSideEffects);
482 }
TEST(AssertPass,DCheckEnabledBinaryOpSingleSideEffectingCall)483 TEST(AssertPass, DCheckEnabledBinaryOpSingleSideEffectingCall) {
484   MultiEvaluateTestContext ctx;
485   PW_DCHECK_INT_EQ(0, ctx.IncrementAndReturnZero());
486   EXPECT_EQ(ctx.counter, kExpectedSideEffects);
487 }
TEST(AssertPass,DCheckEnabledBinaryOpTwoSideEffectingCalls)488 TEST(AssertPass, DCheckEnabledBinaryOpTwoSideEffectingCalls) {
489   MultiEvaluateTestContext ctx;
490   PW_DCHECK_INT_EQ(ctx.IncrementAndReturnZero(), ctx.IncrementAndReturnZero());
491   EXPECT_EQ(ctx.counter, 2 * kExpectedSideEffects);
492 }
TEST(AssertFail,DCheckEnabledBinaryOpSingleSideEffectingCall)493 TEST(AssertFail, DCheckEnabledBinaryOpSingleSideEffectingCall) {
494   MultiEvaluateTestContext ctx;
495   PW_DCHECK_INT_EQ(12314, ctx.IncrementAndReturnZero());
496   EXPECT_EQ(ctx.counter, kExpectedSideEffects);
497 }
TEST(AssertFail,DCheckEnabledBinaryOpTwoSideEffectingCalls)498 TEST(AssertFail, DCheckEnabledBinaryOpTwoSideEffectingCalls) {
499   MultiEvaluateTestContext ctx;
500   PW_DCHECK_INT_EQ(ctx.IncrementAndReturnZero() + 10,
501                    ctx.IncrementAndReturnZero());
502   EXPECT_EQ(ctx.counter, 2 * kExpectedSideEffects);
503 }
TEST(AssertPass,DCheckOkSingleSideEffectingCall)504 TEST(AssertPass, DCheckOkSingleSideEffectingCall) {
505   MultiEvaluateTestContext ctx;
506   PW_DCHECK_OK(ctx.IncrementAndReturnZero() ? pw::OkStatus() : pw::OkStatus());
507   EXPECT_EQ(ctx.counter, kExpectedSideEffects);
508 }
TEST(AssertFail,DCheckOkSingleSideEffectingCall)509 TEST(AssertFail, DCheckOkSingleSideEffectingCall) {
510   MultiEvaluateTestContext ctx;
511   PW_DCHECK_OK(ctx.IncrementAndReturnZero() ? pw::Status::NotFound()
512                                             : pw::Status::NotFound());
513   EXPECT_EQ(ctx.counter, kExpectedSideEffects);
514 }
515 
516 // Verify PW_CHECK_OK, including message handling.
TEST_F(AssertFailTest,StatusNotOK)517 TEST_F(AssertFailTest, StatusNotOK) {
518   pw::Status status = pw::Status::Unknown();
519   PW_CHECK_OK(status);
520   EXPECT_MESSAGE("Check failed: status (=UNKNOWN) == OkStatus() (=OK). ");
521 }
522 
TEST_F(AssertFailTest,StatusNotOKMessageNoArguments)523 TEST_F(AssertFailTest, StatusNotOKMessageNoArguments) {
524   pw::Status status = pw::Status::Unknown();
525   PW_CHECK_OK(status, "msg");
526   EXPECT_MESSAGE("Check failed: status (=UNKNOWN) == OkStatus() (=OK). msg");
527 }
528 
TEST_F(AssertFailTest,StatusNotOKMessageArguments)529 TEST_F(AssertFailTest, StatusNotOKMessageArguments) {
530   pw::Status status = pw::Status::Unknown();
531   PW_CHECK_OK(status, "msg: %d", 5);
532   EXPECT_MESSAGE("Check failed: status (=UNKNOWN) == OkStatus() (=OK). msg: 5");
533 }
534 
TEST_F(AssertPassTest,StatusWithSizeOK)535 TEST_F(AssertPassTest, StatusWithSizeOK) {
536   pw::StatusWithSize status_size = pw::StatusWithSize(123);
537   PW_CHECK_OK(status_size);
538 }
539 
TEST_F(AssertFailTest,StatusWithSizeNotOK)540 TEST_F(AssertFailTest, StatusWithSizeNotOK) {
541   pw::StatusWithSize status_size = pw::StatusWithSize::Unknown();
542   PW_CHECK_OK(status_size);
543   EXPECT_MESSAGE("Check failed: status_size (=UNKNOWN) == OkStatus() (=OK). ");
544 }
545 
TEST_F(AssertPassTest,ResultOK)546 TEST_F(AssertPassTest, ResultOK) {
547   pw::Result<int> result = 123;
548   PW_CHECK_OK(result);
549 }
550 
TEST_F(AssertFailTest,ResultNotOK)551 TEST_F(AssertFailTest, ResultNotOK) {
552   pw::Result<int> result = pw::Status::Unknown();
553   PW_CHECK_OK(result);
554   EXPECT_MESSAGE("Check failed: result (=UNKNOWN) == OkStatus() (=OK). ");
555 }
556 
557 // Example expression for the test below.
DoTheThing()558 pw::Status DoTheThing() { return pw::Status::ResourceExhausted(); }
559 
TEST_F(AssertFailTest,NonTrivialExpression)560 TEST_F(AssertFailTest, NonTrivialExpression) {
561   PW_CHECK_OK(DoTheThing());
562   EXPECT_MESSAGE(
563       "Check failed: DoTheThing() (=RESOURCE_EXHAUSTED) == OkStatus() (=OK). ");
564 }
565 
566 // Note: This function seems pointless but it is not, since pw::Status::FOO
567 // constants are not actually status objects, but code objects. This way we can
568 // ensure the macros work with both real status objects and literals.
TEST_F(AssertPassTest,Function)569 TEST_F(AssertPassTest, Function) { PW_CHECK_OK(pw::OkStatus()); }
TEST_F(AssertPassTest,Enum)570 TEST_F(AssertPassTest, Enum) { PW_CHECK_OK(PW_STATUS_OK); }
TEST_F(AssertFailTest,Function)571 TEST_F(AssertFailTest, Function) { PW_CHECK_OK(pw::Status::Unknown()); }
TEST_F(AssertFailTest,Enum)572 TEST_F(AssertFailTest, Enum) { PW_CHECK_OK(PW_STATUS_UNKNOWN); }
573 
574 #if PW_ASSERT_ENABLE_DEBUG
575 
576 // In debug mode, the asserts should check their arguments.
TEST_F(AssertPassTest,DCheckFunction)577 TEST_F(AssertPassTest, DCheckFunction) { PW_DCHECK_OK(pw::OkStatus()); }
TEST_F(AssertPassTest,DCheckEnum)578 TEST_F(AssertPassTest, DCheckEnum) { PW_DCHECK_OK(PW_STATUS_OK); }
TEST_F(AssertFailTest,DCheckFunction)579 TEST_F(AssertFailTest, DCheckFunction) { PW_DCHECK_OK(pw::Status::Unknown()); }
TEST_F(AssertFailTest,DCheckEnum)580 TEST_F(AssertFailTest, DCheckEnum) { PW_DCHECK_OK(PW_STATUS_UNKNOWN); }
581 #else   // PW_ASSERT_ENABLE_DEBUG
582 
583 // In release mode, all the asserts should pass.
TEST_F(AssertPassTest,DCheckFunction_Ok)584 TEST_F(AssertPassTest, DCheckFunction_Ok) { PW_DCHECK_OK(pw::OkStatus()); }
TEST_F(AssertPassTest,DCheckEnum_Ok)585 TEST_F(AssertPassTest, DCheckEnum_Ok) { PW_DCHECK_OK(PW_STATUS_OK); }
TEST_F(AssertPassTest,DCheckFunction_Err)586 TEST_F(AssertPassTest, DCheckFunction_Err) {
587   PW_DCHECK_OK(pw::Status::Unknown());
588 }
TEST_F(AssertPassTest,DCheckEnum_Err)589 TEST_F(AssertPassTest, DCheckEnum_Err) { PW_DCHECK_OK(PW_STATUS_UNKNOWN); }
590 #endif  // PW_ASSERT_ENABLE_DEBUG
591 
592 // TODO(keir): Figure out how to run some of these tests is C.
593 
594 }  // namespace
595