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