xref: /aosp_15_r20/external/pigweed/pw_assert/assert_backend_compile_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 series of "tests" is more a compile test to verify that the assert
16 // backend is able to compile the constructs promised by the assert facade.
17 // Truly testing the backend in a general way from the facade is impossible
18 // since the device will go down when an assert triggers, and so that must be
19 // handled inside the individual backends.
20 //
21 // NOTE: While these tests are not intended to run, it *is* possible to run
22 // them with the assert_basic backend, in a special mode where the assert
23 // statements fall through instead of aborting.
24 //
25 // To run these "tests" for pw_assert_basic, you must modify two things:
26 //
27 //   (1) Set DISABLE_ASSERT_TEST_EXECUTION 0 in assert_backend_compile_test.cc
28 //   (2) Set DISABLE_ASSERT_TEST_EXECUTION 0 in assert_backend_compile_test.c
29 //   (3) Set PW_ASSERT_BASIC_DISABLE_NORETURN 1 in assert_basic.h
30 //   (4) Compile and run the resulting binary, paying attention to the
31 //       displayed error messages. If "FAIL IF DISPLAYED" is printed, the
32 //       test has failed. If any "FAIL_IF_HIDDEN" asserts are not displayed,
33 //       the test has failed. Obviously manually verifying these is a pain
34 //       and so this is not a suitable test for production.
35 //
36 // TODO: b/235289499 - Add verification of the actually recorded asserts
37 // statements.
38 
39 #include "pw_assert/short.h"
40 #include "pw_status/status.h"
41 #include "pw_unit_test/framework.h"
42 
43 // This is a global constant to feed into the formatter for tests.
44 // Intended to pair with FAIL_IF_DISPLAYED_ARGS or FAIL_IF_HIDDEN_ARGS.
45 static const int z = 10;
46 
47 // At some point in the future when there is a proper test system in place for
48 // crashing, the below strings can help indicate pass/fail for a check.
49 
50 #define FAIL_IF_DISPLAYED "FAIL IF DISPLAYED"
51 #define FAIL_IF_DISPLAYED_ARGS "FAIL IF DISPLAYED: %d"
52 
53 #define FAIL_IF_HIDDEN "FAIL IF HIDDEN"
54 #define FAIL_IF_HIDDEN_ARGS "FAIL IF HIDDEN: %d"
55 
56 // This switch exists to support compiling and/or running the tests.
57 #define DISABLE_ASSERT_TEST_EXECUTION 1
58 #if DISABLE_ASSERT_TEST_EXECUTION
59 #define MAYBE_SKIP_TEST return
60 #else
61 #define MAYBE_SKIP_TEST ;
62 #endif
63 
64 namespace {
65 
TEST(Crash,WithAndWithoutMessageArguments)66 TEST(Crash, WithAndWithoutMessageArguments) {
67   MAYBE_SKIP_TEST;
68   PW_CRASH(FAIL_IF_HIDDEN);
69   PW_CRASH(FAIL_IF_HIDDEN_ARGS, z);
70 }
71 
TEST(Check,NoMessage)72 TEST(Check, NoMessage) {
73   MAYBE_SKIP_TEST;
74   PW_CHECK(true);
75   PW_CHECK(false);
76 }
77 
TEST(Check,WithMessageAndArgs)78 TEST(Check, WithMessageAndArgs) {
79   MAYBE_SKIP_TEST;
80   PW_CHECK(true, FAIL_IF_DISPLAYED);
81   PW_CHECK(true, FAIL_IF_DISPLAYED_ARGS, z);
82 
83   PW_CHECK(false, FAIL_IF_HIDDEN);
84   PW_CHECK(false, FAIL_IF_HIDDEN_ARGS, z);
85 }
86 
TEST(Check,IntComparison)87 TEST(Check, IntComparison) {
88   MAYBE_SKIP_TEST;
89   int x_int = 50;
90   int y_int = 66;
91 
92   PW_CHECK_INT_LE(x_int, y_int);
93   PW_CHECK_INT_LE(x_int, y_int, "INT: " FAIL_IF_DISPLAYED);
94   PW_CHECK_INT_LE(x_int, y_int, "INT: " FAIL_IF_DISPLAYED_ARGS, z);
95 
96   PW_CHECK_INT_GE(x_int, y_int);
97   PW_CHECK_INT_GE(x_int, y_int, "INT: " FAIL_IF_HIDDEN);
98   PW_CHECK_INT_GE(x_int, y_int, "INT: " FAIL_IF_HIDDEN_ARGS, z);
99 }
100 
TEST(Check,UintComparison)101 TEST(Check, UintComparison) {
102   MAYBE_SKIP_TEST;
103   unsigned int x_uint = 50;
104   unsigned int y_uint = 66;
105 
106   PW_CHECK_UINT_LE(x_uint, y_uint);
107   PW_CHECK_UINT_LE(x_uint, y_uint, "UINT: " FAIL_IF_DISPLAYED);
108   PW_CHECK_UINT_LE(x_uint, y_uint, "UINT: " FAIL_IF_DISPLAYED_ARGS, z);
109 
110   PW_CHECK_UINT_GE(x_uint, y_uint);
111   PW_CHECK_UINT_GE(x_uint, y_uint, "UINT: " FAIL_IF_HIDDEN);
112   PW_CHECK_UINT_GE(x_uint, y_uint, "UINT: " FAIL_IF_HIDDEN_ARGS, z);
113 }
114 
TEST(Check,PtrComparison)115 TEST(Check, PtrComparison) {
116   MAYBE_SKIP_TEST;
117   void* x_ptr = reinterpret_cast<void*>(50);
118   void* y_ptr = reinterpret_cast<void*>(66);
119 
120   PW_CHECK_PTR_EQ(x_ptr, y_ptr);
121   PW_CHECK_PTR_LE(x_ptr, y_ptr, "PTR: " FAIL_IF_DISPLAYED);
122   PW_CHECK_PTR_LE(x_ptr, y_ptr, "PTR: " FAIL_IF_DISPLAYED_ARGS, z);
123 
124   PW_CHECK_PTR_GE(x_ptr, y_ptr);
125   PW_CHECK_PTR_GE(x_ptr, y_ptr, "PTR: " FAIL_IF_HIDDEN);
126   PW_CHECK_PTR_GE(x_ptr, y_ptr, "PTR: " FAIL_IF_HIDDEN_ARGS, z);
127 }
128 
TEST(Check,FloatComparison)129 TEST(Check, FloatComparison) {
130   MAYBE_SKIP_TEST;
131   float x_float = 50.5;
132   float y_float = 66.5;
133 
134   PW_CHECK_FLOAT_EXACT_LE(x_float, y_float);
135   PW_CHECK_FLOAT_EXACT_LE(x_float, y_float, "FLOAT: " FAIL_IF_DISPLAYED);
136   PW_CHECK_FLOAT_EXACT_LE(
137       x_float, y_float, "FLOAT: " FAIL_IF_DISPLAYED_ARGS, z);
138 
139   PW_CHECK_FLOAT_EXACT_GE(x_float, y_float);
140   PW_CHECK_FLOAT_EXACT_GE(x_float, y_float, "FLOAT: " FAIL_IF_HIDDEN);
141   PW_CHECK_FLOAT_EXACT_GE(x_float, y_float, "FLOAT: " FAIL_IF_HIDDEN_ARGS, z);
142 }
143 
144 // Don't exhaustively test the DCHECKs but have a sampling of them.
TEST(DCheck,Sampling)145 TEST(DCheck, Sampling) {
146   MAYBE_SKIP_TEST;
147   PW_DCHECK(5 == 10);
148   PW_DCHECK(5 == 10, "Message");
149   PW_DCHECK(5 == 10, "Message: %d", 5);
150   PW_DCHECK_INT_LE(5.4, 10.0);
151   PW_DCHECK_FLOAT_EXACT_EQ(5.4, 10.0, "Message");
152 }
153 
Add3(int a,int b,int c)154 static int Add3(int a, int b, int c) { return a + b + c; }
155 
TEST(Check,ComparisonArgumentsWithCommas)156 TEST(Check, ComparisonArgumentsWithCommas) {
157   MAYBE_SKIP_TEST;
158   int x_int = 50;
159   int y_int = 66;
160 
161   PW_CHECK_INT_LE(Add3(1, 2, 3), y_int);
162   PW_CHECK_INT_LE(x_int, Add3(1, 2, 3));
163 
164   PW_CHECK_INT_LE(Add3(1, 2, 3), y_int, FAIL_IF_DISPLAYED);
165   PW_CHECK_INT_LE(x_int, Add3(1, 2, 3), FAIL_IF_DISPLAYED_ARGS, z);
166 
167   PW_CHECK_INT_LE(Add3(1, 2, 3), Add3(1, 2, 3), "INT: " FAIL_IF_DISPLAYED);
168   PW_CHECK_INT_LE(x_int, y_int, "INT: " FAIL_IF_DISPLAYED_ARGS, z);
169 }
170 
TEST(Check,ShortNamesWork)171 TEST(Check, ShortNamesWork) {
172   MAYBE_SKIP_TEST;
173 
174   // Crash
175   CRASH(FAIL_IF_HIDDEN);
176   CRASH(FAIL_IF_HIDDEN_ARGS, z);
177 
178   // Check
179   CHECK(true, FAIL_IF_DISPLAYED);
180   CHECK(true, FAIL_IF_DISPLAYED_ARGS, z);
181   CHECK(false, FAIL_IF_HIDDEN);
182   CHECK(false, FAIL_IF_HIDDEN_ARGS, z);
183 
184   // Check with binary comparison
185   int x_int = 50;
186   int y_int = 66;
187 
188   CHECK_INT_LE(Add3(1, 2, 3), y_int);
189   CHECK_INT_LE(x_int, Add3(1, 2, 3));
190 
191   CHECK_INT_LE(Add3(1, 2, 3), y_int, FAIL_IF_DISPLAYED);
192   CHECK_INT_LE(x_int, Add3(1, 2, 3), FAIL_IF_DISPLAYED_ARGS, z);
193 
194   CHECK_INT_LE(Add3(1, 2, 3), Add3(1, 2, 3), "INT: " FAIL_IF_DISPLAYED);
195   CHECK_INT_LE(x_int, y_int, "INT: " FAIL_IF_DISPLAYED_ARGS, z);
196 }
197 
MakeStatus(pw::Status status)198 pw::Status MakeStatus(pw::Status status) { return status; }
199 
TEST(Check,CheckOkMacrosCompile)200 TEST(Check, CheckOkMacrosCompile) {
201   MAYBE_SKIP_TEST;
202   pw::Status status = pw::Status::Unknown();
203 
204   // Typical case with long names.
205   PW_CHECK_OK(status);
206   PW_CHECK_OK(status, "msg");
207   PW_CHECK_OK(status, "msg: %d", 5);
208 
209   // Short names.
210   CHECK_OK(status);
211   CHECK_OK(status, "msg");
212   CHECK_OK(status, "msg: %d", 5);
213 
214   // Status from a literal.
215   PW_CHECK_OK(pw::OkStatus());
216 
217   // Status from a function.
218   PW_CHECK_OK(MakeStatus(pw::OkStatus()));
219 
220   // Status from C enums.
221   PW_CHECK_OK(PW_STATUS_OK);
222 }
223 
224 // These are defined in assert_test.c, to test C compatibility.
225 extern "C" void AssertBackendCompileTestsInC();
226 
TEST(Check,AssertBackendCompileTestsInC)227 TEST(Check, AssertBackendCompileTestsInC) {
228   MAYBE_SKIP_TEST;
229   AssertBackendCompileTestsInC();
230 }
231 
232 }  // namespace
233