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(pwbug/88): Add verification of the actually recorded asserts statements.
37
38 #include "gtest/gtest.h"
39 #include "pw_assert/short.h"
40 #include "pw_status/status.h"
41
42 // This is a global constant to feed into the formatter for tests.
43 // Intended to pair with FAIL_IF_DISPLAYED_ARGS or FAIL_IF_HIDDEN_ARGS.
44 static const int z = 10;
45
46 // At some point in the future when there is a proper test system in place for
47 // crashing, the below strings can help indicate pass/fail for a check.
48
49 #define FAIL_IF_DISPLAYED "FAIL IF DISPLAYED"
50 #define FAIL_IF_DISPLAYED_ARGS "FAIL IF DISPLAYED: %d"
51
52 #define FAIL_IF_HIDDEN "FAIL IF HIDDEN"
53 #define FAIL_IF_HIDDEN_ARGS "FAIL IF HIDDEN: %d"
54
55 // This switch exists to support compiling and/or running the tests.
56 #define DISABLE_ASSERT_TEST_EXECUTION 1
57 #if DISABLE_ASSERT_TEST_EXECUTION
58 #define MAYBE_SKIP_TEST return
59 #else
60 #define MAYBE_SKIP_TEST ;
61 #endif
62
63 namespace {
64
TEST(Crash,WithAndWithoutMessageArguments)65 TEST(Crash, WithAndWithoutMessageArguments) {
66 MAYBE_SKIP_TEST;
67 PW_CRASH(FAIL_IF_HIDDEN);
68 PW_CRASH(FAIL_IF_HIDDEN_ARGS, z);
69 }
70
TEST(Check,NoMessage)71 TEST(Check, NoMessage) {
72 MAYBE_SKIP_TEST;
73 PW_CHECK(true);
74 PW_CHECK(false);
75 }
76
TEST(Check,WithMessageAndArgs)77 TEST(Check, WithMessageAndArgs) {
78 MAYBE_SKIP_TEST;
79 PW_CHECK(true, FAIL_IF_DISPLAYED);
80 PW_CHECK(true, FAIL_IF_DISPLAYED_ARGS, z);
81
82 PW_CHECK(false, FAIL_IF_HIDDEN);
83 PW_CHECK(false, FAIL_IF_HIDDEN_ARGS, z);
84 }
85
TEST(Check,IntComparison)86 TEST(Check, IntComparison) {
87 MAYBE_SKIP_TEST;
88 int x_int = 50;
89 int y_int = 66;
90
91 PW_CHECK_INT_LE(x_int, y_int);
92 PW_CHECK_INT_LE(x_int, y_int, "INT: " FAIL_IF_DISPLAYED);
93 PW_CHECK_INT_LE(x_int, y_int, "INT: " FAIL_IF_DISPLAYED_ARGS, z);
94
95 PW_CHECK_INT_GE(x_int, y_int);
96 PW_CHECK_INT_GE(x_int, y_int, "INT: " FAIL_IF_HIDDEN);
97 PW_CHECK_INT_GE(x_int, y_int, "INT: " FAIL_IF_HIDDEN_ARGS, z);
98 }
99
TEST(Check,UintComparison)100 TEST(Check, UintComparison) {
101 MAYBE_SKIP_TEST;
102 unsigned int x_uint = 50;
103 unsigned int y_uint = 66;
104
105 PW_CHECK_UINT_LE(x_uint, y_uint);
106 PW_CHECK_UINT_LE(x_uint, y_uint, "UINT: " FAIL_IF_DISPLAYED);
107 PW_CHECK_UINT_LE(x_uint, y_uint, "UINT: " FAIL_IF_DISPLAYED_ARGS, z);
108
109 PW_CHECK_UINT_GE(x_uint, y_uint);
110 PW_CHECK_UINT_GE(x_uint, y_uint, "UINT: " FAIL_IF_HIDDEN);
111 PW_CHECK_UINT_GE(x_uint, y_uint, "UINT: " FAIL_IF_HIDDEN_ARGS, z);
112 }
113
TEST(Check,PtrComparison)114 TEST(Check, PtrComparison) {
115 MAYBE_SKIP_TEST;
116 void* x_ptr = reinterpret_cast<void*>(50);
117 void* y_ptr = reinterpret_cast<void*>(66);
118
119 PW_CHECK_PTR_EQ(x_ptr, y_ptr);
120 PW_CHECK_PTR_LE(x_ptr, y_ptr, "PTR: " FAIL_IF_DISPLAYED);
121 PW_CHECK_PTR_LE(x_ptr, y_ptr, "PTR: " FAIL_IF_DISPLAYED_ARGS, z);
122
123 PW_CHECK_PTR_GE(x_ptr, y_ptr);
124 PW_CHECK_PTR_GE(x_ptr, y_ptr, "PTR: " FAIL_IF_HIDDEN);
125 PW_CHECK_PTR_GE(x_ptr, y_ptr, "PTR: " FAIL_IF_HIDDEN_ARGS, z);
126 }
127
TEST(Check,FloatComparison)128 TEST(Check, FloatComparison) {
129 MAYBE_SKIP_TEST;
130 float x_float = 50.5;
131 float y_float = 66.5;
132
133 PW_CHECK_FLOAT_EXACT_LE(x_float, y_float);
134 PW_CHECK_FLOAT_EXACT_LE(x_float, y_float, "FLOAT: " FAIL_IF_DISPLAYED);
135 PW_CHECK_FLOAT_EXACT_LE(
136 x_float, y_float, "FLOAT: " FAIL_IF_DISPLAYED_ARGS, z);
137
138 PW_CHECK_FLOAT_EXACT_GE(x_float, y_float);
139 PW_CHECK_FLOAT_EXACT_GE(x_float, y_float, "FLOAT: " FAIL_IF_HIDDEN);
140 PW_CHECK_FLOAT_EXACT_GE(x_float, y_float, "FLOAT: " FAIL_IF_HIDDEN_ARGS, z);
141 }
142
143 // Don't exhaustively test the DCHECKs but have a sampling of them.
TEST(DCheck,Sampling)144 TEST(DCheck, Sampling) {
145 MAYBE_SKIP_TEST;
146 PW_DCHECK(5 == 10);
147 PW_DCHECK(5 == 10, "Message");
148 PW_DCHECK(5 == 10, "Message: %d", 5);
149 PW_DCHECK_INT_LE(5.4, 10.0);
150 PW_DCHECK_FLOAT_EXACT_EQ(5.4, 10.0, "Message");
151 }
152
Add3(int a,int b,int c)153 static int Add3(int a, int b, int c) { return a + b + c; }
154
TEST(Check,ComparisonArgumentsWithCommas)155 TEST(Check, ComparisonArgumentsWithCommas) {
156 MAYBE_SKIP_TEST;
157 int x_int = 50;
158 int y_int = 66;
159
160 PW_CHECK_INT_LE(Add3(1, 2, 3), y_int);
161 PW_CHECK_INT_LE(x_int, Add3(1, 2, 3));
162
163 PW_CHECK_INT_LE(Add3(1, 2, 3), y_int, FAIL_IF_DISPLAYED);
164 PW_CHECK_INT_LE(x_int, Add3(1, 2, 3), FAIL_IF_DISPLAYED_ARGS, z);
165
166 PW_CHECK_INT_LE(Add3(1, 2, 3), Add3(1, 2, 3), "INT: " FAIL_IF_DISPLAYED);
167 PW_CHECK_INT_LE(x_int, y_int, "INT: " FAIL_IF_DISPLAYED_ARGS, z);
168 }
169
TEST(Check,ShortNamesWork)170 TEST(Check, ShortNamesWork) {
171 MAYBE_SKIP_TEST;
172
173 // Crash
174 CRASH(FAIL_IF_HIDDEN);
175 CRASH(FAIL_IF_HIDDEN_ARGS, z);
176
177 // Check
178 CHECK(true, FAIL_IF_DISPLAYED);
179 CHECK(true, FAIL_IF_DISPLAYED_ARGS, z);
180 CHECK(false, FAIL_IF_HIDDEN);
181 CHECK(false, FAIL_IF_HIDDEN_ARGS, z);
182
183 // Check with binary comparison
184 int x_int = 50;
185 int y_int = 66;
186
187 CHECK_INT_LE(Add3(1, 2, 3), y_int);
188 CHECK_INT_LE(x_int, Add3(1, 2, 3));
189
190 CHECK_INT_LE(Add3(1, 2, 3), y_int, FAIL_IF_DISPLAYED);
191 CHECK_INT_LE(x_int, Add3(1, 2, 3), FAIL_IF_DISPLAYED_ARGS, z);
192
193 CHECK_INT_LE(Add3(1, 2, 3), Add3(1, 2, 3), "INT: " FAIL_IF_DISPLAYED);
194 CHECK_INT_LE(x_int, y_int, "INT: " FAIL_IF_DISPLAYED_ARGS, z);
195 }
196
MakeStatus(pw::Status status)197 pw::Status MakeStatus(pw::Status status) { return status; }
198
TEST(Check,CheckOkMacrosCompile)199 TEST(Check, CheckOkMacrosCompile) {
200 MAYBE_SKIP_TEST;
201 pw::Status status = pw::Status::Unknown();
202
203 // Typical case with long names.
204 PW_CHECK_OK(status);
205 PW_CHECK_OK(status, "msg");
206 PW_CHECK_OK(status, "msg: %d", 5);
207
208 // Short names.
209 CHECK_OK(status);
210 CHECK_OK(status, "msg");
211 CHECK_OK(status, "msg: %d", 5);
212
213 // Status from a literal.
214 PW_CHECK_OK(pw::OkStatus());
215
216 // Status from a function.
217 PW_CHECK_OK(MakeStatus(pw::OkStatus()));
218
219 // Status from C enums.
220 PW_CHECK_OK(PW_STATUS_OK);
221 }
222
223 // These are defined in assert_test.c, to test C compatibility.
224 extern "C" void AssertBackendCompileTestsInC();
225
TEST(Check,AssertBackendCompileTestsInC)226 TEST(Check, AssertBackendCompileTestsInC) {
227 MAYBE_SKIP_TEST;
228 AssertBackendCompileTestsInC();
229 }
230
231 } // namespace
232