Improves thread-safe death tests by changing to the original working directory before they are executed; also fixes out-dated comments about death tests.
This commit is contained in:
@@ -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");
|
||||
}
|
||||
|
||||
|
||||
@@ -91,6 +91,38 @@ const char* MakeTempDir() {
|
||||
}
|
||||
#endif // _WIN32_WCE
|
||||
|
||||
#ifndef _WIN32_WCE
|
||||
|
||||
TEST(GetCurrentDirTest, ReturnsCurrentDir) {
|
||||
EXPECT_FALSE(FilePath::GetCurrentDir().IsEmpty());
|
||||
|
||||
#ifdef GTEST_OS_WINDOWS
|
||||
_chdir(PATH_SEP);
|
||||
const FilePath cwd = FilePath::GetCurrentDir();
|
||||
// Skips the ":".
|
||||
const char* const cwd_without_drive = strchr(cwd.c_str(), ':');
|
||||
ASSERT_TRUE(cwd_without_drive != NULL);
|
||||
EXPECT_STREQ(PATH_SEP, cwd_without_drive + 1);
|
||||
#else
|
||||
chdir(PATH_SEP);
|
||||
EXPECT_STREQ(PATH_SEP, FilePath::GetCurrentDir().c_str());
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // _WIN32_WCE
|
||||
|
||||
TEST(IsEmptyTest, ReturnsTrueForEmptyPath) {
|
||||
EXPECT_TRUE(FilePath("").IsEmpty());
|
||||
EXPECT_TRUE(FilePath(NULL).IsEmpty());
|
||||
}
|
||||
|
||||
TEST(IsEmptyTest, ReturnsFalseForNonEmptyPath) {
|
||||
EXPECT_FALSE(FilePath("a").IsEmpty());
|
||||
EXPECT_FALSE(FilePath(".").IsEmpty());
|
||||
EXPECT_FALSE(FilePath("a/b").IsEmpty());
|
||||
EXPECT_FALSE(FilePath("a\\b\\").IsEmpty());
|
||||
}
|
||||
|
||||
// FilePath's functions used by UnitTestOptions::GetOutputFile.
|
||||
|
||||
// RemoveDirectoryName "" -> ""
|
||||
|
||||
@@ -1142,7 +1142,8 @@ TEST(ParseInt32FlagTest, ParsesAndReturnsValidValue) {
|
||||
}
|
||||
|
||||
// For the same reason we are not explicitly testing everything in the
|
||||
// Test class, there are no separate tests for the following classes:
|
||||
// Test class, there are no separate tests for the following classes
|
||||
// (except for some trivial cases):
|
||||
//
|
||||
// TestCase, UnitTest, UnitTestResultPrinter.
|
||||
//
|
||||
@@ -1150,6 +1151,11 @@ TEST(ParseInt32FlagTest, ParsesAndReturnsValidValue) {
|
||||
//
|
||||
// TEST, TEST_F, RUN_ALL_TESTS
|
||||
|
||||
TEST(UnitTestTest, CanGetOriginalWorkingDir) {
|
||||
ASSERT_TRUE(UnitTest::GetInstance()->original_working_dir() != NULL);
|
||||
EXPECT_STRNE(UnitTest::GetInstance()->original_working_dir(), "");
|
||||
}
|
||||
|
||||
// This group of tests is for predicate assertions (ASSERT_PRED*, etc)
|
||||
// of various arities. They do not attempt to be exhaustive. Rather,
|
||||
// view them as smoke tests that can be easily reviewed and verified.
|
||||
|
||||
Reference in New Issue
Block a user