diff options
author | Benjamin Kramer <benny.kra@googlemail.com> | 2010-06-02 22:01:25 +0000 |
---|---|---|
committer | Benjamin Kramer <benny.kra@googlemail.com> | 2010-06-02 22:01:25 +0000 |
commit | e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0 (patch) | |
tree | 1656513dd240b9ed4690589b9934d0e5371694fb /utils/unittest/googletest | |
parent | 18f30e6f5e80787808fe1455742452a5210afe07 (diff) | |
download | external_llvm-e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0.zip external_llvm-e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0.tar.gz external_llvm-e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0.tar.bz2 |
Merge gtest-1.3.0.
OSX users: make sure that CrashReporter is disabled when running unit tests.
Death tests are enabled now so you'll get a ton of message boxes.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@105352 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils/unittest/googletest')
20 files changed, 2089 insertions, 468 deletions
diff --git a/utils/unittest/googletest/gtest-death-test.cc b/utils/unittest/googletest/gtest-death-test.cc index 617e301..149b8a6 100644 --- a/utils/unittest/googletest/gtest-death-test.cc +++ b/utils/unittest/googletest/gtest-death-test.cc @@ -27,17 +27,31 @@ // (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) +// Author: wan@google.com (Zhanyong Wan), vladl@google.com (Vlad Losev) // // This file implements death tests. #include <gtest/gtest-death-test.h> #include <gtest/internal/gtest-port.h> -#ifdef 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 <fcntl.h> #include <limits.h> #include <stdarg.h> + +#if GTEST_OS_WINDOWS +#include <windows.h> +#else +#include <sys/mman.h> +#include <sys/wait.h> +#endif // GTEST_OS_WINDOWS + #endif // GTEST_HAS_DEATH_TEST #include <gtest/gtest-message.h> @@ -48,9 +62,9 @@ // included, or there will be a compiler error. This trick is to // prevent a user from accidentally including gtest-internal-inl.h in // his code. -#define GTEST_IMPLEMENTATION +#define GTEST_IMPLEMENTATION_ 1 #include "gtest/internal/gtest-internal-inl.h" -#undef GTEST_IMPLEMENTATION +#undef GTEST_IMPLEMENTATION_ namespace testing { @@ -68,6 +82,18 @@ 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. " + "Ignored and always uses fork() on POSIX systems where clone() is not " + "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 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, "", @@ -79,7 +105,7 @@ GTEST_DEFINE_string_( "death test. FOR INTERNAL USE ONLY."); } // namespace internal -#ifdef GTEST_HAS_DEATH_TEST +#if GTEST_HAS_DEATH_TEST // ExitedWithCode constructor. ExitedWithCode::ExitedWithCode(int exit_code) : exit_code_(exit_code) { @@ -87,9 +113,14 @@ ExitedWithCode::ExitedWithCode(int exit_code) : exit_code_(exit_code) { // ExitedWithCode function-call operator. bool ExitedWithCode::operator()(int exit_status) const { +#if GTEST_OS_WINDOWS + return exit_status == exit_code_; +#else return WIFEXITED(exit_status) && WEXITSTATUS(exit_status) == exit_code_; +#endif // GTEST_OS_WINDOWS } +#if !GTEST_OS_WINDOWS // KilledBySignal constructor. KilledBySignal::KilledBySignal(int signum) : signum_(signum) { } @@ -98,6 +129,7 @@ KilledBySignal::KilledBySignal(int signum) : signum_(signum) { bool KilledBySignal::operator()(int exit_status) const { return WIFSIGNALED(exit_status) && WTERMSIG(exit_status) == signum_; } +#endif // !GTEST_OS_WINDOWS namespace internal { @@ -107,6 +139,9 @@ namespace internal { // specified by wait(2). static String ExitSummary(int exit_code) { Message m; +#if GTEST_OS_WINDOWS + m << "Exited with exit status " << exit_code; +#else if (WIFEXITED(exit_code)) { m << "Exited with exit status " << WEXITSTATUS(exit_code); } else if (WIFSIGNALED(exit_code)) { @@ -117,6 +152,7 @@ static String ExitSummary(int exit_code) { m << " (core dumped)"; } #endif +#endif // GTEST_OS_WINDOWS return m.GetString(); } @@ -126,6 +162,7 @@ bool ExitedUnsuccessfully(int exit_status) { return !ExitedWithCode(0)(exit_status); } +#if !GTEST_OS_WINDOWS // 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 @@ -133,17 +170,14 @@ bool ExitedUnsuccessfully(int exit_status) { static 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 << " "; + << " in a threaded context. For this test, " << GTEST_NAME_ << " "; if (thread_count == 0) msg << "couldn't detect the number of threads."; else msg << "detected " << thread_count << " threads."; return msg.GetString(); } - -// Static string containing a description of the outcome of the -// last death test. -static String last_death_test_message; +#endif // !GTEST_OS_WINDOWS // Flag characters for reporting a death test that did not die. static const char kDeathTestLived = 'L'; @@ -159,29 +193,33 @@ static const char kDeathTestInternalError = 'I'; enum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED }; // Routine for aborting the program which is safe to call from an -// exec-style death test child process, in which case the the error +// exec-style death test child process, in which case the error // message is propagated back to the parent process. Otherwise, the // message is simply printed to stderr. In either case, the program // then exits with status 1. -void DeathTestAbort(const char* format, ...) { - // This function may be called from a threadsafe-style death test - // child process, which operates on a very small stack. Use the - // heap for any additional non-miniscule memory requirements. +void DeathTestAbort(const String& message) { + // On a POSIX system, this function may be called from a threadsafe-style + // death test child process, which operates on a very small stack. Use + // the heap for any additional non-minuscule memory requirements. const InternalRunDeathTestFlag* const flag = GetUnitTestImpl()->internal_run_death_test_flag(); - va_list args; - va_start(args, format); - if (flag != NULL) { - FILE* parent = fdopen(flag->status_fd, "w"); +// Suppress MSVC complaints about POSIX functions. +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable: 4996) +#endif // _MSC_VER + FILE* parent = fdopen(flag->status_fd(), "w"); +#ifdef _MSC_VER +#pragma warning(pop) +#endif // _MSC_VER fputc(kDeathTestInternalError, parent); - vfprintf(parent, format, args); - fclose(parent); - va_end(args); + fprintf(parent, "%s", message.c_str()); + fflush(parent); _exit(1); } else { - vfprintf(stderr, format, args); - va_end(args); + fprintf(stderr, "%s", message.c_str()); + fflush(stderr); abort(); } } @@ -191,8 +229,9 @@ void DeathTestAbort(const char* format, ...) { #define GTEST_DEATH_TEST_CHECK_(expression) \ do { \ if (!(expression)) { \ - DeathTestAbort("CHECK failed: File %s, line %d: %s", \ - __FILE__, __LINE__, #expression); \ + DeathTestAbort(::testing::internal::String::Format(\ + "CHECK failed: File %s, line %d: %s", \ + __FILE__, __LINE__, #expression)); \ } \ } while (0) @@ -205,16 +244,59 @@ void DeathTestAbort(const char* format, ...) { // something other than EINTR, DeathTestAbort is called. #define GTEST_DEATH_TEST_CHECK_SYSCALL_(expression) \ do { \ - int retval; \ + int gtest_retval; \ do { \ - retval = (expression); \ - } while (retval == -1 && errno == EINTR); \ - if (retval == -1) { \ - DeathTestAbort("CHECK failed: File %s, line %d: %s != -1", \ - __FILE__, __LINE__, #expression); \ + gtest_retval = (expression); \ + } while (gtest_retval == -1 && errno == EINTR); \ + if (gtest_retval == -1) { \ + DeathTestAbort(::testing::internal::String::Format(\ + "CHECK failed: File %s, line %d: %s != -1", \ + __FILE__, __LINE__, #expression)); \ } \ } while (0) +// Returns the message describing the last system error, regardless of the +// platform. +String GetLastSystemErrorMessage() { +#if GTEST_OS_WINDOWS + const DWORD error_num = ::GetLastError(); + + if (error_num == NULL) + return String(""); + + char* message_ptr; + + ::FormatMessageA( + // The caller does not provide a buffer. The function will allocate one. + FORMAT_MESSAGE_ALLOCATE_BUFFER | + // The function must look up an error message in its system error + // message table. + FORMAT_MESSAGE_FROM_SYSTEM | + // Do not expand insert sequences in the message definition. + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, // Message source. Ignored in this call. + error_num, + 0x0, // Use system-default language. + reinterpret_cast<LPSTR>(&message_ptr), + 0, // Buffer size. Ignored in this call. + NULL); // Message arguments. Ignored in this call. + + const String message = message_ptr; + ::LocalFree(message_ptr); + return message; +#else + return errno == 0 ? String("") : String(strerror(errno)); +#endif // GTEST_OS_WINDOWS +} + +// TODO(vladl@google.com): Move the definition of FailFromInternalError +// here. +#if GTEST_OS_WINDOWS +static void FailFromInternalError(HANDLE handle); +#else +static void FailFromInternalError(int fd); +#endif // GTEST_OS_WINDOWS + // Death test constructor. Increments the running death test count // for the current test. DeathTest::DeathTest() { @@ -234,61 +316,393 @@ bool DeathTest::Create(const char* statement, const RE* regex, } const char* DeathTest::LastMessage() { - return last_death_test_message.c_str(); + return last_death_test_message_.c_str(); } +void DeathTest::set_last_death_test_message(const String& message) { + last_death_test_message_ = message; +} + +String DeathTest::last_death_test_message_; + +// Provides cross platform implementation for some death functionality. +// TODO(vladl@google.com): Merge this class with DeathTest in +// gtest-death-test-internal.h. +class DeathTestImpl : public DeathTest { + protected: + DeathTestImpl(const char* statement, const RE* regex) + : statement_(statement), + regex_(regex), + spawned_(false), + status_(-1), + outcome_(IN_PROGRESS) {} + + virtual bool Passed(bool status_ok); + + const char* statement() const { return statement_; } + const RE* regex() const { return regex_; } + bool spawned() const { return spawned_; } + void set_spawned(bool spawned) { spawned_ = spawned; } + int status() const { return status_; } + void set_status(int status) { status_ = status; } + DeathTestOutcome outcome() const { return outcome_; } + void set_outcome(DeathTestOutcome outcome) { outcome_ = outcome; } + + private: + // The textual content of the code this object is testing. This class + // doesn't own this string and should not attempt to delete it. + const char* const statement_; + // The regular expression which test output must match. DeathTestImpl + // doesn't own this object and should not attempt to delete it. + const RE* const regex_; + // True if the death test child process has been successfully spawned. + bool spawned_; + // The exit status of the child process. + int status_; + // How the death test concluded. + DeathTestOutcome outcome_; +}; + +// TODO(vladl@google.com): Move definition of DeathTestImpl::Passed() here. + +#if GTEST_OS_WINDOWS +// WindowsDeathTest implements death tests on Windows. Due to the +// specifics of starting new processes on Windows, death tests there are +// always threadsafe, and Google Test considers the +// --gtest_death_test_style=fast setting to be equivalent to +// --gtest_death_test_style=threadsafe there. +// +// A few implementation notes: Like the Linux version, the Windows +// implementation uses pipes for child-to-parent communication. But due to +// the specifics of pipes on Windows, some extra steps are required: +// +// 1. The parent creates a communication pipe and stores handles to both +// ends of it. +// 2. The parent starts the child and provides it with the information +// necessary to acquire the handle to the write end of the pipe. +// 3. The child acquires the write end of the pipe and signals the parent +// using a Windows event. +// 4. Now the parent can release the write end of the pipe on its side. If +// this is done before step 3, the object's reference count goes down to +// 0 and it is destroyed, preventing the child from acquiring it. The +// parent now has to release it, or read operations on the read end of +// the pipe will not return when the child terminates. +// 5. The parent reads child's output through the pipe (outcome code and +// any possible error messages) from the pipe, and its stderr and then +// determines whether to fail the test. +// +// Note: to distinguish Win32 API calls from the local method and function +// calls, the former are explicitly resolved in the global namespace. +// +class WindowsDeathTest : public DeathTestImpl { + public: + WindowsDeathTest(const char* statement, + const RE* regex, + const char* file, + int line) + : DeathTestImpl(statement, regex), file_(file), line_(line) {} + + // All of these virtual functions are inherited from DeathTest. + virtual int Wait(); + virtual void Abort(AbortReason reason); + 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_; + // Handle to the read end of the pipe to the child process. + // The child keeps its write end of the pipe in the status_handle_ + // field of its InternalRunDeathTestFlag class. + AutoHandle read_handle_; + // Handle to the write end of the pipe to the child process. + AutoHandle write_handle_; + // Child process handle. + AutoHandle child_handle_; + // Event the child process uses to signal the parent that it has + // acquired the handle to the write end of the pipe. After seeing this + // event the parent can release its own handles to make sure its + // ReadFile() calls return when the child terminates. + AutoHandle event_handle_; +}; + +// 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. +// TODO(vladl@google.com): Outcome classification logic is common with +// ForkingDeathTes::Wait(). Refactor it into a +// common function. +int WindowsDeathTest::Wait() { + if (!spawned()) + return 0; + + // Wait until the child either signals that it has acquired the write end + // of the pipe or it dies. + const HANDLE wait_handles[2] = { child_handle_.Get(), event_handle_.Get() }; + switch (::WaitForMultipleObjects(2, + wait_handles, + FALSE, // Waits for any of the handles. + INFINITE)) { + case WAIT_OBJECT_0: + case WAIT_OBJECT_0 + 1: + break; + default: + GTEST_DEATH_TEST_CHECK_(false); // Should not get here. + } + + // The child has acquired the write end of the pipe or exited. + // We release the handle on our side and continue. + write_handle_.Reset(); + event_handle_.Reset(); + + // ReadFile() blocks until data is available (signifying the + // failure of the death test) or until the pipe is closed (signifying + // its success), so it's okay to call this in the parent before or + // after the child process has exited. + char flag; + DWORD bytes_read; + GTEST_DEATH_TEST_CHECK_(::ReadFile(read_handle_.Get(), + &flag, + 1, + &bytes_read, + NULL) || + ::GetLastError() == ERROR_BROKEN_PIPE); + + if (bytes_read == 0) { + set_outcome(DIED); + } else if (bytes_read == 1) { + switch (flag) { + case kDeathTestReturned: + set_outcome(RETURNED); + break; + case kDeathTestLived: + set_outcome(LIVED); + break; + case kDeathTestInternalError: + FailFromInternalError(read_handle_.Get()); // Does not return. + break; + default: + GTEST_LOG_(FATAL, + Message() << "Death test child process reported " + << " unexpected status byte (" + << static_cast<unsigned int>(flag) << ")"); + } + } else { + GTEST_LOG_(FATAL, + Message() << "Read from death test child process failed: " + << GetLastSystemErrorMessage()); + } + read_handle_.Reset(); // Done with reading. + + // Waits for the child process to exit if it haven't already. This + // returns immediately if the child has already exited, regardless of + // whether previous calls to WaitForMultipleObjects synchronized on this + // handle or not. + GTEST_DEATH_TEST_CHECK_( + WAIT_OBJECT_0 == ::WaitForSingleObject(child_handle_.Get(), + INFINITE)); + DWORD status; + GTEST_DEATH_TEST_CHECK_(::GetExitCodeProcess(child_handle_.Get(), + &status)); + child_handle_.Reset(); + set_status(static_cast<int>(status)); + return this->status(); +} + +// TODO(vladl@google.com): define a cross-platform way to write to +// status_fd to be used both here and in ForkingDeathTest::Abort(). +// +// Signals that the death test did not die as expected. This is called +// from the child process only. +void WindowsDeathTest::Abort(AbortReason reason) { + const InternalRunDeathTestFlag* const internal_flag = + GetUnitTestImpl()->internal_run_death_test_flag(); + // The parent process considers the death test to be a failure if + // it finds any data in our pipe. So, here we write a single flag byte + // to the pipe, then exit. + const char status_ch = + reason == TEST_DID_NOT_DIE ? kDeathTestLived : kDeathTestReturned; + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable: 4996) +#endif // _MSC_VER + GTEST_DEATH_TEST_CHECK_SYSCALL_(write(internal_flag->status_fd(), + &status_ch, 1)); +#ifdef _MSC_VER +#pragma warning(pop) +#endif // _MSC_VER + + // The write handle will be closed when the child terminates in _exit(). + _exit(1); // Exits w/o any normal exit hooks (we were supposed to crash) +} + +// The AssumeRole process for a Windows 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 WindowsDeathTest::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. + return EXECUTE_TEST; + } + + // WindowsDeathTest uses an anonymous pipe to communicate results of + // a death test. + SECURITY_ATTRIBUTES handles_are_inheritable = { + sizeof(SECURITY_ATTRIBUTES), NULL, TRUE }; + HANDLE read_handle, write_handle; + GTEST_DEATH_TEST_CHECK_(::CreatePipe(&read_handle, &write_handle, + &handles_are_inheritable, + 0)); // Default buffer size. + read_handle_.Reset(read_handle); + write_handle_.Reset(write_handle); + event_handle_.Reset(::CreateEvent( + &handles_are_inheritable, + TRUE, // The event will automatically reset to non-signaled state. + FALSE, // The initial state is non-signalled. + NULL)); // The even is unnamed. + GTEST_DEATH_TEST_CHECK_(event_handle_.Get() != NULL); + const String filter_flag = String::Format("--%s%s=%s.%s", + GTEST_FLAG_PREFIX_, kFilterFlag, + info->test_case_name(), + info->name()); + const String internal_flag = String::Format( + "--%s%s=%s|%d|%d|%u|%Iu|%Iu", + GTEST_FLAG_PREFIX_, + kInternalRunDeathTestFlag, + file_, line_, + death_test_index, + static_cast<unsigned int>(::GetCurrentProcessId()), + // size_t has the same with as pointers on both 32-bit and 64-bit + // Windows platforms. + // See http://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx. + reinterpret_cast<size_t>(write_handle), + reinterpret_cast<size_t>(event_handle_.Get())); + + char executable_path[_MAX_PATH + 1]; // NOLINT + GTEST_DEATH_TEST_CHECK_( + _MAX_PATH + 1 != ::GetModuleFileNameA(NULL, + executable_path, + _MAX_PATH)); + + String command_line = String::Format("%s %s \"%s\"", + ::GetCommandLineA(), + filter_flag.c_str(), + internal_flag.c_str()); + + DeathTest::set_last_death_test_message(""); + + CaptureStderr(); + // Flush the log buffers since the log streams are shared with the child. + FlushInfoLog(); + + // The child process will share the standard handles with the parent. + STARTUPINFOA startup_info; + memset(&startup_info, 0, sizeof(STARTUPINFO)); + startup_info.dwFlags = STARTF_USESTDHANDLES; + startup_info.hStdInput = ::GetStdHandle(STD_INPUT_HANDLE); + startup_info.hStdOutput = ::GetStdHandle(STD_OUTPUT_HANDLE); + startup_info.hStdError = ::GetStdHandle(STD_ERROR_HANDLE); + + PROCESS_INFORMATION process_info; + GTEST_DEATH_TEST_CHECK_(::CreateProcessA( + executable_path, + const_cast<char*>(command_line.c_str()), + NULL, // Retuned process handle is not inheritable. + NULL, // Retuned thread handle is not inheritable. + TRUE, // Child inherits all inheritable handles (for write_handle_). + 0x0, // Default creation flags. + NULL, // Inherit the parent's environment. + UnitTest::GetInstance()->original_working_dir(), + &startup_info, + &process_info)); + child_handle_.Reset(process_info.hProcess); + ::CloseHandle(process_info.hThread); + set_spawned(true); + return OVERSEE_TEST; +} +#else // We are not on Windows. + // ForkingDeathTest provides implementations for most of the abstract // methods of the DeathTest interface. Only the AssumeRole method is // left undefined. -class ForkingDeathTest : public DeathTest { +class ForkingDeathTest : public DeathTestImpl { public: ForkingDeathTest(const char* statement, const RE* regex); // All of these virtual functions are inherited from DeathTest. virtual int Wait(); - virtual bool Passed(bool status_ok); virtual void Abort(AbortReason reason); protected: - void set_forked(bool forked) { forked_ = forked; } void set_child_pid(pid_t child_pid) { child_pid_ = child_pid; } void set_read_fd(int fd) { read_fd_ = fd; } void set_write_fd(int fd) { write_fd_ = fd; } private: - // The textual content of the code this object is testing. - const char* const statement_; - // The regular expression which test output must match. - const RE* const regex_; - // True if the death test successfully forked. - bool forked_; // PID of child process during death test; 0 in the child process itself. pid_t child_pid_; // File descriptors for communicating the death test's status byte. int read_fd_; // Always -1 in the child process. int write_fd_; // Always -1 in the parent process. - // The exit status of the child process. - int status_; - // How the death test concluded. - DeathTestOutcome outcome_; }; // Constructs a ForkingDeathTest. ForkingDeathTest::ForkingDeathTest(const char* statement, const RE* regex) - : DeathTest(), - statement_(statement), - regex_(regex), - forked_(false), + : DeathTestImpl(statement, regex), child_pid_(-1), read_fd_(-1), - write_fd_(-1), - status_(-1), - outcome_(IN_PROGRESS) { + write_fd_(-1) { } +#endif // GTEST_OS_WINDOWS + +// This is called from a death test parent process to read a failure +// message from the death test child process and log it with the FATAL +// severity. On Windows, the message is read from a pipe handle. On other +// platforms, it is read from a file descriptor. +// TODO(vladl@google.com): Re-factor the code to merge common parts after +// the reading code is abstracted. +#if GTEST_OS_WINDOWS +static void FailFromInternalError(HANDLE handle) { + Message error; + char buffer[256]; -// Reads an internal failure message from a file descriptor, then calls -// LOG(FATAL) with that message. Called from a death test parent process -// to read a failure message from the death test child process. + bool read_succeeded = true; + DWORD bytes_read; + do { + // ERROR_BROKEN_PIPE arises when the other end of the pipe has been + // closed. This is a normal condition for us. + bytes_read = 0; + read_succeeded = ::ReadFile(handle, + buffer, + sizeof(buffer) - 1, + &bytes_read, + NULL) || ::GetLastError() == ERROR_BROKEN_PIPE; + buffer[bytes_read] = 0; + error << buffer; + } while (read_succeeded && bytes_read > 0); + + if (read_succeeded) { + GTEST_LOG_(FATAL, error); + } else { + const DWORD last_error = ::GetLastError(); + const String message = GetLastSystemErrorMessage(); + GTEST_LOG_(FATAL, + Message() << "Error while reading death test internal: " + << message << " [" << last_error << "]"); + } +} +#else static void FailFromInternalError(int fd) { Message error; char buffer[256]; @@ -301,21 +715,24 @@ static void FailFromInternalError(int fd) { } } while (num_read == -1 && errno == EINTR); - // TODO(smcafee): Maybe just FAIL the test instead? if (num_read == 0) { GTEST_LOG_(FATAL, error); } else { + const int last_error = errno; + const String message = GetLastSystemErrorMessage(); GTEST_LOG_(FATAL, Message() << "Error while reading death test internal: " - << strerror(errno) << " [" << errno << "]"); + << message << " [" << last_error << "]"); } } +#endif // GTEST_OS_WINDOWS +#if !GTEST_OS_WINDOWS // 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 ForkingDeathTest::Wait() { - if (!forked_) + if (!spawned()) return 0; // The read() here blocks until data is available (signifying the @@ -330,14 +747,14 @@ int ForkingDeathTest::Wait() { } while (bytes_read == -1 && errno == EINTR); if (bytes_read == 0) { - outcome_ = DIED; + set_outcome(DIED); } else if (bytes_read == 1) { switch (flag) { case kDeathTestReturned: - outcome_ = RETURNED; + set_outcome(RETURNED); break; case kDeathTestLived: - outcome_ = LIVED; + set_outcome(LIVED); break; case kDeathTestInternalError: FailFromInternalError(read_fd_); // Does not return. @@ -349,28 +766,34 @@ int ForkingDeathTest::Wait() { << ")"); } } else { + const String error_message = GetLastSystemErrorMessage(); GTEST_LOG_(FATAL, Message() << "Read from death test child process failed: " - << strerror(errno)); + << error_message); } GTEST_DEATH_TEST_CHECK_SYSCALL_(close(read_fd_)); - GTEST_DEATH_TEST_CHECK_SYSCALL_(waitpid(child_pid_, &status_, 0)); - return status_; + int status; + GTEST_DEATH_TEST_CHECK_SYSCALL_(waitpid(child_pid_, &status, 0)); + set_status(status); + return status; } +#endif // !GTEST_OS_WINDOWS // Assesses the success or failure of a death test, using both private // members which have previously been set, and one argument: // // Private data members: -// outcome: an enumeration describing how the death test +// outcome: An enumeration describing how the death test // concluded: DIED, LIVED, or RETURNED. The death test fails -// in the latter two cases -// status: the exit status of the child process, in the format -// specified by wait(2) -// regex: a regular expression object to be applied to +// in the latter two cases. +// status: The exit status of the child process. On *nix, it is in the +// in the format specified by wait(2). On Windows, this is the +// value supplied to the ExitProcess() API or a numeric code +// of the exception that terminated the program. +// regex: A regular expression object to be applied to // the test's captured standard error output; the death test -// fails if it does not match +// fails if it does not match. // // Argument: // status_ok: true if exit_status is acceptable in the context of @@ -378,9 +801,9 @@ int ForkingDeathTest::Wait() { // // Returns true iff all of the above conditions are met. Otherwise, the // first failing condition, in the order given above, is the one that is -// reported. Also sets the static variable last_death_test_message. -bool ForkingDeathTest::Passed(bool status_ok) { - if (!forked_) +// reported. Also sets the last death test message string. +bool DeathTestImpl::Passed(bool status_ok) { + if (!spawned()) return false; #if GTEST_HAS_GLOBAL_STRING @@ -392,8 +815,8 @@ bool ForkingDeathTest::Passed(bool status_ok) { bool success = false; Message buffer; - buffer << "Death test: " << statement_ << "\n"; - switch (outcome_) { + buffer << "Death test: " << statement() << "\n"; + switch (outcome()) { case LIVED: buffer << " Result: failed to die.\n" << " Error msg: " << error_message; @@ -404,16 +827,16 @@ bool ForkingDeathTest::Passed(bool status_ok) { break; case DIED: if (status_ok) { - if (RE::PartialMatch(error_message, *regex_)) { + if (RE::PartialMatch(error_message, *regex())) { success = true; } else { buffer << " Result: died but not with expected error.\n" - << " Expected: " << regex_->pattern() << "\n" + << " Expected: " << regex()->pattern() << "\n" << "Actual msg: " << error_message; } } else { buffer << " Result: died but not with expected exit code:\n" - << " " << ExitSummary(status_) << "\n"; + << " " << ExitSummary(status()) << "\n"; } break; case IN_PROGRESS: @@ -422,13 +845,14 @@ bool ForkingDeathTest::Passed(bool status_ok) { "DeathTest::Passed somehow called before conclusion of test"); } - last_death_test_message = buffer.GetString(); + DeathTest::set_last_death_test_message(buffer.GetString()); return success; } +#if !GTEST_OS_WINDOWS // Signals that the death test code which should have exited, didn't. // Should be called only in a death test child process. -// Writes a status byte to the child's status file desriptor, then +// Writes a status byte to the child's status file descriptor, then // calls _exit(1). void ForkingDeathTest::Abort(AbortReason reason) { // The parent process considers the death test to be a failure if @@ -461,7 +885,7 @@ DeathTest::TestRole NoExecDeathTest::AssumeRole() { int pipe_fd[2]; GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1); - last_death_test_message = ""; + DeathTest::set_last_death_test_message(""); CaptureStderr(); // When we fork the process below, the log file buffers are copied, but the // file descriptors are shared. We flush all log files here so that closing @@ -486,7 +910,7 @@ DeathTest::TestRole NoExecDeathTest::AssumeRole() { } else { GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); set_read_fd(pipe_fd[0]); - set_forked(true); + set_spawned(true); return OVERSEE_TEST; } } @@ -513,9 +937,9 @@ class Arguments { Arguments() { args_.push_back(NULL); } + ~Arguments() { - for (std::vector<char*>::iterator i = args_.begin(); - i + 1 != args_.end(); + for (std::vector<char*>::iterator i = args_.begin(); i != args_.end(); ++i) { free(*i); } @@ -546,6 +970,22 @@ struct ExecDeathTestArgs { 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. // This function is called in a clone()-ed process and thus must avoid // any potentially unsafe operations like malloc or libc functions. @@ -560,8 +1000,9 @@ static int ExecDeathTestChildMain(void* child_arg) { UnitTest::GetInstance()->original_working_dir(); // We can safely call chdir() as it's a direct system call. if (chdir(original_dir) != 0) { - DeathTestAbort("chdir(\"%s\") failed: %s", - original_dir, strerror(errno)); + DeathTestAbort(String::Format("chdir(\"%s\") failed: %s", + original_dir, + GetLastSystemErrorMessage().c_str())); return EXIT_FAILURE; } @@ -570,9 +1011,11 @@ static int ExecDeathTestChildMain(void* child_arg) { // unsafe. Since execve() doesn't search the PATH, the user must // invoke the test program via a valid path that contains at least // one path separator. - execve(args->argv[0], args->argv, environ); - DeathTestAbort("execve(%s, ...) in %s failed: %s", - args->argv[0], original_dir, strerror(errno)); + execve(args->argv[0], args->argv, GetEnviron()); + DeathTestAbort(String::Format("execve(%s, ...) in %s failed: %s", + args->argv[0], + original_dir, + GetLastSystemErrorMessage().c_str())); return EXIT_FAILURE; } @@ -581,12 +1024,12 @@ static int ExecDeathTestChildMain(void* child_arg) { // This could be accomplished more elegantly by a single recursive // function, but we want to guard against the unlikely possibility of // a smart compiler optimizing the recursion away. -static bool StackLowerThanAddress(const void* ptr) { +bool StackLowerThanAddress(const void* ptr) { int dummy; return &dummy < ptr; } -static bool StackGrowsDown() { +bool StackGrowsDown() { int dummy; return StackLowerThanAddress(&dummy); } @@ -595,18 +1038,36 @@ static bool StackGrowsDown() { // that uses clone(2). It dies with an error message if anything goes // wrong. 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 }; - const pid_t child_pid = clone(&ExecDeathTestChildMain, stack_top, - SIGCHLD, &args); + pid_t child_pid; + +#if GTEST_HAS_CLONE + const bool use_fork = GTEST_FLAG(death_test_use_fork); + + 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); + _exit(0); + } + GTEST_DEATH_TEST_CHECK_(child_pid != -1); - GTEST_DEATH_TEST_CHECK_(munmap(stack, stack_size) != -1); return child_pid; } @@ -622,7 +1083,7 @@ DeathTest::TestRole ExecDeathTest::AssumeRole() { const int death_test_index = info->result()->death_test_count(); if (flag != NULL) { - set_write_fd(flag->status_fd); + set_write_fd(flag->status_fd()); return EXECUTE_TEST; } @@ -634,19 +1095,18 @@ DeathTest::TestRole ExecDeathTest::AssumeRole() { const String filter_flag = String::Format("--%s%s=%s.%s", - GTEST_FLAG_PREFIX, kFilterFlag, + GTEST_FLAG_PREFIX_, kFilterFlag, info->test_case_name(), info->name()); const String internal_flag = - String::Format("--%s%s=%s:%d:%d:%d", - GTEST_FLAG_PREFIX, kInternalRunDeathTestFlag, file_, line_, - death_test_index, pipe_fd[1]); + String::Format("--%s%s=%s|%d|%d|%d", + GTEST_FLAG_PREFIX_, kInternalRunDeathTestFlag, + file_, line_, death_test_index, pipe_fd[1]); Arguments args; args.AddArguments(GetArgvs()); - args.AddArgument("--logtostderr"); args.AddArgument(filter_flag.c_str()); args.AddArgument(internal_flag.c_str()); - last_death_test_message = ""; + DeathTest::set_last_death_test_message(""); CaptureStderr(); // See the comment in NoExecDeathTest::AssumeRole for why the next line @@ -657,10 +1117,12 @@ DeathTest::TestRole ExecDeathTest::AssumeRole() { GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); set_child_pid(child_pid); set_read_fd(pipe_fd[0]); - set_forked(true); + set_spawned(true); return OVERSEE_TEST; } +#endif // !GTEST_OS_WINDOWS + // Creates a concrete DeathTest-derived class that depends on the // --gtest_death_test_style flag, and sets the pointer pointed to // by the "test" argument to its address. If the test should be @@ -676,28 +1138,36 @@ bool DefaultDeathTestFactory::Create(const char* statement, const RE* regex, ->increment_death_test_count(); if (flag != NULL) { - if (death_test_index > flag->index) { - last_death_test_message = String::Format( + if (death_test_index > flag->index()) { + DeathTest::set_last_death_test_message(String::Format( "Death test count (%d) somehow exceeded expected maximum (%d)", - death_test_index, flag->index); + death_test_index, flag->index())); return false; } - if (!(flag->file == file && flag->line == line && - flag->index == death_test_index)) { + if (!(flag->file() == file && flag->line() == line && + flag->index() == death_test_index)) { *test = NULL; return true; } } +#if GTEST_OS_WINDOWS + if (GTEST_FLAG(death_test_style) == "threadsafe" || + GTEST_FLAG(death_test_style) == "fast") { + *test = new WindowsDeathTest(statement, regex, file, line); + } +#else if (GTEST_FLAG(death_test_style) == "threadsafe") { *test = new ExecDeathTest(statement, regex, file, line); } else if (GTEST_FLAG(death_test_style) == "fast") { *test = new NoExecDeathTest(statement, regex); - } else { - last_death_test_message = String::Format( + } +#endif // GTEST_OS_WINDOWS + else { // NOLINT - this is more readable than unbalanced brackets inside #if. + DeathTest::set_last_death_test_message(String::Format( "Unknown death test style \"%s\" encountered", - GTEST_FLAG(death_test_style).c_str()); + GTEST_FLAG(death_test_style).c_str())); return false; } @@ -707,6 +1177,8 @@ bool DefaultDeathTestFactory::Create(const char* statement, const RE* regex, // Splits a given string on a given delimiter, populating a given // vector with the fields. GTEST_HAS_DEATH_TEST implies that we have // ::std::string, so we can use it here. +// TODO(vladl@google.com): Get rid of std::vector to be able to build on +// Visual C++ 7.1 with exceptions disabled. static void SplitString(const ::std::string& str, char delimiter, ::std::vector< ::std::string>* dest) { ::std::vector< ::std::string> parsed; @@ -724,25 +1196,72 @@ static void SplitString(const ::std::string& str, char delimiter, dest->swap(parsed); } -// Attempts to parse a string into a positive integer. Returns true -// if that is possible. GTEST_HAS_DEATH_TEST implies that we have -// ::std::string, so we can use it here. -static bool ParsePositiveInt(const ::std::string& str, int* number) { - // Fail fast if the given string does not begin with a digit; - // this bypasses strtol's "optional leading whitespace and plus - // or minus sign" semantics, which are undesirable here. - if (str.empty() || !isdigit(str[0])) { - return false; +#if GTEST_OS_WINDOWS +// Recreates the pipe and event handles from the provided parameters, +// signals the event, and returns a file descriptor wrapped around the pipe +// handle. This function is called in the child process only. +int GetStatusFileDescriptor(unsigned int parent_process_id, + size_t status_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)); + if (parent_process_handle.Get() == INVALID_HANDLE_VALUE) { + DeathTestAbort(String::Format("Unable to open parent process %u", + parent_process_id)); } - char* endptr; - const long parsed = strtol(str.c_str(), &endptr, 10); // NOLINT - if (*endptr == '\0' && parsed <= INT_MAX) { - *number = static_cast<int>(parsed); - return true; - } else { - return false; + + // TODO(vladl@google.com): Replace the following check with a + // compile-time assertion when available. + GTEST_CHECK_(sizeof(HANDLE) <= sizeof(size_t)); + + const HANDLE status_handle = + reinterpret_cast<HANDLE>(status_handle_as_size_t); + HANDLE dup_status_handle; + + // The newly initialized handle is accessible only in in the parent + // process. To obtain one accessible within the child, we need to use + // DuplicateHandle. + if (!::DuplicateHandle(parent_process_handle.Get(), status_handle, + ::GetCurrentProcess(), &dup_status_handle, + 0x0, // Requested privileges ignored since + // DUPLICATE_SAME_ACCESS is used. + FALSE, // Request non-inheritable handler. + DUPLICATE_SAME_ACCESS)) { + DeathTestAbort(String::Format( + "Unable to duplicate the pipe handle %Iu from the parent process %u", + status_handle_as_size_t, parent_process_id)); } + + const HANDLE event_handle = reinterpret_cast<HANDLE>(event_handle_as_size_t); + HANDLE dup_event_handle; + + if (!::DuplicateHandle(parent_process_handle.Get(), event_handle, + ::GetCurrentProcess(), &dup_event_handle, + 0x0, + FALSE, + DUPLICATE_SAME_ACCESS)) { + DeathTestAbort(String::Format( + "Unable to duplicate the event handle %Iu from the parent process %u", + event_handle_as_size_t, parent_process_id)); + } + + const int status_fd = + ::_open_osfhandle(reinterpret_cast<intptr_t>(dup_status_handle), + O_APPEND | O_TEXT); + if (status_fd == -1) { + DeathTestAbort(String::Format( + "Unable to convert pipe handle %Iu to a file descriptor", + status_handle_as_size_t)); + } + + // Signals the parent that the write end of the pipe has been acquired + // so the parent can release its own write end. + ::SetEvent(dup_event_handle); + + return status_fd; } +#endif // GTEST_OS_WINDOWS // Returns a newly created InternalRunDeathTestFlag object with fields // initialized from the GTEST_FLAG(internal_run_death_test) flag if @@ -750,22 +1269,43 @@ static bool ParsePositiveInt(const ::std::string& str, int* number) { InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() { if (GTEST_FLAG(internal_run_death_test) == "") return NULL; - InternalRunDeathTestFlag* const internal_run_death_test_flag = - new InternalRunDeathTestFlag; // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we // can use it here. + int line = -1; + int index = -1; ::std::vector< ::std::string> fields; - SplitString(GTEST_FLAG(internal_run_death_test).c_str(), ':', &fields); + SplitString(GTEST_FLAG(internal_run_death_test).c_str(), '|', &fields); + int status_fd = -1; + +#if GTEST_OS_WINDOWS + unsigned int parent_process_id = 0; + size_t status_handle_as_size_t = 0; + size_t event_handle_as_size_t = 0; + + if (fields.size() != 6 + || !ParseNaturalNumber(fields[1], &line) + || !ParseNaturalNumber(fields[2], &index) + || !ParseNaturalNumber(fields[3], &parent_process_id) + || !ParseNaturalNumber(fields[4], &status_handle_as_size_t) + || !ParseNaturalNumber(fields[5], &event_handle_as_size_t)) { + DeathTestAbort(String::Format( + "Bad --gtest_internal_run_death_test flag: %s", + GTEST_FLAG(internal_run_death_test).c_str())); + } + status_fd = GetStatusFileDescriptor(parent_process_id, + status_handle_as_size_t, + event_handle_as_size_t); +#else if (fields.size() != 4 - || !ParsePositiveInt(fields[1], &internal_run_death_test_flag->line) - || !ParsePositiveInt(fields[2], &internal_run_death_test_flag->index) - || !ParsePositiveInt(fields[3], - &internal_run_death_test_flag->status_fd)) { - DeathTestAbort("Bad --gtest_internal_run_death_test flag: %s", - GTEST_FLAG(internal_run_death_test).c_str()); - } - internal_run_death_test_flag->file = fields[0].c_str(); - return internal_run_death_test_flag; + || !ParseNaturalNumber(fields[1], &line) + || !ParseNaturalNumber(fields[2], &index) + || !ParseNaturalNumber(fields[3], &status_fd)) { + DeathTestAbort(String::Format( + "Bad --gtest_internal_run_death_test flag: %s", + GTEST_FLAG(internal_run_death_test).c_str())); + } +#endif // GTEST_OS_WINDOWS + return new InternalRunDeathTestFlag(fields[0], line, index, status_fd); } } // namespace internal diff --git a/utils/unittest/googletest/gtest-filepath.cc b/utils/unittest/googletest/gtest-filepath.cc index 493ba0b..07f828c 100644 --- a/utils/unittest/googletest/gtest-filepath.cc +++ b/utils/unittest/googletest/gtest-filepath.cc @@ -36,21 +36,22 @@ #ifdef _WIN32_WCE #include <windows.h> -#elif defined(GTEST_OS_WINDOWS) +#elif GTEST_OS_WINDOWS #include <direct.h> #include <io.h> #include <sys/stat.h> -#elif defined(GTEST_OS_SYMBIAN) +#elif GTEST_OS_SYMBIAN // Symbian OpenC has PATH_MAX in sys/syslimits.h #include <sys/syslimits.h> #include <unistd.h> #else #include <limits.h> -#include <sys/stat.h> -#include <unistd.h> +#include <sys/stat.h> // NOLINT +#include <unistd.h> // NOLINT +#include <climits> // Some Linux distributions define PATH_MAX here. #endif // _WIN32_WCE or _WIN32 -#ifdef GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS #define GTEST_PATH_MAX_ _MAX_PATH #elif defined(PATH_MAX) #define GTEST_PATH_MAX_ PATH_MAX @@ -65,7 +66,7 @@ namespace testing { namespace internal { -#ifdef GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS const char kPathSeparator = '\\'; const char kPathSeparatorString[] = "\\"; #ifdef _WIN32_WCE @@ -90,7 +91,7 @@ FilePath FilePath::GetCurrentDir() { // Windows CE doesn't have a current directory, so we just return // something reasonable. return FilePath(kCurrentDirectoryString); -#elif defined(GTEST_OS_WINDOWS) +#elif GTEST_OS_WINDOWS char cwd[GTEST_PATH_MAX_ + 1] = {}; return FilePath(_getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd); #else @@ -144,19 +145,28 @@ FilePath FilePath::MakeFileName(const FilePath& directory, const FilePath& base_name, int number, const char* extension) { - FilePath dir(directory.RemoveTrailingPathSeparator()); - if (number == 0) { - return FilePath(String::Format("%s%c%s.%s", dir.c_str(), kPathSeparator, - base_name.c_str(), extension)); - } - return FilePath(String::Format("%s%c%s_%d.%s", dir.c_str(), kPathSeparator, - base_name.c_str(), number, extension)); + const FilePath file_name( + (number == 0) ? + String::Format("%s.%s", base_name.c_str(), extension) : + String::Format("%s_%d.%s", base_name.c_str(), number, extension)); + return ConcatPaths(directory, file_name); +} + +// Given directory = "dir", relative_path = "test.xml", returns "dir/test.xml". +// On Windows, uses \ as the separator rather than /. +FilePath FilePath::ConcatPaths(const FilePath& directory, + const FilePath& relative_path) { + if (directory.IsEmpty()) + return relative_path; + const FilePath dir(directory.RemoveTrailingPathSeparator()); + return FilePath(String::Format("%s%c%s", dir.c_str(), kPathSeparator, + relative_path.c_str())); } // Returns true if pathname describes something findable in the file-system, // either a file, directory, or whatever. bool FilePath::FileOrDirectoryExists() const { -#ifdef GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS #ifdef _WIN32_WCE LPCWSTR unicode = String::AnsiToUtf16(pathname_.c_str()); const DWORD attributes = GetFileAttributes(unicode); @@ -176,7 +186,7 @@ bool FilePath::FileOrDirectoryExists() const { // that exists. bool FilePath::DirectoryExists() const { bool result = false; -#ifdef GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS // Don't strip off trailing separator if path is a root directory on // Windows (like "C:\\"). const FilePath& path(IsRootDirectory() ? *this : @@ -205,15 +215,27 @@ bool FilePath::DirectoryExists() const { // Returns true if pathname describes a root directory. (Windows has one // root directory per disk drive.) bool FilePath::IsRootDirectory() const { -#ifdef GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS + // TODO(wan@google.com): 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_.GetLength() == 3 && IsAbsolutePath(); +#else + return pathname_ == kPathSeparatorString; +#endif +} + +// Returns true if pathname describes an absolute path. +bool FilePath::IsAbsolutePath() const { const char* const name = pathname_.c_str(); - return pathname_.GetLength() == 3 && +#if GTEST_OS_WINDOWS + return pathname_.GetLength() >= 3 && ((name[0] >= 'a' && name[0] <= 'z') || (name[0] >= 'A' && name[0] <= 'Z')) && name[1] == ':' && name[2] == kPathSeparator; #else - return pathname_ == kPathSeparatorString; + return name[0] == kPathSeparator; #endif } @@ -264,7 +286,7 @@ bool FilePath::CreateDirectoriesRecursively() const { // directory for any reason, including if the parent directory does not // exist. Not named "CreateDirectory" because that's a macro on Windows. bool FilePath::CreateFolder() const { -#ifdef GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS #ifdef _WIN32_WCE FilePath removed_sep(this->RemoveTrailingPathSeparator()); LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str()); diff --git a/utils/unittest/googletest/gtest-port.cc b/utils/unittest/googletest/gtest-port.cc index 9878cae..abc7149 100644 --- a/utils/unittest/googletest/gtest-port.cc +++ b/utils/unittest/googletest/gtest-port.cc @@ -35,9 +35,16 @@ #include <stdlib.h> #include <stdio.h> -#ifdef GTEST_HAS_DEATH_TEST -#include <regex.h> -#endif // GTEST_HAS_DEATH_TEST +#if GTEST_OS_WINDOWS +#include <io.h> +#include <sys/stat.h> +#else +#include <unistd.h> +#endif // GTEST_OS_WINDOWS + +#if GTEST_USES_SIMPLE_RE +#include <string.h> +#endif #ifdef _WIN32_WCE #include <windows.h> // For TerminateProcess() @@ -47,11 +54,26 @@ #include <gtest/gtest-message.h> #include <gtest/internal/gtest-string.h> +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +#include "gtest/internal/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION_ namespace testing { namespace internal { -#ifdef GTEST_HAS_DEATH_TEST +#if GTEST_OS_WINDOWS +// Microsoft does not provide a definition of STDERR_FILENO. +const int kStdErrFileno = 2; +#else +const int kStdErrFileno = STDERR_FILENO; +#endif // GTEST_OS_WINDOWS + +#if GTEST_USES_POSIX_RE // Implements RE. Currently only needed for death tests. @@ -93,7 +115,13 @@ void RE::Init(const char* regex) { // previous expression returns false. Otherwise partial_regex_ may // not be properly initialized can may cause trouble when it's // freed. - is_valid_ = (regcomp(&partial_regex_, regex, REG_EXTENDED) == 0) && is_valid_; + // + // Some implementation of POSIX regex (e.g. on at least some + // versions of Cygwin) doesn't accept the empty string as a valid + // regex. We change it to an equivalent form "()" to be safe. + const char* const partial_regex = (*regex == '\0') ? "()" : regex; + is_valid_ = (regcomp(&partial_regex_, partial_regex, REG_EXTENDED) == 0) + && is_valid_; EXPECT_TRUE(is_valid_) << "Regular expression \"" << regex << "\" is not a valid POSIX Extended regular expression."; @@ -101,7 +129,262 @@ void RE::Init(const char* regex) { delete[] full_pattern; } -#endif // GTEST_HAS_DEATH_TEST +#elif GTEST_USES_SIMPLE_RE + +// Returns true iff ch appears anywhere in str (excluding the +// terminating '\0' character). +bool IsInSet(char ch, const char* str) { + return ch != '\0' && strchr(str, ch) != NULL; +} + +// Returns true iff ch belongs to the given classification. Unlike +// similar functions in <ctype.h>, these aren't affected by the +// current locale. +bool IsDigit(char ch) { return '0' <= ch && ch <= '9'; } +bool IsPunct(char ch) { + return IsInSet(ch, "^-!\"#$%&'()*+,./:;<=>?@[\\]_`{|}~"); +} +bool IsRepeat(char ch) { return IsInSet(ch, "?*+"); } +bool IsWhiteSpace(char ch) { return IsInSet(ch, " \f\n\r\t\v"); } +bool IsWordChar(char ch) { + return ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') || + ('0' <= ch && ch <= '9') || ch == '_'; +} + +// Returns true iff "\\c" is a supported escape sequence. +bool IsValidEscape(char c) { + return (IsPunct(c) || IsInSet(c, "dDfnrsStvwW")); +} + +// Returns true iff the given atom (specified by escaped and pattern) +// matches ch. The result is undefined if the atom is invalid. +bool AtomMatchesChar(bool escaped, char pattern_char, char ch) { + if (escaped) { // "\\p" where p is pattern_char. + switch (pattern_char) { + case 'd': return IsDigit(ch); + case 'D': return !IsDigit(ch); + case 'f': return ch == '\f'; + case 'n': return ch == '\n'; + case 'r': return ch == '\r'; + case 's': return IsWhiteSpace(ch); + case 'S': return !IsWhiteSpace(ch); + case 't': return ch == '\t'; + case 'v': return ch == '\v'; + case 'w': return IsWordChar(ch); + case 'W': return !IsWordChar(ch); + } + return IsPunct(pattern_char) && pattern_char == ch; + } + + return (pattern_char == '.' && ch != '\n') || pattern_char == ch; +} + +// Helper function used by ValidateRegex() to format error messages. +String FormatRegexSyntaxError(const char* regex, int index) { + return (Message() << "Syntax error at index " << index + << " in simple regular expression \"" << regex << "\": ").GetString(); +} + +// Generates non-fatal failures and returns false if regex is invalid; +// otherwise returns true. +bool ValidateRegex(const char* regex) { + if (regex == NULL) { + // TODO(wan@google.com): 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."; + return false; + } + + bool is_valid = true; + + // True iff ?, *, or + can follow the previous atom. + bool prev_repeatable = false; + for (int i = 0; regex[i]; i++) { + if (regex[i] == '\\') { // An escape sequence + i++; + if (regex[i] == '\0') { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1) + << "'\\' cannot appear at the end."; + return false; + } + + if (!IsValidEscape(regex[i])) { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1) + << "invalid escape sequence \"\\" << regex[i] << "\"."; + is_valid = false; + } + prev_repeatable = true; + } else { // Not an escape sequence. + const char ch = regex[i]; + + if (ch == '^' && i > 0) { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i) + << "'^' can only appear at the beginning."; + is_valid = false; + } else if (ch == '$' && regex[i + 1] != '\0') { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i) + << "'$' can only appear at the end."; + is_valid = false; + } else if (IsInSet(ch, "()[]{}|")) { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i) + << "'" << ch << "' is unsupported."; + is_valid = false; + } else if (IsRepeat(ch) && !prev_repeatable) { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i) + << "'" << ch << "' can only follow a repeatable token."; + is_valid = false; + } + + prev_repeatable = !IsInSet(ch, "^$?*+"); + } + } + + return is_valid; +} + +// Matches a repeated regex atom followed by a valid simple regular +// expression. The regex atom is defined as c if escaped is false, +// or \c otherwise. repeat is the repetition meta character (?, *, +// or +). The behavior is undefined if str contains too many +// characters to be indexable by size_t, in which case the test will +// probably time out anyway. We are fine with this limitation as +// std::string has it too. +bool MatchRepetitionAndRegexAtHead( + bool escaped, char c, char repeat, const char* regex, + const char* str) { + const size_t min_count = (repeat == '+') ? 1 : 0; + const size_t max_count = (repeat == '?') ? 1 : + static_cast<size_t>(-1) - 1; + // We cannot call numeric_limits::max() as it conflicts with the + // max() macro on Windows. + + for (size_t i = 0; i <= max_count; ++i) { + // We know that the atom matches each of the first i characters in str. + if (i >= min_count && MatchRegexAtHead(regex, str + i)) { + // We have enough matches at the head, and the tail matches too. + // Since we only care about *whether* the pattern matches str + // (as opposed to *how* it matches), there is no need to find a + // greedy match. + return true; + } + if (str[i] == '\0' || !AtomMatchesChar(escaped, c, str[i])) + return false; + } + return false; +} + +// Returns true iff regex matches a prefix of str. regex must be a +// valid simple regular expression and not start with "^", or the +// result is undefined. +bool MatchRegexAtHead(const char* regex, const char* str) { + if (*regex == '\0') // An empty regex matches a prefix of anything. + return true; + + // "$" only matches the end of a string. Note that regex being + // valid guarantees that there's nothing after "$" in it. + if (*regex == '$') + return *str == '\0'; + + // Is the first thing in regex an escape sequence? + const bool escaped = *regex == '\\'; + if (escaped) + ++regex; + if (IsRepeat(regex[1])) { + // MatchRepetitionAndRegexAtHead() calls MatchRegexAtHead(), so + // here's an indirect recursion. It terminates as the regex gets + // shorter in each recursion. + return MatchRepetitionAndRegexAtHead( + escaped, regex[0], regex[1], regex + 2, str); + } else { + // regex isn't empty, isn't "$", and doesn't start with a + // repetition. We match the first atom of regex with the first + // character of str and recurse. + return (*str != '\0') && AtomMatchesChar(escaped, *regex, *str) && + MatchRegexAtHead(regex + 1, str + 1); + } +} + +// Returns true iff regex matches any substring of str. regex must be +// a valid simple regular expression, or the result is undefined. +// +// The algorithm is recursive, but the recursion depth doesn't exceed +// the regex length, so we won't need to worry about running out of +// stack space normally. In rare cases the time complexity can be +// exponential with respect to the regex length + the string length, +// but usually it's must faster (often close to linear). +bool MatchRegexAnywhere(const char* regex, const char* str) { + if (regex == NULL || str == NULL) + return false; + + if (*regex == '^') + return MatchRegexAtHead(regex + 1, str); + + // A successful match can be anywhere in str. + do { + if (MatchRegexAtHead(regex, str)) + return true; + } while (*str++ != '\0'); + return false; +} + +// Implements the RE class. + +RE::~RE() { + free(const_cast<char*>(pattern_)); + free(const_cast<char*>(full_pattern_)); +} + +// Returns true iff regular expression re matches the entire str. +bool RE::FullMatch(const char* str, const RE& re) { + return re.is_valid_ && MatchRegexAnywhere(re.full_pattern_, str); +} + +// Returns true iff regular expression re matches a substring of str +// (including str itself). +bool RE::PartialMatch(const char* str, const RE& re) { + return re.is_valid_ && MatchRegexAnywhere(re.pattern_, str); +} + +// Initializes an RE from its string representation. +void RE::Init(const char* regex) { + pattern_ = full_pattern_ = NULL; + if (regex != NULL) { +#if GTEST_OS_WINDOWS + pattern_ = _strdup(regex); +#else + pattern_ = strdup(regex); +#endif + } + + is_valid_ = ValidateRegex(regex); + if (!is_valid_) { + // No need to calculate the full pattern when the regex is invalid. + return; + } + + const size_t len = strlen(regex); + // Reserves enough bytes to hold the regular expression used for a + // full match: we need space to prepend a '^', append a '$', and + // terminate the string with '\0'. + char* buffer = static_cast<char*>(malloc(len + 3)); + full_pattern_ = buffer; + + if (*regex != '^') + *buffer++ = '^'; // Makes sure full_pattern_ starts with '^'. + + // We don't use snprintf or strncpy, as they trigger a warning when + // compiled with VC++ 8.0. + memcpy(buffer, regex, len); + buffer += len; + + if (len == 0 || regex[len - 1] != '$') + *buffer++ = '$'; // Makes sure full_pattern_ ends with '$'. + + *buffer = '\0'; +} + +#endif // GTEST_USES_POSIX_RE // Logs a message at the given severity level. void GTestLog(GTestLogSeverity severity, const char* file, @@ -112,11 +395,19 @@ void GTestLog(GTestLogSeverity severity, const char* file, severity == GTEST_ERROR ? "[ ERROR ]" : "[ FATAL ]"; fprintf(stderr, "\n%s %s:%d: %s\n", marker, file, line, msg); if (severity == GTEST_FATAL) { + fflush(NULL); // abort() is not guaranteed to flush open file streams. abort(); } } -#ifdef GTEST_HAS_DEATH_TEST +#if GTEST_HAS_STD_STRING + +// Disable Microsoft deprecation warnings for POSIX functions called from +// this class (creat, dup, dup2, and close) +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable: 4996) +#endif // _MSC_VER // Defines the stderr capturer. @@ -124,16 +415,26 @@ class CapturedStderr { public: // The ctor redirects stderr to a temporary file. CapturedStderr() { - uncaptured_fd_ = dup(STDERR_FILENO); + uncaptured_fd_ = dup(kStdErrFileno); +#if GTEST_OS_WINDOWS + char temp_dir_path[MAX_PATH + 1] = { '\0' }; // NOLINT + char temp_file_path[MAX_PATH + 1] = { '\0' }; // NOLINT + + ::GetTempPathA(sizeof(temp_dir_path), temp_dir_path); + ::GetTempFileNameA(temp_dir_path, "gtest_redir", 0, temp_file_path); + const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE); + filename_ = temp_file_path; +#else // There's no guarantee that a test has write access to the // current directory, so we create the temporary file in the /tmp // directory instead. char name_template[] = "/tmp/captured_stderr.XXXXXX"; const int captured_fd = mkstemp(name_template); filename_ = name_template; +#endif // GTEST_OS_WINDOWS fflush(NULL); - dup2(captured_fd, STDERR_FILENO); + dup2(captured_fd, kStdErrFileno); close(captured_fd); } @@ -145,7 +446,7 @@ class CapturedStderr { void StopCapture() { // Restores the original stream. fflush(NULL); - dup2(uncaptured_fd_, STDERR_FILENO); + dup2(uncaptured_fd_, kStdErrFileno); close(uncaptured_fd_); uncaptured_fd_ = -1; } @@ -160,6 +461,10 @@ class CapturedStderr { ::std::string filename_; }; +#ifdef _MSC_VER +#pragma warning(pop) +#endif // _MSC_VER + static CapturedStderr* g_captured_stderr = NULL; // Returns the size (in bytes) of a file. @@ -169,8 +474,6 @@ static size_t GetFileSize(FILE * file) { } // Reads the entire content of a file as a string. -// GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we can -// use it here. static ::std::string ReadEntireFile(FILE * file) { const size_t file_size = GetFileSize(file); char* const buffer = new char[file_size]; @@ -206,9 +509,18 @@ void CaptureStderr() { // use it here. ::std::string GetCapturedStderr() { g_captured_stderr->StopCapture(); + +// Disables Microsoft deprecation warning for fopen and fclose. +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable: 4996) +#endif // _MSC_VER FILE* const file = fopen(g_captured_stderr->filename().c_str(), "r"); const ::std::string content = ReadEntireFile(file); fclose(file); +#ifdef _MSC_VER +#pragma warning(pop) +#endif // _MSC_VER delete g_captured_stderr; g_captured_stderr = NULL; @@ -216,6 +528,10 @@ void CaptureStderr() { return content; } +#endif // GTEST_HAS_STD_STRING + +#if GTEST_HAS_DEATH_TEST + // A copy of all command line arguments. Set by InitGoogleTest(). ::std::vector<String> g_argvs; @@ -235,7 +551,8 @@ void abort() { // given flag. For example, FlagToEnvVar("foo") will return // "GTEST_FOO" in the open-source version. static String FlagToEnvVar(const char* flag) { - const String full_flag = (Message() << GTEST_FLAG_PREFIX << flag).GetString(); + const String full_flag = + (Message() << GTEST_FLAG_PREFIX_ << flag).GetString(); Message env_var; for (int i = 0; i != full_flag.GetLength(); i++) { @@ -245,17 +562,6 @@ static String FlagToEnvVar(const char* flag) { return env_var.GetString(); } -// Reads and returns the Boolean environment variable corresponding to -// the given flag; if it's not set, returns default_value. -// -// The value is considered true iff it's not "0". -bool BoolFromGTestEnv(const char* flag, bool default_value) { - const String env_var = FlagToEnvVar(flag); - const char* const string_value = GetEnv(env_var.c_str()); - return string_value == NULL ? - default_value : strcmp(string_value, "0") != 0; -} - // Parses 'str' for a 32-bit signed integer. If successful, writes // the result to *value and returns true; otherwise leaves *value // unchanged and returns false. @@ -297,6 +603,17 @@ bool ParseInt32(const Message& src_text, const char* str, Int32* value) { return true; } +// Reads and returns the Boolean environment variable corresponding to +// the given flag; if it's not set, returns default_value. +// +// The value is considered true iff it's not "0". +bool BoolFromGTestEnv(const char* flag, bool default_value) { + const String env_var = FlagToEnvVar(flag); + const char* const string_value = GetEnv(env_var.c_str()); + return string_value == NULL ? + default_value : strcmp(string_value, "0") != 0; +} + // Reads and returns a 32-bit integer stored in the environment // variable corresponding to the given flag; if it isn't set or // doesn't represent a valid 32-bit integer, returns default_value. diff --git a/utils/unittest/googletest/gtest-test-part.cc b/utils/unittest/googletest/gtest-test-part.cc index 2e80f21..0f0116b 100644 --- a/utils/unittest/googletest/gtest-test-part.cc +++ b/utils/unittest/googletest/gtest-test-part.cc @@ -38,9 +38,9 @@ // included, or there will be a compiler error. This trick is to // prevent a user from accidentally including gtest-internal-inl.h in // his code. -#define GTEST_IMPLEMENTATION +#define GTEST_IMPLEMENTATION_ 1 #include "gtest/internal/gtest-internal-inl.h" -#undef GTEST_IMPLEMENTATION +#undef GTEST_IMPLEMENTATION_ namespace testing { diff --git a/utils/unittest/googletest/gtest-typed-test.cc b/utils/unittest/googletest/gtest-typed-test.cc index d42a159..e45e2ab 100644 --- a/utils/unittest/googletest/gtest-typed-test.cc +++ b/utils/unittest/googletest/gtest-typed-test.cc @@ -35,7 +35,7 @@ namespace testing { namespace internal { -#ifdef GTEST_HAS_TYPED_TEST_P +#if GTEST_HAS_TYPED_TEST_P // Verifies that registered_tests match the test names in // defined_test_names_; returns registered_tests if successful, or @@ -85,6 +85,7 @@ const char* TypedTestCasePState::VerifyRegisteredTestNames( if (errors_str != "") { fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(), errors_str.c_str()); + fflush(stderr); abort(); } diff --git a/utils/unittest/googletest/gtest.cc b/utils/unittest/googletest/gtest.cc index b5a654f..8f4252d 100644 --- a/utils/unittest/googletest/gtest.cc +++ b/utils/unittest/googletest/gtest.cc @@ -43,11 +43,11 @@ #include <wchar.h> #include <wctype.h> -#ifdef GTEST_OS_LINUX +#if GTEST_OS_LINUX // TODO(kenton@google.com): Use autoconf to detect availability of // gettimeofday(). -#define GTEST_HAS_GETTIMEOFDAY +#define GTEST_HAS_GETTIMEOFDAY_ 1 #include <fcntl.h> #include <limits.h> @@ -60,22 +60,22 @@ #include <string> #include <vector> -#elif defined(GTEST_OS_SYMBIAN) -#define GTEST_HAS_GETTIMEOFDAY +#elif GTEST_OS_SYMBIAN +#define GTEST_HAS_GETTIMEOFDAY_ 1 #include <sys/time.h> // NOLINT -#elif defined(GTEST_OS_ZOS) -#define GTEST_HAS_GETTIMEOFDAY +#elif GTEST_OS_ZOS +#define GTEST_HAS_GETTIMEOFDAY_ 1 #include <sys/time.h> // NOLINT // On z/OS we additionally need strings.h for strcasecmp. -#include <strings.h> +#include <strings.h> // NOLINT #elif defined(_WIN32_WCE) // We are on Windows CE. #include <windows.h> // NOLINT -#elif defined(GTEST_OS_WINDOWS) // We are on Windows proper. +#elif GTEST_OS_WINDOWS // We are on Windows proper. #include <io.h> // NOLINT #include <sys/timeb.h> // NOLINT @@ -89,9 +89,9 @@ // TODO(kenton@google.com): There are other ways to get the time on // Windows, like GetTickCount() or GetSystemTimeAsFileTime(). MinGW // supports these. consider using them instead. -#define GTEST_HAS_GETTIMEOFDAY +#define GTEST_HAS_GETTIMEOFDAY_ 1 #include <sys/time.h> // NOLINT -#endif +#endif // defined(__MINGW__) || defined(__MINGW32__) // cpplint thinks that the header is already included, so we want to // silence it. @@ -102,13 +102,17 @@ // Assume other platforms have gettimeofday(). // TODO(kenton@google.com): Use autoconf to detect availability of // gettimeofday(). -#define GTEST_HAS_GETTIMEOFDAY +#define GTEST_HAS_GETTIMEOFDAY_ 1 // cpplint thinks that the header is already included, so we want to // silence it. #include <sys/time.h> // NOLINT #include <unistd.h> // NOLINT +#endif // GTEST_OS_LINUX + +#if GTEST_HAS_EXCEPTIONS +#include <stdexcept> #endif // Indicates that this translation unit is part of Google Test's @@ -116,11 +120,11 @@ // included, or there will be a compiler error. This trick is to // prevent a user from accidentally including gtest-internal-inl.h in // his code. -#define GTEST_IMPLEMENTATION +#define GTEST_IMPLEMENTATION_ 1 #include "gtest/internal/gtest-internal-inl.h" -#undef GTEST_IMPLEMENTATION +#undef GTEST_IMPLEMENTATION_ -#ifdef GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS #define fileno _fileno #define isatty _isatty #define vsnprintf _vsnprintf @@ -145,6 +149,13 @@ static const char kUniversalFilter[] = "*"; // The default output file for XML output. static const char kDefaultOutputFile[] = "test_detail.xml"; +// The environment variable name for the test shard index. +static const char kTestShardIndex[] = "GTEST_SHARD_INDEX"; +// The environment variable name for the total number of test shards. +static const char kTestTotalShards[] = "GTEST_TOTAL_SHARDS"; +// The environment variable name for the test shard status file. +static const char kTestShardStatusFile[] = "GTEST_SHARD_STATUS_FILE"; + namespace internal { // The text used in failure messages to indicate the start of the @@ -154,6 +165,11 @@ const char kStackTraceMarker[] = "\nStack trace:\n"; } // namespace internal GTEST_DEFINE_bool_( + also_run_disabled_tests, + internal::BoolFromGTestEnv("also_run_disabled_tests", false), + "Run disabled tests too, in addition to the tests normally being run."); + +GTEST_DEFINE_bool_( break_on_failure, internal::BoolFromGTestEnv("break_on_failure", false), "True iff a failed assertion should be a debugger break-point."); @@ -161,7 +177,7 @@ GTEST_DEFINE_bool_( GTEST_DEFINE_bool_( catch_exceptions, internal::BoolFromGTestEnv("catch_exceptions", false), - "True iff " GTEST_NAME + "True iff " GTEST_NAME_ " should catch exceptions and treat them as test failures."); GTEST_DEFINE_string_( @@ -199,7 +215,7 @@ GTEST_DEFINE_string_( GTEST_DEFINE_bool_( print_time, internal::BoolFromGTestEnv("print_time", false), - "True iff " GTEST_NAME + "True iff " GTEST_NAME_ " should display elapsed time in text output."); GTEST_DEFINE_int32_( @@ -216,11 +232,22 @@ GTEST_DEFINE_int32_( GTEST_DEFINE_bool_( show_internal_stack_frames, false, - "True iff " GTEST_NAME " should include internal stack frames when " + "True iff " GTEST_NAME_ " should include internal stack frames when " "printing test failure stack traces."); +GTEST_DEFINE_bool_( + throw_on_failure, + internal::BoolFromGTestEnv("throw_on_failure", false), + "When this flag is specified, a failed assertion will throw an exception " + "if exceptions are enabled or exit the program with a non-zero code " + "otherwise."); + namespace internal { +// g_help_flag is true iff the --help flag or an equivalent form is +// specified on the command line. +static bool g_help_flag = false; + // GTestIsInitialized() returns true iff the user has initialized // Google Test. Useful for catching the user mistake of not initializing // Google Test before calling RUN_ALL_TESTS(). @@ -290,7 +317,7 @@ String g_executable_path; FilePath GetCurrentExecutableName() { FilePath result; -#if defined(_WIN32_WCE) || defined(GTEST_OS_WINDOWS) +#if defined(_WIN32_WCE) || GTEST_OS_WINDOWS result.Set(FilePath(g_executable_path).RemoveExtension("exe")); #else result.Set(FilePath(g_executable_path)); @@ -314,16 +341,28 @@ String UnitTestOptions::GetOutputFormat() { // Returns the name of the requested output file, or the default if none // was explicitly specified. -String UnitTestOptions::GetOutputFile() { +String UnitTestOptions::GetAbsolutePathToOutputFile() { const char* const gtest_output_flag = GTEST_FLAG(output).c_str(); if (gtest_output_flag == NULL) return String(""); const char* const colon = strchr(gtest_output_flag, ':'); if (colon == NULL) - return String(kDefaultOutputFile); + return String(internal::FilePath::ConcatPaths( + internal::FilePath( + UnitTest::GetInstance()->original_working_dir()), + internal::FilePath(kDefaultOutputFile)).ToString() ); internal::FilePath output_name(colon + 1); + if (!output_name.IsAbsolutePath()) + // TODO(wan@google.com): on Windows \some\path is not an absolute + // path (as its meaning depends on the current drive), yet the + // following logic for turning it into an absolute path is wrong. + // Fix it. + output_name = internal::FilePath::ConcatPaths( + internal::FilePath(UnitTest::GetInstance()->original_working_dir()), + internal::FilePath(colon + 1)); + if (!output_name.IsDirectory()) return output_name.ToString(); @@ -357,7 +396,7 @@ bool UnitTestOptions::PatternMatchesString(const char *pattern, bool UnitTestOptions::MatchesFilter(const String& name, const char* filter) { const char *cur_pattern = filter; - while (true) { + for (;;) { if (PatternMatchesString(cur_pattern, name.c_str())) { return true; } @@ -409,7 +448,7 @@ bool UnitTestOptions::FilterMatchesTest(const String &test_case_name, !MatchesFilter(full_name, negative.c_str())); } -#ifdef GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS // Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the // given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise. // This function is useful as an __except condition. @@ -719,7 +758,7 @@ static TimeInMillis GetTimeInMillis() { return now_int64.QuadPart; } return 0; -#elif defined(GTEST_OS_WINDOWS) && !defined(GTEST_HAS_GETTIMEOFDAY) +#elif GTEST_OS_WINDOWS && !GTEST_HAS_GETTIMEOFDAY_ __timeb64 now; #ifdef _MSC_VER // MSVC 8 deprecates _ftime64(), so we want to suppress warning 4996 @@ -734,7 +773,7 @@ static TimeInMillis GetTimeInMillis() { _ftime64(&now); #endif // _MSC_VER return static_cast<TimeInMillis>(now.time) * 1000 + now.millitm; -#elif defined(GTEST_HAS_GETTIMEOFDAY) +#elif GTEST_HAS_GETTIMEOFDAY_ struct timeval now; gettimeofday(&now, NULL); return static_cast<TimeInMillis>(now.tv_sec) * 1000 + now.tv_usec / 1000; @@ -769,7 +808,7 @@ static char* CloneString(const char* str, size_t length) { char* const clone = new char[length + 1]; // MSVC 8 deprecates strncpy(), so we want to suppress warning // 4996 (deprecated function) there. -#ifdef GTEST_OS_WINDOWS // We are on Windows. +#if GTEST_OS_WINDOWS // We are on Windows. #pragma warning(push) // Saves the current warning state. #pragma warning(disable:4996) // Temporarily disables warning 4996. strncpy(clone, str, length); @@ -1290,7 +1329,7 @@ AssertionResult IsNotSubstring( namespace internal { -#ifdef GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS namespace { @@ -1418,14 +1457,14 @@ char* CodePointToUtf8(UInt32 code_point, char* str) { // null-terminate the destination string. // MSVC 8 deprecates strncpy(), so we want to suppress warning // 4996 (deprecated function) there. -#ifdef GTEST_OS_WINDOWS // We are on Windows. +#if GTEST_OS_WINDOWS // We are on Windows. #pragma warning(push) // Saves the current warning state. #pragma warning(disable:4996) // Temporarily disables warning 4996. #endif strncpy(str, String::Format("(Invalid Unicode 0x%X)", code_point).c_str(), 32); -#ifdef GTEST_OS_WINDOWS // We are on Windows. -#pragma warning(pop) // Restores the warning state. +#if GTEST_OS_WINDOWS // We are on Windows. +#pragma warning(pop) // Restores the warning state. #endif str[31] = '\0'; // Makes sure no change in the format to strncpy leaves // the result unterminated. @@ -1441,23 +1480,19 @@ char* CodePointToUtf8(UInt32 code_point, char* str) { // and thus should be combined into a single Unicode code point // using CreateCodePointFromUtf16SurrogatePair. inline bool IsUtf16SurrogatePair(wchar_t first, wchar_t second) { - if (sizeof(wchar_t) == 2) - return (first & 0xFC00) == 0xD800 && (second & 0xFC00) == 0xDC00; - else - return false; + return sizeof(wchar_t) == 2 && + (first & 0xFC00) == 0xD800 && (second & 0xFC00) == 0xDC00; } // Creates a Unicode code point from UTF16 surrogate pair. inline UInt32 CreateCodePointFromUtf16SurrogatePair(wchar_t first, wchar_t second) { - if (sizeof(wchar_t) == 2) { - const UInt32 mask = (1 << 10) - 1; - return (((first & mask) << 10) | (second & mask)) + 0x10000; - } else { - // This should not be called, but we provide a sensible default - // in case it is. - return static_cast<UInt32>(first); - } + const UInt32 mask = (1 << 10) - 1; + return (sizeof(wchar_t) == 2) ? + (((first & mask) << 10) | (second & mask)) + 0x10000 : + // This function should not be called when the condition is + // false, but we provide a sensible default in case it is. + static_cast<UInt32>(first); } // Converts a wide string to a narrow string in UTF-8 encoding. @@ -1572,7 +1607,7 @@ bool String::CaseInsensitiveCStringEquals(const char * lhs, const char * rhs) { if ( rhs == NULL ) return false; -#ifdef GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS return _stricmp(lhs, rhs) == 0; #else // GTEST_OS_WINDOWS return strcasecmp(lhs, rhs) == 0; @@ -1597,9 +1632,9 @@ bool String::CaseInsensitiveWideCStringEquals(const wchar_t* lhs, if ( rhs == NULL ) return false; -#ifdef GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS return _wcsicmp(lhs, rhs) == 0; -#elif defined(GTEST_OS_LINUX) +#elif GTEST_OS_LINUX return wcscasecmp(lhs, rhs) == 0; #else // Mac OS X and Cygwin don't define wcscasecmp. Other unknown OSes @@ -1610,7 +1645,7 @@ bool String::CaseInsensitiveWideCStringEquals(const wchar_t* lhs, right = towlower(*rhs++); } while (left && left == right); return left == right; -#endif // OS selector +#endif // OS selector } // Constructs a String by copying a given number of chars from a @@ -1700,7 +1735,7 @@ String String::Format(const char * format, ...) { char buffer[4096]; // MSVC 8 deprecates vsnprintf(), so we want to suppress warning // 4996 (deprecated function) there. -#ifdef GTEST_OS_WINDOWS // We are on Windows. +#if GTEST_OS_WINDOWS // We are on Windows. #pragma warning(push) // Saves the current warning state. #pragma warning(disable:4996) // Temporarily disables warning 4996. const int size = @@ -1807,7 +1842,7 @@ bool TestResult::ValidateTestProperty(const TestProperty& test_property) { << "Reserved key used in RecordProperty(): " << key << " ('name', 'status', 'time', and 'classname' are reserved by " - << GTEST_NAME << ")"; + << GTEST_NAME_ << ")"; return false; } return true; @@ -1897,7 +1932,7 @@ void Test::RecordProperty(const char* key, int value) { RecordProperty(key, value_message.GetString().c_str()); } -#ifdef GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS // We are on Windows. // Adds an "exception thrown" fatal failure to the current test. @@ -1993,7 +2028,7 @@ void Test::Run() { if (!HasSameFixtureClass()) return; internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); -#if defined(GTEST_OS_WINDOWS) && !defined(__MINGW32__) +#if GTEST_OS_WINDOWS && !defined(__MINGW32__) // We are on Windows. impl->os_stack_trace_getter()->UponLeavingGTest(); __try { @@ -2102,7 +2137,7 @@ TestInfo* MakeAndRegisterTestInfo( return test_info; } -#ifdef GTEST_HAS_PARAM_TEST +#if GTEST_HAS_PARAM_TEST void ReportInvalidTestCaseType(const char* test_case_name, const char* file, int line) { Message errors; @@ -2201,7 +2236,7 @@ namespace internal { // and INSTANTIATE_TEST_CASE_P into regular tests and registers those. // This will be done just once during the program runtime. void UnitTestImpl::RegisterParameterizedTests() { -#ifdef GTEST_HAS_PARAM_TEST +#if GTEST_HAS_PARAM_TEST if (!parameterized_tests_registered_) { parameterized_test_registry_.RegisterTests(); parameterized_tests_registered_ = true; @@ -2227,7 +2262,7 @@ void TestInfoImpl::Run() { const TimeInMillis start = GetTimeInMillis(); impl->os_stack_trace_getter()->UponLeavingGTest(); -#if defined(GTEST_OS_WINDOWS) && !defined(__MINGW32__) +#if GTEST_OS_WINDOWS && !defined(__MINGW32__) // We are on Windows. Test* test = NULL; @@ -2418,14 +2453,20 @@ static const char * TestPartResultTypeToString(TestPartResultType type) { return "Unknown result type"; } +// Prints a TestPartResult to a String. +static internal::String PrintTestPartResultToString( + const TestPartResult& test_part_result) { + return (Message() + << internal::FormatFileLocation(test_part_result.file_name(), + test_part_result.line_number()) + << " " << TestPartResultTypeToString(test_part_result.type()) + << test_part_result.message()).GetString(); +} + // Prints a TestPartResult. static void PrintTestPartResult( - const TestPartResult & test_part_result) { - printf("%s %s%s\n", - internal::FormatFileLocation(test_part_result.file_name(), - test_part_result.line_number()).c_str(), - TestPartResultTypeToString(test_part_result.type()), - test_part_result.message()); + const TestPartResult& test_part_result) { + printf("%s\n", PrintTestPartResultToString(test_part_result).c_str()); fflush(stdout); } @@ -2434,12 +2475,13 @@ static void PrintTestPartResult( namespace internal { enum GTestColor { + COLOR_DEFAULT, COLOR_RED, COLOR_GREEN, COLOR_YELLOW }; -#if defined(GTEST_OS_WINDOWS) && !defined(_WIN32_WCE) +#if GTEST_OS_WINDOWS && !defined(_WIN32_WCE) // Returns the character attribute for the given color. WORD GetColorAttribute(GTestColor color) { @@ -2447,20 +2489,21 @@ WORD GetColorAttribute(GTestColor color) { case COLOR_RED: return FOREGROUND_RED; case COLOR_GREEN: return FOREGROUND_GREEN; case COLOR_YELLOW: return FOREGROUND_RED | FOREGROUND_GREEN; + default: return 0; } - return 0; } #else -// Returns the ANSI color code for the given color. +// Returns the ANSI color code for the given color. COLOR_DEFAULT is +// an invalid input. const char* GetAnsiColorCode(GTestColor color) { switch (color) { case COLOR_RED: return "1"; case COLOR_GREEN: return "2"; case COLOR_YELLOW: return "3"; + default: return NULL; }; - return NULL; } #endif // GTEST_OS_WINDOWS && !_WIN32_WCE @@ -2470,7 +2513,7 @@ bool ShouldUseColor(bool stdout_is_tty) { const char* const gtest_color = GTEST_FLAG(color).c_str(); if (String::CaseInsensitiveCStringEquals(gtest_color, "auto")) { -#ifdef GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS // On Windows the TERM variable is usually not set, but the // console there does support colors. return stdout_is_tty; @@ -2502,11 +2545,13 @@ void ColoredPrintf(GTestColor color, const char* fmt, ...) { va_list args; va_start(args, fmt); -#if defined(_WIN32_WCE) || defined(GTEST_OS_SYMBIAN) || defined(GTEST_OS_ZOS) - static const bool use_color = false; +#if defined(_WIN32_WCE) || GTEST_OS_SYMBIAN || GTEST_OS_ZOS + const bool use_color = false; #else - static const bool use_color = ShouldUseColor(isatty(fileno(stdout)) != 0); -#endif // !_WIN32_WCE + static const bool in_color_mode = + ShouldUseColor(isatty(fileno(stdout)) != 0); + const bool use_color = in_color_mode && (color != COLOR_DEFAULT); +#endif // defined(_WIN32_WCE) || GTEST_OS_SYMBIAN || GTEST_OS_ZOS // The '!= 0' comparison is necessary to satisfy MSVC 7.1. if (!use_color) { @@ -2515,7 +2560,7 @@ void ColoredPrintf(GTestColor color, const char* fmt, ...) { return; } -#if defined(GTEST_OS_WINDOWS) && !defined(_WIN32_WCE) +#if GTEST_OS_WINDOWS && !defined(_WIN32_WCE) const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE); // Gets the current text color. @@ -2533,13 +2578,14 @@ void ColoredPrintf(GTestColor color, const char* fmt, ...) { printf("\033[0;3%sm", GetAnsiColorCode(color)); vprintf(fmt, args); printf("\033[m"); // Resets the terminal to default. -#endif // GTEST_OS_WINDOWS && !_WIN32_WCE +#endif // GTEST_OS_WINDOWS && !defined(_WIN32_WCE) va_end(args); } } // namespace internal using internal::ColoredPrintf; +using internal::COLOR_DEFAULT; using internal::COLOR_RED; using internal::COLOR_GREEN; using internal::COLOR_YELLOW; @@ -2579,7 +2625,14 @@ void PrettyUnitTestResultPrinter::OnUnitTestStart( // tests may be skipped. if (!internal::String::CStringEquals(filter, kUniversalFilter)) { ColoredPrintf(COLOR_YELLOW, - "Note: %s filter = %s\n", GTEST_NAME, filter); + "Note: %s filter = %s\n", GTEST_NAME_, filter); + } + + if (internal::ShouldShard(kTestTotalShards, kTestShardIndex, false)) { + ColoredPrintf(COLOR_YELLOW, + "Note: This is test shard %s of %s.\n", + internal::GetEnv(kTestShardIndex), + internal::GetEnv(kTestTotalShards)); } const internal::UnitTestImpl* const impl = unit_test->impl(); @@ -2736,7 +2789,7 @@ void PrettyUnitTestResultPrinter::OnUnitTestEnd( } int num_disabled = impl->disabled_test_count(); - if (num_disabled) { + if (num_disabled && !GTEST_FLAG(also_run_disabled_tests)) { if (!num_failures) { printf("\n"); // Add a spacer if no FAILURE banner is displayed. } @@ -2899,7 +2952,7 @@ void XmlUnitTestResultPrinter::OnUnitTestEnd(const UnitTest* unit_test) { if (output_dir.CreateDirectoriesRecursively()) { // MSVC 8 deprecates fopen(), so we want to suppress warning 4996 // (deprecated function) there. -#ifdef GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS // We are on Windows. #pragma warning(push) // Saves the current warning state. #pragma warning(disable:4996) // Temporarily disables warning 4996. @@ -3164,7 +3217,7 @@ void OsStackTraceGetter::UponLeavingGTest() { const char* const OsStackTraceGetter::kElidedFramesMarker = - "... " GTEST_NAME " internal frames ..."; + "... " GTEST_NAME_ " internal frames ..."; } // namespace internal @@ -3213,6 +3266,19 @@ Environment* UnitTest::AddEnvironment(Environment* env) { return env; } +#if GTEST_HAS_EXCEPTIONS +// A failed Google Test assertion will throw an exception of this type +// when exceptions are enabled. We derive it from std::runtime_error, +// which is for errors presumably detectable only at run time. Since +// std::runtime_error inherits from std::exception, many testing +// frameworks know how to extract and print the message inside it. +class GoogleTestFailureException : public ::std::runtime_error { + public: + explicit GoogleTestFailureException(const TestPartResult& failure) + : runtime_error(PrintTestPartResultToString(failure).c_str()) {} +}; +#endif + // Adds a TestPartResult to the current TestResult object. All Google Test // assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) eventually call // this to report their results. The user code should use the @@ -3228,7 +3294,7 @@ void UnitTest::AddTestPartResult(TestPartResultType result_type, internal::MutexLock lock(&mutex_); if (impl_->gtest_trace_stack()->size() > 0) { - msg << "\n" << GTEST_NAME << " trace:"; + msg << "\n" << GTEST_NAME_ << " trace:"; for (internal::ListNode<internal::TraceInfo>* node = impl_->gtest_trace_stack()->Head(); @@ -3249,11 +3315,23 @@ void UnitTest::AddTestPartResult(TestPartResultType result_type, impl_->GetTestPartResultReporterForCurrentThread()-> ReportTestPartResult(result); - // If this is a failure and the user wants the debugger to break on - // failures ... - if (result_type != TPRT_SUCCESS && GTEST_FLAG(break_on_failure)) { - // ... then we generate a seg fault. - *static_cast<int*>(NULL) = 1; + if (result_type != TPRT_SUCCESS) { + // gunit_break_on_failure takes precedence over + // gunit_throw_on_failure. This allows a user to set the latter + // in the code (perhaps in order to use Google Test assertions + // with another testing framework) and specify the former on the + // command line for debugging. + if (GTEST_FLAG(break_on_failure)) { + *static_cast<int*>(NULL) = 1; + } else if (GTEST_FLAG(throw_on_failure)) { +#if GTEST_HAS_EXCEPTIONS + throw GoogleTestFailureException(result); +#else + // We cannot call abort() as it generates a pop-up in debug mode + // that cannot be suppressed in VC 7.1 or below. + exit(1); +#endif + } } } @@ -3271,19 +3349,48 @@ void UnitTest::RecordPropertyForCurrentTest(const char* key, // We don't protect this under mutex_, as we only support calling it // from the main thread. int UnitTest::Run() { -#if defined(GTEST_OS_WINDOWS) && !defined(__MINGW32__) - +#if GTEST_OS_WINDOWS && !defined(__MINGW32__) + + const bool in_death_test_child_process = + internal::GTEST_FLAG(internal_run_death_test).GetLength() > 0; + + // Either the user wants Google Test to catch exceptions thrown by the + // tests or this is executing in the context of death test child + // process. In either case the user does not want to see pop-up dialogs + // about crashes - they are expected.. + if (GTEST_FLAG(catch_exceptions) || in_death_test_child_process) { + // process. In either case the user does not want to see pop-up dialogs + // about crashes - they are expected.. + if (GTEST_FLAG(catch_exceptions) || in_death_test_child_process) { #if !defined(_WIN32_WCE) - // SetErrorMode doesn't exist on CE. - if (GTEST_FLAG(catch_exceptions)) { - // The user wants Google Test to catch exceptions thrown by the tests. - - // This lets fatal errors be handled by us, instead of causing pop-ups. + // SetErrorMode doesn't exist on CE. SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX); - } #endif // _WIN32_WCE + // Death test children can be terminated with _abort(). On Windows, + // _abort() can show a dialog with a warning message. This forces the + // abort message to go to stderr instead. + _set_error_mode(_OUT_TO_STDERR); + + // In the debug version, Visual Studio pops up a separate dialog + // offering a choice to debug the aborted program. We need to suppress + // this dialog or it will pop up for every EXPECT/ASSERT_DEATH statement + // executed. Google Test will notify the user of any unexpected + // failure via stderr. +#if _MSC_VER >= 1400 + // VC++ doesn't define _set_abort_behavior() prior to the version 8.0. + // Users of prior VC versions shall suffer the agony and pain of + // clicking through the countless debug dialogs. + // TODO(vladl@google.com): find a way to suppress the abort dialog() in the + // debug mode when compiled with VC 7.1 or lower. + if (!GTEST_FLAG(break_on_failure)) + _set_abort_behavior( + 0x0, // Clear the following flags: + _WRITE_ABORT_MSG | _CALL_REPORTFAULT); // pop-up window, core dump. +#endif // _MSC_VER >= 1400 + } + __try { return impl_->RunAllTests(); } __except(internal::UnitTestOptions::GTestShouldProcessSEH( @@ -3322,7 +3429,7 @@ const TestInfo* UnitTest::current_test_info() const { return impl_->current_test_info(); } -#ifdef GTEST_HAS_PARAM_TEST +#if GTEST_HAS_PARAM_TEST // Returns ParameterizedTestCaseRegistry object used to keep track of // value-parameterized tests and instantiate and register them. // L < mutex_ @@ -3377,7 +3484,7 @@ UnitTestImpl::UnitTestImpl(UnitTest* parent) per_thread_test_part_result_reporter_( &default_per_thread_test_part_result_reporter_), test_cases_(), -#ifdef GTEST_HAS_PARAM_TEST +#if GTEST_HAS_PARAM_TEST parameterized_test_registry_(), parameterized_tests_registered_(false), #endif // GTEST_HAS_PARAM_TEST @@ -3387,7 +3494,7 @@ UnitTestImpl::UnitTestImpl(UnitTest* parent) ad_hoc_test_result_(), result_printer_(NULL), os_stack_trace_getter_(NULL), -#ifdef GTEST_HAS_DEATH_TEST +#if GTEST_HAS_DEATH_TEST elapsed_time_(0), internal_run_death_test_flag_(NULL), death_test_factory_(new DefaultDeathTestFactory) { @@ -3495,8 +3602,17 @@ int UnitTestImpl::RunAllTests() { return 1; } + // Do not run any test if the --help flag was specified. + if (g_help_flag) + return 0; + RegisterParameterizedTests(); + // Even if sharding is not on, test runners may want to use the + // GTEST_SHARD_STATUS_FILE to query whether the test supports the sharding + // protocol. + internal::WriteToShardStatusFileIfNeeded(); + // Lists all the tests and exits if the --gtest_list_tests // flag was specified. if (GTEST_FLAG(list_tests)) { @@ -3508,16 +3624,22 @@ int UnitTestImpl::RunAllTests() { // death test. bool in_subprocess_for_death_test = false; -#ifdef GTEST_HAS_DEATH_TEST +#if GTEST_HAS_DEATH_TEST internal_run_death_test_flag_.reset(ParseInternalRunDeathTestFlag()); in_subprocess_for_death_test = (internal_run_death_test_flag_.get() != NULL); #endif // GTEST_HAS_DEATH_TEST UnitTestEventListenerInterface * const printer = result_printer(); + const bool should_shard = ShouldShard(kTestTotalShards, kTestShardIndex, + in_subprocess_for_death_test); + // Compares the full test names with the filter to decide which // tests to run. - const bool has_tests_to_run = FilterTests() > 0; + const bool has_tests_to_run = FilterTests(should_shard + ? HONOR_SHARDING_PROTOCOL + : IGNORE_SHARDING_PROTOCOL) > 0; + // True iff at least one test has failed. bool failed = false; @@ -3573,14 +3695,128 @@ int UnitTestImpl::RunAllTests() { return failed ? 1 : 0; } +// Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file +// if the variable is present. If a file already exists at this location, this +// function will write over it. If the variable is present, but the file cannot +// be created, prints an error and exits. +void WriteToShardStatusFileIfNeeded() { + const char* const test_shard_file = GetEnv(kTestShardStatusFile); + if (test_shard_file != NULL) { +#ifdef _MSC_VER // MSVC 8 deprecates fopen(). +#pragma warning(push) // Saves the current warning state. +#pragma warning(disable:4996) // Temporarily disables warning on + // deprecated functions. +#endif + FILE* const file = fopen(test_shard_file, "w"); +#ifdef _MSC_VER +#pragma warning(pop) // Restores the warning state. +#endif + if (file == NULL) { + ColoredPrintf(COLOR_RED, + "Could not write to the test shard status file \"%s\" " + "specified by the %s environment variable.\n", + test_shard_file, kTestShardStatusFile); + fflush(stdout); + exit(EXIT_FAILURE); + } + fclose(file); + } +} + +// Checks whether sharding is enabled by examining the relevant +// environment variable values. If the variables are present, +// but inconsistent (i.e., shard_index >= total_shards), prints +// an error and exits. If in_subprocess_for_death_test, sharding is +// disabled because it must only be applied to the original test +// process. Otherwise, we could filter out death tests we intended to execute. +bool ShouldShard(const char* total_shards_env, + const char* shard_index_env, + bool in_subprocess_for_death_test) { + if (in_subprocess_for_death_test) { + return false; + } + + const Int32 total_shards = Int32FromEnvOrDie(total_shards_env, -1); + const Int32 shard_index = Int32FromEnvOrDie(shard_index_env, -1); + + if (total_shards == -1 && shard_index == -1) { + return false; + } else if (total_shards == -1 && shard_index != -1) { + const Message msg = Message() + << "Invalid environment variables: you have " + << kTestShardIndex << " = " << shard_index + << ", but have left " << kTestTotalShards << " unset.\n"; + ColoredPrintf(COLOR_RED, msg.GetString().c_str()); + fflush(stdout); + exit(EXIT_FAILURE); + } else if (total_shards != -1 && shard_index == -1) { + const Message msg = Message() + << "Invalid environment variables: you have " + << kTestTotalShards << " = " << total_shards + << ", but have left " << kTestShardIndex << " unset.\n"; + ColoredPrintf(COLOR_RED, msg.GetString().c_str()); + fflush(stdout); + exit(EXIT_FAILURE); + } else if (shard_index < 0 || shard_index >= total_shards) { + const Message msg = Message() + << "Invalid environment variables: we require 0 <= " + << kTestShardIndex << " < " << kTestTotalShards + << ", but you have " << kTestShardIndex << "=" << shard_index + << ", " << kTestTotalShards << "=" << total_shards << ".\n"; + ColoredPrintf(COLOR_RED, msg.GetString().c_str()); + fflush(stdout); + exit(EXIT_FAILURE); + } + + return total_shards > 1; +} + +// Parses the environment variable var as an Int32. If it is unset, +// returns default_val. If it is not an Int32, prints an error +// and aborts. +Int32 Int32FromEnvOrDie(const char* const var, Int32 default_val) { + const char* str_val = GetEnv(var); + if (str_val == NULL) { + return default_val; + } + + Int32 result; + if (!ParseInt32(Message() << "The value of environment variable " << var, + str_val, &result)) { + exit(EXIT_FAILURE); + } + return result; +} + +// Given the total number of shards, the shard index, and the test id, +// returns true iff the test should be run on this shard. The test id is +// some arbitrary but unique non-negative integer assigned to each test +// method. Assumes that 0 <= shard_index < total_shards. +bool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id) { + return (test_id % total_shards) == shard_index; +} + // Compares the name of each test with the user-specified filter to // decide whether the test should be run, then records the result in // each TestCase and TestInfo object. +// If shard_tests == true, further filters tests based on sharding +// variables in the environment - see +// http://code.google.com/p/googletest/wiki/GoogleTestAdvancedGuide. // Returns the number of tests that should run. -int UnitTestImpl::FilterTests() { +int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) { + const Int32 total_shards = shard_tests == HONOR_SHARDING_PROTOCOL ? + Int32FromEnvOrDie(kTestTotalShards, -1) : -1; + const Int32 shard_index = shard_tests == HONOR_SHARDING_PROTOCOL ? + Int32FromEnvOrDie(kTestShardIndex, -1) : -1; + + // num_runnable_tests are the number of tests that will + // run across all shards (i.e., match filter and are not disabled). + // num_selected_tests are the number of tests to be run on + // this shard. int num_runnable_tests = 0; + int num_selected_tests = 0; for (const internal::ListNode<TestCase *> *test_case_node = - test_cases_.Head(); + test_cases_.Head(); test_case_node != NULL; test_case_node = test_case_node->next()) { TestCase * const test_case = test_case_node->element(); @@ -3588,7 +3824,7 @@ int UnitTestImpl::FilterTests() { test_case->set_should_run(false); for (const internal::ListNode<TestInfo *> *test_info_node = - test_case->test_info_list().Head(); + test_case->test_info_list().Head(); test_info_node != NULL; test_info_node = test_info_node->next()) { TestInfo * const test_info = test_info_node->element(); @@ -3596,23 +3832,30 @@ int UnitTestImpl::FilterTests() { // A test is disabled if test case name or test name matches // kDisableTestFilter. const bool is_disabled = - internal::UnitTestOptions::MatchesFilter(test_case_name, - kDisableTestFilter) || - internal::UnitTestOptions::MatchesFilter(test_name, - kDisableTestFilter); + internal::UnitTestOptions::MatchesFilter(test_case_name, + kDisableTestFilter) || + internal::UnitTestOptions::MatchesFilter(test_name, + kDisableTestFilter); test_info->impl()->set_is_disabled(is_disabled); - const bool should_run = !is_disabled && + const bool is_runnable = + (GTEST_FLAG(also_run_disabled_tests) || !is_disabled) && internal::UnitTestOptions::FilterMatchesTest(test_case_name, test_name); - test_info->impl()->set_should_run(should_run); - test_case->set_should_run(test_case->should_run() || should_run); - if (should_run) { - num_runnable_tests++; - } + + const bool is_selected = is_runnable && + (shard_tests == IGNORE_SHARDING_PROTOCOL || + ShouldRunTestOnShard(total_shards, shard_index, + num_runnable_tests)); + + num_runnable_tests += is_runnable; + num_selected_tests += is_selected; + + test_info->impl()->set_should_run(is_selected); + test_case->set_should_run(test_case->should_run() || is_selected); } } - return num_runnable_tests; + return num_selected_tests; } // Lists all tests by name. @@ -3658,7 +3901,7 @@ UnitTestEventListenerInterface* UnitTestImpl::result_printer() { return result_printer_; } -#ifdef GTEST_HAS_DEATH_TEST +#if GTEST_HAS_DEATH_TEST if (internal_run_death_test_flag_.get() != NULL) { result_printer_ = new NullUnitTestResultPrinter; return result_printer_; @@ -3669,7 +3912,7 @@ UnitTestEventListenerInterface* UnitTestImpl::result_printer() { const String& output_format = internal::UnitTestOptions::GetOutputFormat(); if (output_format == "xml") { repeater->AddListener(new XmlUnitTestResultPrinter( - internal::UnitTestOptions::GetOutputFile().c_str())); + internal::UnitTestOptions::GetAbsolutePathToOutputFile().c_str())); } else if (output_format != "") { printf("WARNING: unrecognized output format \"%s\" ignored.\n", output_format.c_str()); @@ -3757,6 +4000,22 @@ int GetFailedPartCount(const TestResult* result) { return result->failed_part_count(); } +// Used by the GTEST_HIDE_UNREACHABLE_CODE_ macro to suppress unreachable +// code warnings. +namespace { +class ClassUniqueToAlwaysTrue {}; +} + +bool AlwaysTrue() { +#if GTEST_HAS_EXCEPTIONS + // This condition is always false so AlwaysTrue() never actually throws, + // but it makes the compiler think that it may throw. + if (atoi("42") == 36) // NOLINT + throw ClassUniqueToAlwaysTrue(); +#endif // GTEST_HAS_EXCEPTIONS + return true; +} + // Parses a string as a command line flag. The string should have // the format "--flag=value". When def_optional is true, the "=value" // part can be omitted. @@ -3768,8 +4027,8 @@ const char* ParseFlagValue(const char* str, // str and flag must not be NULL. if (str == NULL || flag == NULL) return NULL; - // The flag must start with "--" followed by GTEST_FLAG_PREFIX. - const String flag_str = String::Format("--%s%s", GTEST_FLAG_PREFIX, flag); + // The flag must start with "--" followed by GTEST_FLAG_PREFIX_. + const String flag_str = String::Format("--%s%s", GTEST_FLAG_PREFIX_, flag); const size_t flag_len = flag_str.GetLength(); if (strncmp(str, flag_str.c_str(), flag_len) != 0) return NULL; @@ -3846,6 +4105,102 @@ bool ParseStringFlag(const char* str, const char* flag, String* value) { return true; } +// Prints a string containing code-encoded text. The following escape +// sequences can be used in the string to control the text color: +// +// @@ prints a single '@' character. +// @R changes the color to red. +// @G changes the color to green. +// @Y changes the color to yellow. +// @D changes to the default terminal text color. +// +// TODO(wan@google.com): Write tests for this once we add stdout +// capturing to Google Test. +static void PrintColorEncoded(const char* str) { + GTestColor color = COLOR_DEFAULT; // The current color. + + // Conceptually, we split the string into segments divided by escape + // sequences. Then we print one segment at a time. At the end of + // each iteration, the str pointer advances to the beginning of the + // next segment. + for (;;) { + const char* p = strchr(str, '@'); + if (p == NULL) { + ColoredPrintf(color, "%s", str); + return; + } + + ColoredPrintf(color, "%s", String(str, p - str).c_str()); + + const char ch = p[1]; + str = p + 2; + if (ch == '@') { + ColoredPrintf(color, "@"); + } else if (ch == 'D') { + color = COLOR_DEFAULT; + } else if (ch == 'R') { + color = COLOR_RED; + } else if (ch == 'G') { + color = COLOR_GREEN; + } else if (ch == 'Y') { + color = COLOR_YELLOW; + } else { + --str; + } + } +} + +static const char kColorEncodedHelpMessage[] = +"This program contains tests written using " GTEST_NAME_ ". You can use the\n" +"following command line flags to control its behavior:\n" +"\n" +"Test Selection:\n" +" @G--" GTEST_FLAG_PREFIX_ "list_tests@D\n" +" List the names of all tests instead of running them. The name of\n" +" TEST(Foo, Bar) is \"Foo.Bar\".\n" +" @G--" GTEST_FLAG_PREFIX_ "filter=@YPOSTIVE_PATTERNS" + "[@G-@YNEGATIVE_PATTERNS]@D\n" +" Run only the tests whose name matches one of the positive patterns but\n" +" none of the negative patterns. '?' matches any single character; '*'\n" +" matches any substring; ':' separates two patterns.\n" +" @G--" GTEST_FLAG_PREFIX_ "also_run_disabled_tests@D\n" +" Run all disabled tests too.\n" +" @G--" GTEST_FLAG_PREFIX_ "repeat=@Y[COUNT]@D\n" +" Run the tests repeatedly; use a negative count to repeat forever.\n" +"\n" +"Test Output:\n" +" @G--" GTEST_FLAG_PREFIX_ "color=@Y(@Gyes@Y|@Gno@Y|@Gauto@Y)@D\n" +" Enable/disable colored output. The default is @Gauto@D.\n" +" -@G-" GTEST_FLAG_PREFIX_ "print_time@D\n" +" Print the elapsed time of each test.\n" +" @G--" GTEST_FLAG_PREFIX_ "output=xml@Y[@G:@YDIRECTORY_PATH@G" + GTEST_PATH_SEP_ "@Y|@G:@YFILE_PATH]@D\n" +" Generate an XML report in the given directory or with the given file\n" +" name. @YFILE_PATH@D defaults to @Gtest_details.xml@D.\n" +"\n" +"Failure Behavior:\n" +" @G--" GTEST_FLAG_PREFIX_ "break_on_failure@D\n" +" Turn assertion failures into debugger break-points.\n" +" @G--" GTEST_FLAG_PREFIX_ "throw_on_failure@D\n" +" Turn assertion failures into C++ exceptions.\n" +#if GTEST_OS_WINDOWS +" @G--" GTEST_FLAG_PREFIX_ "catch_exceptions@D\n" +" Suppress pop-ups caused by exceptions.\n" +#endif // GTEST_OS_WINDOWS +"\n" +"Except for @G--" GTEST_FLAG_PREFIX_ "list_tests@D, you can alternatively set " + "the corresponding\n" +"environment variable of a flag (all letters in upper-case). For example, to\n" +"print the elapsed time, you can either specify @G--" GTEST_FLAG_PREFIX_ + "print_time@D or set the\n" +"@G" GTEST_FLAG_PREFIX_UPPER_ "PRINT_TIME@D environment variable to a " + "non-zero value.\n" +"\n" +"For more information, please read the " GTEST_NAME_ " documentation at\n" +"@G" GTEST_PROJECT_URL_ "@D. If you find a bug in " GTEST_NAME_ "\n" +"(not one in your own code or tests), please report it to\n" +"@G<" GTEST_DEV_EMAIL_ ">@D.\n"; + // Parses the command line for Google Test flags, without initializing // other parts of Google Test. The type parameter CharType can be // instantiated to either char or wchar_t. @@ -3860,20 +4215,25 @@ void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) { using internal::ParseStringFlag; // Do we see a Google Test flag? - if (ParseBoolFlag(arg, kBreakOnFailureFlag, + if (ParseBoolFlag(arg, kAlsoRunDisabledTestsFlag, + >EST_FLAG(also_run_disabled_tests)) || + ParseBoolFlag(arg, kBreakOnFailureFlag, >EST_FLAG(break_on_failure)) || ParseBoolFlag(arg, kCatchExceptionsFlag, >EST_FLAG(catch_exceptions)) || ParseStringFlag(arg, kColorFlag, >EST_FLAG(color)) || ParseStringFlag(arg, kDeathTestStyleFlag, >EST_FLAG(death_test_style)) || + ParseBoolFlag(arg, kDeathTestUseFork, + >EST_FLAG(death_test_use_fork)) || ParseStringFlag(arg, kFilterFlag, >EST_FLAG(filter)) || ParseStringFlag(arg, kInternalRunDeathTestFlag, >EST_FLAG(internal_run_death_test)) || ParseBoolFlag(arg, kListTestsFlag, >EST_FLAG(list_tests)) || ParseStringFlag(arg, kOutputFlag, >EST_FLAG(output)) || ParseBoolFlag(arg, kPrintTimeFlag, >EST_FLAG(print_time)) || - ParseInt32Flag(arg, kRepeatFlag, >EST_FLAG(repeat)) + ParseInt32Flag(arg, kRepeatFlag, >EST_FLAG(repeat)) || + ParseBoolFlag(arg, kThrowOnFailureFlag, >EST_FLAG(throw_on_failure)) ) { // Yes. Shift the remainder of the argv list left by one. Note // that argv has (*argc + 1) elements, the last one always being @@ -3889,8 +4249,18 @@ void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) { // We also need to decrement the iterator as we just removed // an element. i--; + } else if (arg_string == "--help" || arg_string == "-h" || + arg_string == "-?" || arg_string == "/?") { + g_help_flag = true; } } + + if (g_help_flag) { + // We print the help here instead of in RUN_ALL_TESTS(), as the + // latter may not be called at all if the user is using Google + // Test with another testing framework. + PrintColorEncoded(kColorEncodedHelpMessage); + } } // Parses the command line for Google Test flags, without initializing @@ -3917,7 +4287,7 @@ void InitGoogleTestImpl(int* argc, CharType** argv) { internal::g_executable_path = internal::StreamableToString(argv[0]); -#ifdef GTEST_HAS_DEATH_TEST +#if GTEST_HAS_DEATH_TEST g_argvs.clear(); for (int i = 0; i != *argc; i++) { g_argvs.push_back(StreamableToString(argv[i])); diff --git a/utils/unittest/googletest/include/gtest/gtest-death-test.h b/utils/unittest/googletest/include/gtest/gtest-death-test.h index f0e109a..dcb2b66 100644 --- a/utils/unittest/googletest/include/gtest/gtest-death-test.h +++ b/utils/unittest/googletest/include/gtest/gtest-death-test.h @@ -49,7 +49,7 @@ namespace testing { // after forking. GTEST_DECLARE_string_(death_test_style); -#ifdef GTEST_HAS_DEATH_TEST +#if GTEST_HAS_DEATH_TEST // The following macros are useful for writing death tests. @@ -86,6 +86,57 @@ GTEST_DECLARE_string_(death_test_style); // // ASSERT_EXIT(client.HangUpServer(), KilledBySIGHUP, "Hanging up!"); // +// On the regular expressions used in death tests: +// +// On POSIX-compliant systems (*nix), we use the <regex.h> library, +// which uses the POSIX extended regex syntax. +// +// On other platforms (e.g. Windows), we only support a simple regex +// syntax implemented as part of Google Test. This limited +// implementation should be enough most of the time when writing +// death tests; though it lacks many features you can find in PCRE +// or POSIX extended regex syntax. For example, we don't support +// union ("x|y"), grouping ("(xy)"), brackets ("[xy]"), and +// repetition count ("x{5,7}"), among others. +// +// Below is the syntax that we do support. We chose it to be a +// subset of both PCRE and POSIX extended regex, so it's easy to +// learn wherever you come from. In the following: 'A' denotes a +// literal character, period (.), or a single \\ escape sequence; +// 'x' and 'y' denote regular expressions; 'm' and 'n' are for +// natural numbers. +// +// c matches any literal character c +// \\d matches any decimal digit +// \\D matches any character that's not a decimal digit +// \\f matches \f +// \\n matches \n +// \\r matches \r +// \\s matches any ASCII whitespace, including \n +// \\S matches any character that's not a whitespace +// \\t matches \t +// \\v matches \v +// \\w matches any letter, _, or decimal digit +// \\W matches any character that \\w doesn't match +// \\c matches any literal character c, which must be a punctuation +// . matches any single character except \n +// A? matches 0 or 1 occurrences of A +// A* matches 0 or many occurrences of A +// A+ matches 1 or many occurrences of A +// ^ matches the beginning of a string (not that of each line) +// $ matches the end of a string (not that of each line) +// xy matches x followed by y +// +// If you accidentally use PCRE or POSIX extended regex features +// not implemented by us, you will get a run-time failure. In that +// case, please try to rewrite your regular expression within the +// above syntax. +// +// This implementation is *not* meant to be as highly tuned or robust +// as a compiled regex library, but should perform well enough for a +// death test, which already incurs significant overhead by launching +// a child process. +// // Known caveats: // // A "threadsafe" style death test obtains the path to the test @@ -133,6 +184,7 @@ class ExitedWithCode { const int exit_code_; }; +#if !GTEST_OS_WINDOWS // Tests that an exit code describes an exit due to termination by a // given signal. class KilledBySignal { @@ -142,6 +194,7 @@ class KilledBySignal { private: const int signum_; }; +#endif // !GTEST_OS_WINDOWS // EXPECT_DEBUG_DEATH asserts that the given statements die in debug mode. // The death testing framework causes this to have interesting semantics, diff --git a/utils/unittest/googletest/include/gtest/gtest-message.h b/utils/unittest/googletest/include/gtest/gtest-message.h index 7effd08..99ae454 100644 --- a/utils/unittest/googletest/include/gtest/gtest-message.h +++ b/utils/unittest/googletest/include/gtest/gtest-message.h @@ -102,7 +102,7 @@ class Message { } ~Message() { delete ss_; } -#ifdef GTEST_OS_SYMBIAN +#if GTEST_OS_SYMBIAN // Streams a value (either a pointer or not) to this object. template <typename T> inline Message& operator <<(const T& value) { @@ -187,7 +187,7 @@ class Message { } private: -#ifdef GTEST_OS_SYMBIAN +#if GTEST_OS_SYMBIAN // These are needed as the Nokia Symbian Compiler cannot decide between // const T& and const T* in a function template. The Nokia compiler _can_ // decide between class template specializations for T and T*, so a diff --git a/utils/unittest/googletest/include/gtest/gtest-param-test.h b/utils/unittest/googletest/include/gtest/gtest-param-test.h index 0cf05dc..c9d4f24 100644 --- a/utils/unittest/googletest/include/gtest/gtest-param-test.h +++ b/utils/unittest/googletest/include/gtest/gtest-param-test.h @@ -151,7 +151,7 @@ INSTANTIATE_TEST_CASE_P(AnotherInstantiationName, FooTest, ValuesIn(pets)); #include <gtest/internal/gtest-port.h> -#ifdef GTEST_HAS_PARAM_TEST +#if GTEST_HAS_PARAM_TEST #include <gtest/internal/gtest-internal.h> #include <gtest/internal/gtest-param-util.h> @@ -1190,7 +1190,7 @@ inline internal::ParamGenerator<bool> Bool() { return Values(false, true); } -#ifdef GTEST_HAS_COMBINE +#if GTEST_HAS_COMBINE // Combine() allows the user to combine two or more sequences to produce // values of a Cartesian product of those sequences' elements. // diff --git a/utils/unittest/googletest/include/gtest/gtest-typed-test.h b/utils/unittest/googletest/include/gtest/gtest-typed-test.h index dec42cf..519edfe 100644 --- a/utils/unittest/googletest/include/gtest/gtest-typed-test.h +++ b/utils/unittest/googletest/include/gtest/gtest-typed-test.h @@ -151,7 +151,7 @@ INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes); // Implements typed tests. -#ifdef GTEST_HAS_TYPED_TEST +#if GTEST_HAS_TYPED_TEST // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // @@ -186,7 +186,7 @@ INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes); // Implements type-parameterized tests. -#ifdef GTEST_HAS_TYPED_TEST_P +#if GTEST_HAS_TYPED_TEST_P // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // diff --git a/utils/unittest/googletest/include/gtest/gtest.h b/utils/unittest/googletest/include/gtest/gtest.h index ebd3123..9b72b63 100644 --- a/utils/unittest/googletest/include/gtest/gtest.h +++ b/utils/unittest/googletest/include/gtest/gtest.h @@ -93,17 +93,59 @@ namespace testing { -// The upper limit for valid stack trace depths. -const int kMaxStackTraceDepth = 100; +// Declares the flags. -// This flag specifies the maximum number of stack frames to be -// printed in a failure message. -GTEST_DECLARE_int32_(stack_trace_depth); +// This flag temporary enables the disabled tests. +GTEST_DECLARE_bool_(also_run_disabled_tests); + +// This flag brings the debugger on an assertion failure. +GTEST_DECLARE_bool_(break_on_failure); + +// This flag controls whether Google Test catches all test-thrown exceptions +// and logs them as failures. +GTEST_DECLARE_bool_(catch_exceptions); + +// This flag enables using colors in terminal output. Available values are +// "yes" to enable colors, "no" (disable colors), or "auto" (the default) +// to let Google Test decide. +GTEST_DECLARE_string_(color); + +// This flag sets up the filter to select by name using a glob pattern +// the tests to run. If the filter is not given all tests are executed. +GTEST_DECLARE_string_(filter); + +// This flag causes the Google Test to list tests. None of the tests listed +// are actually run if the flag is provided. +GTEST_DECLARE_bool_(list_tests); + +// This flag controls whether Google Test emits a detailed XML report to a file +// in addition to its normal textual output. +GTEST_DECLARE_string_(output); + +// This flags control whether Google Test prints the elapsed time for each +// test. +GTEST_DECLARE_bool_(print_time); + +// This flag sets how many times the tests are repeated. The default value +// is 1. If the value is -1 the tests are repeating forever. +GTEST_DECLARE_int32_(repeat); // This flag controls whether Google Test includes Google Test internal // stack frames in failure stack traces. GTEST_DECLARE_bool_(show_internal_stack_frames); +// This flag specifies the maximum number of stack frames to be +// printed in a failure message. +GTEST_DECLARE_int32_(stack_trace_depth); + +// When this flag is specified, a failed assertion will throw an +// exception if exceptions are enabled, or exit the program with a +// non-zero code otherwise. +GTEST_DECLARE_bool_(throw_on_failure); + +// The upper limit for valid stack trace depths. +const int kMaxStackTraceDepth = 100; + namespace internal { class GTestFlagSaver; @@ -353,7 +395,7 @@ class TestInfo { // Returns the result of the test. const internal::TestResult* result() const; private: -#ifdef GTEST_HAS_DEATH_TEST +#if GTEST_HAS_DEATH_TEST friend class internal::DefaultDeathTestFactory; #endif // GTEST_HAS_DEATH_TEST friend class internal::TestInfoImpl; @@ -484,7 +526,7 @@ class UnitTest { // or NULL if no test is running. const TestInfo* current_test_info() const; -#ifdef GTEST_HAS_PARAM_TEST +#if GTEST_HAS_PARAM_TEST // Returns the ParameterizedTestCaseRegistry object used to keep track of // value-parameterized tests and instantiate and register them. internal::ParameterizedTestCaseRegistry& parameterized_test_registry(); @@ -614,10 +656,20 @@ AssertionResult CmpHelperEQ(const char* expected_expression, const char* actual_expression, const T1& expected, const T2& actual) { +#ifdef _MSC_VER +#pragma warning(push) // Saves the current warning state. +#pragma warning(disable:4389) // Temporarily disables warning on + // signed/unsigned mismatch. +#endif + if (expected == actual) { return AssertionSuccess(); } +#ifdef _MSC_VER +#pragma warning(pop) // Restores the warning state. +#endif + return EqFailure(expected_expression, actual_expression, FormatForComparisonFailureMessage(expected, actual), @@ -688,7 +740,7 @@ class EqHelper<true> { template <typename T1, typename T2> static AssertionResult Compare(const char* expected_expression, const char* actual_expression, - const T1& expected, + const T1& /* expected */, T2* actual) { // We already know that 'expected' is a null pointer. return CmpHelperEQ(expected_expression, actual_expression, @@ -893,7 +945,7 @@ class AssertHelper { } // namespace internal -#ifdef GTEST_HAS_PARAM_TEST +#if GTEST_HAS_PARAM_TEST // The abstract base class that all value-parameterized tests inherit from. // // This class adds support for accessing the test parameter value via @@ -1187,7 +1239,7 @@ AssertionResult DoubleLE(const char* expr1, const char* expr2, double val1, double val2); -#ifdef GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS // Macros that test for HRESULT failure and success, these are only useful // on Windows, and rely on Windows SDK macros and APIs to compile. @@ -1242,6 +1294,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. // @@ -1269,7 +1367,7 @@ AssertionResult DoubleLE(const char* expr1, const char* expr2, // value, as it always calls GetTypeId<>() from the Google Test // framework. #define TEST(test_case_name, test_name)\ - GTEST_TEST_(test_case_name, test_name,\ + GTEST_TEST_(test_case_name, test_name, \ ::testing::Test, ::testing::internal::GetTestTypeId()) @@ -1300,7 +1398,7 @@ AssertionResult DoubleLE(const char* expr1, const char* expr2, // } #define TEST_F(test_fixture, test_name)\ - GTEST_TEST_(test_fixture, test_name, test_fixture,\ + GTEST_TEST_(test_fixture, test_name, test_fixture, \ ::testing::internal::GetTypeId<test_fixture>()) // Use this macro in main() to run all tests. It returns 0 if all diff --git a/utils/unittest/googletest/include/gtest/internal/gtest-death-test-internal.h b/utils/unittest/googletest/include/gtest/internal/gtest-death-test-internal.h index 0769fca..ff2e490 100644 --- a/utils/unittest/googletest/include/gtest/internal/gtest-death-test-internal.h +++ b/utils/unittest/googletest/include/gtest/internal/gtest-death-test-internal.h @@ -39,6 +39,10 @@ #include <gtest/internal/gtest-internal.h> +#if GTEST_HAS_DEATH_TEST && GTEST_OS_WINDOWS +#include <io.h> +#endif // GTEST_HAS_DEATH_TEST && GTEST_OS_WINDOWS + namespace testing { namespace internal { @@ -46,9 +50,10 @@ 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 +#if GTEST_HAS_DEATH_TEST // DeathTest is a class that hides much of the complexity of the // GTEST_DEATH_TEST_ macro. It is abstract; its static Create method @@ -120,7 +125,12 @@ class DeathTest { // the last death test. static const char* LastMessage(); + static void set_last_death_test_message(const String& message); + private: + // A string containing a description of the outcome of the last death test. + static String last_death_test_message_; + GTEST_DISALLOW_COPY_AND_ASSIGN_(DeathTest); }; @@ -166,7 +176,7 @@ bool ExitedUnsuccessfully(int exit_status); case ::testing::internal::DeathTest::EXECUTE_TEST: { \ ::testing::internal::DeathTest::ReturnSentinel \ gtest_sentinel(gtest_dt); \ - { statement; } \ + GTEST_HIDE_UNREACHABLE_CODE_(statement); \ gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \ break; \ } \ @@ -178,14 +188,42 @@ bool ExitedUnsuccessfully(int exit_status); // The symbol "fail" here expands to something into which a message // can be streamed. -// A struct representing the parsed contents of the +// A class representing the parsed contents of the // --gtest_internal_run_death_test flag, as it existed when // RUN_ALL_TESTS was called. -struct InternalRunDeathTestFlag { - String file; - int line; - int index; - int status_fd; +class InternalRunDeathTestFlag { + public: + InternalRunDeathTestFlag(const String& file, + int line, + int index, + int status_fd) + : file_(file), line_(line), index_(index), status_fd_(status_fd) {} + + ~InternalRunDeathTestFlag() { + if (status_fd_ >= 0) +// Suppress MSVC complaints about POSIX functions. +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable: 4996) +#endif // _MSC_VER + close(status_fd_); +#ifdef _MSC_VER +#pragma warning(pop) +#endif // _MSC_VER + } + + String file() const { return file_; } + int line() const { return line_; } + int index() const { return index_; } + int status_fd() const { return status_fd_; } + + private: + String file_; + int line_; + int index_; + int status_fd_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(InternalRunDeathTestFlag); }; // Returns a newly created InternalRunDeathTestFlag object with fields diff --git a/utils/unittest/googletest/include/gtest/internal/gtest-filepath.h b/utils/unittest/googletest/include/gtest/internal/gtest-filepath.h index 9a0682a..1b2f586 100644 --- a/utils/unittest/googletest/include/gtest/internal/gtest-filepath.h +++ b/utils/unittest/googletest/include/gtest/internal/gtest-filepath.h @@ -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 testing/base/internal/gtest-internal.h +// This file is #included in <gtest/internal/gtest-internal.h>. // Do not include this header file separately! #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ @@ -93,6 +93,12 @@ class FilePath { int number, const char* extension); + // Given directory = "dir", relative_path = "test.xml", + // returns "dir/test.xml". + // On Windows, uses \ as the separator rather than /. + static FilePath ConcatPaths(const FilePath& directory, + const FilePath& relative_path); + // Returns a pathname for a file that does not currently exist. The pathname // will be directory/base_name.extension or // directory/base_name_<number>.extension if directory/base_name.extension @@ -164,6 +170,9 @@ class FilePath { // root directory per disk drive.) bool IsRootDirectory() const; + // Returns true if pathname describes an absolute path. + bool IsAbsolutePath() const; + private: // Replaces multiple consecutive separators with a single separator. // For example, "bar///foo" becomes "bar/foo". Does not eliminate other diff --git a/utils/unittest/googletest/include/gtest/internal/gtest-internal-inl.h b/utils/unittest/googletest/include/gtest/internal/gtest-internal-inl.h index b8f67c1..d079a3e 100644 --- a/utils/unittest/googletest/include/gtest/internal/gtest-internal-inl.h +++ b/utils/unittest/googletest/include/gtest/internal/gtest-internal-inl.h @@ -37,20 +37,24 @@ #ifndef GTEST_SRC_GTEST_INTERNAL_INL_H_ #define GTEST_SRC_GTEST_INTERNAL_INL_H_ -// GTEST_IMPLEMENTATION is defined iff the current translation unit is -// part of Google Test's implementation. -#ifndef GTEST_IMPLEMENTATION +// GTEST_IMPLEMENTATION_ is defined to 1 iff the current translation unit is +// part of Google Test's implementation; otherwise it's undefined. +#if !GTEST_IMPLEMENTATION_ // A user is trying to include this from his code - just say no. #error "gtest-internal-inl.h is part of Google Test's internal implementation." #error "It must not be included except by Google Test itself." -#endif // GTEST_IMPLEMENTATION +#endif // GTEST_IMPLEMENTATION_ +#include <errno.h> #include <stddef.h> +#include <stdlib.h> // For strtoll/_strtoul64. + +#include <string> #include <gtest/internal/gtest-port.h> -#ifdef GTEST_OS_WINDOWS -#include <windows.h> // NOLINT +#if GTEST_OS_WINDOWS +#include <windows.h> // For DWORD. #endif // GTEST_OS_WINDOWS #include <gtest/gtest.h> @@ -60,19 +64,10 @@ namespace testing { // Declares the flags. // -// We don't want the users to modify these flags in the code, but want -// Google Test's own unit tests to be able to access them. Therefore we -// declare them here as opposed to in gtest.h. -GTEST_DECLARE_bool_(break_on_failure); -GTEST_DECLARE_bool_(catch_exceptions); -GTEST_DECLARE_string_(color); -GTEST_DECLARE_string_(filter); -GTEST_DECLARE_bool_(list_tests); -GTEST_DECLARE_string_(output); -GTEST_DECLARE_bool_(print_time); -GTEST_DECLARE_int32_(repeat); -GTEST_DECLARE_int32_(stack_trace_depth); -GTEST_DECLARE_bool_(show_internal_stack_frames); +// We don't want the users to modify this flag in the code, but want +// Google Test's own unit tests to be able to access it. Therefore we +// declare it here as opposed to in gtest.h. +GTEST_DECLARE_bool_(death_test_use_fork); namespace internal { @@ -81,6 +76,7 @@ namespace internal { extern const TypeId kTestTypeIdInGoogleTest; // Names of the flags (needed for parsing Google Test flags). +const char kAlsoRunDisabledTestsFlag[] = "also_run_disabled_tests"; const char kBreakOnFailureFlag[] = "break_on_failure"; const char kCatchExceptionsFlag[] = "catch_exceptions"; const char kColorFlag[] = "color"; @@ -89,6 +85,7 @@ const char kListTestsFlag[] = "list_tests"; const char kOutputFlag[] = "output"; const char kPrintTimeFlag[] = "print_time"; const char kRepeatFlag[] = "repeat"; +const char kThrowOnFailureFlag[] = "throw_on_failure"; // This class saves the values of all Google Test flags in its c'tor, and // restores them in its d'tor. @@ -96,37 +93,45 @@ class GTestFlagSaver { public: // The c'tor. GTestFlagSaver() { + also_run_disabled_tests_ = GTEST_FLAG(also_run_disabled_tests); break_on_failure_ = GTEST_FLAG(break_on_failure); 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); output_ = GTEST_FLAG(output); print_time_ = GTEST_FLAG(print_time); repeat_ = GTEST_FLAG(repeat); + throw_on_failure_ = GTEST_FLAG(throw_on_failure); } // The d'tor is not virtual. DO NOT INHERIT FROM THIS CLASS. ~GTestFlagSaver() { + GTEST_FLAG(also_run_disabled_tests) = also_run_disabled_tests_; GTEST_FLAG(break_on_failure) = break_on_failure_; 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_; GTEST_FLAG(output) = output_; GTEST_FLAG(print_time) = print_time_; GTEST_FLAG(repeat) = repeat_; + GTEST_FLAG(throw_on_failure) = throw_on_failure_; } private: // Fields for saving the original values of flags. + bool also_run_disabled_tests_; bool break_on_failure_; bool catch_exceptions_; String color_; String death_test_style_; + bool death_test_use_fork_; String filter_; String internal_run_death_test_; bool list_tests_; @@ -134,6 +139,7 @@ class GTestFlagSaver { bool print_time_; bool pretty_; internal::Int32 repeat_; + bool throw_on_failure_; } GTEST_ATTRIBUTE_UNUSED_; // Converts a Unicode code point to a narrow string in UTF-8 encoding. @@ -164,6 +170,32 @@ String WideStringToUtf8(const wchar_t* str, int num_chars); // Returns the number of active threads, or 0 when there is an error. size_t GetThreadCount(); +// Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file +// if the variable is present. If a file already exists at this location, this +// function will write over it. If the variable is present, but the file cannot +// be created, prints an error and exits. +void WriteToShardStatusFileIfNeeded(); + +// Checks whether sharding is enabled by examining the relevant +// environment variable values. If the variables are present, +// but inconsistent (e.g., shard_index >= total_shards), prints +// an error and exits. If in_subprocess_for_death_test, sharding is +// disabled because it must only be applied to the original test +// process. Otherwise, we could filter out death tests we intended to execute. +bool ShouldShard(const char* total_shards_str, const char* shard_index_str, + bool in_subprocess_for_death_test); + +// Parses the environment variable var as an Int32. If it is unset, +// returns default_val. If it is not an Int32, prints an error and +// and aborts. +Int32 Int32FromEnvOrDie(const char* env_var, Int32 default_val); + +// Given the total number of shards, the shard index, and the test id, +// returns true iff the test should be run on this shard. The test id is +// some arbitrary but unique non-negative integer assigned to each test +// method. Assumes that 0 <= shard_index < total_shards. +bool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id); + // List is a simple singly-linked list container. // // We cannot use std::list as Microsoft's implementation of STL has @@ -790,9 +822,10 @@ class UnitTestOptions { // Returns the output format, or "" for normal printed output. static String GetOutputFormat(); - // Returns the name of the requested output file, or the default if none - // was explicitly specified. - static String GetOutputFile(); + // Returns the absolute path of the requested output file, or the + // default (test_detail.xml in the original working directory) if + // none was explicitly specified. + static String GetAbsolutePathToOutputFile(); // Functions for processing the gtest_filter flag. @@ -808,7 +841,7 @@ class UnitTestOptions { static bool FilterMatchesTest(const String &test_case_name, const String &test_name); -#ifdef GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS // Function for supporting the gtest_catch_exception flag. // Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the @@ -891,6 +924,8 @@ class DefaultGlobalTestPartResultReporter private: UnitTestImpl* const unit_test_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultGlobalTestPartResultReporter); }; // This is the default per thread test part result reporter used in @@ -905,6 +940,8 @@ class DefaultPerThreadTestPartResultReporter private: UnitTestImpl* const unit_test_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultPerThreadTestPartResultReporter); }; // The private implementation of the UnitTest class. We don't protect @@ -1066,7 +1103,7 @@ class UnitTestImpl { tear_down_tc)->AddTestInfo(test_info); } -#ifdef GTEST_HAS_PARAM_TEST +#if GTEST_HAS_PARAM_TEST // Returns ParameterizedTestCaseRegistry object used to keep track of // value-parameterized tests and instantiate and register them. internal::ParameterizedTestCaseRegistry& parameterized_test_registry() { @@ -1108,11 +1145,18 @@ class UnitTestImpl { ad_hoc_test_result_.Clear(); } + enum ReactionToSharding { + HONOR_SHARDING_PROTOCOL, + IGNORE_SHARDING_PROTOCOL + }; + // Matches the full name of each test against the user-specified // filter to decide whether the test should run, then records the // result in each TestCase and TestInfo object. + // If shard_tests == HONOR_SHARDING_PROTOCOL, further filters tests + // based on sharding variables in the environment. // Returns the number of tests that should run. - int FilterTests(); + int FilterTests(ReactionToSharding shard_tests); // Lists all the tests by name. void ListAllTests(); @@ -1139,7 +1183,7 @@ class UnitTestImpl { return gtest_trace_stack_.pointer(); } -#ifdef GTEST_HAS_DEATH_TEST +#if GTEST_HAS_DEATH_TEST // Returns a pointer to the parsed --gtest_internal_run_death_test // flag, or NULL if that flag was not specified. // This information is useful only in a death test child process. @@ -1188,7 +1232,7 @@ class UnitTestImpl { internal::List<TestCase*> test_cases_; // The list of TestCases. -#ifdef GTEST_HAS_PARAM_TEST +#if GTEST_HAS_PARAM_TEST // ParameterizedTestRegistry object used to register value-parameterized // tests. internal::ParameterizedTestCaseRegistry parameterized_test_registry_; @@ -1237,7 +1281,7 @@ class UnitTestImpl { // How long the test took to run, in milliseconds. TimeInMillis elapsed_time_; -#ifdef GTEST_HAS_DEATH_TEST +#if GTEST_HAS_DEATH_TEST // The decomposed components of the gtest_internal_run_death_test flag, // parsed when RUN_ALL_TESTS is called. internal::scoped_ptr<InternalRunDeathTestFlag> internal_run_death_test_flag_; @@ -1256,11 +1300,98 @@ inline UnitTestImpl* GetUnitTestImpl() { return UnitTest::GetInstance()->impl(); } +// Internal helper functions for implementing the simple regular +// expression matcher. +bool IsInSet(char ch, const char* str); +bool IsDigit(char ch); +bool IsPunct(char ch); +bool IsRepeat(char ch); +bool IsWhiteSpace(char ch); +bool IsWordChar(char ch); +bool IsValidEscape(char ch); +bool AtomMatchesChar(bool escaped, char pattern, char ch); +bool ValidateRegex(const char* regex); +bool MatchRegexAtHead(const char* regex, const char* str); +bool MatchRepetitionAndRegexAtHead( + bool escaped, char ch, char repeat, const char* regex, const char* str); +bool MatchRegexAnywhere(const char* regex, const char* str); + // Parses the command line for Google Test flags, without initializing // other parts of Google Test. void ParseGoogleTestFlagsOnly(int* argc, char** argv); void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv); +#if GTEST_HAS_DEATH_TEST + +// Returns the message describing the last system error, regardless of the +// platform. +String GetLastSystemErrorMessage(); + +#if GTEST_OS_WINDOWS +// Provides leak-safe Windows kernel handle ownership. +class AutoHandle { + public: + AutoHandle() : handle_(INVALID_HANDLE_VALUE) {} + explicit AutoHandle(HANDLE handle) : handle_(handle) {} + + ~AutoHandle() { Reset(); } + + HANDLE Get() const { return handle_; } + void Reset() { Reset(INVALID_HANDLE_VALUE); } + void Reset(HANDLE handle) { + if (handle != handle_) { + if (handle_ != INVALID_HANDLE_VALUE) + ::CloseHandle(handle_); + handle_ = handle; + } + } + + private: + HANDLE handle_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(AutoHandle); +}; +#endif // GTEST_OS_WINDOWS + +// Attempts to parse a string into a positive integer pointed to by the +// number parameter. Returns true if that is possible. +// GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we can use +// it here. +template <typename Integer> +bool ParseNaturalNumber(const ::std::string& str, Integer* number) { + // Fail fast if the given string does not begin with a digit; + // this bypasses strtoXXX's "optional leading whitespace and plus + // or minus sign" semantics, which are undesirable here. + if (str.empty() || !isdigit(str[0])) { + return false; + } + errno = 0; + + char* end; + // BiggestConvertible is the largest integer type that system-provided + // string-to-number conversion routines can return. +#if GTEST_OS_WINDOWS + typedef unsigned __int64 BiggestConvertible; + const BiggestConvertible parsed = _strtoui64(str.c_str(), &end, 10); +#else + typedef unsigned long long BiggestConvertible; // NOLINT + const BiggestConvertible parsed = strtoull(str.c_str(), &end, 10); +#endif // GTEST_OS_WINDOWS + const bool parse_success = *end == '\0' && errno == 0; + + // TODO(vladl@google.com): Convert this to compile time assertion when it is + // available. + GTEST_CHECK_(sizeof(Integer) <= sizeof(parsed)); + + const Integer result = static_cast<Integer>(parsed); + if (parse_success && static_cast<BiggestConvertible>(result) == parsed) { + *number = result; + return true; + } + return false; +} +#endif // GTEST_HAS_DEATH_TEST + } // namespace internal } // namespace testing diff --git a/utils/unittest/googletest/include/gtest/internal/gtest-internal.h b/utils/unittest/googletest/include/gtest/internal/gtest-internal.h index 242ffea..def4b59 100644 --- a/utils/unittest/googletest/include/gtest/internal/gtest-internal.h +++ b/utils/unittest/googletest/include/gtest/internal/gtest-internal.h @@ -39,7 +39,7 @@ #include <gtest/internal/gtest-port.h> -#ifdef GTEST_OS_LINUX +#if GTEST_OS_LINUX #include <stdlib.h> #include <sys/types.h> #include <sys/wait.h> @@ -566,7 +566,7 @@ class TestFactoryImpl : public TestFactoryBase { virtual Test* CreateTest() { return new TestClass; } }; -#ifdef GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS // Predicate-formatters for implementing the HRESULT checking macros // {ASSERT|EXPECT}_HRESULT_{SUCCEEDED|FAILED} @@ -620,7 +620,7 @@ TestInfo* MakeAndRegisterTestInfo( TearDownTestCaseFunc tear_down_tc, TestFactoryBase* factory); -#if defined(GTEST_HAS_TYPED_TEST) || defined(GTEST_HAS_TYPED_TEST_P) +#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P // State of the definition of a type-parameterized test case. class TypedTestCasePState { @@ -636,6 +636,7 @@ class TypedTestCasePState { fprintf(stderr, "%s Test %s must be defined before " "REGISTER_TYPED_TEST_CASE_P(%s, ...).\n", FormatFileLocation(file, line).c_str(), test_name, case_name); + fflush(stderr); abort(); } defined_test_names_.insert(test_name); @@ -768,6 +769,9 @@ String GetCurrentOsStackTraceExceptTop(UnitTest* unit_test, int skip_count); // Returns the number of failed test parts in the given test result object. int GetFailedPartCount(const TestResult* result); +// A helper for suppressing warnings on unreachable code in some macros. +bool AlwaysTrue(); + } // namespace internal } // namespace testing @@ -784,12 +788,18 @@ int GetFailedPartCount(const TestResult* result); #define GTEST_SUCCESS_(message) \ GTEST_MESSAGE_(message, ::testing::TPRT_SUCCESS) +// Suppresses MSVC warnings 4072 (unreachable code) for the code following +// statement if it returns or throws (or doesn't return or throw in some +// situations). +#define GTEST_HIDE_UNREACHABLE_CODE_(statement) \ + if (::testing::internal::AlwaysTrue()) { statement; } + #define GTEST_TEST_THROW_(statement, expected_exception, fail) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (const char* gtest_msg = "") { \ bool gtest_caught_expected = false; \ try { \ - statement; \ + GTEST_HIDE_UNREACHABLE_CODE_(statement); \ } \ catch (expected_exception const&) { \ gtest_caught_expected = true; \ @@ -813,7 +823,7 @@ int GetFailedPartCount(const TestResult* result); GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (const char* gtest_msg = "") { \ try { \ - statement; \ + GTEST_HIDE_UNREACHABLE_CODE_(statement); \ } \ catch (...) { \ gtest_msg = "Expected: " #statement " doesn't throw an exception.\n" \ @@ -829,7 +839,7 @@ int GetFailedPartCount(const TestResult* result); if (const char* gtest_msg = "") { \ bool gtest_caught_any = false; \ try { \ - statement; \ + GTEST_HIDE_UNREACHABLE_CODE_(statement); \ } \ catch (...) { \ gtest_caught_any = true; \ @@ -855,7 +865,7 @@ int GetFailedPartCount(const TestResult* result); GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (const char* gtest_msg = "") { \ ::testing::internal::HasNewFatalFailureHelper gtest_fatal_failure_checker; \ - { statement; } \ + GTEST_HIDE_UNREACHABLE_CODE_(statement); \ if (gtest_fatal_failure_checker.has_new_fatal_failure()) { \ gtest_msg = "Expected: " #statement " doesn't generate new fatal " \ "failures in the current thread.\n" \ diff --git a/utils/unittest/googletest/include/gtest/internal/gtest-param-util-generated.h b/utils/unittest/googletest/include/gtest/internal/gtest-param-util-generated.h index 17f3f7b..ad06e02 100644 --- a/utils/unittest/googletest/include/gtest/internal/gtest-param-util-generated.h +++ b/utils/unittest/googletest/include/gtest/internal/gtest-param-util-generated.h @@ -46,7 +46,7 @@ #include <gtest/internal/gtest-port.h> -#ifdef GTEST_HAS_PARAM_TEST +#if GTEST_HAS_PARAM_TEST #include <gtest/internal/gtest-param-util.h> @@ -2659,7 +2659,7 @@ class ValueArray50 { const T50 v50_; }; -#ifdef GTEST_HAS_COMBINE +#if GTEST_HAS_COMBINE // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // Generates values from the Cartesian product of values produced diff --git a/utils/unittest/googletest/include/gtest/internal/gtest-param-util.h b/utils/unittest/googletest/include/gtest/internal/gtest-param-util.h index 3bb07ec..5559ab4 100644 --- a/utils/unittest/googletest/include/gtest/internal/gtest-param-util.h +++ b/utils/unittest/googletest/include/gtest/internal/gtest-param-util.h @@ -40,7 +40,7 @@ #include <gtest/internal/gtest-port.h> -#ifdef GTEST_HAS_PARAM_TEST +#if GTEST_HAS_PARAM_TEST #if GTEST_HAS_RTTI #include <typeinfo> diff --git a/utils/unittest/googletest/include/gtest/internal/gtest-port.h b/utils/unittest/googletest/include/gtest/internal/gtest-port.h index 20a95c9..d949ec1 100644 --- a/utils/unittest/googletest/include/gtest/internal/gtest-port.h +++ b/utils/unittest/googletest/include/gtest/internal/gtest-port.h @@ -63,21 +63,15 @@ // This header defines the following utilities: // -// Macros indicating the name of the Google C++ Testing Framework project: -// GTEST_NAME - a string literal of the project name. -// GTEST_FLAG_PREFIX - a string literal of the prefix all Google -// Test flag names share. -// GTEST_FLAG_PREFIX_UPPER - a string literal of the prefix all Google -// Test flag names share, in upper case. -// -// Macros indicating the current platform: -// GTEST_OS_CYGWIN - defined iff compiled on Cygwin. -// GTEST_OS_LINUX - defined iff compiled on Linux. -// GTEST_OS_MAC - defined iff compiled on Mac OS X. -// GTEST_OS_SOLARIS - defined iff compiled on Sun Solaris. -// GTEST_OS_SYMBIAN - defined iff compiled for Symbian. -// GTEST_OS_WINDOWS - defined iff compiled on Windows. -// GTEST_OS_ZOS - defined iff compiled on IBM z/OS. +// Macros indicating the current platform (defined to 1 if compiled on +// the given platform; otherwise undefined): +// GTEST_OS_CYGWIN - Cygwin +// GTEST_OS_LINUX - Linux +// GTEST_OS_MAC - Mac OS X +// GTEST_OS_SOLARIS - Sun Solaris +// GTEST_OS_SYMBIAN - Symbian +// GTEST_OS_WINDOWS - Windows +// GTEST_OS_ZOS - z/OS // // Among the platforms, Cygwin, Linux, Max OS X, and Windows have the // most stable support. Since core members of the Google Test project @@ -86,17 +80,19 @@ // googletestframework@googlegroups.com (patches for fixing them are // even more welcome!). // -// Note that it is possible that none of the GTEST_OS_ macros are defined. +// Note that it is possible that none of the GTEST_OS_* macros are defined. // -// Macros indicating available Google Test features: -// GTEST_HAS_COMBINE - defined iff Combine construct is supported -// in value-parameterized tests. -// GTEST_HAS_DEATH_TEST - defined iff death tests are supported. -// GTEST_HAS_PARAM_TEST - defined iff value-parameterized tests are -// supported. -// GTEST_HAS_TYPED_TEST - defined iff typed tests are supported. -// GTEST_HAS_TYPED_TEST_P - defined iff type-parameterized tests are -// supported. +// Macros indicating available Google Test features (defined to 1 if +// the corresponding feature is supported; otherwise undefined): +// GTEST_HAS_COMBINE - the Combine() function (for value-parameterized +// tests) +// GTEST_HAS_DEATH_TEST - death tests +// GTEST_HAS_PARAM_TEST - value-parameterized tests +// GTEST_HAS_TYPED_TEST - typed tests +// GTEST_HAS_TYPED_TEST_P - type-parameterized tests +// GTEST_USES_POSIX_RE - enhanced POSIX regex is used. +// GTEST_USES_SIMPLE_RE - our own simple regex is used; +// the above two are mutually exclusive. // // Macros for basic C++ coding: // GTEST_AMBIGUOUS_ELSE_BLOCKER_ - for disabling a gcc warning. @@ -155,9 +151,11 @@ #include <stdio.h> #include <iostream> // Used for GTEST_CHECK_ -#define GTEST_NAME "Google Test" -#define GTEST_FLAG_PREFIX "gtest_" -#define GTEST_FLAG_PREFIX_UPPER "GTEST_" +#define GTEST_DEV_EMAIL_ "googletestframework@@googlegroups.com" +#define GTEST_FLAG_PREFIX_ "gtest_" +#define GTEST_FLAG_PREFIX_UPPER_ "GTEST_" +#define GTEST_NAME_ "Google Test" +#define GTEST_PROJECT_URL_ "http://code.google.com/p/googletest/" // Determines the version of gcc that is used to compile this. #ifdef __GNUC__ @@ -168,49 +166,76 @@ // Determines the platform on which Google Test is compiled. #ifdef __CYGWIN__ -#define GTEST_OS_CYGWIN +#define GTEST_OS_CYGWIN 1 #elif __SYMBIAN32__ -#define GTEST_OS_SYMBIAN +#define GTEST_OS_SYMBIAN 1 #elif defined _MSC_VER // TODO(kenton@google.com): GTEST_OS_WINDOWS is currently used to mean // both "The OS is Windows" and "The compiler is MSVC". These // meanings really should be separated in order to better support // Windows compilers other than MSVC. -#define GTEST_OS_WINDOWS +#define GTEST_OS_WINDOWS 1 #elif defined __APPLE__ -#define GTEST_OS_MAC +#define GTEST_OS_MAC 1 #elif defined __linux__ -#define GTEST_OS_LINUX +#define GTEST_OS_LINUX 1 #elif defined __MVS__ -#define GTEST_OS_ZOS +#define GTEST_OS_ZOS 1 #elif defined(__sun) && defined(__SVR4) -#define GTEST_OS_SOLARIS +#define GTEST_OS_SOLARIS 1 #elif defined(__HAIKU__) #define GTEST_OS_HAIKU #endif // _MSC_VER -// Determines whether ::std::string and ::string are available. +#if GTEST_OS_CYGWIN || GTEST_OS_LINUX || GTEST_OS_MAC -#ifndef GTEST_HAS_STD_STRING -// The user didn't tell us whether ::std::string is available, so we -// need to figure it out. +// On some platforms, <regex.h> needs someone to define size_t, and +// won't compile otherwise. We can #include it here as we already +// included <stdlib.h>, which is guaranteed to define size_t through +// <stddef.h>. +#include <regex.h> // NOLINT +#define GTEST_USES_POSIX_RE 1 -#ifdef GTEST_OS_WINDOWS +#else + +// <regex.h> may not be available on this platform. Use our own +// simple regex implementation instead. +#define GTEST_USES_SIMPLE_RE 1 + +#endif // GTEST_OS_CYGWIN || GTEST_OS_LINUX || GTEST_OS_MAC + +// Defines GTEST_HAS_EXCEPTIONS to 1 if exceptions are enabled, or 0 +// otherwise. + +#ifdef _MSC_VER // Compiled by MSVC? // Assumes that exceptions are enabled by default. -#ifndef _HAS_EXCEPTIONS +#ifndef _HAS_EXCEPTIONS // MSVC uses this macro to enable exceptions. #define _HAS_EXCEPTIONS 1 #endif // _HAS_EXCEPTIONS -// GTEST_HAS_EXCEPTIONS is non-zero iff exceptions are enabled. It is -// always defined, while _HAS_EXCEPTIONS is defined only on Windows. #define GTEST_HAS_EXCEPTIONS _HAS_EXCEPTIONS -// On Windows, we can use ::std::string if the compiler version is VS -// 2005 or above, or if exceptions are enabled. -#define GTEST_HAS_STD_STRING ((_MSC_VER >= 1400) || GTEST_HAS_EXCEPTIONS) -#else // We are on Linux or Mac OS. +#else // The compiler is not MSVC. +// gcc defines __EXCEPTIONS to 1 iff exceptions are enabled. For +// other compilers, we assume exceptions are disabled to be +// conservative. +#if defined(__GNUC__) && __EXCEPTIONS +#define GTEST_HAS_EXCEPTIONS 1 +#else #define GTEST_HAS_EXCEPTIONS 0 -#define GTEST_HAS_STD_STRING 1 -#endif // GTEST_OS_WINDOWS +#endif // defined(__GNUC__) && __EXCEPTIONS +#endif // _MSC_VER +// Determines whether ::std::string and ::string are available. + +#ifndef GTEST_HAS_STD_STRING +// The user didn't tell us whether ::std::string is available, so we +// need to figure it out. The only environment that we know +// ::std::string is not available is MSVC 7.1 or lower with exceptions +// disabled. +#if defined(_MSC_VER) && (_MSC_VER < 1400) && !GTEST_HAS_EXCEPTIONS +#define GTEST_HAS_STD_STRING 0 +#else +#define GTEST_HAS_STD_STRING 1 +#endif #endif // GTEST_HAS_STD_STRING #ifndef GTEST_HAS_GLOBAL_STRING @@ -227,21 +252,23 @@ // TODO(wan@google.com): uses autoconf to detect whether ::std::wstring // is available. -#if defined(GTEST_OS_CYGWIN) || defined(GTEST_OS_SOLARIS) || defined(GTEST_OS_HAIKU) || defined(_MINIX) -// At least some versions of cygwin don't support ::std::wstring. +#if GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || GTEST_OS_HAIKU || defined(_MINIX) +// Cygwin 1.5 and below doesn't support ::std::wstring. +// Cygwin 1.7 might add wstring support; this should be updated when clear. // Solaris' libc++ doesn't support it either. // Minix currently doesn't support it either. #define GTEST_HAS_STD_WSTRING 0 #else #define GTEST_HAS_STD_WSTRING GTEST_HAS_STD_STRING -#endif // defined(GTEST_OS_CYGWIN) || defined(GTEST_OS_SOLARIS) +#endif // GTEST_OS_CYGWIN || GTEST_OS_SOLARIS #endif // GTEST_HAS_STD_WSTRING #ifndef GTEST_HAS_GLOBAL_WSTRING // The user didn't tell us whether ::wstring is available, so we need // to figure it out. -#define GTEST_HAS_GLOBAL_WSTRING GTEST_HAS_GLOBAL_STRING +#define GTEST_HAS_GLOBAL_WSTRING \ + (GTEST_HAS_STD_WSTRING && GTEST_HAS_GLOBAL_STRING) #endif // GTEST_HAS_GLOBAL_WSTRING #if GTEST_HAS_STD_STRING || GTEST_HAS_GLOBAL_STRING || \ @@ -295,13 +322,7 @@ // Determines whether <pthread.h> is available. #ifndef GTEST_HAS_PTHREAD // The user didn't tell us, so we need to figure it out. - -#if defined(GTEST_OS_LINUX) || defined(GTEST_OS_MAC) -#define GTEST_HAS_PTHREAD 1 -#else -#define GTEST_HAS_PTHREAD 0 -#endif // GTEST_OS_LINUX || GTEST_OS_MAC - +#define GTEST_HAS_PTHREAD (GTEST_OS_LINUX || GTEST_OS_MAC) #endif // GTEST_HAS_PTHREAD // Determines whether tr1/tuple is available. If you have tr1/tuple @@ -342,33 +363,36 @@ #ifndef GTEST_HAS_CLONE // The user didn't tell us, so we need to figure it out. -#if defined(GTEST_OS_LINUX) && !defined(__ia64__) +#if GTEST_OS_LINUX && !defined(__ia64__) #define GTEST_HAS_CLONE 1 #else #define GTEST_HAS_CLONE 0 -#endif // defined(GTEST_OS_LINUX) && !defined(__ia64__) +#endif // GTEST_OS_LINUX && !defined(__ia64__) #endif // GTEST_HAS_CLONE // Determines whether to support death tests. -#if GTEST_HAS_STD_STRING && GTEST_HAS_CLONE -#define GTEST_HAS_DEATH_TEST -// On some platforms, <regex.h> needs someone to define size_t, and -// won't compile otherwise. We can #include it here as we already -// included <stdlib.h>, which is guaranteed to define size_t through -// <stddef.h>. -#include <regex.h> +// Google Test does not support death tests for VC 7.1 and earlier for +// these reasons: +// 1. std::vector does not build in VC 7.1 when exceptions are disabled. +// 2. std::string does not build in VC 7.1 when exceptions are disabled +// (this is covered by GTEST_HAS_STD_STRING guard). +// 3. abort() in a VC 7.1 application compiled as GUI in debug config +// pops up a dialog window that cannot be suppressed programmatically. +#if GTEST_HAS_STD_STRING && (GTEST_OS_LINUX || \ + GTEST_OS_MAC || \ + GTEST_OS_CYGWIN || \ + (GTEST_OS_WINDOWS && _MSC_VER >= 1400)) +#define GTEST_HAS_DEATH_TEST 1 #include <vector> -#include <fcntl.h> -#include <sys/mman.h> -#endif // GTEST_HAS_STD_STRING && GTEST_HAS_CLONE +#endif // Determines whether to support value-parameterized tests. #if defined(__GNUC__) || (_MSC_VER >= 1400) // TODO(vladl@google.com): get the implementation rid of vector and list // to compile on MSVC 7.1. -#define GTEST_HAS_PARAM_TEST +#define GTEST_HAS_PARAM_TEST 1 #endif // defined(__GNUC__) || (_MSC_VER >= 1400) // Determines whether to support type-driven tests. @@ -376,21 +400,19 @@ // Typed tests need <typeinfo> and variadic macros, which gcc and VC // 8.0+ support. #if defined(__GNUC__) || (_MSC_VER >= 1400) -#define GTEST_HAS_TYPED_TEST -#define GTEST_HAS_TYPED_TEST_P +#define GTEST_HAS_TYPED_TEST 1 +#define GTEST_HAS_TYPED_TEST_P 1 #endif // defined(__GNUC__) || (_MSC_VER >= 1400) // Determines whether to support Combine(). This only makes sense when // value-parameterized tests are enabled. -#if defined(GTEST_HAS_PARAM_TEST) && GTEST_HAS_TR1_TUPLE -#define GTEST_HAS_COMBINE -#endif // defined(GTEST_HAS_PARAM_TEST) && GTEST_HAS_TR1_TUPLE +#if GTEST_HAS_PARAM_TEST && GTEST_HAS_TR1_TUPLE +#define GTEST_HAS_COMBINE 1 +#endif // GTEST_HAS_PARAM_TEST && GTEST_HAS_TR1_TUPLE // Determines whether the system compiler uses UTF-16 for encoding wide strings. -#if defined(GTEST_OS_WINDOWS) || defined(GTEST_OS_CYGWIN) || \ - defined(GTEST_OS_SYMBIAN) -#define GTEST_WIDE_STRING_USES_UTF16_ 1 -#endif +#define GTEST_WIDE_STRING_USES_UTF16_ \ + (GTEST_OS_WINDOWS || GTEST_OS_CYGWIN || GTEST_OS_SYMBIAN) // Defines some utility macros. @@ -491,8 +513,6 @@ class scoped_ptr { GTEST_DISALLOW_COPY_AND_ASSIGN_(scoped_ptr); }; -#ifdef GTEST_HAS_DEATH_TEST - // Defines RE. // A simple C++ wrapper for <regex.h>. It uses the POSIX Enxtended @@ -550,12 +570,16 @@ class RE { // String type here, in order to simplify dependencies between the // files. const char* pattern_; + bool is_valid_; +#if GTEST_USES_POSIX_RE regex_t full_regex_; // For FullMatch(). regex_t partial_regex_; // For PartialMatch(). - bool is_valid_; -}; +#else // GTEST_USES_SIMPLE_RE + const char* full_pattern_; // For FullMatch(); +#endif -#endif // GTEST_HAS_DEATH_TEST + GTEST_DISALLOW_COPY_AND_ASSIGN_(RE); +}; // Defines logging utilities: // GTEST_LOG_() - logs messages at the specified severity level. @@ -584,14 +608,17 @@ inline void FlushInfoLog() { fflush(NULL); } // CaptureStderr - starts capturing stderr. // GetCapturedStderr - stops capturing stderr and returns the captured string. -#ifdef GTEST_HAS_DEATH_TEST +#if GTEST_HAS_STD_STRING +void CaptureStderr(); +::std::string GetCapturedStderr(); +#endif // GTEST_HAS_STD_STRING + +#if GTEST_HAS_DEATH_TEST // A copy of all command line arguments. Set by InitGoogleTest(). extern ::std::vector<String> g_argvs; -void CaptureStderr(); // GTEST_HAS_DEATH_TEST implies we have ::std::string. -::std::string GetCapturedStderr(); const ::std::vector<String>& GetArgvs(); #endif // GTEST_HAS_DEATH_TEST @@ -675,10 +702,15 @@ struct is_pointer : public false_type {}; template <typename T> struct is_pointer<T*> : public true_type {}; +#if GTEST_OS_WINDOWS +#define GTEST_PATH_SEP_ "\\" +#else +#define GTEST_PATH_SEP_ "/" +#endif // GTEST_OS_WINDOWS + // Defines BiggestInt as the biggest signed integer type the compiler // supports. - -#ifdef GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS typedef __int64 BiggestInt; #else typedef long long BiggestInt; // NOLINT @@ -736,7 +768,7 @@ class TypeWithSize<4> { template <> class TypeWithSize<8> { public: -#ifdef GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS typedef __int64 Int; typedef unsigned __int64 UInt; #else @@ -759,7 +791,7 @@ inline const char* GetEnv(const char* name) { #ifdef _WIN32_WCE // We are on Windows CE. // CE has no environment variables. return NULL; -#elif defined(GTEST_OS_WINDOWS) // We are on Windows proper. +#elif GTEST_OS_WINDOWS // We are on Windows proper. // MSVC 8 deprecates getenv(), so we want to suppress warning 4996 // (deprecated function) there. #pragma warning(push) // Saves the current warning state. diff --git a/utils/unittest/googletest/include/gtest/internal/gtest-string.h b/utils/unittest/googletest/include/gtest/internal/gtest-string.h index 178f14e..566a6b5 100644 --- a/utils/unittest/googletest/include/gtest/internal/gtest-string.h +++ b/utils/unittest/googletest/include/gtest/internal/gtest-string.h @@ -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 testing/base/internal/gtest-internal.h. +// This header file is #included by <gtest/internal/gtest-internal.h>. // It should not be #included by other files. #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ diff --git a/utils/unittest/googletest/include/gtest/internal/gtest-type-util.h b/utils/unittest/googletest/include/gtest/internal/gtest-type-util.h index 815da4b..1ea7d18 100644 --- a/utils/unittest/googletest/include/gtest/internal/gtest-type-util.h +++ b/utils/unittest/googletest/include/gtest/internal/gtest-type-util.h @@ -45,7 +45,7 @@ #include <gtest/internal/gtest-port.h> #include <gtest/internal/gtest-string.h> -#if defined(GTEST_HAS_TYPED_TEST) || defined(GTEST_HAS_TYPED_TEST_P) +#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P #ifdef __GNUC__ #include <cxxabi.h> |