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
d4b5281d
Commit
d4b5281d
authored
May 01, 2018
by
Fabrice de Gans-Riberi
Browse files
Add Fuchsia support for death test.
parent
278aba36
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
200 additions
and
4 deletions
+200
-4
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
+186
-3
googletest/src/gtest-port.cc
googletest/src/gtest-port.cc
+10
-0
No files found.
googletest/include/gtest/gtest.h
View file @
d4b5281d
...
...
@@ -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 @
d4b5281d
...
...
@@ -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 @
d4b5281d
...
...
@@ -62,6 +62,11 @@
# include <spawn.h>
# endif // GTEST_OS_QNX
# if GTEST_OS_FUCHSIA
# include <launchpad/launchpad.h>
# include <zircon/syscalls.h>
# endif // GTEST_OS_FUCHSIA
#endif // GTEST_HAS_DEATH_TEST
#include "gtest/gtest-message.h"
...
...
@@ -127,7 +132,7 @@ 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.
...
...
@@ -216,7 +221,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
...
...
@@ -781,7 +786,178 @@ 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_
;
// zx_handle_t crash_port_;
};
// 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
];
}
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
;
ReadAndInterpretStatusByte
();
// 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
);
// Do we need this?
// // Attempt to read the crash port.
// zx_port_packet_t packet;
// status = zx_port_wait(crash_port_, past, &packet, 1)
// if (status == ZX_ERR_TIMED_OUT) {
// // Process did not crash.
// set_outcome(LIVED);
// return status();
// }
zx_info_process_t
buffer
;
size_t
actual
;
size_t
avail
;
status_zx
=
zx_object_get_info
(
child_process_
,
ZX_INFO_PROCESS
,
&
buffer
,
sizeof
(
buffer
),
&
actual
,
&
avail
);
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
(
flag
->
write_fd
());
return
EXECUTE_TEST
;
}
// Create the crash port to report on.
// zx_status_t status = zx_port_create(0, &crash_port_);
// GTEST_DEATH_TEST_CHECK_(status == ZX_OK);
CaptureStderr
();
// Flush the log buffers since the log streams are shared with the child.
FlushInfoLog
();
// Build the child process launcher.
launchpad_t
*
lp
;
zx_status_t
status
;
status
=
launchpad_create
(
ZX_HANDLE_INVALID
,
"processname"
,
&
lp
);
GTEST_DEATH_TEST_CHECK_
(
status
==
ZX_OK
);
// Build the writing pipe for the child.
int
write_fd
;
status
=
launchpad_add_pipe
(
lp
,
&
write_fd
,
read_fd
());
GTEST_DEATH_TEST_CHECK_
(
status
==
ZX_OK
);
// Build the child 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
)
+
"|"
+
StreamableToString
(
write_fd
);
Arguments
args
;
args
.
AddArguments
(
GetInjectableArgvs
());
args
.
AddArgument
(
filter_flag
.
c_str
());
args
.
AddArgument
(
internal_flag
.
c_str
());
status
=
launchpad_load_from_file
(
lp
,
args
.
Argv
()[
0
]);
GTEST_DEATH_TEST_CHECK_
(
status
==
ZX_OK
);
status
=
launchpad_set_args
(
lp
,
GetArgvs
().
size
()
+
2
,
args
.
Argv
());
GTEST_DEATH_TEST_CHECK_
(
status
==
ZX_OK
);
// Launch the child process.
zx_handle_t
proc
;
const
char
*
errmsg
;
status
=
launchpad_go
(
lp
,
&
proc
,
&
errmsg
);
GTEST_DEATH_TEST_CHECK_
(
status
==
ZX_OK
);
child_process_
=
proc
;
// bind the crash port. This should be moved to before launching the process.
// FIXME: I don't think this is necessary
// status = zx_task_bind_exception_port(child_process_, crash_port_, 0xabcabc, 0);
// 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 +1380,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"
)
{
...
...
googletest/src/gtest-port.cc
View file @
d4b5281d
...
...
@@ -63,6 +63,10 @@
# include <sys/types.h>
#endif // GTEST_OS_AIX
#if GTEST_OS_FUCHSIA
# include <zircon/syscalls.h>
#endif
#include "gtest/gtest-spi.h"
#include "gtest/gtest-message.h"
#include "gtest/internal/gtest-internal.h"
...
...
@@ -156,6 +160,12 @@ size_t GetThreadCount() {
}
}
#elif GTEST_OS_FUCHSIA
size_t
GetThreadCount
()
{
return
static_cast
<
size_t
>
(
zx_system_get_num_cpus
());
}
#else
size_t
GetThreadCount
()
{
...
...
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