Enables death tests on Cygwin and Mac (by Vlad Losev); fixes a python test on Mac.
This commit is contained in:
		@@ -376,12 +376,13 @@
 | 
			
		||||
//      (this is covered by GTEST_HAS_STD_STRING guard).
 | 
			
		||||
//   3. abort() in a VC 7.1 application compiled as GUI in debug config
 | 
			
		||||
//      pops up a dialog window that cannot be suppressed programmatically.
 | 
			
		||||
#if GTEST_HAS_STD_STRING && (GTEST_HAS_CLONE || \
 | 
			
		||||
                             GTEST_OS_WINDOWS && _MSC_VER >= 1400)
 | 
			
		||||
#if GTEST_HAS_STD_STRING && (GTEST_OS_LINUX || \
 | 
			
		||||
                             GTEST_OS_MAC || \
 | 
			
		||||
                             GTEST_OS_CYGWIN || \
 | 
			
		||||
                             (GTEST_OS_WINDOWS && _MSC_VER >= 1400))
 | 
			
		||||
#define GTEST_HAS_DEATH_TEST 1
 | 
			
		||||
#include <vector>
 | 
			
		||||
#endif  // GTEST_HAS_STD_STRING && (GTEST_HAS_CLONE ||
 | 
			
		||||
        //                          GTEST_OS_WINDOWS && _MSC_VER >= 1400)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Determines whether to support value-parameterized tests.
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -35,6 +35,11 @@
 | 
			
		||||
#include <gtest/internal/gtest-port.h>
 | 
			
		||||
 | 
			
		||||
#if GTEST_HAS_DEATH_TEST
 | 
			
		||||
 | 
			
		||||
#if GTEST_OS_MAC
 | 
			
		||||
#include <crt_externs.h>
 | 
			
		||||
#endif  // GTEST_OS_MAC
 | 
			
		||||
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <limits.h>
 | 
			
		||||
@@ -44,6 +49,7 @@
 | 
			
		||||
#include <windows.h>
 | 
			
		||||
#else
 | 
			
		||||
#include <sys/mman.h>
 | 
			
		||||
#include <sys/wait.h>
 | 
			
		||||
#endif  // GTEST_OS_WINDOWS
 | 
			
		||||
 | 
			
		||||
#endif  // GTEST_HAS_DEATH_TEST
 | 
			
		||||
