1 //
2 // Copyright 2022 The Abseil 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 // https://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 #include "absl/log/check.h"
17
18 #include <ostream>
19 #include <string>
20
21 #include "gmock/gmock.h"
22 #include "gtest/gtest.h"
23 #include "absl/base/attributes.h"
24 #include "absl/base/config.h"
25 #include "absl/log/internal/test_helpers.h"
26
27 namespace {
28 using ::testing::AllOf;
29 using ::testing::HasSubstr;
30 using ::testing::Not;
31
32 auto* test_env ABSL_ATTRIBUTE_UNUSED = ::testing::AddGlobalTestEnvironment(
33 new absl::log_internal::LogTestEnvironment);
34
35 #if GTEST_HAS_DEATH_TEST
36
TEST(CHECKDeathTest,TestBasicValues)37 TEST(CHECKDeathTest, TestBasicValues) {
38 CHECK(true);
39
40 EXPECT_DEATH(CHECK(false), "Check failed: false");
41
42 int i = 2;
43 CHECK(i != 3); // NOLINT
44 }
45
46 #endif // GTEST_HAS_DEATH_TEST
47
TEST(CHECKTest,TestLogicExpressions)48 TEST(CHECKTest, TestLogicExpressions) {
49 int i = 5;
50 CHECK(i > 0 && i < 10);
51 CHECK(i < 0 || i > 3);
52 }
53
54 #if ABSL_INTERNAL_CPLUSPLUS_LANG >= 201703L
__anon75512ef80202(int i) 55 ABSL_CONST_INIT const auto global_var_check = [](int i) {
56 CHECK(i > 0); // NOLINT
57 return i + 1;
58 }(3);
59
__anon75512ef80302(int i) 60 ABSL_CONST_INIT const auto global_var = [](int i) {
61 CHECK_GE(i, 0); // NOLINT
62 return i + 1;
63 }(global_var_check);
64 #endif // ABSL_INTERNAL_CPLUSPLUS_LANG
65
TEST(CHECKTest,TestPlacementsInCompoundStatements)66 TEST(CHECKTest, TestPlacementsInCompoundStatements) {
67 // check placement inside if/else clauses
68 if (true) CHECK(true);
69
70 if (false)
71 ; // NOLINT
72 else
73 CHECK(true);
74
75 switch (0)
76 case 0:
77 CHECK(true); // NOLINT
78
79 #if ABSL_INTERNAL_CPLUSPLUS_LANG >= 201703L
80 constexpr auto var = [](int i) {
81 CHECK(i > 0); // NOLINT
82 return i + 1;
83 }(global_var);
84 (void)var;
85 #endif // ABSL_INTERNAL_CPLUSPLUS_LANG
86 }
87
TEST(CHECKTest,TestBoolConvertible)88 TEST(CHECKTest, TestBoolConvertible) {
89 struct Tester {
90 } tester;
91 CHECK([&]() { return &tester; }());
92 }
93
94 #if GTEST_HAS_DEATH_TEST
95
TEST(CHECKDeathTest,TestChecksWithSideeffects)96 TEST(CHECKDeathTest, TestChecksWithSideeffects) {
97 int var = 0;
98 CHECK([&var]() {
99 ++var;
100 return true;
101 }());
102 EXPECT_EQ(var, 1);
103
104 EXPECT_DEATH(CHECK([&var]() {
105 ++var;
106 return false;
107 }()) << var,
108 "Check failed: .* 2");
109 }
110
111 #endif // GTEST_HAS_DEATH_TEST
112
113 #if GTEST_HAS_DEATH_TEST
114
TEST(CHECKDeachTest,TestOrderOfInvocationsBetweenCheckAndMessage)115 TEST(CHECKDeachTest, TestOrderOfInvocationsBetweenCheckAndMessage) {
116 int counter = 0;
117
118 auto GetStr = [&counter]() -> std::string {
119 return counter++ == 0 ? "" : "non-empty";
120 };
121
122 EXPECT_DEATH(CHECK(!GetStr().empty()) << GetStr(), HasSubstr("non-empty"));
123 }
124
TEST(CHECKTest,TestSecondaryFailure)125 TEST(CHECKTest, TestSecondaryFailure) {
126 auto FailingRoutine = []() {
127 CHECK(false) << "Secondary";
128 return false;
129 };
130 EXPECT_DEATH(CHECK(FailingRoutine()) << "Primary",
131 AllOf(HasSubstr("Secondary"), Not(HasSubstr("Primary"))));
132 }
133
TEST(CHECKTest,TestSecondaryFailureInMessage)134 TEST(CHECKTest, TestSecondaryFailureInMessage) {
135 auto MessageGen = []() {
136 CHECK(false) << "Secondary";
137 return "Primary";
138 };
139 EXPECT_DEATH(CHECK(false) << MessageGen(),
140 AllOf(HasSubstr("Secondary"), Not(HasSubstr("Primary"))));
141 }
142
143 #endif // GTEST_HAS_DEATH_TEST
144
TEST(CHECKTest,TestBinaryChecksWithPrimitives)145 TEST(CHECKTest, TestBinaryChecksWithPrimitives) {
146 CHECK_EQ(1, 1);
147 CHECK_NE(1, 2);
148 CHECK_GE(1, 1);
149 CHECK_GE(2, 1);
150 CHECK_LE(1, 1);
151 CHECK_LE(1, 2);
152 CHECK_GT(2, 1);
153 CHECK_LT(1, 2);
154 }
155
156 // For testing using CHECK*() on anonymous enums.
157 enum { CASE_A, CASE_B };
158
TEST(CHECKTest,TestBinaryChecksWithEnumValues)159 TEST(CHECKTest, TestBinaryChecksWithEnumValues) {
160 // Tests using CHECK*() on anonymous enums.
161 CHECK_EQ(CASE_A, CASE_A);
162 CHECK_NE(CASE_A, CASE_B);
163 CHECK_GE(CASE_A, CASE_A);
164 CHECK_GE(CASE_B, CASE_A);
165 CHECK_LE(CASE_A, CASE_A);
166 CHECK_LE(CASE_A, CASE_B);
167 CHECK_GT(CASE_B, CASE_A);
168 CHECK_LT(CASE_A, CASE_B);
169 }
170
TEST(CHECKTest,TestBinaryChecksWithNullptr)171 TEST(CHECKTest, TestBinaryChecksWithNullptr) {
172 const void* p_null = nullptr;
173 const void* p_not_null = &p_null;
174 CHECK_EQ(p_null, nullptr);
175 CHECK_EQ(nullptr, p_null);
176 CHECK_NE(p_not_null, nullptr);
177 CHECK_NE(nullptr, p_not_null);
178 }
179
180 #if GTEST_HAS_DEATH_TEST
181
182 // Test logging of various char-typed values by failing CHECK*().
TEST(CHECKDeathTest,TestComparingCharsValues)183 TEST(CHECKDeathTest, TestComparingCharsValues) {
184 {
185 char a = ';';
186 char b = 'b';
187 EXPECT_DEATH(CHECK_EQ(a, b), "Check failed: a == b \\(';' vs. 'b'\\)");
188 b = 1;
189 EXPECT_DEATH(CHECK_EQ(a, b),
190 "Check failed: a == b \\(';' vs. char value 1\\)");
191 }
192 {
193 signed char a = ';';
194 signed char b = 'b';
195 EXPECT_DEATH(CHECK_EQ(a, b), "Check failed: a == b \\(';' vs. 'b'\\)");
196 b = -128;
197 EXPECT_DEATH(CHECK_EQ(a, b),
198 "Check failed: a == b \\(';' vs. signed char value -128\\)");
199 }
200 {
201 unsigned char a = ';';
202 unsigned char b = 'b';
203 EXPECT_DEATH(CHECK_EQ(a, b), "Check failed: a == b \\(';' vs. 'b'\\)");
204 b = 128;
205 EXPECT_DEATH(CHECK_EQ(a, b),
206 "Check failed: a == b \\(';' vs. unsigned char value 128\\)");
207 }
208 }
209
TEST(CHECKDeathTest,TestNullValuesAreReportedCleanly)210 TEST(CHECKDeathTest, TestNullValuesAreReportedCleanly) {
211 const char* a = nullptr;
212 const char* b = nullptr;
213 EXPECT_DEATH(CHECK_NE(a, b),
214 "Check failed: a != b \\(\\(null\\) vs. \\(null\\)\\)");
215
216 a = "xx";
217 EXPECT_DEATH(CHECK_EQ(a, b), "Check failed: a == b \\(xx vs. \\(null\\)\\)");
218 EXPECT_DEATH(CHECK_EQ(b, a), "Check failed: b == a \\(\\(null\\) vs. xx\\)");
219
220 std::nullptr_t n{};
221 EXPECT_DEATH(CHECK_NE(n, nullptr),
222 "Check failed: n != nullptr \\(\\(null\\) vs. \\(null\\)\\)");
223 }
224
225 #endif // GTEST_HAS_DEATH_TEST
226
TEST(CHECKTest,TestSTREQ)227 TEST(CHECKTest, TestSTREQ) {
228 CHECK_STREQ("this", "this");
229 CHECK_STREQ(nullptr, nullptr);
230 CHECK_STRCASEEQ("this", "tHiS");
231 CHECK_STRCASEEQ(nullptr, nullptr);
232 CHECK_STRNE("this", "tHiS");
233 CHECK_STRNE("this", nullptr);
234 CHECK_STRCASENE("this", "that");
235 CHECK_STRCASENE(nullptr, "that");
236 CHECK_STREQ((std::string("a") + "b").c_str(), "ab");
237 CHECK_STREQ(std::string("test").c_str(),
238 (std::string("te") + std::string("st")).c_str());
239 }
240
TEST(CHECKTest,TestComparisonPlacementsInCompoundStatements)241 TEST(CHECKTest, TestComparisonPlacementsInCompoundStatements) {
242 // check placement inside if/else clauses
243 if (true) CHECK_EQ(1, 1);
244 if (true) CHECK_STREQ("c", "c");
245
246 if (false)
247 ; // NOLINT
248 else
249 CHECK_LE(0, 1);
250
251 if (false)
252 ; // NOLINT
253 else
254 CHECK_STRNE("a", "b");
255
256 switch (0)
257 case 0:
258 CHECK_NE(1, 0);
259
260 switch (0)
261 case 0:
262 CHECK_STRCASEEQ("A", "a");
263
264 #if ABSL_INTERNAL_CPLUSPLUS_LANG >= 201703L
265 constexpr auto var = [](int i) {
266 CHECK_GT(i, 0);
267 return i + 1;
268 }(global_var);
269 (void)var;
270
271 // CHECK_STR... checks are not supported in constexpr routines.
272 // constexpr auto var2 = [](int i) {
273 // CHECK_STRNE("c", "d");
274 // return i + 1;
275 // }(global_var);
276
277 #if defined(__GNUC__)
278 int var3 = (({ CHECK_LE(1, 2); }), global_var < 10) ? 1 : 0;
279 (void)var3;
280
281 int var4 = (({ CHECK_STREQ("a", "a"); }), global_var < 10) ? 1 : 0;
282 (void)var4;
283 #endif // __GNUC__
284 #endif // ABSL_INTERNAL_CPLUSPLUS_LANG
285 }
286
TEST(CHECKTest,TestDCHECK)287 TEST(CHECKTest, TestDCHECK) {
288 #ifdef NDEBUG
289 DCHECK(1 == 2) << " DCHECK's shouldn't be compiled in normal mode";
290 #endif
291 DCHECK(1 == 1); // NOLINT(readability/check)
292 DCHECK_EQ(1, 1);
293 DCHECK_NE(1, 2);
294 DCHECK_GE(1, 1);
295 DCHECK_GE(2, 1);
296 DCHECK_LE(1, 1);
297 DCHECK_LE(1, 2);
298 DCHECK_GT(2, 1);
299 DCHECK_LT(1, 2);
300
301 // Test DCHECK on std::nullptr_t
302 const void* p_null = nullptr;
303 const void* p_not_null = &p_null;
304 DCHECK_EQ(p_null, nullptr);
305 DCHECK_EQ(nullptr, p_null);
306 DCHECK_NE(p_not_null, nullptr);
307 DCHECK_NE(nullptr, p_not_null);
308 }
309
TEST(CHECKTest,TestQCHECK)310 TEST(CHECKTest, TestQCHECK) {
311 // The tests that QCHECK does the same as CHECK
312 QCHECK(1 == 1); // NOLINT(readability/check)
313 QCHECK_EQ(1, 1);
314 QCHECK_NE(1, 2);
315 QCHECK_GE(1, 1);
316 QCHECK_GE(2, 1);
317 QCHECK_LE(1, 1);
318 QCHECK_LE(1, 2);
319 QCHECK_GT(2, 1);
320 QCHECK_LT(1, 2);
321
322 // Tests using QCHECK*() on anonymous enums.
323 QCHECK_EQ(CASE_A, CASE_A);
324 QCHECK_NE(CASE_A, CASE_B);
325 QCHECK_GE(CASE_A, CASE_A);
326 QCHECK_GE(CASE_B, CASE_A);
327 QCHECK_LE(CASE_A, CASE_A);
328 QCHECK_LE(CASE_A, CASE_B);
329 QCHECK_GT(CASE_B, CASE_A);
330 QCHECK_LT(CASE_A, CASE_B);
331 }
332
TEST(CHECKTest,TestQCHECKPlacementsInCompoundStatements)333 TEST(CHECKTest, TestQCHECKPlacementsInCompoundStatements) {
334 // check placement inside if/else clauses
335 if (true) QCHECK(true);
336
337 if (false)
338 ; // NOLINT
339 else
340 QCHECK(true);
341
342 if (false)
343 ; // NOLINT
344 else
345 QCHECK(true);
346
347 switch (0)
348 case 0:
349 QCHECK(true);
350
351 #if ABSL_INTERNAL_CPLUSPLUS_LANG >= 201703L
352 constexpr auto var = [](int i) {
353 QCHECK(i > 0); // NOLINT
354 return i + 1;
355 }(global_var);
356 (void)var;
357
358 #if defined(__GNUC__)
359 int var2 = (({ CHECK_LE(1, 2); }), global_var < 10) ? 1 : 0;
360 (void)var2;
361 #endif // __GNUC__
362 #endif // ABSL_INTERNAL_CPLUSPLUS_LANG
363 }
364
365 class ComparableType {
366 public:
ComparableType(int v)367 explicit ComparableType(int v) : v_(v) {}
368
MethodWithCheck(int i)369 void MethodWithCheck(int i) {
370 CHECK_EQ(*this, i);
371 CHECK_EQ(i, *this);
372 }
373
Get() const374 int Get() const { return v_; }
375
376 private:
operator ==(const ComparableType & lhs,const ComparableType & rhs)377 friend bool operator==(const ComparableType& lhs, const ComparableType& rhs) {
378 return lhs.v_ == rhs.v_;
379 }
operator !=(const ComparableType & lhs,const ComparableType & rhs)380 friend bool operator!=(const ComparableType& lhs, const ComparableType& rhs) {
381 return lhs.v_ != rhs.v_;
382 }
operator <(const ComparableType & lhs,const ComparableType & rhs)383 friend bool operator<(const ComparableType& lhs, const ComparableType& rhs) {
384 return lhs.v_ < rhs.v_;
385 }
operator <=(const ComparableType & lhs,const ComparableType & rhs)386 friend bool operator<=(const ComparableType& lhs, const ComparableType& rhs) {
387 return lhs.v_ <= rhs.v_;
388 }
operator >(const ComparableType & lhs,const ComparableType & rhs)389 friend bool operator>(const ComparableType& lhs, const ComparableType& rhs) {
390 return lhs.v_ > rhs.v_;
391 }
operator >=(const ComparableType & lhs,const ComparableType & rhs)392 friend bool operator>=(const ComparableType& lhs, const ComparableType& rhs) {
393 return lhs.v_ >= rhs.v_;
394 }
operator ==(const ComparableType & lhs,int rhs)395 friend bool operator==(const ComparableType& lhs, int rhs) {
396 return lhs.v_ == rhs;
397 }
operator ==(int lhs,const ComparableType & rhs)398 friend bool operator==(int lhs, const ComparableType& rhs) {
399 return lhs == rhs.v_;
400 }
401
operator <<(std::ostream & out,const ComparableType & v)402 friend std::ostream& operator<<(std::ostream& out, const ComparableType& v) {
403 return out << "ComparableType{" << v.Get() << "}";
404 }
405
406 int v_;
407 };
408
TEST(CHECKTest,TestUserDefinedCompOp)409 TEST(CHECKTest, TestUserDefinedCompOp) {
410 CHECK_EQ(ComparableType{0}, ComparableType{0});
411 CHECK_NE(ComparableType{1}, ComparableType{2});
412 CHECK_LT(ComparableType{1}, ComparableType{2});
413 CHECK_LE(ComparableType{1}, ComparableType{2});
414 CHECK_GT(ComparableType{2}, ComparableType{1});
415 CHECK_GE(ComparableType{2}, ComparableType{2});
416 }
417
TEST(CHECKTest,TestCheckInMethod)418 TEST(CHECKTest, TestCheckInMethod) {
419 ComparableType v{1};
420 v.MethodWithCheck(1);
421 }
422
TEST(CHECKDeathTest,TestUserDefinedStreaming)423 TEST(CHECKDeathTest, TestUserDefinedStreaming) {
424 ComparableType v1{1};
425 ComparableType v2{2};
426
427 EXPECT_DEATH(
428 CHECK_EQ(v1, v2),
429 HasSubstr(
430 "Check failed: v1 == v2 (ComparableType{1} vs. ComparableType{2})"));
431 }
432
433 } // namespace
434