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
045e7f9e
Unverified
Commit
045e7f9e
authored
May 07, 2018
by
Gennadiy Civil
Committed by
GitHub
May 07, 2018
Browse files
Merge pull request #1593 from Steelskin/fuchsia_death_test
Add death test support for Fuchsia.
parents
278aba36
960149f9
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
243 additions
and
18 deletions
+243
-18
googletest/include/gtest/gtest-death-test.h
googletest/include/gtest/gtest-death-test.h
+1
-1
googletest/include/gtest/gtest.h
googletest/include/gtest/gtest.h
+2
-0
googletest/include/gtest/internal/gtest-port.h
googletest/include/gtest/internal/gtest-port.h
+2
-1
googletest/src/gtest-death-test.cc
googletest/src/gtest-death-test.cc
+202
-11
googletest/src/gtest-port.cc
googletest/src/gtest-port.cc
+24
-0
googletest/test/gtest-death-test_test.cc
googletest/test/gtest-death-test_test.cc
+4
-3
googletest/test/gtest-options_test.cc
googletest/test/gtest-options_test.cc
+6
-0
googletest/test/gtest-port_test.cc
googletest/test/gtest-port_test.cc
+2
-2
No files found.
googletest/include/gtest/gtest-death-test.h
View file @
045e7f9e
...
...
@@ -198,7 +198,7 @@ class GTEST_API_ ExitedWithCode {
const
int
exit_code_
;
};
# if !GTEST_OS_WINDOWS
# if !GTEST_OS_WINDOWS
&& !GTEST_OS_FUCHSIA
// Tests that an exit code describes an exit due to termination by a
// given signal.
class
GTEST_API_
KilledBySignal
{
...
...
googletest/include/gtest/gtest.h
View file @
045e7f9e
...
...
@@ -172,6 +172,7 @@ class TestEventListenersAccessor;
class
TestEventRepeater
;
class
UnitTestRecordPropertyTestHelper
;
class
WindowsDeathTest
;
class
FuchsiaDeathTest
;
class
UnitTestImpl
*
GetUnitTestImpl
();
void
ReportFailureInUnknownLocation
(
TestPartResult
::
Type
result_type
,
const
std
::
string
&
message
);
...
...
@@ -593,6 +594,7 @@ class GTEST_API_ TestResult {
friend
class
internal
::
TestResultAccessor
;
friend
class
internal
::
UnitTestImpl
;
friend
class
internal
::
WindowsDeathTest
;
friend
class
internal
::
FuchsiaDeathTest
;
// Gets the vector of TestPartResults.
const
std
::
vector
<
TestPartResult
>&
test_part_results
()
const
{
...
...
googletest/include/gtest/internal/gtest-port.h
View file @
045e7f9e
...
...
@@ -813,7 +813,8 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
(GTEST_OS_MAC && !GTEST_OS_IOS) || \
(GTEST_OS_WINDOWS_DESKTOP && _MSC_VER >= 1400) || \
GTEST_OS_WINDOWS_MINGW || GTEST_OS_AIX || GTEST_OS_HPUX || \
GTEST_OS_OPENBSD || GTEST_OS_QNX || GTEST_OS_FREEBSD || GTEST_OS_NETBSD)
GTEST_OS_OPENBSD || GTEST_OS_QNX || GTEST_OS_FREEBSD || \
GTEST_OS_NETBSD || GTEST_OS_FUCHSIA)
# define GTEST_HAS_DEATH_TEST 1
#endif
...
...
googletest/src/gtest-death-test.cc
View file @
045e7f9e
...
...
@@ -62,6 +62,12 @@
# include <spawn.h>
# endif // GTEST_OS_QNX
# if GTEST_OS_FUCHSIA
# include <fdio/io.h>
# include <launchpad/launchpad.h>
# include <zircon/syscalls.h>
# endif // GTEST_OS_FUCHSIA
#endif // GTEST_HAS_DEATH_TEST
#include "gtest/gtest-message.h"
...
...
@@ -127,10 +133,10 @@ static bool g_in_fast_death_test_child = false;
// tests. IMPORTANT: This is an internal utility. Using it may break the
// implementation of death tests. User code MUST NOT use it.
bool
InDeathTestChild
()
{
# if GTEST_OS_WINDOWS
# if GTEST_OS_WINDOWS
|| GTEST_OS_FUCHSIA
// On Windows, death tests are thread-safe regardless of the value
of the
// death_test_style flag.
// On Windows
and Fuchsia
, death tests are thread-safe regardless of the value
//
of the
death_test_style flag.
return
!
GTEST_FLAG
(
internal_run_death_test
).
empty
();
# else
...
...
@@ -150,7 +156,7 @@ ExitedWithCode::ExitedWithCode(int exit_code) : exit_code_(exit_code) {
// ExitedWithCode function-call operator.
bool
ExitedWithCode
::
operator
()(
int
exit_status
)
const
{
# if GTEST_OS_WINDOWS
# if GTEST_OS_WINDOWS
|| GTEST_OS_FUCHSIA
return
exit_status
==
exit_code_
;
...
...
@@ -158,10 +164,10 @@ bool ExitedWithCode::operator()(int exit_status) const {
return
WIFEXITED
(
exit_status
)
&&
WEXITSTATUS
(
exit_status
)
==
exit_code_
;
# endif // GTEST_OS_WINDOWS
# endif // GTEST_OS_WINDOWS
|| GTEST_OS_FUCHSIA
}
# if !GTEST_OS_WINDOWS
# if !GTEST_OS_WINDOWS
&& !GTEST_OS_FUCHSIA
// KilledBySignal constructor.
KilledBySignal
::
KilledBySignal
(
int
signum
)
:
signum_
(
signum
)
{
}
...
...
@@ -189,7 +195,7 @@ namespace internal {
static
std
::
string
ExitSummary
(
int
exit_code
)
{
Message
m
;
# if GTEST_OS_WINDOWS
# if GTEST_OS_WINDOWS
|| GTEST_OS_FUCHSIA
m
<<
"Exited with exit status "
<<
exit_code
;
...
...
@@ -205,7 +211,7 @@ static std::string ExitSummary(int exit_code) {
m
<<
" (core dumped)"
;
}
# endif
# endif // GTEST_OS_WINDOWS
# endif // GTEST_OS_WINDOWS
|| GTEST_OS_FUCHSIA
return
m
.
GetString
();
}
...
...
@@ -216,7 +222,7 @@ bool ExitedUnsuccessfully(int exit_status) {
return
!
ExitedWithCode
(
0
)(
exit_status
);
}
# if !GTEST_OS_WINDOWS
# if !GTEST_OS_WINDOWS
&& !GTEST_OS_FUCHSIA
// Generates a textual failure message when a death test finds more than
// one thread running, or cannot determine the number of threads, prior
// to executing the given statement. It is the responsibility of the
...
...
@@ -231,7 +237,7 @@ static std::string DeathTestThreadWarning(size_t thread_count) {
msg
<<
"detected "
<<
thread_count
<<
" threads."
;
return
msg
.
GetString
();
}
# endif // !GTEST_OS_WINDOWS
# endif // !GTEST_OS_WINDOWS
&& !GTEST_OS_FUCHSIA
// Flag characters for reporting a death test that did not die.
static
const
char
kDeathTestLived
=
'L'
;
...
...
@@ -239,6 +245,13 @@ static const char kDeathTestReturned = 'R';
static
const
char
kDeathTestThrew
=
'T'
;
static
const
char
kDeathTestInternalError
=
'I'
;
#if GTEST_OS_FUCHSIA
// File descriptor used for the pipe in the child process.
static
const
int
kFuchsiaReadPipeFd
=
3
;
#endif
// An enumeration describing all of the possible ways that a death test can
// conclude. DIED means that the process died while executing the test
// code; LIVED means that process lived beyond the end of the test code;
...
...
@@ -781,7 +794,168 @@ DeathTest::TestRole WindowsDeathTest::AssumeRole() {
set_spawned
(
true
);
return
OVERSEE_TEST
;
}
# else // We are not on Windows.
# elif GTEST_OS_FUCHSIA
class
FuchsiaDeathTest
:
public
DeathTestImpl
{
public:
FuchsiaDeathTest
(
const
char
*
a_statement
,
const
RE
*
a_regex
,
const
char
*
file
,
int
line
)
:
DeathTestImpl
(
a_statement
,
a_regex
),
file_
(
file
),
line_
(
line
)
{}
// All of these virtual functions are inherited from DeathTest.
virtual
int
Wait
();
virtual
TestRole
AssumeRole
();
private:
// The name of the file in which the death test is located.
const
char
*
const
file_
;
// The line number on which the death test is located.
const
int
line_
;
zx_handle_t
child_process_
;
};
// Utility class for accumulating command-line arguments.
class
Arguments
{
public:
Arguments
()
{
args_
.
push_back
(
NULL
);
}
~
Arguments
()
{
for
(
std
::
vector
<
char
*>::
iterator
i
=
args_
.
begin
();
i
!=
args_
.
end
();
++
i
)
{
free
(
*
i
);
}
}
void
AddArgument
(
const
char
*
argument
)
{
args_
.
insert
(
args_
.
end
()
-
1
,
posix
::
StrDup
(
argument
));
}
template
<
typename
Str
>
void
AddArguments
(
const
::
std
::
vector
<
Str
>&
arguments
)
{
for
(
typename
::
std
::
vector
<
Str
>::
const_iterator
i
=
arguments
.
begin
();
i
!=
arguments
.
end
();
++
i
)
{
args_
.
insert
(
args_
.
end
()
-
1
,
posix
::
StrDup
(
i
->
c_str
()));
}
}
char
*
const
*
Argv
()
{
return
&
args_
[
0
];
}
int
size
()
{
return
args_
.
size
()
-
1
;
}
private:
std
::
vector
<
char
*>
args_
;
};
// Waits for the child in a death test to exit, returning its exit
// status, or 0 if no child process exists. As a side effect, sets the
// outcome data member.
int
FuchsiaDeathTest
::
Wait
()
{
if
(
!
spawned
())
return
0
;
// Wait for child process to terminate.
zx_status_t
status_zx
;
zx_signals_t
signals
;
status_zx
=
zx_object_wait_one
(
child_process_
,
ZX_PROCESS_TERMINATED
,
ZX_TIME_INFINITE
,
&
signals
);
GTEST_DEATH_TEST_CHECK_
(
status_zx
==
ZX_OK
);
ReadAndInterpretStatusByte
();
zx_info_process_t
buffer
;
status_zx
=
zx_object_get_info
(
child_process_
,
ZX_INFO_PROCESS
,
&
buffer
,
sizeof
(
buffer
),
nullptr
,
nullptr
);
GTEST_DEATH_TEST_CHECK_
(
status_zx
==
ZX_OK
);
GTEST_DEATH_TEST_CHECK_
(
buffer
.
exited
);
set_status
(
buffer
.
return_code
);
return
status
();
}
// The AssumeRole process for a Fuchsia death test. It creates a child
// process with the same executable as the current process to run the
// death test. The child process is given the --gtest_filter and
// --gtest_internal_run_death_test flags such that it knows to run the
// current death test only.
DeathTest
::
TestRole
FuchsiaDeathTest
::
AssumeRole
()
{
const
UnitTestImpl
*
const
impl
=
GetUnitTestImpl
();
const
InternalRunDeathTestFlag
*
const
flag
=
impl
->
internal_run_death_test_flag
();
const
TestInfo
*
const
info
=
impl
->
current_test_info
();
const
int
death_test_index
=
info
->
result
()
->
death_test_count
();
if
(
flag
!=
NULL
)
{
// ParseInternalRunDeathTestFlag() has performed all the necessary
// processing.
set_write_fd
(
kFuchsiaReadPipeFd
);
return
EXECUTE_TEST
;
}
CaptureStderr
();
// Flush the log buffers since the log streams are shared with the child.
FlushInfoLog
();
// Build the child process command line.
const
std
::
string
filter_flag
=
std
::
string
(
"--"
)
+
GTEST_FLAG_PREFIX_
+
kFilterFlag
+
"="
+
info
->
test_case_name
()
+
"."
+
info
->
name
();
const
std
::
string
internal_flag
=
std
::
string
(
"--"
)
+
GTEST_FLAG_PREFIX_
+
kInternalRunDeathTestFlag
+
"="
+
file_
+
"|"
+
StreamableToString
(
line_
)
+
"|"
+
StreamableToString
(
death_test_index
);
Arguments
args
;
args
.
AddArguments
(
GetInjectableArgvs
());
args
.
AddArgument
(
filter_flag
.
c_str
());
args
.
AddArgument
(
internal_flag
.
c_str
());
// Build the child process launcher.
zx_status_t
status
;
launchpad_t
*
lp
;
status
=
launchpad_create
(
ZX_HANDLE_INVALID
,
args
.
Argv
()[
0
],
&
lp
);
GTEST_DEATH_TEST_CHECK_
(
status
==
ZX_OK
);
// Build the pipe for communication with the child.
int
read_fd
;
status
=
launchpad_add_pipe
(
lp
,
&
read_fd
,
kFuchsiaReadPipeFd
);
GTEST_DEATH_TEST_CHECK_
(
status
==
ZX_OK
);
set_read_fd
(
read_fd
);
// Set the command line arguments.
status
=
launchpad_load_from_file
(
lp
,
args
.
Argv
()[
0
]);
GTEST_DEATH_TEST_CHECK_
(
status
==
ZX_OK
);
status
=
launchpad_set_args
(
lp
,
args
.
size
(),
args
.
Argv
());
GTEST_DEATH_TEST_CHECK_
(
status
==
ZX_OK
);
// Clone all the things (environment, stdio, namespace, ...).
launchpad_clone
(
lp
,
LP_CLONE_ALL
);
// Launch the child process.
status
=
launchpad_go
(
lp
,
&
child_process_
,
nullptr
);
GTEST_DEATH_TEST_CHECK_
(
status
==
ZX_OK
);
set_spawned
(
true
);
return
OVERSEE_TEST
;
}
#else // We are neither on Windows, nor on Fuchsia.
// ForkingDeathTest provides implementations for most of the abstract
// methods of the DeathTest interface. Only the AssumeRole method is
...
...
@@ -1204,6 +1378,13 @@ bool DefaultDeathTestFactory::Create(const char* statement, const RE* regex,
*
test
=
new
WindowsDeathTest
(
statement
,
regex
,
file
,
line
);
}
# elif GTEST_OS_FUCHSIA
if
(
GTEST_FLAG
(
death_test_style
)
==
"threadsafe"
||
GTEST_FLAG
(
death_test_style
)
==
"fast"
)
{
*
test
=
new
FuchsiaDeathTest
(
statement
,
regex
,
file
,
line
);
}
# else
if
(
GTEST_FLAG
(
death_test_style
)
==
"threadsafe"
)
{
...
...
@@ -1324,6 +1505,16 @@ InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() {
write_fd
=
GetStatusFileDescriptor
(
parent_process_id
,
write_handle_as_size_t
,
event_handle_as_size_t
);
# elif GTEST_OS_FUCHSIA
if
(
fields
.
size
()
!=
3
||
!
ParseNaturalNumber
(
fields
[
1
],
&
line
)
||
!
ParseNaturalNumber
(
fields
[
2
],
&
index
))
{
DeathTestAbort
(
"Bad --gtest_internal_run_death_test flag: "
+
GTEST_FLAG
(
internal_run_death_test
));
}
# else
if
(
fields
.
size
()
!=
4
...
...
googletest/src/gtest-port.cc
View file @
045e7f9e
...
...
@@ -63,6 +63,11 @@
# include <sys/types.h>
#endif // GTEST_OS_AIX
#if GTEST_OS_FUCHSIA
# include <zircon/process.h>
# include <zircon/syscalls.h>
#endif // GTEST_OS_FUCHSIA
#include "gtest/gtest-spi.h"
#include "gtest/gtest-message.h"
#include "gtest/internal/gtest-internal.h"
...
...
@@ -156,6 +161,25 @@ size_t GetThreadCount() {
}
}
#elif GTEST_OS_FUCHSIA
size_t
GetThreadCount
()
{
int
dummy_buffer
;
size_t
avail
;
zx_status_t
status
=
zx_object_get_info
(
zx_process_self
(),
ZX_INFO_PROCESS_THREADS
,
&
dummy_buffer
,
0
,
nullptr
,
&
avail
);
if
(
status
==
ZX_OK
)
{
return
avail
;
}
else
{
return
0
;
}
}
#else
size_t
GetThreadCount
()
{
...
...
googletest/test/gtest-death-test_test.cc
View file @
045e7f9e
...
...
@@ -200,7 +200,7 @@ int DieInDebugElse12(int* sideeffect) {
return
12
;
}
# if GTEST_OS_WINDOWS
# if GTEST_OS_WINDOWS
|| GTEST_OS_FUCHSIA
// Tests the ExitedWithCode predicate.
TEST
(
ExitStatusPredicateTest
,
ExitedWithCode
)
{
...
...
@@ -272,7 +272,7 @@ TEST(ExitStatusPredicateTest, KilledBySignal) {
EXPECT_FALSE
(
pred_kill
(
status_segv
));
}
# endif // GTEST_OS_WINDOWS
# endif // GTEST_OS_WINDOWS
|| GTEST_OS_FUCHSIA
// Tests that the death test macros expand to code which may or may not
// be followed by operator<<, and that in either case the complete text
...
...
@@ -787,8 +787,9 @@ static void TestExitMacros() {
// See http://msdn.microsoft.com/en-us/library/dwwzkt4c(VS.71).aspx.
EXPECT_EXIT
(
raise
(
SIGABRT
),
testing
::
ExitedWithCode
(
3
),
""
)
<<
"b_ar"
;
# el
se
# el
if !GTEST_OS_FUCHSIA
// Fuchsia has no unix signals.
EXPECT_EXIT
(
raise
(
SIGKILL
),
testing
::
KilledBySignal
(
SIGKILL
),
""
)
<<
"foo"
;
ASSERT_EXIT
(
raise
(
SIGUSR2
),
testing
::
KilledBySignal
(
SIGUSR2
),
""
)
<<
"bar"
;
...
...
googletest/test/gtest-options_test.cc
View file @
045e7f9e
...
...
@@ -103,6 +103,8 @@ TEST(OutputFileHelpersTest, GetCurrentExecutableName) {
_strcmpi
(
"gtest-options-ex_test"
,
exe_str
.
c_str
())
==
0
||
_strcmpi
(
"gtest_all_test"
,
exe_str
.
c_str
())
==
0
||
_strcmpi
(
"gtest_dll_test"
,
exe_str
.
c_str
())
==
0
;
#elif GTEST_OS_FUCHSIA
const
bool
success
=
exe_str
==
"app"
;
#else
// TODO(wan@google.com): remove the hard-coded "lt-" prefix when
// Chandler Carruth's libtool replacement is ready.
...
...
@@ -116,6 +118,8 @@ TEST(OutputFileHelpersTest, GetCurrentExecutableName) {
FAIL
()
<<
"GetCurrentExecutableName() returns "
<<
exe_str
;
}
#if !GTEST_OS_FUCHSIA
class
XmlOutputChangeDirTest
:
public
Test
{
protected:
virtual
void
SetUp
()
{
...
...
@@ -202,6 +206,8 @@ TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithAbsolutePath) {
#endif
}
#endif // !GTEST_OS_FUCHSIA
}
// namespace
}
// namespace internal
}
// namespace testing
googletest/test/gtest-port_test.cc
View file @
045e7f9e
...
...
@@ -296,7 +296,7 @@ TEST(FormatCompilerIndependentFileLocationTest, FormatsUknownFileAndLine) {
EXPECT_EQ
(
"unknown file"
,
FormatCompilerIndependentFileLocation
(
NULL
,
-
1
));
}
#if GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_QNX
#if GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_QNX
|| GTEST_OS_FUCHSIA
void
*
ThreadFunc
(
void
*
data
)
{
internal
::
Mutex
*
mutex
=
static_cast
<
internal
::
Mutex
*>
(
data
);
mutex
->
Lock
();
...
...
@@ -340,7 +340,7 @@ TEST(GetThreadCountTest, ReturnsCorrectValue) {
TEST
(
GetThreadCountTest
,
ReturnsZeroWhenUnableToCountThreads
)
{
EXPECT_EQ
(
0U
,
GetThreadCount
());
}
#endif // GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_QNX
#endif // GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_QNX
|| GTEST_OS_FUCHSIA
TEST
(
GtestCheckDeathTest
,
DiesWithCorrectOutputOnFailure
)
{
const
bool
a_false_condition
=
false
;
...
...
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