@@ -80,8 +86,9 @@ GTEST_DEFINE_bool_(
 | 
			
		||||
    death_test_use_fork,
 | 
			
		||||
    internal::BoolFromGTestEnv("death_test_use_fork", false),
 | 
			
		||||
    "Instructs to use fork()/_exit() instead of clone() in death tests. "
 | 
			
		||||
    "Useful when running under valgrind or similar tools if those "
 | 
			
		||||
    "do not support clone(). Valgrind 3.3.1 will just fail if "
 | 
			
		||||
    "Ignored and always uses fork() on POSIX systems where clone() is not "
 | 
			
		||||
    "implemented. Useful when running under valgrind or similar tools if "
 | 
			
		||||
    "those do not support clone(). Valgrind 3.3.1 will just fail if "
 | 
			
		||||
    "it sees an unsupported combination of clone() flags. "
 | 
			
		||||
    "It is not recommended to use this flag w/o valgrind though it will "
 | 
			
		||||
    "work in 99% of the cases. Once valgrind is fixed, this flag will "
 | 
			
		||||
@@ -963,6 +970,22 @@ struct ExecDeathTestArgs {
 | 
			
		||||
  int close_fd;       // File descriptor to close; the read end of a pipe
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if GTEST_OS_MAC
 | 
			
		||||
inline char** GetEnviron() {
 | 
			
		||||
  // When Google Test is built as a framework on MacOS X, the environ variable
 | 
			
		||||
  // is unavailable. Apple's documentation (man environ) recommends using
 | 
			
		||||
  // _NSGetEnviron() instead.
 | 
			
		||||
  return *_NSGetEnviron();
 | 
			
		||||
}
 | 
			
		||||
#else
 | 
			
		||||
extern "C" char** environ;        // Some POSIX platforms expect you
 | 
			
		||||
                                  // to declare environ. extern "C" makes
 | 
			
		||||
                                  // it reside in the global namespace.
 | 
			
		||||
inline char** GetEnviron() {
 | 
			
		||||
  return environ;
 | 
			
		||||
}
 | 
			
		||||
#endif  // GTEST_OS_MAC
 | 
			
		||||
 | 
			
		||||
// The main function for a threadsafe-style death test child process.
 | 
			
		||||
// This function is called in a clone()-ed process and thus must avoid
 | 
			
		||||
// any potentially unsafe operations like malloc or libc functions.
 | 
			
		||||
@@ -988,7 +1011,7 @@ static int ExecDeathTestChildMain(void* child_arg) {
 | 
			
		||||
  // unsafe.  Since execve() doesn't search the PATH, the user must
 | 
			
		||||
  // invoke the test program via a valid path that contains at least
 | 
			
		||||
  // one path separator.
 | 
			
		||||
  execve(args->argv[0], args->argv, environ);
 | 
			
		||||
  execve(args->argv[0], args->argv, GetEnviron());
 | 
			
		||||
  DeathTestAbort(String::Format("execve(%s, ...) in %s failed: %s",
 | 
			
		||||
                                args->argv[0],
 | 
			
		||||
                                original_dir,
 | 
			
		||||
@@ -1001,12 +1024,12 @@ static int ExecDeathTestChildMain(void* child_arg) {
 | 
			
		||||
// This could be accomplished more elegantly by a single recursive
 | 
			
		||||
// function, but we want to guard against the unlikely possibility of
 | 
			
		||||
// a smart compiler optimizing the recursion away.
 | 
			
		||||
static bool StackLowerThanAddress(const void* ptr) {
 | 
			
		||||
bool StackLowerThanAddress(const void* ptr) {
 | 
			
		||||
  int dummy;
 | 
			
		||||
  return &dummy < ptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool StackGrowsDown() {
 | 
			
		||||
bool StackGrowsDown() {
 | 
			
		||||
  int dummy;
 | 
			
		||||
  return StackLowerThanAddress(&dummy);
 | 
			
		||||
}
 | 
			
		||||
@@ -1015,28 +1038,36 @@ static bool StackGrowsDown() {
 | 
			
		||||
// that uses clone(2).  It dies with an error message if anything goes
 | 
			
		||||
// wrong.
 | 
			
		||||
static pid_t ExecDeathTestFork(char* const* argv, int close_fd) {
 | 
			
		||||
  ExecDeathTestArgs args = { argv, close_fd };
 | 
			
		||||
  pid_t child_pid;
 | 
			
		||||
 | 
			
		||||
#if GTEST_HAS_CLONE
 | 
			
		||||
  const bool use_fork = GTEST_FLAG(death_test_use_fork);
 | 
			
		||||
 | 
			
		||||
  if (!use_fork) {
 | 
			
		||||
    static const bool stack_grows_down = StackGrowsDown();
 | 
			
		||||
    const size_t stack_size = getpagesize();
 | 
			
		||||
    // MMAP_ANONYMOUS is not defined on Mac, so we use MAP_ANON instead.
 | 
			
		||||
    void* const stack = mmap(NULL, stack_size, PROT_READ | PROT_WRITE,
 | 
			
		||||
                           MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
 | 
			
		||||
                             MAP_ANON | MAP_PRIVATE, -1, 0);
 | 
			
		||||
    GTEST_DEATH_TEST_CHECK_(stack != MAP_FAILED);
 | 
			
		||||
    void* const stack_top =
 | 
			
		||||
        static_cast<char*>(stack) + (stack_grows_down ? stack_size : 0);
 | 
			
		||||
  ExecDeathTestArgs args = { argv, close_fd };
 | 
			
		||||
  pid_t child_pid;
 | 
			
		||||
  if (GTEST_FLAG(death_test_use_fork)) {
 | 
			
		||||
    // Valgrind-friendly version. As of valgrind 3.3.1 the clone() call below
 | 
			
		||||
    // is not supported (valgrind will fail with an error message).
 | 
			
		||||
    if ((child_pid = fork()) == 0) {
 | 
			
		||||
 | 
			
		||||
    child_pid = clone(&ExecDeathTestChildMain, stack_top, SIGCHLD, &args);
 | 
			
		||||
 | 
			
		||||
    GTEST_DEATH_TEST_CHECK_(munmap(stack, stack_size) != -1);
 | 
			
		||||
  }
 | 
			
		||||
#else
 | 
			
		||||
  const bool use_fork = true;
 | 
			
		||||
#endif  // GTEST_HAS_CLONE
 | 
			
		||||
 | 
			
		||||
  if (use_fork && (child_pid = fork()) == 0) {
 | 
			
		||||
      ExecDeathTestChildMain(&args);
 | 
			
		||||
      _exit(0);
 | 
			
		||||
  }
 | 
			
		||||
  } else {
 | 
			
		||||
    child_pid = clone(&ExecDeathTestChildMain, stack_top,
 | 
			
		||||
                      SIGCHLD, &args);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  GTEST_DEATH_TEST_CHECK_(child_pid != -1);
 | 
			
		||||
  GTEST_DEATH_TEST_CHECK_(munmap(stack, stack_size) != -1);
 | 
			
		||||
  return child_pid;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -41,6 +41,7 @@
 | 
			
		||||
#include <direct.h>          // For chdir().
 | 
			
		||||
#else
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <sys/wait.h>        // For waitpid.
 | 
			
		||||
#include <limits>            // For std::numeric_limits.
 | 
			
		||||
#endif  // GTEST_OS_WINDOWS
 | 
			
		||||
 | 
			
		||||
@@ -414,7 +415,7 @@ void SetPthreadFlag() {
 | 
			
		||||
 | 
			
		||||
}  // namespace
 | 
			
		||||
 | 
			
		||||
#if !GTEST_OS_WINDOWS
 | 
			
		||||
#if GTEST_HAS_CLONE
 | 
			
		||||
 | 
			
		||||
TEST_F(TestForDeathTest, DoesNotExecuteAtforkHooks) {
 | 
			
		||||
  if (!testing::GTEST_FLAG(death_test_use_fork)) {
 | 
			
		||||
@@ -426,7 +427,7 @@ TEST_F(TestForDeathTest, DoesNotExecuteAtforkHooks) {
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif  // !GTEST_OS_WINDOWS
 | 
			
		||||
#endif  // GTEST_HAS_CLONE
 | 
			
		||||
 | 
			
		||||
// Tests that a method of another class can be used in a death test.
 | 
			
		||||
TEST_F(TestForDeathTest, MethodOfAnotherClass) {
 | 
			
		||||
 
 | 
			
		||||
@@ -202,7 +202,7 @@ class GTestFilterUnitTest(unittest.TestCase):
 | 
			
		||||
    for slice_var in list_of_sets:
 | 
			
		||||
      full_partition.extend(slice_var)
 | 
			
		||||
    self.assertEqual(len(set_var), len(full_partition))
 | 
			
		||||
    self.assertEqual(sorted(set_var), sorted(full_partition))
 | 
			
		||||
    self.assertEqual(sets.Set(set_var), sets.Set(full_partition))
 | 
			
		||||
 | 
			
		||||
  def RunAndVerify(self, gtest_filter, tests_to_run):
 | 
			
		||||
    """Runs gtest_flag_unittest_ with the given filter, and verifies
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user