Unverified Commit 687964c8 authored by Conor Burgess's avatar Conor Burgess Committed by GitHub
Browse files

Merge branch 'master' into fix-argc

parents f11a8f91 02a8ca87
......@@ -28,9 +28,6 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// A sample program demonstrating using Google C++ testing framework.
//
// Author: wan@google.com (Zhanyong Wan)
// This sample shows how to write a more complex unit test for a class
// that has multiple member functions.
......
......@@ -28,8 +28,6 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// A sample program demonstrating using Google C++ testing framework.
//
// Author: wan@google.com (Zhanyong Wan)
#ifndef GTEST_SAMPLES_SAMPLE3_INL_H_
#define GTEST_SAMPLES_SAMPLE3_INL_H_
......
......@@ -28,9 +28,6 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// A sample program demonstrating using Google C++ testing framework.
//
// Author: wan@google.com (Zhanyong Wan)
// In this example, we use a more advanced feature of Google Test called
// test fixture.
......
......@@ -28,8 +28,6 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// A sample program demonstrating using Google C++ testing framework.
//
// Author: wan@google.com (Zhanyong Wan)
#include <stdio.h>
......
......@@ -28,9 +28,6 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// A sample program demonstrating using Google C++ testing framework.
//
// Author: wan@google.com (Zhanyong Wan)
#ifndef GTEST_SAMPLES_SAMPLE4_H_
#define GTEST_SAMPLES_SAMPLE4_H_
......
......@@ -26,8 +26,7 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
#include "sample4.h"
#include "gtest/gtest.h"
......
......@@ -26,8 +26,7 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
// This sample teaches how to reuse a test fixture in multiple test
// cases by deriving sub-fixtures from it.
......
......@@ -26,8 +26,7 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
// This sample shows how to test common properties of multiple
// implementations of the same interface (aka interface tests).
......
......@@ -26,8 +26,7 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: vladl@google.com (Vlad Losev)
// This sample shows how to test common properties of multiple
// implementations of an interface (aka interface tests) using
......
......@@ -26,8 +26,7 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: vladl@google.com (Vlad Losev)
// This sample shows how to test code relying on some global flag variables.
// Combine() helps with generating all possible combinations of such flags,
......
......@@ -25,8 +25,7 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: vladl@google.com (Vlad Losev)
// This sample shows how to use Google Test listener API to implement
// an alternative console output and how to use the UnitTest reflection API
......
......@@ -52,7 +52,7 @@ EXAMPLES
This tool is experimental. In particular, it assumes that there is no
conditional inclusion of Google Test headers. Please report any
problems to googletestframework@googlegroups.com. You can read
https://github.com/google/googletest/blob/master/googletest/docs/AdvancedGuide.md for
https://github.com/google/googletest/blob/master/googletest/docs/advanced.md for
more information.
"""
......
......@@ -115,10 +115,9 @@ def HeaderPreamble(n):
#ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
#define GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
// Makes sure this header is not included before gtest.h.
#ifndef GTEST_INCLUDE_GTEST_GTEST_H_
# error Do not include gtest_pred_impl.h directly. Include gtest.h instead.
#endif // GTEST_INCLUDE_GTEST_GTEST_H_
#include "gtest/gtest.h"
namespace testing {
// This header implements a family of generic predicate assertion
// macros:
......@@ -295,16 +294,17 @@ def HeaderPostamble():
return """
} // namespace testing
#endif // GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
"""
def GenerateFile(path, content):
"""Given a file path and a content string, overwrites it with the
given content."""
"""Given a file path and a content string
overwrites it with the given content.
"""
print 'Updating file %s . . .' % path
f = file(path, 'w+')
print >>f, content,
f.close()
......@@ -314,8 +314,8 @@ def GenerateFile(path, content):
def GenerateHeader(n):
"""Given the maximum arity n, updates the header file that implements
the predicate assertions."""
the predicate assertions.
"""
GenerateFile(HEADER,
HeaderPreamble(n)
+ ''.join([ImplementationForArity(i) for i in OneTo(n)])
......
......@@ -242,7 +242,7 @@ class AbstractRpcServer(object):
The authentication process works as follows:
1) We get a username and password from the user
2) We use ClientLogin to obtain an AUTH token for the user
(see http://code.google.com/apis/accounts/AuthForInstalledApps.html).
(see https://developers.google.com/identity/protocols/AuthForInstalledApps).
3) We pass the auth token to /_ah/login on the server to obtain an
authentication cookie. If login was successful, it tries to redirect
us to the URL we provided.
......@@ -506,7 +506,7 @@ def EncodeMultipartFormData(fields, files):
(content_type, body) ready for httplib.HTTP instance.
Source:
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/146306
https://web.archive.org/web/20160116052001/code.activestate.com/recipes/146306
"""
BOUNDARY = '-M-A-G-I-C---B-O-U-N-D-A-R-Y-'
CRLF = '\r\n'
......@@ -807,7 +807,7 @@ class SubversionVCS(VersionControlSystem):
# svn cat translates keywords but svn diff doesn't. As a result of this
# behavior patching.PatchChunks() fails with a chunk mismatch error.
# This part was originally written by the Review Board development team
# who had the same problem (http://reviews.review-board.org/r/276/).
# who had the same problem (https://reviews.reviewboard.org/r/276/).
# Mapping of keywords to known aliases
svn_keywords = {
# Standard keywords
......@@ -860,7 +860,7 @@ class SubversionVCS(VersionControlSystem):
status_lines = status.splitlines()
# If file is in a cl, the output will begin with
# "\n--- Changelist 'cl_name':\n". See
# http://svn.collab.net/repos/svn/trunk/notes/changelist-design.txt
# https://web.archive.org/web/20090918234815/svn.collab.net/repos/svn/trunk/notes/changelist-design.txt
if (len(status_lines) == 3 and
not status_lines[0] and
status_lines[1].startswith("--- Changelist")):
......
......@@ -26,10 +26,9 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: mheule@google.com (Markus Heule)
//
// Google C++ Testing Framework (Google Test)
// Google C++ Testing and Mocking Framework (Google Test)
//
// Sometimes it's desirable to build Google Test by compiling a single file.
// This file serves this purpose.
......
......@@ -26,8 +26,7 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan), vladl@google.com (Vlad Losev)
//
// This file implements death tests.
......@@ -62,6 +61,14 @@
# include <spawn.h>
# endif // GTEST_OS_QNX
# if GTEST_OS_FUCHSIA
# include <lib/fdio/io.h>
# include <lib/fdio/spawn.h>
# include <zircon/processargs.h>
# include <zircon/syscalls.h>
# include <zircon/syscalls/port.h>
# endif // GTEST_OS_FUCHSIA
#endif // GTEST_HAS_DEATH_TEST
#include "gtest/gtest-message.h"
......@@ -73,7 +80,11 @@ namespace testing {
// Constants.
// The default death test style.
static const char kDefaultDeathTestStyle[] = "threadsafe";
//
// This is defined in internal/gtest-port.h as "fast", but can be overridden by
// a definition in internal/custom/gtest-port.h. The recommended value, which is
// used internally at Google, is "threadsafe".
static const char kDefaultDeathTestStyle[] = GTEST_DEFAULT_DEATH_TEST_STYLE;
GTEST_DEFINE_string_(
death_test_style,
......@@ -113,7 +124,7 @@ namespace internal {
// Valid only for fast death tests. Indicates the code is running in the
// child process of a fast style death test.
# if !GTEST_OS_WINDOWS
# if !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA
static bool g_in_fast_death_test_child = false;
# endif
......@@ -123,10 +134,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
......@@ -146,7 +157,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_;
......@@ -154,10 +165,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) {
}
......@@ -174,7 +185,7 @@ bool KilledBySignal::operator()(int exit_status) const {
# endif // defined(GTEST_KILLED_BY_SIGNAL_OVERRIDE_)
return WIFSIGNALED(exit_status) && WTERMSIG(exit_status) == signum_;
}
# endif // !GTEST_OS_WINDOWS
# endif // !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA
namespace internal {
......@@ -185,7 +196,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;
......@@ -201,7 +212,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();
}
......@@ -212,7 +223,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
......@@ -221,13 +232,19 @@ static std::string DeathTestThreadWarning(size_t thread_count) {
Message msg;
msg << "Death tests use fork(), which is unsafe particularly"
<< " in a threaded context. For this test, " << GTEST_NAME_ << " ";
if (thread_count == 0)
if (thread_count == 0) {
msg << "couldn't detect the number of threads.";
else
} else {
msg << "detected " << thread_count << " threads.";
}
msg << " See "
"https://github.com/google/googletest/blob/master/googletest/docs/"
"advanced.md#death-tests-and-threads"
<< " for more explanation and suggested solutions, especially if"
<< " this is the last message you see before your test times out.";
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';
......@@ -235,6 +252,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;
......@@ -242,7 +266,7 @@ static const char kDeathTestInternalError = 'I';
// statement, which is not allowed; THREW means that the test statement
// returned control by throwing an exception. IN_PROGRESS means the test
// has not yet concluded.
// TODO(vladl@google.com): Unify names and possibly values for
// FIXME: Unify names and possibly values for
// AbortReason, DeathTestOutcome, and flag characters above.
enum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED, THREW };
......@@ -557,7 +581,6 @@ bool DeathTestImpl::Passed(bool status_ok) {
if (status_ok) {
# if GTEST_USES_PCRE
// PCRE regexes support embedded NULs.
// GTEST_USES_PCRE is defined only in google3 mode
const bool matched = RE::PartialMatch(error_message, *regex());
# else
const bool matched = RE::PartialMatch(error_message.c_str(), *regex());
......@@ -777,7 +800,200 @@ 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) {}
virtual ~FuchsiaDeathTest() {
zx_status_t status = zx_handle_close(child_process_);
GTEST_DEATH_TEST_CHECK_(status == ZX_OK);
status = zx_handle_close(port_);
GTEST_DEATH_TEST_CHECK_(status == ZX_OK);
}
// 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_INVALID;
zx_handle_t port_ = ZX_HANDLE_INVALID;
};
// 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;
// Register to wait for the child process to terminate.
zx_status_t status_zx;
status_zx = zx_object_wait_async(child_process_,
port_,
0 /* key */,
ZX_PROCESS_TERMINATED,
ZX_WAIT_ASYNC_ONCE);
GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);
// Wait for it to terminate, or an exception to be received.
zx_port_packet_t packet;
status_zx = zx_port_wait(port_, ZX_TIME_INFINITE, &packet);
GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);
if (ZX_PKT_IS_EXCEPTION(packet.type)) {
// Process encountered an exception. Kill it directly rather than letting
// other handlers process the event.
status_zx = zx_task_kill(child_process_);
GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);
// Now wait for |child_process_| to terminate.
zx_signals_t signals = 0;
status_zx = zx_object_wait_one(
child_process_, ZX_PROCESS_TERMINATED, ZX_TIME_INFINITE, &signals);
GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);
GTEST_DEATH_TEST_CHECK_(signals & ZX_PROCESS_TERMINATED);
} else {
// Process terminated.
GTEST_DEATH_TEST_CHECK_(ZX_PKT_IS_SIGNAL_ONE(packet.type));
GTEST_DEATH_TEST_CHECK_(packet.signal.observed & ZX_PROCESS_TERMINATED);
}
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 pipe for communication with the child.
zx_status_t status;
zx_handle_t child_pipe_handle;
uint32_t type;
status = fdio_pipe_half(&child_pipe_handle, &type);
GTEST_DEATH_TEST_CHECK_(status >= 0);
set_read_fd(status);
// Set the pipe handle for the child.
fdio_spawn_action_t add_handle_action = {};
add_handle_action.action = FDIO_SPAWN_ACTION_ADD_HANDLE;
add_handle_action.h.id = PA_HND(type, kFuchsiaReadPipeFd);
add_handle_action.h.handle = child_pipe_handle;
// Spawn the child process.
status = fdio_spawn_etc(ZX_HANDLE_INVALID, FDIO_SPAWN_CLONE_ALL,
args.Argv()[0], args.Argv(), nullptr, 1,
&add_handle_action, &child_process_, nullptr);
GTEST_DEATH_TEST_CHECK_(status == ZX_OK);
// Create an exception port and attach it to the |child_process_|, to allow
// us to suppress the system default exception handler from firing.
status = zx_port_create(0, &port_);
GTEST_DEATH_TEST_CHECK_(status == ZX_OK);
status = zx_task_bind_exception_port(
child_process_, port_, 0 /* key */, 0 /*options */);
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
......@@ -1200,6 +1416,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") {
......@@ -1225,17 +1448,17 @@ bool DefaultDeathTestFactory::Create(const char* statement, const RE* regex,
// signals the event, and returns a file descriptor wrapped around the pipe
// handle. This function is called in the child process only.
static int GetStatusFileDescriptor(unsigned int parent_process_id,
size_t write_handle_as_size_t,
size_t event_handle_as_size_t) {
size_t write_handle_as_size_t,
size_t event_handle_as_size_t) {
AutoHandle parent_process_handle(::OpenProcess(PROCESS_DUP_HANDLE,
FALSE, // Non-inheritable.
parent_process_id));
FALSE, // Non-inheritable.
parent_process_id));
if (parent_process_handle.Get() == INVALID_HANDLE_VALUE) {
DeathTestAbort("Unable to open parent process " +
StreamableToString(parent_process_id));
}
// TODO(vladl@google.com): Replace the following check with a
// FIXME: Replace the following check with a
// compile-time assertion when available.
GTEST_CHECK_(sizeof(HANDLE) <= sizeof(size_t));
......@@ -1320,6 +1543,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
......
......@@ -250,7 +250,7 @@ bool FilePath::DirectoryExists() const {
// root directory per disk drive.)
bool FilePath::IsRootDirectory() const {
#if GTEST_OS_WINDOWS
// TODO(wan@google.com): on Windows a network share like
// FIXME: on Windows a network share like
// \\server\share can be a root directory, although it cannot be the
// current directory. Handle this properly.
return pathname_.length() == 3 && IsAbsolutePath();
......@@ -350,7 +350,7 @@ FilePath FilePath::RemoveTrailingPathSeparator() const {
// Removes any redundant separators that might be in the pathname.
// For example, "bar///foo" becomes "bar/foo". Does not eliminate other
// redundancies that might be in a pathname involving "." or "..".
// TODO(wan@google.com): handle Windows network shares (e.g. \\server\share).
// FIXME: handle Windows network shares (e.g. \\server\share).
void FilePath::Normalize() {
if (pathname_.c_str() == NULL) {
pathname_ = "";
......
......@@ -27,10 +27,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Utility functions and classes used by the Google C++ testing framework.
//
// Author: wan@google.com (Zhanyong Wan)
//
// Utility functions and classes used by the Google C++ testing framework.//
// This file contains purely Google Test's internal implementation. Please
// DO NOT #INCLUDE IT IN A USER PROGRAM.
......@@ -59,7 +56,7 @@
# include <windows.h> // NOLINT
#endif // GTEST_OS_WINDOWS
#include "gtest/gtest.h" // NOLINT
#include "gtest/gtest.h"
#include "gtest/gtest-spi.h"
namespace testing {
......@@ -446,6 +443,16 @@ class OsStackTraceGetter : public OsStackTraceGetterInterface {
virtual void UponLeavingGTest();
private:
#if GTEST_HAS_ABSL
Mutex mutex_; // Protects all internal state.
// We save the stack frame below the frame that calls user code.
// We do this because the address of the frame immediately below
// the user code changes between the call to UponLeavingGTest()
// and any calls to the stack trace code from within the user code.
void* caller_frame_ = nullptr;
#endif // GTEST_HAS_ABSL
GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetter);
};
......@@ -984,7 +991,7 @@ bool ParseNaturalNumber(const ::std::string& str, Integer* number) {
const bool parse_success = *end == '\0' && errno == 0;
// TODO(vladl@google.com): Convert this to compile time assertion when it is
// FIXME: Convert this to compile time assertion when it is
// available.
GTEST_CHECK_(sizeof(Integer) <= sizeof(parsed));
......@@ -1024,7 +1031,7 @@ class TestResultAccessor {
#if GTEST_CAN_STREAM_RESULTS_
// Streams test results to the given port on the given host machine.
class GTEST_API_ StreamingListener : public EmptyTestEventListener {
class StreamingListener : public EmptyTestEventListener {
public:
// Abstract base class for writing strings to a socket.
class AbstractSocketWriter {
......
......@@ -26,8 +26,7 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
#include "gtest/internal/gtest-port.h"
......@@ -63,6 +62,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 +160,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() {
......@@ -238,9 +261,9 @@ Mutex::Mutex()
Mutex::~Mutex() {
// Static mutexes are leaked intentionally. It is not thread-safe to try
// to clean them up.
// TODO(yukawa): Switch to Slim Reader/Writer (SRW) Locks, which requires
// FIXME: Switch to Slim Reader/Writer (SRW) Locks, which requires
// nothing to clean it up but is available only on Vista and later.
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa904937.aspx
// https://docs.microsoft.com/en-us/windows/desktop/Sync/slim-reader-writer--srw--locks
if (type_ == kDynamic) {
::DeleteCriticalSection(critical_section_);
delete critical_section_;
......@@ -271,6 +294,43 @@ void Mutex::AssertHeld() {
<< "The current thread is not holding the mutex @" << this;
}
namespace {
// Use the RAII idiom to flag mem allocs that are intentionally never
// deallocated. The motivation is to silence the false positive mem leaks
// that are reported by the debug version of MS's CRT which can only detect
// if an alloc is missing a matching deallocation.
// Example:
// MemoryIsNotDeallocated memory_is_not_deallocated;
// critical_section_ = new CRITICAL_SECTION;
//
class MemoryIsNotDeallocated
{
public:
MemoryIsNotDeallocated() : old_crtdbg_flag_(0) {
#ifdef _MSC_VER
old_crtdbg_flag_ = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
// Set heap allocation block type to _IGNORE_BLOCK so that MS debug CRT
// doesn't report mem leak if there's no matching deallocation.
_CrtSetDbgFlag(old_crtdbg_flag_ & ~_CRTDBG_ALLOC_MEM_DF);
#endif // _MSC_VER
}
~MemoryIsNotDeallocated() {
#ifdef _MSC_VER
// Restore the original _CRTDBG_ALLOC_MEM_DF flag
_CrtSetDbgFlag(old_crtdbg_flag_);
#endif // _MSC_VER
}
private:
int old_crtdbg_flag_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(MemoryIsNotDeallocated);
};
} // namespace
// Initializes owner_thread_id_ and critical_section_ in static mutexes.
void Mutex::ThreadSafeLazyInit() {
// Dynamic mutexes are initialized in the constructor.
......@@ -281,7 +341,11 @@ void Mutex::ThreadSafeLazyInit() {
// If critical_section_init_phase_ was 0 before the exchange, we
// are the first to test it and need to perform the initialization.
owner_thread_id_ = 0;
critical_section_ = new CRITICAL_SECTION;
{
// Use RAII to flag that following mem alloc is never deallocated.
MemoryIsNotDeallocated memory_is_not_deallocated;
critical_section_ = new CRITICAL_SECTION;
}
::InitializeCriticalSection(critical_section_);
// Updates the critical_section_init_phase_ to 2 to signal
// initialization complete.
......@@ -320,7 +384,7 @@ class ThreadWithParamSupport : public ThreadWithParamBase {
Notification* thread_can_start) {
ThreadMainParam* param = new ThreadMainParam(runnable, thread_can_start);
DWORD thread_id;
// TODO(yukawa): Consider to use _beginthreadex instead.
// FIXME: Consider to use _beginthreadex instead.
HANDLE thread_handle = ::CreateThread(
NULL, // Default security.
0, // Default stack size.
......@@ -523,7 +587,8 @@ class ThreadLocalRegistryImpl {
// Returns map of thread local instances.
static ThreadIdToThreadLocals* GetThreadLocalsMapLocked() {
mutex_.AssertHeld();
static ThreadIdToThreadLocals* map = new ThreadIdToThreadLocals;
MemoryIsNotDeallocated memory_is_not_deallocated;
static ThreadIdToThreadLocals* map = new ThreadIdToThreadLocals();
return map;
}
......@@ -672,7 +737,7 @@ static std::string FormatRegexSyntaxError(const char* regex, int index) {
// otherwise returns true.
bool ValidateRegex(const char* regex) {
if (regex == NULL) {
// TODO(wan@google.com): fix the source file location in the
// FIXME: fix the source file location in the
// assertion failures to match where the regex is used in user
// code.
ADD_FAILURE() << "NULL is not a valid simple regular expression.";
......@@ -915,9 +980,10 @@ GTestLog::~GTestLog() {
posix::Abort();
}
}
// Disable Microsoft deprecation warnings for POSIX functions called from
// this class (creat, dup, dup2, and close)
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4996)
GTEST_DISABLE_MSC_DEPRECATED_PUSH_()
#if GTEST_HAS_STREAM_REDIRECTION
......@@ -1001,14 +1067,13 @@ class CapturedStream {
GTEST_DISALLOW_COPY_AND_ASSIGN_(CapturedStream);
};
GTEST_DISABLE_MSC_WARNINGS_POP_()
GTEST_DISABLE_MSC_DEPRECATED_POP_()
static CapturedStream* g_captured_stderr = NULL;
static CapturedStream* g_captured_stdout = NULL;
// Starts capturing an output stream (stdout/stderr).
static void CaptureStream(int fd,
const char* stream_name,
static void CaptureStream(int fd, const char* stream_name,
CapturedStream** stream) {
if (*stream != NULL) {
GTEST_LOG_(FATAL) << "Only one " << stream_name
......@@ -1049,6 +1114,10 @@ std::string GetCapturedStderr() {
#endif // GTEST_HAS_STREAM_REDIRECTION
size_t GetFileSize(FILE* file) {
fseek(file, 0, SEEK_END);
return static_cast<size_t>(ftell(file));
......@@ -1077,22 +1146,36 @@ std::string ReadEntireFile(FILE* file) {
}
#if GTEST_HAS_DEATH_TEST
static const std::vector<std::string>* g_injected_test_argvs = NULL; // Owned.
static const ::std::vector<testing::internal::string>* g_injected_test_argvs =
NULL; // Owned.
void SetInjectableArgvs(const ::std::vector<testing::internal::string>* argvs) {
if (g_injected_test_argvs != argvs)
delete g_injected_test_argvs;
g_injected_test_argvs = argvs;
}
const ::std::vector<testing::internal::string>& GetInjectableArgvs() {
std::vector<std::string> GetInjectableArgvs() {
if (g_injected_test_argvs != NULL) {
return *g_injected_test_argvs;
}
return GetArgvs();
}
void SetInjectableArgvs(const std::vector<std::string>* new_argvs) {
if (g_injected_test_argvs != new_argvs) delete g_injected_test_argvs;
g_injected_test_argvs = new_argvs;
}
void SetInjectableArgvs(const std::vector<std::string>& new_argvs) {
SetInjectableArgvs(
new std::vector<std::string>(new_argvs.begin(), new_argvs.end()));
}
#if GTEST_HAS_GLOBAL_STRING
void SetInjectableArgvs(const std::vector< ::string>& new_argvs) {
SetInjectableArgvs(
new std::vector<std::string>(new_argvs.begin(), new_argvs.end()));
}
#endif // GTEST_HAS_GLOBAL_STRING
void ClearInjectableArgvs() {
delete g_injected_test_argvs;
g_injected_test_argvs = NULL;
}
#endif // GTEST_HAS_DEATH_TEST
#if GTEST_OS_WINDOWS_MOBILE
......@@ -1167,11 +1250,12 @@ bool ParseInt32(const Message& src_text, const char* str, Int32* value) {
bool BoolFromGTestEnv(const char* flag, bool default_value) {
#if defined(GTEST_GET_BOOL_FROM_ENV_)
return GTEST_GET_BOOL_FROM_ENV_(flag, default_value);
#endif // defined(GTEST_GET_BOOL_FROM_ENV_)
#else
const std::string env_var = FlagToEnvVar(flag);
const char* const string_value = posix::GetEnv(env_var.c_str());
return string_value == NULL ?
default_value : strcmp(string_value, "0") != 0;
#endif // defined(GTEST_GET_BOOL_FROM_ENV_)
}
// Reads and returns a 32-bit integer stored in the environment
......@@ -1180,7 +1264,7 @@ bool BoolFromGTestEnv(const char* flag, bool default_value) {
Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) {
#if defined(GTEST_GET_INT32_FROM_ENV_)
return GTEST_GET_INT32_FROM_ENV_(flag, default_value);
#endif // defined(GTEST_GET_INT32_FROM_ENV_)
#else
const std::string env_var = FlagToEnvVar(flag);
const char* const string_value = posix::GetEnv(env_var.c_str());
if (string_value == NULL) {
......@@ -1198,37 +1282,36 @@ Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) {
}
return result;
#endif // defined(GTEST_GET_INT32_FROM_ENV_)
}
// As a special case for the 'output' flag, if GTEST_OUTPUT is not
// set, we look for XML_OUTPUT_FILE, which is set by the Bazel build
// system. The value of XML_OUTPUT_FILE is a filename without the
// "xml:" prefix of GTEST_OUTPUT.
// Note that this is meant to be called at the call site so it does
// not check that the flag is 'output'
// In essence this checks an env variable called XML_OUTPUT_FILE
// and if it is set we prepend "xml:" to its value, if it not set we return ""
std::string OutputFlagAlsoCheckEnvVar(){
std::string default_value_for_output_flag = "";
const char* xml_output_file_env = posix::GetEnv("XML_OUTPUT_FILE");
if (NULL != xml_output_file_env) {
default_value_for_output_flag = std::string("xml:") + xml_output_file_env;
}
return default_value_for_output_flag;
}
// Reads and returns the string environment variable corresponding to
// the given flag; if it's not set, returns default_value.
std::string StringFromGTestEnv(const char* flag, const char* default_value) {
const char* StringFromGTestEnv(const char* flag, const char* default_value) {
#if defined(GTEST_GET_STRING_FROM_ENV_)
return GTEST_GET_STRING_FROM_ENV_(flag, default_value);
#endif // defined(GTEST_GET_STRING_FROM_ENV_)
#else
const std::string env_var = FlagToEnvVar(flag);
const char* value = posix::GetEnv(env_var.c_str());
if (value != NULL) {
return value;
}
// As a special case for the 'output' flag, if GTEST_OUTPUT is not
// set, we look for XML_OUTPUT_FILE, which is set by the Bazel build
// system. The value of XML_OUTPUT_FILE is a filename without the
// "xml:" prefix of GTEST_OUTPUT.
//
// The net priority order after flag processing is thus:
// --gtest_output command line flag
// GTEST_OUTPUT environment variable
// XML_OUTPUT_FILE environment variable
// 'default_value'
if (strcmp(flag, "output") == 0) {
value = posix::GetEnv("XML_OUTPUT_FILE");
if (value != NULL) {
return std::string("xml:") + value;
}
}
return default_value;
const char* const value = posix::GetEnv(env_var.c_str());
return value == NULL ? default_value : value;
#endif // defined(GTEST_GET_STRING_FROM_ENV_)
}
} // namespace internal
......
......@@ -26,10 +26,9 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
// Google Test - The Google C++ Testing Framework
// Google Test - The Google C++ Testing and Mocking Framework
//
// This file implements a universal value printer that can print a
// value of any type T:
......@@ -90,7 +89,7 @@ void PrintBytesInObjectToImpl(const unsigned char* obj_bytes, size_t count,
// If the object size is bigger than kThreshold, we'll have to omit
// some details by printing only the first and the last kChunkSize
// bytes.
// TODO(wan): let the user control the threshold using a flag.
// FIXME: let the user control the threshold using a flag.
if (count < kThreshold) {
PrintByteSegmentInObjectTo(obj_bytes, 0, count, os);
} else {
......@@ -357,8 +356,10 @@ void PrintTo(const wchar_t* s, ostream* os) {
namespace {
bool ContainsUnprintableControlCodes(const char* str, size_t length) {
const unsigned char *s = reinterpret_cast<const unsigned char *>(str);
for (size_t i = 0; i < length; i++) {
char ch = *str++;
unsigned char ch = *s++;
if (std::iscntrl(ch)) {
switch (ch) {
case '\t':
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment