From f46f3eaf059b7b3ca00a3428c594bd477bc1839c Mon Sep 17 00:00:00 2001 From: vladlosev Date: Fri, 28 Oct 2011 16:19:04 +0000 Subject: Adds support for detection of running in death test child processes. git-svn-id: http://googletest.googlecode.com/svn/trunk@606 861a406c-534a-0410-8894-cb66d6ee9925 --- include/gtest/gtest-death-test.h | 11 +++++++++++ src/gtest-death-test.cc | 32 +++++++++++++++++++++++++++++++- test/gtest-death-test_test.cc | 21 +++++++++++++++++++++ 3 files changed, 63 insertions(+), 1 deletion(-) diff --git a/include/gtest/gtest-death-test.h b/include/gtest/gtest-death-test.h index a27883f..16f08b8 100644 --- a/include/gtest/gtest-death-test.h +++ b/include/gtest/gtest-death-test.h @@ -51,6 +51,17 @@ GTEST_DECLARE_string_(death_test_style); #if GTEST_HAS_DEATH_TEST +namespace internal { + +// Returns a Boolean value indicating whether the caller is currently +// executing in the context of the death test child process. Tools such as +// Valgrind heap checkers may need this to modify their behavior in death +// tests. IMPORTANT: This is an internal utility. Using it may break the +// implementation of death tests. User code MUST NOT use it. +GTEST_API_ bool InDeathTestChild(); + +} // namespace internal + // The following macros are useful for writing death tests. // Here's what happens when an ASSERT_DEATH* or EXPECT_DEATH* is diff --git a/src/gtest-death-test.cc b/src/gtest-death-test.cc index 76aa168..0a0f83b 100644 --- a/src/gtest-death-test.cc +++ b/src/gtest-death-test.cc @@ -109,13 +109,42 @@ GTEST_DEFINE_string_( "Indicates the file, line number, temporal index of " "the single death test to run, and a file descriptor to " "which a success code may be sent, all separated by " - "colons. This flag is specified if and only if the current " + "the '|' characters. This flag is specified if and only if the current " "process is a sub-process launched for running a thread-safe " "death test. FOR INTERNAL USE ONLY."); } // namespace internal #if GTEST_HAS_DEATH_TEST +namespace internal { + +// Valid only for fast death tests. Indicates the code is running in the +// child process of a fast style death test. +static bool g_in_fast_death_test_child = false; + +// Returns a Boolean value indicating whether the caller is currently +// executing in the context of the death test child process. Tools such as +// Valgrind heap checkers may need this to modify their behavior in death +// tests. IMPORTANT: This is an internal utility. Using it may break the +// implementation of death tests. User code MUST NOT use it. +bool InDeathTestChild() { +# if GTEST_OS_WINDOWS + + // On Windows, death tests are thread-safe regardless of the value of the + // death_test_style flag. + return !GTEST_FLAG(internal_run_death_test).empty(); + +# else + + if (GTEST_FLAG(death_test_style) == "threadsafe") + return !GTEST_FLAG(internal_run_death_test).empty(); + else + return g_in_fast_death_test_child; +#endif +} + +} // namespace internal + // ExitedWithCode constructor. ExitedWithCode::ExitedWithCode(int exit_code) : exit_code_(exit_code) { } @@ -825,6 +854,7 @@ DeathTest::TestRole NoExecDeathTest::AssumeRole() { // Event forwarding to the listeners of event listener API mush be shut // down in death test subprocesses. GetUnitTestImpl()->listeners()->SuppressEventForwarding(); + g_in_fast_death_test_child = true; return EXECUTE_TEST; } else { GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); diff --git a/test/gtest-death-test_test.cc b/test/gtest-death-test_test.cc index 15f6719..54f5a1a 100644 --- a/test/gtest-death-test_test.cc +++ b/test/gtest-death-test_test.cc @@ -75,6 +75,7 @@ using testing::internal::DeathTestFactory; using testing::internal::FilePath; using testing::internal::GetLastErrnoDescription; using testing::internal::GetUnitTestImpl; +using testing::internal::InDeathTestChild; using testing::internal::ParseNaturalNumber; using testing::internal::String; @@ -1345,6 +1346,26 @@ TEST(ConditionalDeathMacrosSyntaxDeathTest, SwitchStatement) { #endif // _MSC_VER } +TEST(InDeathTestChildDeathTest, ReportsDeathTestCorrectlyInFastStyle) { + testing::GTEST_FLAG(death_test_style) = "fast"; + EXPECT_FALSE(InDeathTestChild()); + EXPECT_DEATH({ + fprintf(stderr, InDeathTestChild() ? "Inside" : "Outside"); + fflush(stderr); + _exit(1); + }, "Inside"); +} + +TEST(InDeathTestChildDeathTest, ReportsDeathTestCorrectlyInThreadSafeStyle) { + testing::GTEST_FLAG(death_test_style) = "threadsafe"; + EXPECT_FALSE(InDeathTestChild()); + EXPECT_DEATH({ + fprintf(stderr, InDeathTestChild() ? "Inside" : "Outside"); + fflush(stderr); + _exit(1); + }, "Inside"); +} + // Tests that a test case whose name ends with "DeathTest" works fine // on Windows. TEST(NotADeathTest, Test) { -- cgit v1.2.3