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
53e0dc40
Commit
53e0dc40
authored
Jan 08, 2009
by
shiqian
Browse files
Implements the --gtest_death_test_use_fork flag and StaticAssertTypeEq.
parent
0efb17dc
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
213 additions
and
10 deletions
+213
-10
include/gtest/gtest.h
include/gtest/gtest.h
+46
-0
include/gtest/internal/gtest-death-test-internal.h
include/gtest/internal/gtest-death-test-internal.h
+1
-0
include/gtest/internal/gtest-filepath.h
include/gtest/internal/gtest-filepath.h
+1
-1
include/gtest/internal/gtest-string.h
include/gtest/internal/gtest-string.h
+1
-1
src/gtest-death-test.cc
src/gtest-death-test.cc
+23
-2
src/gtest-internal-inl.h
src/gtest-internal-inl.h
+4
-0
src/gtest.cc
src/gtest.cc
+2
-0
test/gtest-death-test_test.cc
test/gtest-death-test_test.cc
+17
-6
test/gtest_env_var_test.py
test/gtest_env_var_test.py
+1
-0
test/gtest_env_var_test_.cc
test/gtest_env_var_test_.cc
+5
-0
test/gtest_nc.cc
test/gtest_nc.cc
+41
-0
test/gtest_nc_test.py
test/gtest_nc_test.py
+12
-0
test/gtest_unittest.cc
test/gtest_unittest.cc
+59
-0
No files found.
include/gtest/gtest.h
View file @
53e0dc40
...
...
@@ -1242,6 +1242,52 @@ AssertionResult DoubleLE(const char* expr1, const char* expr2,
::testing::internal::ScopedTrace GTEST_CONCAT_TOKEN_(gtest_trace_, __LINE__)(\
__FILE__, __LINE__, ::testing::Message() << (message))
namespace
internal
{
// This template is declared, but intentionally undefined.
template
<
typename
T1
,
typename
T2
>
struct
StaticAssertTypeEqHelper
;
template
<
typename
T
>
struct
StaticAssertTypeEqHelper
<
T
,
T
>
{};
}
// namespace internal
// Compile-time assertion for type equality.
// StaticAssertTypeEq<type1, type2>() compiles iff type1 and type2 are
// the same type. The value it returns is not interesting.
//
// Instead of making StaticAssertTypeEq a class template, we make it a
// function template that invokes a helper class template. This
// prevents a user from misusing StaticAssertTypeEq<T1, T2> by
// defining objects of that type.
//
// CAVEAT:
//
// When used inside a method of a class template,
// StaticAssertTypeEq<T1, T2>() is effective ONLY IF the method is
// instantiated. For example, given:
//
// template <typename T> class Foo {
// public:
// void Bar() { testing::StaticAssertTypeEq<int, T>(); }
// };
//
// the code:
//
// void Test1() { Foo<bool> foo; }
//
// will NOT generate a compiler error, as Foo<bool>::Bar() is never
// actually instantiated. Instead, you need:
//
// void Test2() { Foo<bool> foo; foo.Bar(); }
//
// to cause a compiler error.
template
<
typename
T1
,
typename
T2
>
bool
StaticAssertTypeEq
()
{
internal
::
StaticAssertTypeEqHelper
<
T1
,
T2
>
();
return
true
;
}
// Defines a test.
//
...
...
include/gtest/internal/gtest-death-test-internal.h
View file @
53e0dc40
...
...
@@ -46,6 +46,7 @@ GTEST_DECLARE_string_(internal_run_death_test);
// Names of the flags (needed for parsing Google Test flags).
const
char
kDeathTestStyleFlag
[]
=
"death_test_style"
;
const
char
kDeathTestUseFork
[]
=
"death_test_use_fork"
;
const
char
kInternalRunDeathTestFlag
[]
=
"internal_run_death_test"
;
#ifdef GTEST_HAS_DEATH_TEST
...
...
include/gtest/internal/gtest-filepath.h
View file @
53e0dc40
...
...
@@ -34,7 +34,7 @@
// This header file declares classes and functions used internally by
// Google Test. They are subject to change without notice.
//
// This file is #included in test
ing/base
/internal/gtest-internal.h
// This file is #included in
<g
test/internal/gtest-internal.h
>.
// Do not include this header file separately!
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
...
...
include/gtest/internal/gtest-string.h
View file @
53e0dc40
...
...
@@ -35,7 +35,7 @@
// Google Test. They are subject to change without notice. They should not used
// by code external to Google Test.
//
// This header file is #included by test
ing/base
/internal/gtest-internal.h.
// This header file is #included by
<g
test/internal/gtest-internal.h
>
.
// It should not be #included by other files.
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
...
...
src/gtest-death-test.cc
View file @
53e0dc40
...
...
@@ -68,6 +68,17 @@ GTEST_DEFINE_string_(
"
\"
fast
\"
(child process runs the death test immediately "
"after forking)."
);
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 "
"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 "
"most likely be removed."
);
namespace
internal
{
GTEST_DEFINE_string_
(
internal_run_death_test
,
""
,
...
...
@@ -603,8 +614,18 @@ static pid_t ExecDeathTestFork(char* const* argv, int close_fd) {
void
*
const
stack_top
=
static_cast
<
char
*>
(
stack
)
+
(
stack_grows_down
?
stack_size
:
0
);
ExecDeathTestArgs
args
=
{
argv
,
close_fd
};
const
pid_t
child_pid
=
clone
(
&
ExecDeathTestChildMain
,
stack_top
,
SIGCHLD
,
&
args
);
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
)
{
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
;
...
...
src/gtest-internal-inl.h
View file @
53e0dc40
...
...
@@ -66,6 +66,7 @@ namespace testing {
GTEST_DECLARE_bool_
(
break_on_failure
);
GTEST_DECLARE_bool_
(
catch_exceptions
);
GTEST_DECLARE_string_
(
color
);
GTEST_DECLARE_bool_
(
death_test_use_fork
);
GTEST_DECLARE_string_
(
filter
);
GTEST_DECLARE_bool_
(
list_tests
);
GTEST_DECLARE_string_
(
output
);
...
...
@@ -100,6 +101,7 @@ class GTestFlagSaver {
catch_exceptions_
=
GTEST_FLAG
(
catch_exceptions
);
color_
=
GTEST_FLAG
(
color
);
death_test_style_
=
GTEST_FLAG
(
death_test_style
);
death_test_use_fork_
=
GTEST_FLAG
(
death_test_use_fork
);
filter_
=
GTEST_FLAG
(
filter
);
internal_run_death_test_
=
GTEST_FLAG
(
internal_run_death_test
);
list_tests_
=
GTEST_FLAG
(
list_tests
);
...
...
@@ -114,6 +116,7 @@ class GTestFlagSaver {
GTEST_FLAG
(
catch_exceptions
)
=
catch_exceptions_
;
GTEST_FLAG
(
color
)
=
color_
;
GTEST_FLAG
(
death_test_style
)
=
death_test_style_
;
GTEST_FLAG
(
death_test_use_fork
)
=
death_test_use_fork_
;
GTEST_FLAG
(
filter
)
=
filter_
;
GTEST_FLAG
(
internal_run_death_test
)
=
internal_run_death_test_
;
GTEST_FLAG
(
list_tests
)
=
list_tests_
;
...
...
@@ -127,6 +130,7 @@ class GTestFlagSaver {
bool
catch_exceptions_
;
String
color_
;
String
death_test_style_
;
bool
death_test_use_fork_
;
String
filter_
;
String
internal_run_death_test_
;
bool
list_tests_
;
...
...
src/gtest.cc
View file @
53e0dc40
...
...
@@ -3867,6 +3867,8 @@ void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) {
ParseStringFlag
(
arg
,
kColorFlag
,
&
GTEST_FLAG
(
color
))
||
ParseStringFlag
(
arg
,
kDeathTestStyleFlag
,
&
GTEST_FLAG
(
death_test_style
))
||
ParseBoolFlag
(
arg
,
kDeathTestUseFork
,
&
GTEST_FLAG
(
death_test_use_fork
))
||
ParseStringFlag
(
arg
,
kFilterFlag
,
&
GTEST_FLAG
(
filter
))
||
ParseStringFlag
(
arg
,
kInternalRunDeathTestFlag
,
&
GTEST_FLAG
(
internal_run_death_test
))
||
...
...
test/gtest-death-test_test.cc
View file @
53e0dc40
...
...
@@ -347,11 +347,13 @@ void SetPthreadFlag() {
}
// namespace
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_FALSE
(
pthread_flag
);
if
(
!
testing
::
GTEST_FLAG
(
death_test_use_fork
))
{
testing
::
GTEST_FLAG
(
death_test_style
)
=
"threadsafe"
;
pthread_flag
=
false
;
ASSERT_EQ
(
0
,
pthread_atfork
(
&
SetPthreadFlag
,
NULL
,
NULL
));
ASSERT_DEATH
(
_exit
(
1
),
""
);
ASSERT_FALSE
(
pthread_flag
);
}
}
// Tests that a method of another class can be used in a death test.
...
...
@@ -561,7 +563,7 @@ TEST_F(TestForDeathTest, AssertDebugDeathAborts) {
#endif // _NDEBUG
// Tests the *_EXIT family of macros, using a variety of predicates.
TEST_F
(
TestForDeath
Test
,
ExitMacros
)
{
static
void
TestExitMacros
(
)
{
EXPECT_EXIT
(
_exit
(
1
),
testing
::
ExitedWithCode
(
1
),
""
);
ASSERT_EXIT
(
_exit
(
42
),
testing
::
ExitedWithCode
(
42
),
""
);
EXPECT_EXIT
(
raise
(
SIGKILL
),
testing
::
KilledBySignal
(
SIGKILL
),
""
)
<<
"foo"
;
...
...
@@ -578,6 +580,15 @@ TEST_F(TestForDeathTest, ExitMacros) {
},
"This failure is expected, too."
);
}
TEST_F
(
TestForDeathTest
,
ExitMacros
)
{
TestExitMacros
();
}
TEST_F
(
TestForDeathTest
,
ExitMacrosUsingFork
)
{
testing
::
GTEST_FLAG
(
death_test_use_fork
)
=
true
;
TestExitMacros
();
}
TEST_F
(
TestForDeathTest
,
InvalidStyle
)
{
testing
::
GTEST_FLAG
(
death_test_style
)
=
"rococo"
;
EXPECT_NONFATAL_FAILURE
({
// NOLINT
...
...
test/gtest_env_var_test.py
View file @
53e0dc40
...
...
@@ -109,6 +109,7 @@ def TestEnvVarAffectsFlag(command):
if
IS_LINUX
:
TestFlag
(
command
,
'stack_trace_depth'
,
'0'
,
'100'
)
TestFlag
(
command
,
'death_test_style'
,
'thread-safe'
,
'fast'
)
TestFlag
(
command
,
'death_test_use_fork'
,
'1'
,
'0'
)
if
IS_WINDOWS
:
...
...
test/gtest_env_var_test_.cc
View file @
53e0dc40
...
...
@@ -71,6 +71,11 @@ void PrintFlag(const char* flag) {
return
;
}
if
(
strcmp
(
flag
,
"death_test_use_fork"
)
==
0
)
{
cout
<<
GTEST_FLAG
(
death_test_use_fork
);
return
;
}
if
(
strcmp
(
flag
,
"filter"
)
==
0
)
{
cout
<<
GTEST_FLAG
(
filter
);
return
;
...
...
test/gtest_nc.cc
View file @
53e0dc40
...
...
@@ -181,6 +181,47 @@ INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, testing::Types<int>);
// Wrong name prefix: "My" has been used.
INSTANTIATE_TYPED_TEST_CASE_P
(
My
,
FooTest
,
testing
::
Types
<
double
>
);
#elif defined(TEST_STATIC_ASSERT_TYPE_EQ_IS_NOT_A_TYPE)
#include <gtest/gtest.h>
// Tests that StaticAssertTypeEq<T1, T2> cannot be used as a type.
testing
::
StaticAssertTypeEq
<
int
,
int
>
dummy
;
#elif defined(TEST_STATIC_ASSERT_TYPE_EQ_WORKS_IN_NAMESPACE)
#include <gtest/gtest.h>
// Tests that StaticAssertTypeEq<T1, T2> works in a namespace scope.
static
bool
dummy
=
testing
::
StaticAssertTypeEq
<
int
,
const
int
>
();
#elif defined(TEST_STATIC_ASSERT_TYPE_EQ_WORKS_IN_CLASS)
#include <gtest/gtest.h>
template
<
typename
T
>
class
Helper
{
public:
// Tests that StaticAssertTypeEq<T1, T2> works in a class.
Helper
()
{
testing
::
StaticAssertTypeEq
<
int
,
T
>
();
}
void
DoSomething
()
{}
};
void
Test
()
{
Helper
<
bool
>
h
;
h
.
DoSomething
();
// To avoid the "unused variable" warning.
}
#elif defined(TEST_STATIC_ASSERT_TYPE_EQ_WORKS_IN_FUNCTION)
#include <gtest/gtest.h>
void
Test
()
{
// Tests that StaticAssertTypeEq<T1, T2> works inside a function.
testing
::
StaticAssertTypeEq
<
const
int
,
int
>
();
}
#else
// A sanity test. This should compile.
...
...
test/gtest_nc_test.py
View file @
53e0dc40
...
...
@@ -78,6 +78,18 @@ class GTestNCTest(unittest.TestCase):
(
'CATCHES_INSTANTIATE_TYPED_TESET_CASE_P_WITH_SAME_NAME_PREFIX'
,
[
r
'redefinition of.*My.*FooTest'
]),
(
'STATIC_ASSERT_TYPE_EQ_IS_NOT_A_TYPE'
,
[
r
'StaticAssertTypeEq.* does not name a type'
]),
(
'STATIC_ASSERT_TYPE_EQ_WORKS_IN_NAMESPACE'
,
[
r
'StaticAssertTypeEq.*int.*const int'
]),
(
'STATIC_ASSERT_TYPE_EQ_WORKS_IN_CLASS'
,
[
r
'StaticAssertTypeEq.*int.*bool'
]),
(
'STATIC_ASSERT_TYPE_EQ_WORKS_IN_FUNCTION'
,
[
r
'StaticAssertTypeEq.*const int.*int'
]),
(
'SANITY'
,
None
)
]
...
...
test/gtest_unittest.cc
View file @
53e0dc40
...
...
@@ -86,6 +86,7 @@ using testing::DoubleLE;
using
testing
::
FloatLE
;
using
testing
::
GTEST_FLAG
(
break_on_failure
);
using
testing
::
GTEST_FLAG
(
catch_exceptions
);
using
testing
::
GTEST_FLAG
(
death_test_use_fork
);
using
testing
::
GTEST_FLAG
(
color
);
using
testing
::
GTEST_FLAG
(
filter
);
using
testing
::
GTEST_FLAG
(
list_tests
);
...
...
@@ -98,6 +99,7 @@ using testing::IsNotSubstring;
using
testing
::
IsSubstring
;
using
testing
::
Message
;
using
testing
::
ScopedFakeTestPartResultReporter
;
using
testing
::
StaticAssertTypeEq
;
using
testing
::
Test
;
using
testing
::
TestPartResult
;
using
testing
::
TestPartResultArray
;
...
...
@@ -1128,6 +1130,7 @@ class GTestFlagSaverTest : public Test {
GTEST_FLAG
(
break_on_failure
)
=
false
;
GTEST_FLAG
(
catch_exceptions
)
=
false
;
GTEST_FLAG
(
death_test_use_fork
)
=
false
;
GTEST_FLAG
(
color
)
=
"auto"
;
GTEST_FLAG
(
filter
)
=
""
;
GTEST_FLAG
(
list_tests
)
=
false
;
...
...
@@ -1149,6 +1152,7 @@ class GTestFlagSaverTest : public Test {
EXPECT_FALSE
(
GTEST_FLAG
(
break_on_failure
));
EXPECT_FALSE
(
GTEST_FLAG
(
catch_exceptions
));
EXPECT_STREQ
(
"auto"
,
GTEST_FLAG
(
color
).
c_str
());
EXPECT_FALSE
(
GTEST_FLAG
(
death_test_use_fork
));
EXPECT_STREQ
(
""
,
GTEST_FLAG
(
filter
).
c_str
());
EXPECT_FALSE
(
GTEST_FLAG
(
list_tests
));
EXPECT_STREQ
(
""
,
GTEST_FLAG
(
output
).
c_str
());
...
...
@@ -1158,6 +1162,7 @@ class GTestFlagSaverTest : public Test {
GTEST_FLAG
(
break_on_failure
)
=
true
;
GTEST_FLAG
(
catch_exceptions
)
=
true
;
GTEST_FLAG
(
color
)
=
"no"
;
GTEST_FLAG
(
death_test_use_fork
)
=
true
;
GTEST_FLAG
(
filter
)
=
"abc"
;
GTEST_FLAG
(
list_tests
)
=
true
;
GTEST_FLAG
(
output
)
=
"xml:foo.xml"
;
...
...
@@ -4064,6 +4069,7 @@ struct Flags {
// Constructs a Flags struct where each flag has its default value.
Flags
()
:
break_on_failure
(
false
),
catch_exceptions
(
false
),
death_test_use_fork
(
false
),
filter
(
""
),
list_tests
(
false
),
output
(
""
),
...
...
@@ -4088,6 +4094,14 @@ struct Flags {
return
flags
;
}
// Creates a Flags struct where the gtest_death_test_use_fork flag has
// the given value.
static
Flags
DeathTestUseFork
(
bool
death_test_use_fork
)
{
Flags
flags
;
flags
.
death_test_use_fork
=
death_test_use_fork
;
return
flags
;
}
// Creates a Flags struct where the gtest_filter flag has the given
// value.
static
Flags
Filter
(
const
char
*
filter
)
{
...
...
@@ -4131,6 +4145,7 @@ struct Flags {
// These fields store the flag values.
bool
break_on_failure
;
bool
catch_exceptions
;
bool
death_test_use_fork
;
const
char
*
filter
;
bool
list_tests
;
const
char
*
output
;
...
...
@@ -4145,6 +4160,7 @@ class InitGoogleTestTest : public Test {
virtual
void
SetUp
()
{
GTEST_FLAG
(
break_on_failure
)
=
false
;
GTEST_FLAG
(
catch_exceptions
)
=
false
;
GTEST_FLAG
(
death_test_use_fork
)
=
false
;
GTEST_FLAG
(
filter
)
=
""
;
GTEST_FLAG
(
list_tests
)
=
false
;
GTEST_FLAG
(
output
)
=
""
;
...
...
@@ -4167,6 +4183,7 @@ class InitGoogleTestTest : public Test {
static
void
CheckFlags
(
const
Flags
&
expected
)
{
EXPECT_EQ
(
expected
.
break_on_failure
,
GTEST_FLAG
(
break_on_failure
));
EXPECT_EQ
(
expected
.
catch_exceptions
,
GTEST_FLAG
(
catch_exceptions
));
EXPECT_EQ
(
expected
.
death_test_use_fork
,
GTEST_FLAG
(
death_test_use_fork
));
EXPECT_STREQ
(
expected
.
filter
,
GTEST_FLAG
(
filter
).
c_str
());
EXPECT_EQ
(
expected
.
list_tests
,
GTEST_FLAG
(
list_tests
));
EXPECT_STREQ
(
expected
.
output
,
GTEST_FLAG
(
output
).
c_str
());
...
...
@@ -4373,6 +4390,22 @@ TEST_F(InitGoogleTestTest, CatchExceptions) {
TEST_PARSING_FLAGS
(
argv
,
argv2
,
Flags
::
CatchExceptions
(
true
));
}
// Tests parsing --gtest_death_test_use_fork.
TEST_F
(
InitGoogleTestTest
,
DeathTestUseFork
)
{
const
char
*
argv
[]
=
{
"foo.exe"
,
"--gtest_death_test_use_fork"
,
NULL
};
const
char
*
argv2
[]
=
{
"foo.exe"
,
NULL
};
TEST_PARSING_FLAGS
(
argv
,
argv2
,
Flags
::
DeathTestUseFork
(
true
));
}
// Tests having the same flag twice with different values. The
// expected behavior is that the one coming last takes precedence.
TEST_F
(
InitGoogleTestTest
,
DuplicatedFlags
)
{
...
...
@@ -5000,6 +5033,32 @@ TEST(ColoredOutputTest, UsesColorsWhenTermSupportsColors) {
#endif // GTEST_OS_WINDOWS
}
// Verifies that StaticAssertTypeEq works in a namespace scope.
static
bool
dummy1
=
StaticAssertTypeEq
<
bool
,
bool
>
();
static
bool
dummy2
=
StaticAssertTypeEq
<
const
int
,
const
int
>
();
// Verifies that StaticAssertTypeEq works in a class.
template
<
typename
T
>
class
StaticAssertTypeEqTestHelper
{
public:
StaticAssertTypeEqTestHelper
()
{
StaticAssertTypeEq
<
bool
,
T
>
();
}
};
TEST
(
StaticAssertTypeEqTest
,
WorksInClass
)
{
StaticAssertTypeEqTestHelper
<
bool
>
();
}
// Verifies that StaticAssertTypeEq works inside a function.
typedef
int
IntAlias
;
TEST
(
StaticAssertTypeEqTest
,
CompilesForEqualTypes
)
{
StaticAssertTypeEq
<
int
,
IntAlias
>
();
StaticAssertTypeEq
<
int
*
,
IntAlias
*>
();
}
TEST
(
ThreadLocalTest
,
DefaultConstructor
)
{
ThreadLocal
<
int
>
t1
;
EXPECT_EQ
(
0
,
t1
.
get
());
...
...
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