Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
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 @@
...
@@ -376,12 +376,13 @@
// (this is covered by GTEST_HAS_STD_STRING guard).
// (this is covered by GTEST_HAS_STD_STRING guard).
// 3. abort() in a VC 7.1 application compiled as GUI in debug config
// 3. abort() in a VC 7.1 application compiled as GUI in debug config
// pops up a dialog window that cannot be suppressed programmatically.
// pops up a dialog window that cannot be suppressed programmatically.
#if GTEST_HAS_STD_STRING && (GTEST_HAS_CLONE || \
#if GTEST_HAS_STD_STRING && (GTEST_OS_LINUX || \
GTEST_OS_WINDOWS && _MSC_VER >= 1400)
GTEST_OS_MAC || \
GTEST_OS_CYGWIN || \
(GTEST_OS_WINDOWS && _MSC_VER >= 1400))
#define GTEST_HAS_DEATH_TEST 1
#define GTEST_HAS_DEATH_TEST 1
#include <vector>
#include <vector>
#endif // GTEST_HAS_STD_STRING && (GTEST_HAS_CLONE ||
#endif
// GTEST_OS_WINDOWS && _MSC_VER >= 1400)
// Determines whether to support value-parameterized tests.
// Determines whether to support value-parameterized tests.
...
...
src/gtest-death-test.cc
View file @
9623aed8
...
@@ -35,6 +35,11 @@
...
@@ -35,6 +35,11 @@
#include <gtest/internal/gtest-port.h>
#include <gtest/internal/gtest-port.h>
#if GTEST_HAS_DEATH_TEST
#if GTEST_HAS_DEATH_TEST
#if GTEST_OS_MAC
#include <crt_externs.h>
#endif // GTEST_OS_MAC
#include <errno.h>
#include <errno.h>
#include <fcntl.h>
#include <fcntl.h>
#include <limits.h>
#include <limits.h>
...
@@ -44,6 +49,7 @@
...
@@ -44,6 +49,7 @@
#include <windows.h>
#include <windows.h>
#else
#else
#include <sys/mman.h>
#include <sys/mman.h>
#include <sys/wait.h>
#endif // GTEST_OS_WINDOWS
#endif // GTEST_OS_WINDOWS
#endif // GTEST_HAS_DEATH_TEST
#endif // GTEST_HAS_DEATH_TEST
...
@@ -80,8 +86,9 @@ GTEST_DEFINE_bool_(
...
@@ -80,8 +86,9 @@ GTEST_DEFINE_bool_(
death_test_use_fork
,
death_test_use_fork
,
internal
::
BoolFromGTestEnv
(
"death_test_use_fork"
,
false
),
internal
::
BoolFromGTestEnv
(
"death_test_use_fork"
,
false
),
"Instructs to use fork()/_exit() instead of clone() in death tests. "
"Instructs to use fork()/_exit() instead of clone() in death tests. "
"Useful when running under valgrind or similar tools if those "
"Ignored and always uses fork() on POSIX systems where clone() is not "
"do not support clone(). Valgrind 3.3.1 will just fail if "
"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 sees an unsupported combination of clone() flags. "
"It is not recommended to use this flag w/o valgrind though it will "
"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 "
"work in 99% of the cases. Once valgrind is fixed, this flag will "
...
@@ -963,6 +970,22 @@ struct ExecDeathTestArgs {
...
@@ -963,6 +970,22 @@ struct ExecDeathTestArgs {
int
close_fd
;
// File descriptor to close; the read end of a pipe
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.
// The main function for a threadsafe-style death test child process.
// This function is called in a clone()-ed process and thus must avoid
// This function is called in a clone()-ed process and thus must avoid
// any potentially unsafe operations like malloc or libc functions.
// any potentially unsafe operations like malloc or libc functions.
...
@@ -988,7 +1011,7 @@ static int ExecDeathTestChildMain(void* child_arg) {
...
@@ -988,7 +1011,7 @@ static int ExecDeathTestChildMain(void* child_arg) {
// unsafe. Since execve() doesn't search the PATH, the user must
// unsafe. Since execve() doesn't search the PATH, the user must
// invoke the test program via a valid path that contains at least
// invoke the test program via a valid path that contains at least
// one path separator.
// 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"
,
DeathTestAbort
(
String
::
Format
(
"execve(%s, ...) in %s failed: %s"
,
args
->
argv
[
0
],
args
->
argv
[
0
],
original_dir
,
original_dir
,
...
@@ -1001,12 +1024,12 @@ static int ExecDeathTestChildMain(void* child_arg) {
...
@@ -1001,12 +1024,12 @@ static int ExecDeathTestChildMain(void* child_arg) {
// This could be accomplished more elegantly by a single recursive
// This could be accomplished more elegantly by a single recursive
// function, but we want to guard against the unlikely possibility of
// function, but we want to guard against the unlikely possibility of
// a smart compiler optimizing the recursion away.
// a smart compiler optimizing the recursion away.
static
bool
StackLowerThanAddress
(
const
void
*
ptr
)
{
bool
StackLowerThanAddress
(
const
void
*
ptr
)
{
int
dummy
;
int
dummy
;
return
&
dummy
<
ptr
;
return
&
dummy
<
ptr
;
}
}
static
bool
StackGrowsDown
()
{
bool
StackGrowsDown
()
{
int
dummy
;
int
dummy
;
return
StackLowerThanAddress
(
&
dummy
);
return
StackLowerThanAddress
(
&
dummy
);
}
}
...
@@ -1015,28 +1038,36 @@ static bool StackGrowsDown() {
...
@@ -1015,28 +1038,36 @@ static bool StackGrowsDown() {
// that uses clone(2). It dies with an error message if anything goes
// that uses clone(2). It dies with an error message if anything goes
// wrong.
// wrong.
static
pid_t
ExecDeathTestFork
(
char
*
const
*
argv
,
int
close_fd
)
{
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
};
ExecDeathTestArgs
args
=
{
argv
,
close_fd
};
pid_t
child_pid
;
pid_t
child_pid
;
if
(
GTEST_FLAG
(
death_test_use_fork
))
{
// Valgrind-friendly version. As of valgrind 3.3.1 the clone() call below
#if GTEST_HAS_CLONE
// is not supported (valgrind will fail with an error message).
const
bool
use_fork
=
GTEST_FLAG
(
death_test_use_fork
);
if
((
child_pid
=
fork
())
==
0
)
{
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
);
ExecDeathTestChildMain
(
&
args
);
_exit
(
0
);
_exit
(
0
);
}
}
else
{
child_pid
=
clone
(
&
ExecDeathTestChildMain
,
stack_top
,
SIGCHLD
,
&
args
);
}
}
GTEST_DEATH_TEST_CHECK_
(
child_pid
!=
-
1
);
GTEST_DEATH_TEST_CHECK_
(
child_pid
!=
-
1
);
GTEST_DEATH_TEST_CHECK_
(
munmap
(
stack
,
stack_size
)
!=
-
1
);
return
child_pid
;
return
child_pid
;
}
}
...
...
test/gtest-death-test_test.cc
View file @
9623aed8
...
@@ -41,6 +41,7 @@
...
@@ -41,6 +41,7 @@
#include <direct.h> // For chdir().
#include <direct.h> // For chdir().
#else
#else
#include <unistd.h>
#include <unistd.h>
#include <sys/wait.h> // For waitpid.
#include <limits> // For std::numeric_limits.
#include <limits> // For std::numeric_limits.
#endif // GTEST_OS_WINDOWS
#endif // GTEST_OS_WINDOWS
...
@@ -414,7 +415,7 @@ void SetPthreadFlag() {
...
@@ -414,7 +415,7 @@ void SetPthreadFlag() {
}
// namespace
}
// namespace
#if
!
GTEST_
OS_WINDOWS
#if GTEST_
HAS_CLONE
TEST_F
(
TestForDeathTest
,
DoesNotExecuteAtforkHooks
)
{
TEST_F
(
TestForDeathTest
,
DoesNotExecuteAtforkHooks
)
{
if
(
!
testing
::
GTEST_FLAG
(
death_test_use_fork
))
{
if
(
!
testing
::
GTEST_FLAG
(
death_test_use_fork
))
{
...
@@ -426,7 +427,7 @@ TEST_F(TestForDeathTest, DoesNotExecuteAtforkHooks) {
...
@@ -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.
// Tests that a method of another class can be used in a death test.
TEST_F
(
TestForDeathTest
,
MethodOfAnotherClass
)
{
TEST_F
(
TestForDeathTest
,
MethodOfAnotherClass
)
{
...
...
test/gtest_filter_unittest.py
View file @
9623aed8
...
@@ -202,7 +202,7 @@ class GTestFilterUnitTest(unittest.TestCase):
...
@@ -202,7 +202,7 @@ class GTestFilterUnitTest(unittest.TestCase):
for
slice_var
in
list_of_sets
:
for
slice_var
in
list_of_sets
:
full_partition
.
extend
(
slice_var
)
full_partition
.
extend
(
slice_var
)
self
.
assertEqual
(
len
(
set_var
),
len
(
full_partition
))
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
):
def
RunAndVerify
(
self
,
gtest_filter
,
tests_to_run
):
"""Runs gtest_flag_unittest_ with the given filter, and verifies
"""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