OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/basictypes.h" | 5 #include "base/basictypes.h" |
6 #include "base/compiler_specific.h" | 6 #include "base/compiler_specific.h" |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 | 8 |
9 #include "testing/gmock/include/gmock/gmock.h" | 9 #include "testing/gmock/include/gmock/gmock.h" |
10 #include "testing/gtest/include/gtest/gtest.h" | 10 #include "testing/gtest/include/gtest/gtest.h" |
11 | 11 |
12 namespace logging { | 12 namespace logging { |
13 | 13 |
14 namespace { | 14 namespace { |
15 | 15 |
16 using ::testing::Return; | 16 using ::testing::Return; |
17 | 17 |
18 // Needs to be global since log assert handlers can't maintain state. | 18 // Needs to be global since log assert handlers can't maintain state. |
19 int log_sink_call_count = 0; | 19 int log_sink_call_count = 0; |
20 | 20 |
21 #if !defined(OFFICIAL_BUILD) || defined(DCHECK_ALWAYS_ON) || !defined(NDEBUG) | 21 #if !defined(OFFICIAL_BUILD) || defined(DCHECK_ALWAYS_ON) || !defined(NDEBUG) |
22 void LogSink(const std::string& str) { | 22 void LogSink(const std::string& str) { |
23 ++log_sink_call_count; | 23 ++log_sink_call_count; |
24 } | 24 } |
25 #endif | 25 #endif |
26 | 26 |
| 27 template <int N> |
| 28 class ExpectNLogs { |
| 29 public: |
| 30 ExpectNLogs() : previous_log_sing_call_count_(log_sink_call_count) {} |
| 31 virtual ~ExpectNLogs() { |
| 32 EXPECT_EQ(previous_log_sing_call_count_ + N, log_sink_call_count); |
| 33 } |
| 34 |
| 35 private: |
| 36 int n_; |
| 37 int previous_log_sing_call_count_; |
| 38 |
| 39 DISALLOW_COPY_AND_ASSIGN(ExpectNLogs); |
| 40 }; |
| 41 |
| 42 using ExpectNoLogs = ExpectNLogs<0>; |
| 43 using ExpectOneLog = ExpectNLogs<1>; |
| 44 using ExpectOneLogIfDCheckIsOn = ExpectNLogs<DCHECK_IS_ON() ? 1 : 0>; |
| 45 |
| 46 class NeverEvaluated { |
| 47 public: |
| 48 NeverEvaluated() {} |
| 49 virtual ~NeverEvaluated() {} |
| 50 operator bool() { |
| 51 LOG(FATAL) << "Unexpectedly evaluated."; |
| 52 return false; |
| 53 }; |
| 54 |
| 55 private: |
| 56 DISALLOW_COPY_AND_ASSIGN(NeverEvaluated); |
| 57 }; |
| 58 |
| 59 class EvaluatedOnce { |
| 60 public: |
| 61 explicit EvaluatedOnce(bool value) : value_(value) {} |
| 62 virtual ~EvaluatedOnce() { |
| 63 LOG_IF(FATAL, evaluations_ != 1) |
| 64 << "Expected to be evaluated exactly once."; |
| 65 } |
| 66 |
| 67 operator bool() { |
| 68 LOG_IF(FATAL, evaluations_ > 0) |
| 69 << "Unexpectedly evaluated more than once."; |
| 70 ++evaluations_; |
| 71 return value_; |
| 72 }; |
| 73 |
| 74 private: |
| 75 bool value_; |
| 76 int evaluations_ = 0; |
| 77 DISALLOW_COPY_AND_ASSIGN(EvaluatedOnce); |
| 78 }; |
| 79 |
| 80 #if DCHECK_IS_ON() |
| 81 class EvaluatedOnceIfDCheckIsOn : public EvaluatedOnce { |
| 82 public: |
| 83 EvaluatedOnceIfDCheckIsOn(bool value) : EvaluatedOnce(value) {} |
| 84 #else |
| 85 class EvaluatedOnceIfDCheckIsOn : public NeverEvaluated { |
| 86 public: |
| 87 EvaluatedOnceIfDCheckIsOn(bool /* value */) {} |
| 88 #endif // DCHECK_IS_ON |
| 89 ~EvaluatedOnceIfDCheckIsOn() override {} |
| 90 |
| 91 private: |
| 92 DISALLOW_COPY_AND_ASSIGN(EvaluatedOnceIfDCheckIsOn); |
| 93 }; |
| 94 |
27 // Class to make sure any manipulations we do to the min log level are | 95 // Class to make sure any manipulations we do to the min log level are |
28 // contained (i.e., do not affect other unit tests). | 96 // contained (i.e., do not affect other unit tests). |
29 class LogStateSaver { | 97 class LogStateSaver { |
30 public: | 98 public: |
31 LogStateSaver() : old_min_log_level_(GetMinLogLevel()) {} | 99 LogStateSaver() : old_min_log_level_(GetMinLogLevel()) {} |
32 | 100 |
33 ~LogStateSaver() { | 101 ~LogStateSaver() { |
34 SetMinLogLevel(old_min_log_level_); | 102 SetMinLogLevel(old_min_log_level_); |
35 SetLogAssertHandler(NULL); | 103 SetLogAssertHandler(NULL); |
36 log_sink_call_count = 0; | 104 log_sink_call_count = 0; |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
227 | 295 |
228 TEST_F(LoggingTest, DcheckReleaseBehavior) { | 296 TEST_F(LoggingTest, DcheckReleaseBehavior) { |
229 int some_variable = 1; | 297 int some_variable = 1; |
230 // These should still reference |some_variable| so we don't get | 298 // These should still reference |some_variable| so we don't get |
231 // unused variable warnings. | 299 // unused variable warnings. |
232 DCHECK(some_variable) << "test"; | 300 DCHECK(some_variable) << "test"; |
233 DPCHECK(some_variable) << "test"; | 301 DPCHECK(some_variable) << "test"; |
234 DCHECK_EQ(some_variable, 1) << "test"; | 302 DCHECK_EQ(some_variable, 1) << "test"; |
235 } | 303 } |
236 | 304 |
| 305 // Test that DCHECK acts as a single statement in variety of syntactice |
| 306 // situations. |
| 307 TEST_F(LoggingTest, DCheckStatements) { |
| 308 SetLogAssertHandler(&LogSink); |
| 309 |
| 310 { |
| 311 EvaluatedOnceIfDCheckIsOn bool_expr(true); |
| 312 NeverEvaluated bool_expr_unreached; |
| 313 ExpectNoLogs expect_no_logs; |
| 314 if (false) |
| 315 DCHECK(bool_expr_unreached); |
| 316 else |
| 317 DCHECK(bool_expr); |
| 318 } |
| 319 |
| 320 { |
| 321 EvaluatedOnceIfDCheckIsOn bool_expr(true); |
| 322 NeverEvaluated bool_expr_unreached; |
| 323 ExpectNoLogs expect_no_logs; |
| 324 if (true) |
| 325 DCHECK(bool_expr); |
| 326 else |
| 327 DCHECK(bool_expr_unreached); |
| 328 } |
| 329 |
| 330 { |
| 331 EvaluatedOnceIfDCheckIsOn bool_expr(true); |
| 332 NeverEvaluated bool_expr_unreached; |
| 333 ExpectNoLogs expect_no_logs; |
| 334 switch (2) { |
| 335 case 1: |
| 336 DCHECK(bool_expr_unreached); |
| 337 case 2: |
| 338 DCHECK(bool_expr); |
| 339 default: |
| 340 break; |
| 341 } |
| 342 } |
| 343 |
| 344 // Cases with failing checks. |
| 345 { |
| 346 EvaluatedOnceIfDCheckIsOn bool_expr_false(false); |
| 347 NeverEvaluated bool_expr_unreached; |
| 348 ExpectOneLogIfDCheckIsOn expect_one_dlog; |
| 349 if (false) |
| 350 DCHECK(bool_expr_unreached); |
| 351 else |
| 352 DCHECK(bool_expr_false); |
| 353 } |
| 354 |
| 355 { |
| 356 EvaluatedOnceIfDCheckIsOn bool_expr_false(false); |
| 357 NeverEvaluated bool_expr_unreached; |
| 358 ExpectOneLogIfDCheckIsOn expect_one_dlog; |
| 359 if (true) |
| 360 DCHECK(bool_expr_false); |
| 361 else |
| 362 DCHECK(bool_expr_unreached); |
| 363 } |
| 364 |
| 365 { |
| 366 EvaluatedOnceIfDCheckIsOn bool_expr_false(false); |
| 367 NeverEvaluated bool_expr_unreached; |
| 368 ExpectOneLogIfDCheckIsOn expect_one_dlog; |
| 369 switch (2) { |
| 370 case 1: |
| 371 DCHECK(bool_expr_unreached); |
| 372 case 2: |
| 373 DCHECK(bool_expr_false); |
| 374 default: |
| 375 break; |
| 376 } |
| 377 } |
| 378 } |
| 379 |
| 380 TEST_F(LoggingTest, CheckStatements) { |
| 381 SetLogAssertHandler(&LogSink); |
| 382 |
| 383 EXPECT_EQ(0, log_sink_call_count); |
| 384 |
| 385 bool reached = false; |
| 386 if (false) |
| 387 CHECK(false); |
| 388 else |
| 389 CHECK(reached = true); |
| 390 ASSERT_TRUE(reached); |
| 391 |
| 392 reached = false; |
| 393 if (true) |
| 394 CHECK(reached = true); |
| 395 else |
| 396 CHECK(false); |
| 397 ASSERT_TRUE(reached); |
| 398 |
| 399 reached = false; |
| 400 switch (2) { |
| 401 case 1: |
| 402 CHECK(false); |
| 403 case 2: |
| 404 CHECK(reached=true); |
| 405 default: |
| 406 break; |
| 407 } |
| 408 ASSERT_TRUE(reached); |
| 409 |
| 410 // Cases with failing checks. |
| 411 EXPECT_EQ(0, log_sink_call_count); |
| 412 |
| 413 reached = false; |
| 414 if (false) |
| 415 CHECK(reached = true); |
| 416 else |
| 417 CHECK(false); |
| 418 ASSERT_FALSE(reached); |
| 419 ASSERT_EQ(1, log_sink_call_count); |
| 420 |
| 421 reached = false; |
| 422 if (true) |
| 423 CHECK(false); |
| 424 else |
| 425 CHECK(reached = true); |
| 426 ASSERT_FALSE(reached); |
| 427 ASSERT_EQ(2, log_sink_call_count); |
| 428 |
| 429 reached = false; |
| 430 switch (2) { |
| 431 case 1: |
| 432 CHECK(reached = true); |
| 433 case 2: |
| 434 CHECK(false); |
| 435 default: |
| 436 break; |
| 437 } |
| 438 ASSERT_FALSE(reached); |
| 439 ASSERT_EQ(3, log_sink_call_count); |
| 440 } |
| 441 |
| 442 TEST_F(LoggingTest, DCheckEqStatements) { |
| 443 SetLogAssertHandler(&LogSink); |
| 444 |
| 445 EXPECT_EQ(0, log_sink_call_count); |
| 446 |
| 447 bool reached = false; |
| 448 if (false) |
| 449 DCHECK_EQ(false, true); |
| 450 else |
| 451 DCHECK_EQ(true, reached = true); |
| 452 ASSERT_EQ(DCHECK_IS_ON(), reached); |
| 453 |
| 454 reached = false; |
| 455 if (true) |
| 456 DCHECK_EQ(true, reached = true); |
| 457 else |
| 458 DCHECK_EQ(false, true); |
| 459 ASSERT_EQ(DCHECK_IS_ON(), reached); |
| 460 |
| 461 reached = false; |
| 462 switch (2) { |
| 463 case 1: |
| 464 DCHECK_EQ(false, true); |
| 465 case 2: |
| 466 DCHECK_EQ(true, reached=true); |
| 467 default: |
| 468 break; |
| 469 } |
| 470 ASSERT_EQ(DCHECK_IS_ON(), reached); |
| 471 |
| 472 // Cases with failing checks. |
| 473 EXPECT_EQ(0, log_sink_call_count); |
| 474 |
| 475 reached = false; |
| 476 if (false) |
| 477 DCHECK_EQ(true, reached = true); |
| 478 else |
| 479 DCHECK_EQ(false, true); |
| 480 ASSERT_FALSE(reached); |
| 481 ASSERT_EQ(DCHECK_IS_ON() ? 1 : 0, log_sink_call_count); |
| 482 |
| 483 reached = false; |
| 484 if (true) |
| 485 DCHECK_EQ(false, true); |
| 486 else |
| 487 DCHECK_EQ(true, reached = true); |
| 488 ASSERT_FALSE(reached); |
| 489 ASSERT_EQ(DCHECK_IS_ON() ? 2 : 0, log_sink_call_count); |
| 490 |
| 491 reached = false; |
| 492 switch (2) { |
| 493 case 1: |
| 494 DCHECK_EQ(true, reached = true); |
| 495 case 2: |
| 496 DCHECK_EQ(false, true); |
| 497 default: |
| 498 break; |
| 499 } |
| 500 ASSERT_FALSE(reached); |
| 501 ASSERT_EQ(DCHECK_IS_ON() ? 3 : 0, log_sink_call_count); |
| 502 |
| 503 reached = false; |
| 504 if (false) |
| 505 DCHECK_EQ(false, reached = true); |
| 506 ASSERT_FALSE(reached); |
| 507 ASSERT_EQ(DCHECK_IS_ON() ? 3 : 0, log_sink_call_count); |
| 508 } |
| 509 |
| 510 TEST_F(LoggingTest, CheckEqStatements) { |
| 511 SetLogAssertHandler(&LogSink); |
| 512 |
| 513 EXPECT_EQ(0, log_sink_call_count); |
| 514 |
| 515 bool reached = false; |
| 516 if (false) |
| 517 CHECK_EQ(false, true); |
| 518 else |
| 519 CHECK_EQ(true, reached = true); |
| 520 ASSERT_TRUE(reached); |
| 521 |
| 522 reached = false; |
| 523 if (true) |
| 524 CHECK_EQ(true, reached = true); |
| 525 else |
| 526 CHECK_EQ(false, true); |
| 527 ASSERT_TRUE(reached); |
| 528 |
| 529 reached = false; |
| 530 switch (2) { |
| 531 case 1: |
| 532 CHECK_EQ(false, true); |
| 533 case 2: |
| 534 CHECK_EQ(true, reached = true); |
| 535 default: |
| 536 break; |
| 537 } |
| 538 ASSERT_TRUE(reached); |
| 539 |
| 540 // Cases with failing checks. |
| 541 EXPECT_EQ(0, log_sink_call_count); |
| 542 |
| 543 reached = false; |
| 544 if (false) |
| 545 CHECK_EQ(true, reached = true); |
| 546 else |
| 547 CHECK_EQ(false, true); |
| 548 ASSERT_FALSE(reached); |
| 549 ASSERT_EQ(1, log_sink_call_count); |
| 550 |
| 551 reached = false; |
| 552 if (true) |
| 553 CHECK_EQ(false, true); |
| 554 else |
| 555 CHECK_EQ(true, reached = true); |
| 556 ASSERT_FALSE(reached); |
| 557 ASSERT_EQ(2, log_sink_call_count); |
| 558 |
| 559 reached = false; |
| 560 switch (2) { |
| 561 case 1: |
| 562 CHECK_EQ(true, reached = true); |
| 563 case 2: |
| 564 CHECK_EQ(false, true); |
| 565 default: |
| 566 break; |
| 567 } |
| 568 ASSERT_FALSE(reached); |
| 569 ASSERT_EQ(3, log_sink_call_count); |
| 570 |
| 571 reached = false; |
| 572 if (false) |
| 573 CHECK_EQ(false, reached = true); |
| 574 ASSERT_FALSE(reached); |
| 575 ASSERT_EQ(3, log_sink_call_count); |
| 576 } |
| 577 |
| 578 TEST_F(LoggingTest, LogStatements) { |
| 579 bool reached = false; |
| 580 if (true) |
| 581 LOG(INFO) << "Hello: " << (reached = true); |
| 582 else |
| 583 LOG(FATAL) << "Goodbye."; |
| 584 ASSERT_TRUE(reached); |
| 585 |
| 586 reached = false; |
| 587 if (false) |
| 588 LOG(FATAL) << "Goodbye."; |
| 589 else |
| 590 LOG(INFO) << "Hello: " << (reached = true); |
| 591 ASSERT_TRUE(reached); |
| 592 |
| 593 reached = false; |
| 594 if (true) |
| 595 LOG_IF(INFO, reached = true) << "Hello."; |
| 596 else |
| 597 LOG_IF(FATAL, true) << "Goodbye."; |
| 598 ASSERT_TRUE(reached); |
| 599 |
| 600 reached = false; |
| 601 if (false) |
| 602 LOG_IF(FATAL, true) << "Goodbye."; |
| 603 else |
| 604 LOG_IF(INFO, reached = true) << "Hello."; |
| 605 ASSERT_TRUE(reached); |
| 606 |
| 607 reached = false; |
| 608 if (false) |
| 609 LOG_IF(FATAL, true) << "Goodbye."; |
| 610 else |
| 611 LOG_IF(INFO, false) << "Derp: " << (reached = true); |
| 612 ASSERT_FALSE(reached); |
| 613 |
| 614 reached = false; |
| 615 if (false) |
| 616 LOG_IF(FATAL, reached = true) << "Goodbye."; |
| 617 ASSERT_FALSE(reached); |
| 618 |
| 619 reached = false; |
| 620 if (true) |
| 621 DLOG(INFO) << "Hello: " << (reached = true); |
| 622 else |
| 623 DLOG(FATAL) << "Goodbye."; |
| 624 ASSERT_EQ(DLOG_IS_ON(INFO), reached); |
| 625 |
| 626 reached = false; |
| 627 if (false) |
| 628 DLOG(FATAL) << "Goodbye."; |
| 629 else |
| 630 DLOG(INFO) << "Hello: " << (reached = true); |
| 631 ASSERT_EQ(DLOG_IS_ON(INFO), reached); |
| 632 |
| 633 reached = false; |
| 634 if (true) |
| 635 DLOG_IF(INFO, true) << "Hello: " << (reached = true); |
| 636 else |
| 637 DLOG_IF(FATAL, true) << "Goodbye."; |
| 638 ASSERT_EQ(DLOG_IS_ON(INFO), reached); |
| 639 |
| 640 reached = false; |
| 641 if (false) |
| 642 DLOG_IF(FATAL, true) << "Goodbye."; |
| 643 else |
| 644 DLOG_IF(INFO, true) << "Hello: " << (reached = true); |
| 645 ASSERT_EQ(DLOG_IS_ON(INFO), reached); |
| 646 |
| 647 reached = false; |
| 648 if (false) |
| 649 DLOG_IF(FATAL, true) << "Goodbye."; |
| 650 else |
| 651 DLOG_IF(INFO, false) << "Derp: " << (reached = true); |
| 652 ASSERT_FALSE(reached); |
| 653 |
| 654 reached = false; |
| 655 if (false) |
| 656 DLOG_IF(FATAL, reached = true) << "Goodbye."; |
| 657 ASSERT_FALSE(reached); |
| 658 } |
| 659 |
237 // Test that defining an operator<< for a type in a namespace doesn't prevent | 660 // Test that defining an operator<< for a type in a namespace doesn't prevent |
238 // other code in that namespace from calling the operator<<(ostream, wstring) | 661 // other code in that namespace from calling the operator<<(ostream, wstring) |
239 // defined by logging.h. This can fail if operator<<(ostream, wstring) can't be | 662 // defined by logging.h. This can fail if operator<<(ostream, wstring) can't be |
240 // found by ADL, since defining another operator<< prevents name lookup from | 663 // found by ADL, since defining another operator<< prevents name lookup from |
241 // looking in the global namespace. | 664 // looking in the global namespace. |
242 namespace nested_test { | 665 namespace nested_test { |
243 class Streamable {}; | 666 class Streamable {}; |
244 ALLOW_UNUSED_TYPE std::ostream& operator<<(std::ostream& out, | 667 ALLOW_UNUSED_TYPE std::ostream& operator<<(std::ostream& out, |
245 const Streamable&) { | 668 const Streamable&) { |
246 return out << "Streamable"; | 669 return out << "Streamable"; |
247 } | 670 } |
248 TEST_F(LoggingTest, StreamingWstringFindsCorrectOperator) { | 671 TEST_F(LoggingTest, StreamingWstringFindsCorrectOperator) { |
249 std::wstring wstr = L"Hello World"; | 672 std::wstring wstr = L"Hello World"; |
250 std::ostringstream ostr; | 673 std::ostringstream ostr; |
251 ostr << wstr; | 674 ostr << wstr; |
252 EXPECT_EQ("Hello World", ostr.str()); | 675 EXPECT_EQ("Hello World", ostr.str()); |
253 } | 676 } |
254 } // namespace nested_test | 677 } // namespace nested_test |
255 | 678 |
256 } // namespace | 679 } // namespace |
257 | 680 |
258 } // namespace logging | 681 } // namespace logging |
OLD | NEW |