From 40d0ba7a62a8bc749fbaf0747621b0aa10ddf1b9 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Wed, 2 Feb 2011 01:25:37 +0000 Subject: Add markers to death test messages to make them more recogizable (by Jeff Shute). --- src/gtest-death-test.cc | 29 ++++++++++++++++---- test/gtest-death-test_test.cc | 62 ++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 83 insertions(+), 8 deletions(-) diff --git a/src/gtest-death-test.cc b/src/gtest-death-test.cc index 3ab9cf9..3e65193 100644 --- a/src/gtest-death-test.cc +++ b/src/gtest-death-test.cc @@ -438,6 +438,24 @@ void DeathTestImpl::Abort(AbortReason reason) { _exit(1); // Exits w/o any normal exit hooks (we were supposed to crash) } +// Returns an indented copy of stderr output for a death test. +// This makes distinguishing death test output lines from regular log lines +// much easier. +static ::std::string FormatDeathTestOutput(const ::std::string& output) { + ::std::string ret; + for (size_t at = 0; ; ) { + const size_t line_end = output.find('\n', at); + ret += "[ DEATH ] "; + if (line_end == ::std::string::npos) { + ret += output.substr(at); + break; + } + ret += output.substr(at, line_end + 1 - at); + at = line_end + 1; + } + return ret; +} + // Assesses the success or failure of a death test, using both private // members which have previously been set, and one argument: // @@ -473,15 +491,15 @@ bool DeathTestImpl::Passed(bool status_ok) { switch (outcome()) { case LIVED: buffer << " Result: failed to die.\n" - << " Error msg: " << error_message; + << " Error msg:\n" << FormatDeathTestOutput(error_message); break; case THREW: buffer << " Result: threw an exception.\n" - << " Error msg: " << error_message; + << " Error msg:\n" << FormatDeathTestOutput(error_message); break; case RETURNED: buffer << " Result: illegal return in test statement.\n" - << " Error msg: " << error_message; + << " Error msg:\n" << FormatDeathTestOutput(error_message); break; case DIED: if (status_ok) { @@ -491,11 +509,12 @@ bool DeathTestImpl::Passed(bool status_ok) { } else { buffer << " Result: died but not with expected error.\n" << " Expected: " << regex()->pattern() << "\n" - << "Actual msg: " << error_message; + << "Actual msg:\n" << FormatDeathTestOutput(error_message); } } else { buffer << " Result: died but not with expected exit code:\n" - << " " << ExitSummary(status()) << "\n"; + << " " << ExitSummary(status()) << "\n" + << "Actual msg:\n" << FormatDeathTestOutput(error_message); } break; case IN_PROGRESS: diff --git a/test/gtest-death-test_test.cc b/test/gtest-death-test_test.cc index b83b0db..6cc017b 100644 --- a/test/gtest-death-test_test.cc +++ b/test/gtest-death-test_test.cc @@ -103,9 +103,10 @@ class ReplaceDeathTestFactory { } // namespace internal } // namespace testing -void DieInside(const char* function) { - fprintf(stderr, "death inside %s().", function); - fflush(stderr); +void DieWithMessage(const ::std::string& message) { + fprintf(stderr, "%s", message.c_str()); + fflush(stderr); // Make sure the text is printed before the process exits. + // We call _exit() instead of exit(), as the former is a direct // system call and thus safer in the presence of threads. exit() // will invoke user-defined exit-hooks, which may do dangerous @@ -118,6 +119,10 @@ void DieInside(const char* function) { _exit(1); } +void DieInside(const ::std::string& function) { + DieWithMessage("death inside " + function + "()."); +} + // Tests that death tests work. class TestForDeathTest : public testing::Test { @@ -686,6 +691,57 @@ TEST_F(TestForDeathTest, InvalidStyle) { }, "This failure is expected."); } +TEST_F(TestForDeathTest, DeathTestFailedOutput) { + testing::GTEST_FLAG(death_test_style) = "fast"; + EXPECT_NONFATAL_FAILURE( + EXPECT_DEATH(DieWithMessage("death\n"), + "expected message"), + "Actual msg:\n" + "[ DEATH ] death\n"); +} + +TEST_F(TestForDeathTest, DeathTestUnexpectedReturnOutput) { + testing::GTEST_FLAG(death_test_style) = "fast"; + EXPECT_NONFATAL_FAILURE( + EXPECT_DEATH({ + fprintf(stderr, "returning\n"); + fflush(stderr); + return; + }, ""), + " Result: illegal return in test statement.\n" + " Error msg:\n" + "[ DEATH ] returning\n"); +} + +TEST_F(TestForDeathTest, DeathTestBadExitCodeOutput) { + testing::GTEST_FLAG(death_test_style) = "fast"; + EXPECT_NONFATAL_FAILURE( + EXPECT_EXIT(DieWithMessage("exiting with rc 1\n"), + testing::ExitedWithCode(3), + "expected message"), + " Result: died but not with expected exit code:\n" + " Exited with exit status 1\n" + "Actual msg:\n" + "[ DEATH ] exiting with rc 1\n"); +} + +TEST_F(TestForDeathTest, DeathTestMultiLineMatchFail) { + testing::GTEST_FLAG(death_test_style) = "fast"; + EXPECT_NONFATAL_FAILURE( + EXPECT_DEATH(DieWithMessage("line 1\nline 2\nline 3\n"), + "line 1\nxyz\nline 3\n"), + "Actual msg:\n" + "[ DEATH ] line 1\n" + "[ DEATH ] line 2\n" + "[ DEATH ] line 3\n"); +} + +TEST_F(TestForDeathTest, DeathTestMultiLineMatchPass) { + testing::GTEST_FLAG(death_test_style) = "fast"; + EXPECT_DEATH(DieWithMessage("line 1\nline 2\nline 3\n"), + "line 1\nline 2\nline 3\n"); +} + // A DeathTestFactory that returns MockDeathTests. class MockDeathTestFactory : public DeathTestFactory { public: -- cgit v0.12