From 37504994338c114247519331237831f88a9a7c40 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Fri, 6 Feb 2009 00:47:20 +0000 Subject: [PATCH] Adds tests for EXPECT_FATAL_FAILURE and reduces the golden file bloat (by Zhanyong Wan). Fixes more warnings on Windows (by Vlad Losev). --- include/gtest/internal/gtest-internal.h | 16 +++-- src/gtest.cc | 16 +++++ test/gtest_output_test.py | 9 ++- test/gtest_output_test_.cc | 12 ++++ test/gtest_output_test_golden_lin.txt | 43 +----------- test/gtest_output_test_golden_win.txt | 33 ---------- test/gtest_unittest.cc | 88 ++++++++++++++++++++----- 7 files changed, 119 insertions(+), 98 deletions(-) diff --git a/include/gtest/internal/gtest-internal.h b/include/gtest/internal/gtest-internal.h index 541c89b8..b28da96e 100644 --- a/include/gtest/internal/gtest-internal.h +++ b/include/gtest/internal/gtest-internal.h @@ -749,7 +749,7 @@ String GetCurrentOsStackTraceExceptTop(UnitTest* unit_test, int skip_count); int GetFailedPartCount(const TestResult* result); // A helper for suppressing warnings on unreachable code in some macros. -inline bool True() { return true; } +bool AlwaysTrue(); } // namespace internal } // namespace testing @@ -767,12 +767,18 @@ inline bool True() { return true; } #define GTEST_SUCCESS_(message) \ GTEST_MESSAGE_(message, ::testing::TPRT_SUCCESS) +// Suppresses MSVC warnings 4072 (unreachable code) for the code following +// statement if it returns or throws (or doesn't return or throw in some +// situations). +#define GTEST_HIDE_UNREACHABLE_CODE_(statement) \ + if (::testing::internal::AlwaysTrue()) { statement; } + #define GTEST_TEST_THROW_(statement, expected_exception, fail) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (const char* gtest_msg = "") { \ bool gtest_caught_expected = false; \ try { \ - statement; \ + GTEST_HIDE_UNREACHABLE_CODE_(statement); \ } \ catch (expected_exception const&) { \ gtest_caught_expected = true; \ @@ -796,7 +802,7 @@ inline bool True() { return true; } GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (const char* gtest_msg = "") { \ try { \ - statement; \ + GTEST_HIDE_UNREACHABLE_CODE_(statement); \ } \ catch (...) { \ gtest_msg = "Expected: " #statement " doesn't throw an exception.\n" \ @@ -812,7 +818,7 @@ inline bool True() { return true; } if (const char* gtest_msg = "") { \ bool gtest_caught_any = false; \ try { \ - statement; \ + GTEST_HIDE_UNREACHABLE_CODE_(statement); \ } \ catch (...) { \ gtest_caught_any = true; \ @@ -838,7 +844,7 @@ inline bool True() { return true; } GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (const char* gtest_msg = "") { \ ::testing::internal::HasNewFatalFailureHelper gtest_fatal_failure_checker; \ - if (::testing::internal::True()) { statement; } \ + GTEST_HIDE_UNREACHABLE_CODE_(statement); \ if (gtest_fatal_failure_checker.has_new_fatal_failure()) { \ gtest_msg = "Expected: " #statement " doesn't generate new fatal " \ "failures in the current thread.\n" \ diff --git a/src/gtest.cc b/src/gtest.cc index 26077673..8e8238a9 100644 --- a/src/gtest.cc +++ b/src/gtest.cc @@ -3771,6 +3771,22 @@ int GetFailedPartCount(const TestResult* result) { return result->failed_part_count(); } +// Used by the GTEST_HIDE_UNREACHABLE_CODE_ macro to suppress unreachable +// code warnings. +namespace { +class ClassUniqueToAlwaysTrue {}; +} + +bool AlwaysTrue() { +#if GTEST_HAS_EXCEPTIONS + // This condition is always false so AlwaysTrue() never actually throws, + // but it makes the compiler think that it may throw. + if (atoi("42") == 36) // NOLINT + throw ClassUniqueToAlwaysTrue(); +#endif // GTEST_HAS_EXCEPTIONS + return true; +} + // Parses a string as a command line flag. The string should have // the format "--flag=value". When def_optional is true, the "=value" // part can be omitted. diff --git a/test/gtest_output_test.py b/test/gtest_output_test.py index 42cf00c4..9aaade2e 100755 --- a/test/gtest_output_test.py +++ b/test/gtest_output_test.py @@ -61,11 +61,16 @@ else: GOLDEN_NAME = 'gtest_output_test_golden_lin.txt' PROGRAM_PATH = os.path.join(gtest_test_utils.GetBuildDir(), PROGRAM) + +# At least one command we exercise must not have the +# --gtest_internal_skip_environment_and_ad_hoc_tests flag. COMMAND_WITH_COLOR = PROGRAM_PATH + ' --gtest_color=yes' COMMAND_WITH_TIME = (PROGRAM_PATH + ' --gtest_print_time ' - + '--gtest_filter="FatalFailureTest.*:LoggingTest.*"') + '--gtest_internal_skip_environment_and_ad_hoc_tests ' + '--gtest_filter="FatalFailureTest.*:LoggingTest.*"') COMMAND_WITH_DISABLED = (PROGRAM_PATH + ' --gtest_also_run_disabled_tests ' - + '--gtest_filter="*DISABLED_*"') + '--gtest_internal_skip_environment_and_ad_hoc_tests ' + '--gtest_filter="*DISABLED_*"') GOLDEN_PATH = os.path.join(gtest_test_utils.GetSourceDir(), GOLDEN_NAME) diff --git a/test/gtest_output_test_.cc b/test/gtest_output_test_.cc index 31a0672f..5c76609f 100644 --- a/test/gtest_output_test_.cc +++ b/test/gtest_output_test_.cc @@ -60,6 +60,8 @@ using testing::ScopedFakeTestPartResultReporter; using testing::TestPartResultArray; +using testing::internal::String; + // Tests catching fatal failures. // A subroutine used by the following test. @@ -958,6 +960,10 @@ class BarEnvironment : public testing::Environment { } }; +GTEST_DEFINE_bool_(internal_skip_environment_and_ad_hoc_tests, false, + "This flag causes the program to skip test environment " + "tests and ad hoc tests."); + // The main function. // // The idea is to use Google Test to run all the tests we have defined (some @@ -968,6 +974,9 @@ int main(int argc, char **argv) { // We will use a separate Python script to compare the output of // this program with the golden file. testing::InitGoogleTest(&argc, argv); + if (argc >= 2 && + String(argv[1]) == "--gtest_internal_skip_environment_and_ad_hoc_tests") + GTEST_FLAG(internal_skip_environment_and_ad_hoc_tests) = true; #ifdef GTEST_HAS_DEATH_TEST if (testing::internal::GTEST_FLAG(internal_run_death_test) != "") { @@ -978,6 +987,9 @@ int main(int argc, char **argv) { } #endif // GTEST_HAS_DEATH_TEST + if (GTEST_FLAG(internal_skip_environment_and_ad_hoc_tests)) + return RUN_ALL_TESTS(); + // Registers two global test environments. // The golden file verifies that they are set up in the order they // are registered, and torn down in the reverse order. diff --git a/test/gtest_output_test_golden_lin.txt b/test/gtest_output_test_golden_lin.txt index 0a7efca9..ace88d07 100644 --- a/test/gtest_output_test_golden_lin.txt +++ b/test/gtest_output_test_golden_lin.txt @@ -536,20 +536,9 @@ Expected fatal failure. 33 FAILED TESTS  YOU HAVE 1 DISABLED TEST -The non-test part of the code is expected to have 2 failures. - -gtest_output_test_.cc:#: Failure -Value of: false - Actual: false -Expected: true -gtest_output_test_.cc:#: Failure -Value of: 3 -Expected: 2 -Note: Google Test filter = FatalFailureTest.*:LoggingTest.* +Note: Google Test filter = FatalFailureTest.*:LoggingTest.* [==========] Running 4 tests from 2 test cases. [----------] Global test environment set-up. -FooEnvironment::SetUp() called. -BarEnvironment::SetUp() called. [----------] 3 tests from FatalFailureTest [ RUN ] FatalFailureTest.FatalFailureInSubroutine (expecting a failure that x should be 1) @@ -589,14 +578,6 @@ Expected: (3) >= (a[i]), actual: 3 vs 6 [----------] 1 test from LoggingTest (? ms total) [----------] Global test environment tear-down -BarEnvironment::TearDown() called. -gtest_output_test_.cc:#: Failure -Failed -Expected non-fatal failure. -FooEnvironment::TearDown() called. -gtest_output_test_.cc:#: Failure -Failed -Expected fatal failure. [==========] 4 tests from 2 test cases ran. (? ms total) [ PASSED ] 0 tests. [ FAILED ] 4 tests, listed below: @@ -608,34 +589,12 @@ Expected fatal failure. 4 FAILED TESTS YOU HAVE 1 DISABLED TEST -The non-test part of the code is expected to have 2 failures. - -gtest_output_test_.cc:#: Failure -Value of: false - Actual: false -Expected: true -gtest_output_test_.cc:#: Failure -Value of: 3 -Expected: 2 Note: Google Test filter = *DISABLED_* [==========] Running 1 test from 1 test case. [----------] Global test environment set-up. -FooEnvironment::SetUp() called. -BarEnvironment::SetUp() called. [----------] 1 test from DisabledTestsWarningTest [ RUN ] DisabledTestsWarningTest.DISABLED_AlsoRunDisabledTestsFlagSuppressesWarning [ OK ] DisabledTestsWarningTest.DISABLED_AlsoRunDisabledTestsFlagSuppressesWarning [----------] Global test environment tear-down -BarEnvironment::TearDown() called. -gtest_output_test_.cc:#: Failure -Failed -Expected non-fatal failure. -FooEnvironment::TearDown() called. -gtest_output_test_.cc:#: Failure -Failed -Expected fatal failure. [==========] 1 test from 1 test case ran. [ PASSED ] 1 test. -[ FAILED ] 0 tests, listed below: - - 0 FAILED TESTS diff --git a/test/gtest_output_test_golden_win.txt b/test/gtest_output_test_golden_win.txt index 6fe87610..17be5c04 100644 --- a/test/gtest_output_test_golden_win.txt +++ b/test/gtest_output_test_golden_win.txt @@ -483,18 +483,9 @@ Expected fatal failure. 36 FAILED TESTS YOU HAVE 1 DISABLED TEST -The non-test part of the code is expected to have 2 failures. - -gtest_output_test_.cc:#: error: Value of: false - Actual: false -Expected: true -gtest_output_test_.cc:#: error: Value of: 3 -Expected: 2 Note: Google Test filter = FatalFailureTest.*:LoggingTest.* [==========] Running 4 tests from 2 test cases. [----------] Global test environment set-up. -FooEnvironment::SetUp() called. -BarEnvironment::SetUp() called. [----------] 3 tests from FatalFailureTest [ RUN ] FatalFailureTest.FatalFailureInSubroutine (expecting a failure that x should be 1) @@ -529,12 +520,6 @@ gtest_output_test_.cc:#: error: Expected: (3) >= (a[i]), actual: 3 vs 6 [----------] 1 test from LoggingTest (? ms total) [----------] Global test environment tear-down -BarEnvironment::TearDown() called. -gtest_output_test_.cc:#: error: Failed -Expected non-fatal failure. -FooEnvironment::TearDown() called. -gtest_output_test_.cc:#: error: Failed -Expected fatal failure. [==========] 4 tests from 2 test cases ran. (? ms total) [ PASSED ] 0 tests. [ FAILED ] 4 tests, listed below: @@ -546,30 +531,12 @@ Expected fatal failure. 4 FAILED TESTS YOU HAVE 1 DISABLED TEST -The non-test part of the code is expected to have 2 failures. - -gtest_output_test_.cc:#: error: Value of: false - Actual: false -Expected: true -gtest_output_test_.cc:#: error: Value of: 3 -Expected: 2 Note: Google Test filter = *DISABLED_* [==========] Running 1 test from 1 test case. [----------] Global test environment set-up. -FooEnvironment::SetUp() called. -BarEnvironment::SetUp() called. [----------] 1 test from DisabledTestsWarningTest [ RUN ] DisabledTestsWarningTest.DISABLED_AlsoRunDisabledTestsFlagSuppressesWarning [ OK ] DisabledTestsWarningTest.DISABLED_AlsoRunDisabledTestsFlagSuppressesWarning [----------] Global test environment tear-down -BarEnvironment::TearDown() called. -gtest_output_test_.cc:#: error: Failed -Expected non-fatal failure. -FooEnvironment::TearDown() called. -gtest_output_test_.cc:#: error: Failed -Expected fatal failure. [==========] 1 test from 1 test case ran. [ PASSED ] 1 test. -[ FAILED ] 0 tests, listed below: - - 0 FAILED TESTS diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index 847502c7..faf01a38 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -869,37 +869,58 @@ TEST_F(ScopedFakeTestPartResultReporterWithThreadsTest, #endif // GTEST_IS_THREADSAFE && GTEST_HAS_PTHREAD -// Tests EXPECT_{,NON}FATAL_FAILURE{,ON_ALL_THREADS}. +// Tests EXPECT_FATAL_FAILURE{,ON_ALL_THREADS}. -typedef ScopedFakeTestPartResultReporterTest ExpectFailureTest; +typedef ScopedFakeTestPartResultReporterTest ExpectFatalFailureTest; -TEST_F(ExpectFailureTest, ExpectFatalFaliure) { +TEST_F(ExpectFatalFailureTest, CatchesFatalFaliure) { EXPECT_FATAL_FAILURE(AddFailure(FATAL_FAILURE), "Expected fatal failure."); } -TEST_F(ExpectFailureTest, ExpectNonFatalFailure) { - EXPECT_NONFATAL_FAILURE(AddFailure(NONFATAL_FAILURE), - "Expected non-fatal failure."); -} - -TEST_F(ExpectFailureTest, ExpectFatalFailureOnAllThreads) { +TEST_F(ExpectFatalFailureTest, CatchesFatalFailureOnAllThreads) { + // We have another test below to verify that the macro catches fatal + // failures generated on another thread. EXPECT_FATAL_FAILURE_ON_ALL_THREADS(AddFailure(FATAL_FAILURE), "Expected fatal failure."); } -TEST_F(ExpectFailureTest, ExpectNonFatalFailureOnAllThreads) { - EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(AddFailure(NONFATAL_FAILURE), - "Expected non-fatal failure."); +// Tests that EXPECT_FATAL_FAILURE() can be used in a non-void +// function even when the statement in it contains ASSERT_*. + +int NonVoidFunction() { + EXPECT_FATAL_FAILURE(ASSERT_TRUE(false), ""); + EXPECT_FATAL_FAILURE_ON_ALL_THREADS(FAIL(), ""); + return 0; } -// Tests that the EXPECT_{,NON}FATAL_FAILURE{,_ON_ALL_THREADS} accepts -// a statement that contains a macro which expands to code containing -// an unprotected comma. +TEST_F(ExpectFatalFailureTest, CanBeUsedInNonVoidFunction) { + NonVoidFunction(); +} + +// Tests that EXPECT_FATAL_FAILURE(statement, ...) doesn't abort the +// current function even though 'statement' generates a fatal failure. + +void DoesNotAbortHelper(bool* aborted) { + EXPECT_FATAL_FAILURE(ASSERT_TRUE(false), ""); + EXPECT_FATAL_FAILURE_ON_ALL_THREADS(FAIL(), ""); + + *aborted = false; +} + +TEST_F(ExpectFatalFailureTest, DoesNotAbort) { + bool aborted = true; + DoesNotAbortHelper(&aborted); + EXPECT_FALSE(aborted); +} + +// Tests that the EXPECT_FATAL_FAILURE{,_ON_ALL_THREADS} accepts a +// statement that contains a macro which expands to code containing an +// unprotected comma. static int global_var = 0; #define GTEST_USE_UNPROTECTED_COMMA_ global_var++, global_var++ -TEST_F(ExpectFailureTest, AcceptsMacroThatExpandsToUnprotectedComma) { +TEST_F(ExpectFatalFailureTest, AcceptsMacroThatExpandsToUnprotectedComma) { EXPECT_FATAL_FAILURE({ GTEST_USE_UNPROTECTED_COMMA_; AddFailure(FATAL_FAILURE); @@ -909,7 +930,28 @@ TEST_F(ExpectFailureTest, AcceptsMacroThatExpandsToUnprotectedComma) { GTEST_USE_UNPROTECTED_COMMA_; AddFailure(FATAL_FAILURE); }, ""); +} +// Tests EXPECT_NONFATAL_FAILURE{,ON_ALL_THREADS}. + +typedef ScopedFakeTestPartResultReporterTest ExpectNonfatalFailureTest; + +TEST_F(ExpectNonfatalFailureTest, CatchesNonfatalFailure) { + EXPECT_NONFATAL_FAILURE(AddFailure(NONFATAL_FAILURE), + "Expected non-fatal failure."); +} + +TEST_F(ExpectNonfatalFailureTest, CatchesNonfatalFailureOnAllThreads) { + // We have another test below to verify that the macro catches + // non-fatal failures generated on another thread. + EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(AddFailure(NONFATAL_FAILURE), + "Expected non-fatal failure."); +} + +// Tests that the EXPECT_NONFATAL_FAILURE{,_ON_ALL_THREADS} accepts a +// statement that contains a macro which expands to code containing an +// unprotected comma. +TEST_F(ExpectNonfatalFailureTest, AcceptsMacroThatExpandsToUnprotectedComma) { EXPECT_NONFATAL_FAILURE({ GTEST_USE_UNPROTECTED_COMMA_; AddFailure(NONFATAL_FAILURE); @@ -3091,6 +3133,20 @@ TEST(AssertionSyntaxTest, BasicAssertionsBehavesLikeSingleStatement) { } #if GTEST_HAS_EXCEPTIONS +// Tests that the compiler will not complain about unreachable code in the +// EXPECT_THROW/EXPECT_ANY_THROW/EXPECT_NO_THROW macros. +TEST(ExpectThrowTest, DoesNotGenerateUnreachableCodeWarning) { + int n = 0; + + EXPECT_THROW(throw 1, int); + EXPECT_NONFATAL_FAILURE(EXPECT_THROW(n++, int), ""); + EXPECT_NONFATAL_FAILURE(EXPECT_THROW(throw 1, const char*), ""); + EXPECT_NO_THROW(n++); + EXPECT_NONFATAL_FAILURE(EXPECT_NO_THROW(throw 1), ""); + EXPECT_ANY_THROW(throw 1); + EXPECT_NONFATAL_FAILURE(EXPECT_ANY_THROW(n++), ""); +} + TEST(AssertionSyntaxTest, ExceptionAssertionsBehavesLikeSingleStatement) { if (false) EXPECT_THROW(1, bool);