Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
yangql
googletest
Commits
9623aed8
Commit
9623aed8
authored
Mar 17, 2009
by
zhanyong.wan
Browse files
Enables death tests on Cygwin and Mac (by Vlad Losev); fixes a python test on Mac.
parent
62f8d28c
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
61 additions
and
28 deletions
+61
-28
include/gtest/internal/gtest-port.h
include/gtest/internal/gtest-port.h
+5
-4
src/gtest-death-test.cc
src/gtest-death-test.cc
+52
-21
test/gtest-death-test_test.cc
test/gtest-death-test_test.cc
+3
-2
test/gtest_filter_unittest.py
test/gtest_filter_unittest.py
+1
-1
No files found.
include/gtest/internal/gtest-port.h
View file @
9623aed8
...
...
@@ -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.
...
...
src/gtest-death-test.cc
View file @
9623aed8
...
...
@@ -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
,
e
nviron
);
execve
(
args
->
argv
[
0
],
args
->
argv
,
GetE
nviron
()
);
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
)
{
static
const
bool
stack_grows_down
=
StackGrowsDown
();
const
size_t
stack_size
=
getpagesize
();
void
*
const
stack
=
mmap
(
NULL
,
stack_size
,
PROT_READ
|
PROT_WRITE
,
MAP_ANONYMOUS
|
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
)
{
#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_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
);
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
;
}
...
...
test/gtest-death-test_test.cc
View file @
9623aed8
...
...
@@ -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
)
{
...
...
test/gtest_filter_unittest.py
View file @
9623aed8
...
...
@@ -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
(
s
orted
(
set_var
),
s
orted
(
full_partition
))
self
.
assertEqual
(
s
ets
.
Set
(
set_var
),
s
ets
.
Set
(
full_partition
))
def
RunAndVerify
(
self
,
gtest_filter
,
tests_to_run
):
"""Runs gtest_flag_unittest_ with the given filter, and verifies
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment