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#ifndef ABSL_LOG_CHECK_TEST_IMPL_H_ 17#define ABSL_LOG_CHECK_TEST_IMPL_H_ 18 19// Verify that both sets of macros behave identically by parameterizing the 20// entire test file. 21#ifndef ABSL_TEST_CHECK 22#error ABSL_TEST_CHECK must be defined for these tests to work. 23#endif 24 25#include <ostream> 26#include <string> 27 28#include "gmock/gmock.h" 29#include "gtest/gtest.h" 30#include "absl/base/attributes.h" 31#include "absl/base/config.h" 32#include "absl/log/internal/test_helpers.h" 33#include "absl/status/status.h" 34 35// NOLINTBEGIN(misc-definitions-in-headers) 36 37namespace absl_log_internal { 38 39using ::testing::AllOf; 40using ::testing::HasSubstr; 41using ::testing::Not; 42 43auto* test_env ABSL_ATTRIBUTE_UNUSED = ::testing::AddGlobalTestEnvironment( 44 new absl::log_internal::LogTestEnvironment); 45 46#if GTEST_HAS_DEATH_TEST 47 48TEST(CHECKDeathTest, TestBasicValues) { 49 ABSL_TEST_CHECK(true); 50 51 EXPECT_DEATH(ABSL_TEST_CHECK(false), "Check failed: false"); 52 53 int i = 2; 54 ABSL_TEST_CHECK(i != 3); // NOLINT 55} 56 57#endif // GTEST_HAS_DEATH_TEST 58 59TEST(CHECKTest, TestLogicExpressions) { 60 int i = 5; 61 ABSL_TEST_CHECK(i > 0 && i < 10); 62 ABSL_TEST_CHECK(i < 0 || i > 3); 63} 64 65#if ABSL_INTERNAL_CPLUSPLUS_LANG >= 201703L 66ABSL_CONST_INIT const auto global_var_check = [](int i) { 67 ABSL_TEST_CHECK(i > 0); // NOLINT 68 return i + 1; 69}(3); 70 71ABSL_CONST_INIT const auto global_var = [](int i) { 72 ABSL_TEST_CHECK_GE(i, 0); // NOLINT 73 return i + 1; 74}(global_var_check); 75#endif // ABSL_INTERNAL_CPLUSPLUS_LANG 76 77TEST(CHECKTest, TestPlacementsInCompoundStatements) { 78 // check placement inside if/else clauses 79 if (true) ABSL_TEST_CHECK(true); 80 81 if (false) 82 ; // NOLINT 83 else 84 ABSL_TEST_CHECK(true); 85 86 switch (0) 87 case 0: 88 ABSL_TEST_CHECK(true); // NOLINT 89 90#if ABSL_INTERNAL_CPLUSPLUS_LANG >= 201703L 91 constexpr auto var = [](int i) { 92 ABSL_TEST_CHECK(i > 0); // NOLINT 93 return i + 1; 94 }(global_var); 95 (void)var; 96#endif // ABSL_INTERNAL_CPLUSPLUS_LANG 97} 98 99TEST(CHECKTest, TestBoolConvertible) { 100 struct Tester { 101 } tester; 102 ABSL_TEST_CHECK([&]() { return &tester; }()); 103} 104 105#if GTEST_HAS_DEATH_TEST 106 107TEST(CHECKDeathTest, TestChecksWithSideEffects) { 108 int var = 0; 109 ABSL_TEST_CHECK([&var]() { 110 ++var; 111 return true; 112 }()); 113 EXPECT_EQ(var, 1); 114 115 EXPECT_DEATH(ABSL_TEST_CHECK([&var]() { 116 ++var; 117 return false; 118 }()) << var, 119 "Check failed: .* 2"); 120} 121 122#endif // GTEST_HAS_DEATH_TEST 123 124template <int a, int b> 125constexpr int sum() { 126 return a + b; 127} 128#define MACRO_ONE 1 129#define TEMPLATE_SUM(a, b) sum<a, b>() 130#define CONCAT(a, b) a b 131#define IDENTITY(x) x 132 133TEST(CHECKTest, TestPassingMacroExpansion) { 134 ABSL_TEST_CHECK(IDENTITY(true)); 135 ABSL_TEST_CHECK_EQ(TEMPLATE_SUM(MACRO_ONE, 2), 3); 136 ABSL_TEST_CHECK_STREQ(CONCAT("x", "y"), "xy"); 137} 138 139#if GTEST_HAS_DEATH_TEST 140 141TEST(CHECKTest, TestMacroExpansionInMessage) { 142 auto MessageGen = []() { ABSL_TEST_CHECK(IDENTITY(false)); }; 143 EXPECT_DEATH(MessageGen(), HasSubstr("IDENTITY(false)")); 144} 145 146TEST(CHECKTest, TestNestedMacroExpansionInMessage) { 147 EXPECT_DEATH(ABSL_TEST_CHECK(IDENTITY(false)), HasSubstr("IDENTITY(false)")); 148} 149 150TEST(CHECKTest, TestMacroExpansionCompare) { 151 EXPECT_DEATH(ABSL_TEST_CHECK_EQ(IDENTITY(false), IDENTITY(true)), 152 HasSubstr("IDENTITY(false) == IDENTITY(true)")); 153 EXPECT_DEATH(ABSL_TEST_CHECK_GT(IDENTITY(1), IDENTITY(2)), 154 HasSubstr("IDENTITY(1) > IDENTITY(2)")); 155} 156 157TEST(CHECKTest, TestMacroExpansionStrCompare) { 158 EXPECT_DEATH(ABSL_TEST_CHECK_STREQ(IDENTITY("x"), IDENTITY("y")), 159 HasSubstr("IDENTITY(\"x\") == IDENTITY(\"y\")")); 160 EXPECT_DEATH(ABSL_TEST_CHECK_STRCASENE(IDENTITY("a"), IDENTITY("A")), 161 HasSubstr("IDENTITY(\"a\") != IDENTITY(\"A\")")); 162} 163 164TEST(CHECKTest, TestMacroExpansionStatus) { 165 EXPECT_DEATH( 166 ABSL_TEST_CHECK_OK(IDENTITY(absl::FailedPreconditionError("message"))), 167 HasSubstr("IDENTITY(absl::FailedPreconditionError(\"message\"))")); 168} 169 170TEST(CHECKTest, TestMacroExpansionComma) { 171 EXPECT_DEATH(ABSL_TEST_CHECK(TEMPLATE_SUM(MACRO_ONE, 2) == 4), 172 HasSubstr("TEMPLATE_SUM(MACRO_ONE, 2) == 4")); 173} 174 175TEST(CHECKTest, TestMacroExpansionCommaCompare) { 176 EXPECT_DEATH( 177 ABSL_TEST_CHECK_EQ(TEMPLATE_SUM(2, MACRO_ONE), TEMPLATE_SUM(3, 2)), 178 HasSubstr("TEMPLATE_SUM(2, MACRO_ONE) == TEMPLATE_SUM(3, 2)")); 179 EXPECT_DEATH( 180 ABSL_TEST_CHECK_GT(TEMPLATE_SUM(2, MACRO_ONE), TEMPLATE_SUM(3, 2)), 181 HasSubstr("TEMPLATE_SUM(2, MACRO_ONE) > TEMPLATE_SUM(3, 2)")); 182} 183 184TEST(CHECKTest, TestMacroExpansionCommaStrCompare) { 185 EXPECT_DEATH(ABSL_TEST_CHECK_STREQ(CONCAT("x", "y"), "z"), 186 HasSubstr("CONCAT(\"x\", \"y\") == \"z\"")); 187 EXPECT_DEATH(ABSL_TEST_CHECK_STRNE(CONCAT("x", "y"), "xy"), 188 HasSubstr("CONCAT(\"x\", \"y\") != \"xy\"")); 189} 190 191#endif // GTEST_HAS_DEATH_TEST 192 193#undef TEMPLATE_SUM 194#undef CONCAT 195#undef MACRO 196#undef ONE 197 198#if GTEST_HAS_DEATH_TEST 199 200TEST(CHECKDeachTest, TestOrderOfInvocationsBetweenCheckAndMessage) { 201 int counter = 0; 202 203 auto GetStr = [&counter]() -> std::string { 204 return counter++ == 0 ? "" : "non-empty"; 205 }; 206 207 EXPECT_DEATH(ABSL_TEST_CHECK(!GetStr().empty()) << GetStr(), 208 HasSubstr("non-empty")); 209} 210 211TEST(CHECKTest, TestSecondaryFailure) { 212 auto FailingRoutine = []() { 213 ABSL_TEST_CHECK(false) << "Secondary"; 214 return false; 215 }; 216 EXPECT_DEATH(ABSL_TEST_CHECK(FailingRoutine()) << "Primary", 217 AllOf(HasSubstr("Secondary"), Not(HasSubstr("Primary")))); 218} 219 220TEST(CHECKTest, TestSecondaryFailureInMessage) { 221 auto MessageGen = []() { 222 ABSL_TEST_CHECK(false) << "Secondary"; 223 return "Primary"; 224 }; 225 EXPECT_DEATH(ABSL_TEST_CHECK(false) << MessageGen(), 226 AllOf(HasSubstr("Secondary"), Not(HasSubstr("Primary")))); 227} 228 229#endif // GTEST_HAS_DEATH_TEST 230 231TEST(CHECKTest, TestBinaryChecksWithPrimitives) { 232 ABSL_TEST_CHECK_EQ(1, 1); 233 ABSL_TEST_CHECK_NE(1, 2); 234 ABSL_TEST_CHECK_GE(1, 1); 235 ABSL_TEST_CHECK_GE(2, 1); 236 ABSL_TEST_CHECK_LE(1, 1); 237 ABSL_TEST_CHECK_LE(1, 2); 238 ABSL_TEST_CHECK_GT(2, 1); 239 ABSL_TEST_CHECK_LT(1, 2); 240} 241 242// For testing using CHECK*() on anonymous enums. 243enum { CASE_A, CASE_B }; 244 245TEST(CHECKTest, TestBinaryChecksWithEnumValues) { 246 // Tests using CHECK*() on anonymous enums. 247 ABSL_TEST_CHECK_EQ(CASE_A, CASE_A); 248 ABSL_TEST_CHECK_NE(CASE_A, CASE_B); 249 ABSL_TEST_CHECK_GE(CASE_A, CASE_A); 250 ABSL_TEST_CHECK_GE(CASE_B, CASE_A); 251 ABSL_TEST_CHECK_LE(CASE_A, CASE_A); 252 ABSL_TEST_CHECK_LE(CASE_A, CASE_B); 253 ABSL_TEST_CHECK_GT(CASE_B, CASE_A); 254 ABSL_TEST_CHECK_LT(CASE_A, CASE_B); 255} 256 257TEST(CHECKTest, TestBinaryChecksWithNullptr) { 258 const void* p_null = nullptr; 259 const void* p_not_null = &p_null; 260 ABSL_TEST_CHECK_EQ(p_null, nullptr); 261 ABSL_TEST_CHECK_EQ(nullptr, p_null); 262 ABSL_TEST_CHECK_NE(p_not_null, nullptr); 263 ABSL_TEST_CHECK_NE(nullptr, p_not_null); 264} 265 266#if GTEST_HAS_DEATH_TEST 267 268// Test logging of various char-typed values by failing CHECK*(). 269TEST(CHECKDeathTest, TestComparingCharsValues) { 270 { 271 char a = ';'; 272 char b = 'b'; 273 EXPECT_DEATH(ABSL_TEST_CHECK_EQ(a, b), 274 "Check failed: a == b \\(';' vs. 'b'\\)"); 275 b = 1; 276 EXPECT_DEATH(ABSL_TEST_CHECK_EQ(a, b), 277 "Check failed: a == b \\(';' vs. char value 1\\)"); 278 } 279 { 280 signed char a = ';'; 281 signed char b = 'b'; 282 EXPECT_DEATH(ABSL_TEST_CHECK_EQ(a, b), 283 "Check failed: a == b \\(';' vs. 'b'\\)"); 284 b = -128; 285 EXPECT_DEATH(ABSL_TEST_CHECK_EQ(a, b), 286 "Check failed: a == b \\(';' vs. signed char value -128\\)"); 287 } 288 { 289 unsigned char a = ';'; 290 unsigned char b = 'b'; 291 EXPECT_DEATH(ABSL_TEST_CHECK_EQ(a, b), 292 "Check failed: a == b \\(';' vs. 'b'\\)"); 293 b = 128; 294 EXPECT_DEATH(ABSL_TEST_CHECK_EQ(a, b), 295 "Check failed: a == b \\(';' vs. unsigned char value 128\\)"); 296 } 297} 298 299TEST(CHECKDeathTest, TestNullValuesAreReportedCleanly) { 300 const char* a = nullptr; 301 const char* b = nullptr; 302 EXPECT_DEATH(ABSL_TEST_CHECK_NE(a, b), 303 "Check failed: a != b \\(\\(null\\) vs. \\(null\\)\\)"); 304 305 a = "xx"; 306 EXPECT_DEATH(ABSL_TEST_CHECK_EQ(a, b), 307 "Check failed: a == b \\(xx vs. \\(null\\)\\)"); 308 EXPECT_DEATH(ABSL_TEST_CHECK_EQ(b, a), 309 "Check failed: b == a \\(\\(null\\) vs. xx\\)"); 310 311 std::nullptr_t n{}; 312 EXPECT_DEATH(ABSL_TEST_CHECK_NE(n, nullptr), 313 "Check failed: n != nullptr \\(\\(null\\) vs. \\(null\\)\\)"); 314} 315 316#endif // GTEST_HAS_DEATH_TEST 317 318TEST(CHECKTest, TestSTREQ) { 319 ABSL_TEST_CHECK_STREQ("this", "this"); 320 ABSL_TEST_CHECK_STREQ(nullptr, nullptr); 321 ABSL_TEST_CHECK_STRCASEEQ("this", "tHiS"); 322 ABSL_TEST_CHECK_STRCASEEQ(nullptr, nullptr); 323 ABSL_TEST_CHECK_STRNE("this", "tHiS"); 324 ABSL_TEST_CHECK_STRNE("this", nullptr); 325 ABSL_TEST_CHECK_STRCASENE("this", "that"); 326 ABSL_TEST_CHECK_STRCASENE(nullptr, "that"); 327 ABSL_TEST_CHECK_STREQ((std::string("a") + "b").c_str(), "ab"); 328 ABSL_TEST_CHECK_STREQ(std::string("test").c_str(), 329 (std::string("te") + std::string("st")).c_str()); 330} 331 332TEST(CHECKTest, TestComparisonPlacementsInCompoundStatements) { 333 // check placement inside if/else clauses 334 if (true) ABSL_TEST_CHECK_EQ(1, 1); 335 if (true) ABSL_TEST_CHECK_STREQ("c", "c"); 336 337 if (false) 338 ; // NOLINT 339 else 340 ABSL_TEST_CHECK_LE(0, 1); 341 342 if (false) 343 ; // NOLINT 344 else 345 ABSL_TEST_CHECK_STRNE("a", "b"); 346 347 switch (0) 348 case 0: 349 ABSL_TEST_CHECK_NE(1, 0); 350 351 switch (0) 352 case 0: 353 ABSL_TEST_CHECK_STRCASEEQ("A", "a"); 354 355#if ABSL_INTERNAL_CPLUSPLUS_LANG >= 201703L 356 constexpr auto var = [](int i) { 357 ABSL_TEST_CHECK_GT(i, 0); 358 return i + 1; 359 }(global_var); 360 (void)var; 361 362 // CHECK_STR... checks are not supported in constexpr routines. 363 // constexpr auto var2 = [](int i) { 364 // ABSL_TEST_CHECK_STRNE("c", "d"); 365 // return i + 1; 366 // }(global_var); 367 368#if defined(__GNUC__) 369 int var3 = (({ ABSL_TEST_CHECK_LE(1, 2); }), global_var < 10) ? 1 : 0; 370 (void)var3; 371 372 int var4 = (({ ABSL_TEST_CHECK_STREQ("a", "a"); }), global_var < 10) ? 1 : 0; 373 (void)var4; 374#endif // __GNUC__ 375#endif // ABSL_INTERNAL_CPLUSPLUS_LANG 376} 377 378TEST(CHECKTest, TestDCHECK) { 379#ifdef NDEBUG 380 ABSL_TEST_DCHECK(1 == 2) << " DCHECK's shouldn't be compiled in normal mode"; 381#endif 382 ABSL_TEST_DCHECK(1 == 1); // NOLINT(readability/check) 383 ABSL_TEST_DCHECK_EQ(1, 1); 384 ABSL_TEST_DCHECK_NE(1, 2); 385 ABSL_TEST_DCHECK_GE(1, 1); 386 ABSL_TEST_DCHECK_GE(2, 1); 387 ABSL_TEST_DCHECK_LE(1, 1); 388 ABSL_TEST_DCHECK_LE(1, 2); 389 ABSL_TEST_DCHECK_GT(2, 1); 390 ABSL_TEST_DCHECK_LT(1, 2); 391 392 // Test DCHECK on std::nullptr_t 393 const void* p_null = nullptr; 394 const void* p_not_null = &p_null; 395 ABSL_TEST_DCHECK_EQ(p_null, nullptr); 396 ABSL_TEST_DCHECK_EQ(nullptr, p_null); 397 ABSL_TEST_DCHECK_NE(p_not_null, nullptr); 398 ABSL_TEST_DCHECK_NE(nullptr, p_not_null); 399} 400 401TEST(CHECKTest, TestQCHECK) { 402 // The tests that QCHECK does the same as CHECK 403 ABSL_TEST_QCHECK(1 == 1); // NOLINT(readability/check) 404 ABSL_TEST_QCHECK_EQ(1, 1); 405 ABSL_TEST_QCHECK_NE(1, 2); 406 ABSL_TEST_QCHECK_GE(1, 1); 407 ABSL_TEST_QCHECK_GE(2, 1); 408 ABSL_TEST_QCHECK_LE(1, 1); 409 ABSL_TEST_QCHECK_LE(1, 2); 410 ABSL_TEST_QCHECK_GT(2, 1); 411 ABSL_TEST_QCHECK_LT(1, 2); 412 413 // Tests using QCHECK*() on anonymous enums. 414 ABSL_TEST_QCHECK_EQ(CASE_A, CASE_A); 415 ABSL_TEST_QCHECK_NE(CASE_A, CASE_B); 416 ABSL_TEST_QCHECK_GE(CASE_A, CASE_A); 417 ABSL_TEST_QCHECK_GE(CASE_B, CASE_A); 418 ABSL_TEST_QCHECK_LE(CASE_A, CASE_A); 419 ABSL_TEST_QCHECK_LE(CASE_A, CASE_B); 420 ABSL_TEST_QCHECK_GT(CASE_B, CASE_A); 421 ABSL_TEST_QCHECK_LT(CASE_A, CASE_B); 422} 423 424TEST(CHECKTest, TestQCHECKPlacementsInCompoundStatements) { 425 // check placement inside if/else clauses 426 if (true) ABSL_TEST_QCHECK(true); 427 428 if (false) 429 ; // NOLINT 430 else 431 ABSL_TEST_QCHECK(true); 432 433 if (false) 434 ; // NOLINT 435 else 436 ABSL_TEST_QCHECK(true); 437 438 switch (0) 439 case 0: 440 ABSL_TEST_QCHECK(true); 441 442#if ABSL_INTERNAL_CPLUSPLUS_LANG >= 201703L 443 constexpr auto var = [](int i) { 444 ABSL_TEST_QCHECK(i > 0); // NOLINT 445 return i + 1; 446 }(global_var); 447 (void)var; 448 449#if defined(__GNUC__) 450 int var2 = (({ ABSL_TEST_CHECK_LE(1, 2); }), global_var < 10) ? 1 : 0; 451 (void)var2; 452#endif // __GNUC__ 453#endif // ABSL_INTERNAL_CPLUSPLUS_LANG 454} 455 456class ComparableType { 457 public: 458 explicit ComparableType(int v) : v_(v) {} 459 460 void MethodWithCheck(int i) { 461 ABSL_TEST_CHECK_EQ(*this, i); 462 ABSL_TEST_CHECK_EQ(i, *this); 463 } 464 465 int Get() const { return v_; } 466 467 private: 468 friend bool operator==(const ComparableType& lhs, const ComparableType& rhs) { 469 return lhs.v_ == rhs.v_; 470 } 471 friend bool operator!=(const ComparableType& lhs, const ComparableType& rhs) { 472 return lhs.v_ != rhs.v_; 473 } 474 friend bool operator<(const ComparableType& lhs, const ComparableType& rhs) { 475 return lhs.v_ < rhs.v_; 476 } 477 friend bool operator<=(const ComparableType& lhs, const ComparableType& rhs) { 478 return lhs.v_ <= rhs.v_; 479 } 480 friend bool operator>(const ComparableType& lhs, const ComparableType& rhs) { 481 return lhs.v_ > rhs.v_; 482 } 483 friend bool operator>=(const ComparableType& lhs, const ComparableType& rhs) { 484 return lhs.v_ >= rhs.v_; 485 } 486 friend bool operator==(const ComparableType& lhs, int rhs) { 487 return lhs.v_ == rhs; 488 } 489 friend bool operator==(int lhs, const ComparableType& rhs) { 490 return lhs == rhs.v_; 491 } 492 493 friend std::ostream& operator<<(std::ostream& out, const ComparableType& v) { 494 return out << "ComparableType{" << v.Get() << "}"; 495 } 496 497 int v_; 498}; 499 500TEST(CHECKTest, TestUserDefinedCompOp) { 501 ABSL_TEST_CHECK_EQ(ComparableType{0}, ComparableType{0}); 502 ABSL_TEST_CHECK_NE(ComparableType{1}, ComparableType{2}); 503 ABSL_TEST_CHECK_LT(ComparableType{1}, ComparableType{2}); 504 ABSL_TEST_CHECK_LE(ComparableType{1}, ComparableType{2}); 505 ABSL_TEST_CHECK_GT(ComparableType{2}, ComparableType{1}); 506 ABSL_TEST_CHECK_GE(ComparableType{2}, ComparableType{2}); 507} 508 509TEST(CHECKTest, TestCheckInMethod) { 510 ComparableType v{1}; 511 v.MethodWithCheck(1); 512} 513 514TEST(CHECKDeathTest, TestUserDefinedStreaming) { 515 ComparableType v1{1}; 516 ComparableType v2{2}; 517 518 EXPECT_DEATH( 519 ABSL_TEST_CHECK_EQ(v1, v2), 520 HasSubstr( 521 "Check failed: v1 == v2 (ComparableType{1} vs. ComparableType{2})")); 522} 523 524} // namespace absl_log_internal 525 526// NOLINTEND(misc-definitions-in-headers) 527 528#endif // ABSL_LOG_CHECK_TEST_IMPL_H_ 529