aboutsummaryrefslogtreecommitdiffstats
path: root/test/gtest-death-test_test.cc
diff options
context:
space:
mode:
Diffstat (limited to 'test/gtest-death-test_test.cc')
-rw-r--r--test/gtest-death-test_test.cc90
1 files changed, 62 insertions, 28 deletions
diff --git a/test/gtest-death-test_test.cc b/test/gtest-death-test_test.cc
index 4bfd9d63..9d69b2cd 100644
--- a/test/gtest-death-test_test.cc
+++ b/test/gtest-death-test_test.cc
@@ -36,6 +36,8 @@
#ifdef GTEST_HAS_DEATH_TEST
+#include <stdio.h>
+#include <unistd.h>
#include <gtest/gtest-spi.h>
// Indicates that this translation unit is part of Google Test's
@@ -85,13 +87,19 @@ class TestForDeathTest : public testing::Test {
protected:
// A static member function that's expected to die.
static void StaticMemberFunction() {
- GTEST_LOG(FATAL, "death inside StaticMemberFunction().");
+ fprintf(stderr, "%s", "death inside StaticMemberFunction().");
+ // 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
+ // things that conflict with death tests.
+ _exit(1);
}
// A method of the test fixture that may die.
void MemberFunction() {
if (should_die_) {
- GTEST_LOG(FATAL, "death inside MemberFunction().");
+ fprintf(stderr, "%s", "death inside MemberFunction().");
+ _exit(1);
}
}
@@ -157,13 +165,13 @@ int DieInDebugElse12(int* sideeffect) {
return 12;
}
-// Returns the exit status of a process that calls exit(2) with a
+// Returns the exit status of a process that calls _exit(2) with a
// given exit code. This is a helper function for the
// ExitStatusPredicateTest test suite.
static int NormalExitStatus(int exit_code) {
pid_t child_pid = fork();
if (child_pid == 0) {
- exit(exit_code);
+ _exit(exit_code);
}
int status;
waitpid(child_pid, &status, 0);
@@ -179,7 +187,7 @@ static int KilledExitStatus(int signum) {
pid_t child_pid = fork();
if (child_pid == 0) {
raise(signum);
- exit(1);
+ _exit(1);
}
int status;
waitpid(child_pid, &status, 0);
@@ -223,7 +231,7 @@ TEST_F(TestForDeathTest, SingleStatement) {
ASSERT_DEATH(return, "");
if (true)
- EXPECT_DEATH(exit(1), "");
+ EXPECT_DEATH(_exit(1), "");
else
// This empty "else" branch is meant to ensure that EXPECT_DEATH
// doesn't expand into an "if" statement without an "else"
@@ -235,12 +243,12 @@ TEST_F(TestForDeathTest, SingleStatement) {
if (false)
;
else
- EXPECT_DEATH(exit(1), "") << 1 << 2 << 3;
+ EXPECT_DEATH(_exit(1), "") << 1 << 2 << 3;
}
void DieWithEmbeddedNul() {
fprintf(stderr, "Hello%cworld.\n", '\0');
- abort();
+ _exit(1);
}
// Tests that EXPECT_DEATH and ASSERT_DEATH work when the error
@@ -257,24 +265,40 @@ TEST_F(TestForDeathTest, DISABLED_EmbeddedNulInMessage) {
TEST_F(TestForDeathTest, SwitchStatement) {
switch (0)
default:
- ASSERT_DEATH(exit(1), "") << "exit in default switch handler";
+ ASSERT_DEATH(_exit(1), "") << "exit in default switch handler";
switch (0)
case 0:
- EXPECT_DEATH(exit(1), "") << "exit in switch case";
+ EXPECT_DEATH(_exit(1), "") << "exit in switch case";
}
-// Tests that a static member function can be used in a death test.
-TEST_F(TestForDeathTest, StaticMemberFunction) {
+// Tests that a static member function can be used in a "fast" style
+// death test.
+TEST_F(TestForDeathTest, StaticMemberFunctionFastStyle) {
+ testing::GTEST_FLAG(death_test_style) = "fast";
ASSERT_DEATH(StaticMemberFunction(), "death.*StaticMember");
}
-// Tests that a method of the test fixture can be used in a death test.
-TEST_F(TestForDeathTest, MemberFunction) {
+// Tests that a method of the test fixture can be used in a "fast"
+// style death test.
+TEST_F(TestForDeathTest, MemberFunctionFastStyle) {
+ testing::GTEST_FLAG(death_test_style) = "fast";
should_die_ = true;
EXPECT_DEATH(MemberFunction(), "inside.*MemberFunction");
}
+// Tests that death tests work even if the current directory has been
+// changed.
+TEST_F(TestForDeathTest, FastDeathTestInChangedDir) {
+ testing::GTEST_FLAG(death_test_style) = "fast";
+
+ chdir("/");
+ EXPECT_EXIT(_exit(1), testing::ExitedWithCode(1), "");
+
+ chdir("/");
+ ASSERT_DEATH(_exit(1), "");
+}
+
// Repeats a representative sample of death tests in the "threadsafe" style:
TEST_F(TestForDeathTest, StaticMemberFunctionThreadsafeStyle) {
@@ -292,14 +316,24 @@ TEST_F(TestForDeathTest, ThreadsafeDeathTestInLoop) {
testing::GTEST_FLAG(death_test_style) = "threadsafe";
for (int i = 0; i < 3; ++i)
- EXPECT_EXIT(exit(i), testing::ExitedWithCode(i), "") << ": i = " << i;
+ EXPECT_EXIT(_exit(i), testing::ExitedWithCode(i), "") << ": i = " << i;
+}
+
+TEST_F(TestForDeathTest, ThreadsafeDeathTestInChangedDir) {
+ testing::GTEST_FLAG(death_test_style) = "threadsafe";
+
+ chdir("/");
+ EXPECT_EXIT(_exit(1), testing::ExitedWithCode(1), "");
+
+ chdir("/");
+ ASSERT_DEATH(_exit(1), "");
}
TEST_F(TestForDeathTest, MixedStyles) {
testing::GTEST_FLAG(death_test_style) = "threadsafe";
- EXPECT_DEATH(exit(1), "");
+ EXPECT_DEATH(_exit(1), "");
testing::GTEST_FLAG(death_test_style) = "fast";
- EXPECT_DEATH(exit(1), "");
+ EXPECT_DEATH(_exit(1), "");
}
namespace {
@@ -316,7 +350,7 @@ TEST_F(TestForDeathTest, DoesNotExecuteAtforkHooks) {
testing::GTEST_FLAG(death_test_style) = "threadsafe";
pthread_flag = false;
ASSERT_EQ(0, pthread_atfork(&SetPthreadFlag, NULL, NULL));
- ASSERT_DEATH(exit(1), "");
+ ASSERT_DEATH(_exit(1), "");
ASSERT_FALSE(pthread_flag);
}
@@ -528,8 +562,8 @@ TEST_F(TestForDeathTest, AssertDebugDeathAborts) {
// Tests the *_EXIT family of macros, using a variety of predicates.
TEST_F(TestForDeathTest, ExitMacros) {
- EXPECT_EXIT(exit(1), testing::ExitedWithCode(1), "");
- ASSERT_EXIT(exit(42), testing::ExitedWithCode(42), "");
+ EXPECT_EXIT(_exit(1), testing::ExitedWithCode(1), "");
+ ASSERT_EXIT(_exit(42), testing::ExitedWithCode(42), "");
EXPECT_EXIT(raise(SIGKILL), testing::KilledBySignal(SIGKILL), "") << "foo";
ASSERT_EXIT(raise(SIGUSR2), testing::KilledBySignal(SIGUSR2), "") << "bar";
@@ -539,7 +573,7 @@ TEST_F(TestForDeathTest, ExitMacros) {
}, "This failure is expected.");
EXPECT_FATAL_FAILURE({ // NOLINT
- ASSERT_EXIT(exit(0), testing::KilledBySignal(SIGSEGV), "")
+ ASSERT_EXIT(_exit(0), testing::KilledBySignal(SIGSEGV), "")
<< "This failure is expected, too.";
}, "This failure is expected, too.");
}
@@ -547,7 +581,7 @@ TEST_F(TestForDeathTest, ExitMacros) {
TEST_F(TestForDeathTest, InvalidStyle) {
testing::GTEST_FLAG(death_test_style) = "rococo";
EXPECT_NONFATAL_FAILURE({ // NOLINT
- EXPECT_DEATH(exit(0), "") << "This failure is expected.";
+ EXPECT_DEATH(_exit(0), "") << "This failure is expected.";
}, "This failure is expected.");
}
@@ -794,7 +828,7 @@ TEST_F(MacroLogicDeathTest, ChildDoesNotDie) {
// This time there are two calls to Abort: one since the test didn't
// die, and another from the ReturnSentinel when it's destroyed. The
// sentinel normally isn't destroyed if a test doesn't die, since
- // exit(2) is called in that case by ForkingDeathTest, but not by
+ // _exit(2) is called in that case by ForkingDeathTest, but not by
// our MockDeathTest.
ASSERT_EQ(2, factory_->AbortCalls());
EXPECT_EQ(DeathTest::TEST_DID_NOT_DIE,
@@ -813,18 +847,18 @@ static size_t GetSuccessfulTestPartCount() {
// Tests that a successful death test does not register a successful
// test part.
TEST(SuccessRegistrationDeathTest, NoSuccessPart) {
- EXPECT_DEATH(exit(1), "");
+ EXPECT_DEATH(_exit(1), "");
EXPECT_EQ(0u, GetSuccessfulTestPartCount());
}
TEST(StreamingAssertionsDeathTest, DeathTest) {
- EXPECT_DEATH(exit(1), "") << "unexpected failure";
- ASSERT_DEATH(exit(1), "") << "unexpected failure";
+ EXPECT_DEATH(_exit(1), "") << "unexpected failure";
+ ASSERT_DEATH(_exit(1), "") << "unexpected failure";
EXPECT_NONFATAL_FAILURE({ // NOLINT
- EXPECT_DEATH(exit(0), "") << "expected failure";
+ EXPECT_DEATH(_exit(0), "") << "expected failure";
}, "expected failure");
EXPECT_FATAL_FAILURE({ // NOLINT
- ASSERT_DEATH(exit(0), "") << "expected failure";
+ ASSERT_DEATH(_exit(0), "") << "expected failure";
}, "expected failure");
}