diff --git a/googletest/include/gtest/gtest-death-test.h b/googletest/include/gtest/gtest-death-test.h index 6a216bcb..3834292f 100644 --- a/googletest/include/gtest/gtest-death-test.h +++ b/googletest/include/gtest/gtest-death-test.h @@ -1,342 +1,342 @@ // Copyright 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) // // The Google C++ Testing Framework (Google Test) // // This header file defines the public API for death tests. It is // #included by gtest.h so a user doesn't need to include this // directly. #ifndef GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ #define GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ #include "gtest/internal/gtest-death-test-internal.h" namespace testing { // This flag controls the style of death tests. Valid values are "threadsafe", // meaning that the death test child process will re-execute the test binary // from the start, running only a single death test, or "fast", // meaning that the child process will execute the test logic immediately // after forking. GTEST_DECLARE_string_(death_test_style); #if GTEST_HAS_DEATH_TEST namespace internal { // Returns a Boolean value indicating whether the caller is currently // executing in the context of the death test child process. Tools such as // Valgrind heap checkers may need this to modify their behavior in death // tests. IMPORTANT: This is an internal utility. Using it may break the // implementation of death tests. User code MUST NOT use it. GTEST_API_ bool InDeathTestChild(); } // namespace internal // The following macros are useful for writing death tests. // Here's what happens when an ASSERT_DEATH* or EXPECT_DEATH* is // executed: // // 1. It generates a warning if there is more than one active // thread. This is because it's safe to fork() or clone() only // when there is a single thread. // // 2. The parent process clone()s a sub-process and runs the death // test in it; the sub-process exits with code 0 at the end of the // death test, if it hasn't exited already. // // 3. The parent process waits for the sub-process to terminate. // // 4. The parent process checks the exit code and error message of // the sub-process. // // Examples: // // ASSERT_DEATH(server.SendMessage(56, "Hello"), "Invalid port number"); // for (int i = 0; i < 5; i++) { // EXPECT_DEATH(server.ProcessRequest(i), // "Invalid request .* in ProcessRequest()") // << "Failed to die on request " << i; // } // // ASSERT_EXIT(server.ExitNow(), ::testing::ExitedWithCode(0), "Exiting"); // // bool KilledBySIGHUP(int exit_code) { // return WIFSIGNALED(exit_code) && WTERMSIG(exit_code) == SIGHUP; // } // // ASSERT_EXIT(client.HangUpServer(), KilledBySIGHUP, "Hanging up!"); // // On the regular expressions used in death tests: // // On POSIX-compliant systems (*nix), we use the library, // which uses the POSIX extended regex syntax. // // On other platforms (e.g. Windows or Mac), 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 // program from argv[0] and re-executes it in the sub-process. For // simplicity, the current implementation doesn't search the PATH // when launching the sub-process. This means that the user must // invoke the test program via a path that contains at least one // path separator (e.g. path/to/foo_test and // /absolute/path/to/bar_test are fine, but foo_test is not). This // is rarely a problem as people usually don't put the test binary // directory in PATH. // // TODO(wan@google.com): make thread-safe death tests search the PATH. // Asserts that a given statement causes the program to exit, with an // integer exit status that satisfies predicate, and emitting error output // that matches regex. # define ASSERT_EXIT(statement, predicate, regex) \ GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_FATAL_FAILURE_) // Like ASSERT_EXIT, but continues on to successive tests in the // test case, if any: # define EXPECT_EXIT(statement, predicate, regex) \ GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_NONFATAL_FAILURE_) // Asserts that a given statement causes the program to exit, either by // explicitly exiting with a nonzero exit code or being killed by a // signal, and emitting error output that matches regex. # define ASSERT_DEATH(statement, regex) \ ASSERT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex) // Like ASSERT_DEATH, but continues on to successive tests in the // test case, if any: # define EXPECT_DEATH(statement, regex) \ EXPECT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex) // Two predicate classes that can be used in {ASSERT,EXPECT}_EXIT*: // Tests that an exit code describes a normal exit with a given exit code. class GTEST_API_ ExitedWithCode { public: explicit ExitedWithCode(int exit_code); bool operator()(int exit_status) const; private: // No implementation - assignment is unsupported. void operator=(const ExitedWithCode& other); const int exit_code_; }; -# if !GTEST_OS_WINDOWS +# if !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA // Tests that an exit code describes an exit due to termination by a // given signal. class GTEST_API_ KilledBySignal { public: explicit KilledBySignal(int signum); bool operator()(int exit_status) const; 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, // since the sideeffects of the call are only visible in opt mode, and not // in debug mode. // // In practice, this can be used to test functions that utilize the // LOG(DFATAL) macro using the following style: // // int DieInDebugOr12(int* sideeffect) { // if (sideeffect) { // *sideeffect = 12; // } // LOG(DFATAL) << "death"; // return 12; // } // // TEST(TestCase, TestDieOr12WorksInDgbAndOpt) { // int sideeffect = 0; // // Only asserts in dbg. // EXPECT_DEBUG_DEATH(DieInDebugOr12(&sideeffect), "death"); // // #ifdef NDEBUG // // opt-mode has sideeffect visible. // EXPECT_EQ(12, sideeffect); // #else // // dbg-mode no visible sideeffect. // EXPECT_EQ(0, sideeffect); // #endif // } // // This will assert that DieInDebugReturn12InOpt() crashes in debug // mode, usually due to a DCHECK or LOG(DFATAL), but returns the // appropriate fallback value (12 in this case) in opt mode. If you // need to test that a function has appropriate side-effects in opt // mode, include assertions against the side-effects. A general // pattern for this is: // // EXPECT_DEBUG_DEATH({ // // Side-effects here will have an effect after this statement in // // opt mode, but none in debug mode. // EXPECT_EQ(12, DieInDebugOr12(&sideeffect)); // }, "death"); // # ifdef NDEBUG # define EXPECT_DEBUG_DEATH(statement, regex) \ GTEST_EXECUTE_STATEMENT_(statement, regex) # define ASSERT_DEBUG_DEATH(statement, regex) \ GTEST_EXECUTE_STATEMENT_(statement, regex) # else # define EXPECT_DEBUG_DEATH(statement, regex) \ EXPECT_DEATH(statement, regex) # define ASSERT_DEBUG_DEATH(statement, regex) \ ASSERT_DEATH(statement, regex) # endif // NDEBUG for EXPECT_DEBUG_DEATH #endif // GTEST_HAS_DEATH_TEST // This macro is used for implementing macros such as // EXPECT_DEATH_IF_SUPPORTED and ASSERT_DEATH_IF_SUPPORTED on systems where // death tests are not supported. Those macros must compile on such systems // iff EXPECT_DEATH and ASSERT_DEATH compile with the same parameters on // systems that support death tests. This allows one to write such a macro // on a system that does not support death tests and be sure that it will // compile on a death-test supporting system. It is exposed publicly so that // systems that have death-tests with stricter requirements than // GTEST_HAS_DEATH_TEST can write their own equivalent of // EXPECT_DEATH_IF_SUPPORTED and ASSERT_DEATH_IF_SUPPORTED. // // Parameters: // statement - A statement that a macro such as EXPECT_DEATH would test // for program termination. This macro has to make sure this // statement is compiled but not executed, to ensure that // EXPECT_DEATH_IF_SUPPORTED compiles with a certain // parameter iff EXPECT_DEATH compiles with it. // regex - A regex that a macro such as EXPECT_DEATH would use to test // the output of statement. This parameter has to be // compiled but not evaluated by this macro, to ensure that // this macro only accepts expressions that a macro such as // EXPECT_DEATH would accept. // terminator - Must be an empty statement for EXPECT_DEATH_IF_SUPPORTED // and a return statement for ASSERT_DEATH_IF_SUPPORTED. // This ensures that ASSERT_DEATH_IF_SUPPORTED will not // compile inside functions where ASSERT_DEATH doesn't // compile. // // The branch that has an always false condition is used to ensure that // statement and regex are compiled (and thus syntactically correct) but // never executed. The unreachable code macro protects the terminator // statement from generating an 'unreachable code' warning in case // statement unconditionally returns or throws. The Message constructor at // the end allows the syntax of streaming additional messages into the // macro, for compilational compatibility with EXPECT_DEATH/ASSERT_DEATH. # define GTEST_UNSUPPORTED_DEATH_TEST(statement, regex, terminator) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (::testing::internal::AlwaysTrue()) { \ GTEST_LOG_(WARNING) \ << "Death tests are not supported on this platform.\n" \ << "Statement '" #statement "' cannot be verified."; \ } else if (::testing::internal::AlwaysFalse()) { \ ::testing::internal::RE::PartialMatch(".*", (regex)); \ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ terminator; \ } else \ ::testing::Message() // EXPECT_DEATH_IF_SUPPORTED(statement, regex) and // ASSERT_DEATH_IF_SUPPORTED(statement, regex) expand to real death tests if // death tests are supported; otherwise they just issue a warning. This is // useful when you are combining death test assertions with normal test // assertions in one test. #if GTEST_HAS_DEATH_TEST # define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ EXPECT_DEATH(statement, regex) # define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \ ASSERT_DEATH(statement, regex) #else # define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ GTEST_UNSUPPORTED_DEATH_TEST(statement, regex, ) # define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \ GTEST_UNSUPPORTED_DEATH_TEST(statement, regex, return) #endif } // namespace testing #endif // GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ diff --git a/googletest/src/gtest-death-test.cc b/googletest/src/gtest-death-test.cc index 50c15edd..a02d8100 100644 --- a/googletest/src/gtest-death-test.cc +++ b/googletest/src/gtest-death-test.cc @@ -1,1537 +1,1537 @@ // Copyright 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan), vladl@google.com (Vlad Losev) // // This file implements death tests. #include "gtest/gtest-death-test.h" #include "gtest/internal/gtest-port.h" #include "gtest/internal/custom/gtest.h" #if GTEST_HAS_DEATH_TEST # if GTEST_OS_MAC # include # endif // GTEST_OS_MAC # include # include # include # if GTEST_OS_LINUX # include # endif // GTEST_OS_LINUX # include # if GTEST_OS_WINDOWS # include # else # include # include # endif // GTEST_OS_WINDOWS # if GTEST_OS_QNX # include # endif // GTEST_OS_QNX # if GTEST_OS_FUCHSIA # include # include # include # endif // GTEST_OS_FUCHSIA #endif // GTEST_HAS_DEATH_TEST #include "gtest/gtest-message.h" #include "gtest/internal/gtest-string.h" #include "src/gtest-internal-inl.h" namespace testing { // Constants. // The default death test style. // // This is defined in internal/gtest-port.h as "fast", but can be overridden by // a definition in internal/custom/gtest-port.h. The recommended value, which is // used internally at Google, is "threadsafe". static const char kDefaultDeathTestStyle[] = GTEST_DEFAULT_DEATH_TEST_STYLE; GTEST_DEFINE_string_( death_test_style, internal::StringFromGTestEnv("death_test_style", kDefaultDeathTestStyle), "Indicates how to run a death test in a forked child process: " "\"threadsafe\" (child process re-executes the test binary " "from the beginning, running only the specific death test) or " "\"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, "", "Indicates the file, line number, temporal index of " "the single death test to run, and a file descriptor to " "which a success code may be sent, all separated by " "the '|' characters. This flag is specified if and only if the current " "process is a sub-process launched for running a thread-safe " "death test. FOR INTERNAL USE ONLY."); } // namespace internal #if GTEST_HAS_DEATH_TEST namespace internal { // Valid only for fast death tests. Indicates the code is running in the // child process of a fast style death test. # if !GTEST_OS_WINDOWS static bool g_in_fast_death_test_child = false; # endif // Returns a Boolean value indicating whether the caller is currently // executing in the context of the death test child process. Tools such as // Valgrind heap checkers may need this to modify their behavior in death // tests. IMPORTANT: This is an internal utility. Using it may break the // implementation of death tests. User code MUST NOT use it. bool InDeathTestChild() { # if GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA // On Windows, death tests are thread-safe regardless of the value of the // death_test_style flag. return !GTEST_FLAG(internal_run_death_test).empty(); # else if (GTEST_FLAG(death_test_style) == "threadsafe") return !GTEST_FLAG(internal_run_death_test).empty(); else return g_in_fast_death_test_child; #endif } } // namespace internal // ExitedWithCode constructor. ExitedWithCode::ExitedWithCode(int exit_code) : exit_code_(exit_code) { } // ExitedWithCode function-call operator. bool ExitedWithCode::operator()(int exit_status) const { -# if GTEST_OS_WINDOWS +# if GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA return exit_status == exit_code_; # else return WIFEXITED(exit_status) && WEXITSTATUS(exit_status) == exit_code_; # endif // GTEST_OS_WINDOWS } -# if !GTEST_OS_WINDOWS +# if !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA // KilledBySignal constructor. KilledBySignal::KilledBySignal(int signum) : signum_(signum) { } // KilledBySignal function-call operator. bool KilledBySignal::operator()(int exit_status) const { # if defined(GTEST_KILLED_BY_SIGNAL_OVERRIDE_) { bool result; if (GTEST_KILLED_BY_SIGNAL_OVERRIDE_(signum_, exit_status, &result)) { return result; } } # endif // defined(GTEST_KILLED_BY_SIGNAL_OVERRIDE_) return WIFSIGNALED(exit_status) && WTERMSIG(exit_status) == signum_; } # endif // !GTEST_OS_WINDOWS namespace internal { // Utilities needed for death tests. // Generates a textual description of a given exit code, in the format // specified by wait(2). static std::string ExitSummary(int exit_code) { Message m; -# if GTEST_OS_WINDOWS +# if GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA m << "Exited with exit status " << exit_code; # else if (WIFEXITED(exit_code)) { m << "Exited with exit status " << WEXITSTATUS(exit_code); } else if (WIFSIGNALED(exit_code)) { m << "Terminated by signal " << WTERMSIG(exit_code); } # ifdef WCOREDUMP if (WCOREDUMP(exit_code)) { m << " (core dumped)"; } # endif # endif // GTEST_OS_WINDOWS return m.GetString(); } // Returns true if exit_status describes a process that was terminated // by a signal, or exited normally with a nonzero exit code. bool ExitedUnsuccessfully(int exit_status) { return !ExitedWithCode(0)(exit_status); } # if !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA // Generates a textual failure message when a death test finds more than // one thread running, or cannot determine the number of threads, prior // to executing the given statement. It is the responsibility of the // caller not to pass a thread_count of 1. static std::string DeathTestThreadWarning(size_t thread_count) { Message msg; msg << "Death tests use fork(), which is unsafe particularly" << " in a threaded context. For this test, " << GTEST_NAME_ << " "; if (thread_count == 0) msg << "couldn't detect the number of threads."; else msg << "detected " << thread_count << " threads."; return msg.GetString(); } # endif // !GTEST_OS_WINDOWS // Flag characters for reporting a death test that did not die. static const char kDeathTestLived = 'L'; static const char kDeathTestReturned = 'R'; static const char kDeathTestThrew = 'T'; static const char kDeathTestInternalError = 'I'; #if GTEST_OS_FUCHSIA // File descriptor used for the pipe in the child process. static const int kFuchsiaReadPipeFd = 3; #endif // An enumeration describing all of the possible ways that a death test can // conclude. DIED means that the process died while executing the test // code; LIVED means that process lived beyond the end of the test code; // RETURNED means that the test statement attempted to execute a return // statement, which is not allowed; THREW means that the test statement // returned control by throwing an exception. IN_PROGRESS means the test // has not yet concluded. // TODO(vladl@google.com): Unify names and possibly values for // AbortReason, DeathTestOutcome, and flag characters above. enum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED, THREW }; // Routine for aborting the program which is safe to call from an // 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. static void DeathTestAbort(const std::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(); if (flag != NULL) { FILE* parent = posix::FDOpen(flag->write_fd(), "w"); fputc(kDeathTestInternalError, parent); fprintf(parent, "%s", message.c_str()); fflush(parent); _exit(1); } else { fprintf(stderr, "%s", message.c_str()); fflush(stderr); posix::Abort(); } } // A replacement for CHECK that calls DeathTestAbort if the assertion // fails. # define GTEST_DEATH_TEST_CHECK_(expression) \ do { \ if (!::testing::internal::IsTrue(expression)) { \ DeathTestAbort( \ ::std::string("CHECK failed: File ") + __FILE__ + ", line " \ + ::testing::internal::StreamableToString(__LINE__) + ": " \ + #expression); \ } \ } while (::testing::internal::AlwaysFalse()) // This macro is similar to GTEST_DEATH_TEST_CHECK_, but it is meant for // evaluating any system call that fulfills two conditions: it must return // -1 on failure, and set errno to EINTR when it is interrupted and // should be tried again. The macro expands to a loop that repeatedly // evaluates the expression as long as it evaluates to -1 and sets // errno to EINTR. If the expression evaluates to -1 but errno is // something other than EINTR, DeathTestAbort is called. # define GTEST_DEATH_TEST_CHECK_SYSCALL_(expression) \ do { \ int gtest_retval; \ do { \ gtest_retval = (expression); \ } while (gtest_retval == -1 && errno == EINTR); \ if (gtest_retval == -1) { \ DeathTestAbort( \ ::std::string("CHECK failed: File ") + __FILE__ + ", line " \ + ::testing::internal::StreamableToString(__LINE__) + ": " \ + #expression + " != -1"); \ } \ } while (::testing::internal::AlwaysFalse()) // Returns the message describing the last system error in errno. std::string GetLastErrnoDescription() { return errno == 0 ? "" : posix::StrError(errno); } // 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. static void FailFromInternalError(int fd) { Message error; char buffer[256]; int num_read; do { while ((num_read = posix::Read(fd, buffer, 255)) > 0) { buffer[num_read] = '\0'; error << buffer; } } while (num_read == -1 && errno == EINTR); if (num_read == 0) { GTEST_LOG_(FATAL) << error.GetString(); } else { const int last_error = errno; GTEST_LOG_(FATAL) << "Error while reading death test internal: " << GetLastErrnoDescription() << " [" << last_error << "]"; } } // Death test constructor. Increments the running death test count // for the current test. DeathTest::DeathTest() { TestInfo* const info = GetUnitTestImpl()->current_test_info(); if (info == NULL) { DeathTestAbort("Cannot run a death test outside of a TEST or " "TEST_F construct"); } } // Creates and returns a death test by dispatching to the current // death test factory. bool DeathTest::Create(const char* statement, const RE* regex, const char* file, int line, DeathTest** test) { return GetUnitTestImpl()->death_test_factory()->Create( statement, regex, file, line, test); } const char* DeathTest::LastMessage() { return last_death_test_message_.c_str(); } void DeathTest::set_last_death_test_message(const std::string& message) { last_death_test_message_ = message; } std::string DeathTest::last_death_test_message_; // Provides cross platform implementation for some death functionality. class DeathTestImpl : public DeathTest { protected: DeathTestImpl(const char* a_statement, const RE* a_regex) : statement_(a_statement), regex_(a_regex), spawned_(false), status_(-1), outcome_(IN_PROGRESS), read_fd_(-1), write_fd_(-1) {} // read_fd_ is expected to be closed and cleared by a derived class. ~DeathTestImpl() { GTEST_DEATH_TEST_CHECK_(read_fd_ == -1); } void Abort(AbortReason reason); 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 is_spawned) { spawned_ = is_spawned; } int status() const { return status_; } void set_status(int a_status) { status_ = a_status; } DeathTestOutcome outcome() const { return outcome_; } void set_outcome(DeathTestOutcome an_outcome) { outcome_ = an_outcome; } int read_fd() const { return read_fd_; } void set_read_fd(int fd) { read_fd_ = fd; } int write_fd() const { return write_fd_; } void set_write_fd(int fd) { write_fd_ = fd; } // Called in the parent process only. Reads the result code of the death // test child process via a pipe, interprets it to set the outcome_ // member, and closes read_fd_. Outputs diagnostics and terminates in // case of unexpected codes. void ReadAndInterpretStatusByte(); 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_; // Descriptor to the read end of the pipe to the child process. It is // always -1 in the child process. The child keeps its write end of the // pipe in write_fd_. int read_fd_; // Descriptor to the child's write end of the pipe to the parent process. // It is always -1 in the parent process. The parent keeps its end of the // pipe in read_fd_. int write_fd_; }; // Called in the parent process only. Reads the result code of the death // test child process via a pipe, interprets it to set the outcome_ // member, and closes read_fd_. Outputs diagnostics and terminates in // case of unexpected codes. void DeathTestImpl::ReadAndInterpretStatusByte() { char flag; int bytes_read; // The read() here 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 // the child process has exited. do { bytes_read = posix::Read(read_fd(), &flag, 1); } while (bytes_read == -1 && errno == EINTR); if (bytes_read == 0) { set_outcome(DIED); } else if (bytes_read == 1) { switch (flag) { case kDeathTestReturned: set_outcome(RETURNED); break; case kDeathTestThrew: set_outcome(THREW); break; case kDeathTestLived: set_outcome(LIVED); break; case kDeathTestInternalError: FailFromInternalError(read_fd()); // Does not return. break; default: GTEST_LOG_(FATAL) << "Death test child process reported " << "unexpected status byte (" << static_cast(flag) << ")"; } } else { GTEST_LOG_(FATAL) << "Read from death test child process failed: " << GetLastErrnoDescription(); } GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Close(read_fd())); set_read_fd(-1); } // 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 descriptor, then // calls _exit(1). void DeathTestImpl::Abort(AbortReason reason) { // 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 : reason == TEST_THREW_EXCEPTION ? kDeathTestThrew : kDeathTestReturned; GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Write(write_fd(), &status_ch, 1)); // We are leaking the descriptor here because on some platforms (i.e., // when built as Windows DLL), destructors of global objects will still // run after calling _exit(). On such systems, write_fd_ will be // indirectly closed from the destructor of UnitTestImpl, causing double // close if it is also closed here. On debug configurations, double close // may assert. As there are no in-process buffers to flush here, we are // relying on the OS to close the descriptor after the process terminates // when the destructors are not run. _exit(1); // Exits w/o any normal exit hooks (we were supposed to crash) } // Returns an indented copy of stderr output for a death test. // This makes distinguishing death test output lines from regular log lines // much easier. static ::std::string FormatDeathTestOutput(const ::std::string& output) { ::std::string ret; for (size_t at = 0; ; ) { const size_t line_end = output.find('\n', at); ret += "[ DEATH ] "; if (line_end == ::std::string::npos) { ret += output.substr(at); break; } ret += output.substr(at, line_end + 1 - at); at = line_end + 1; } return ret; } // 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 // concluded: DIED, LIVED, THREW, or RETURNED. The death test // fails in the latter three 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. // // Argument: // status_ok: true if exit_status is acceptable in the context of // this particular death test, which fails if it is false // // 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 last death test message string. bool DeathTestImpl::Passed(bool status_ok) { if (!spawned()) return false; const std::string error_message = GetCapturedStderr(); bool success = false; Message buffer; buffer << "Death test: " << statement() << "\n"; switch (outcome()) { case LIVED: buffer << " Result: failed to die.\n" << " Error msg:\n" << FormatDeathTestOutput(error_message); break; case THREW: buffer << " Result: threw an exception.\n" << " Error msg:\n" << FormatDeathTestOutput(error_message); break; case RETURNED: buffer << " Result: illegal return in test statement.\n" << " Error msg:\n" << FormatDeathTestOutput(error_message); break; case DIED: if (status_ok) { # if GTEST_USES_PCRE // PCRE regexes support embedded NULs. // GTEST_USES_PCRE is defined only in google3 mode const bool matched = RE::PartialMatch(error_message, *regex()); # else const bool matched = RE::PartialMatch(error_message.c_str(), *regex()); # endif // GTEST_USES_PCRE if (matched) { success = true; } else { buffer << " Result: died but not with expected error.\n" << " Expected: " << regex()->pattern() << "\n" << "Actual msg:\n" << FormatDeathTestOutput(error_message); } } else { buffer << " Result: died but not with expected exit code:\n" << " " << ExitSummary(status()) << "\n" << "Actual msg:\n" << FormatDeathTestOutput(error_message); } break; case IN_PROGRESS: default: GTEST_LOG_(FATAL) << "DeathTest::Passed somehow called before conclusion of test"; } DeathTest::set_last_death_test_message(buffer.GetString()); return success; } # 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* a_statement, const RE* a_regex, const char* file, int line) : DeathTestImpl(a_statement, a_regex), file_(file), line_(line) {} // All of these virtual functions are inherited from DeathTest. virtual int Wait(); virtual TestRole AssumeRole(); private: // The name of the file in which the death test is located. const char* const file_; // The line number on which the death test is located. const int line_; // 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. 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(); ReadAndInterpretStatusByte(); // 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_code; GTEST_DEATH_TEST_CHECK_( ::GetExitCodeProcess(child_handle_.Get(), &status_code) != FALSE); child_handle_.Reset(); set_status(static_cast(status_code)); return status(); } // 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. set_write_fd(flag->write_fd()); 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. != FALSE); set_read_fd(::_open_osfhandle(reinterpret_cast(read_handle), O_RDONLY)); 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 std::string filter_flag = std::string("--") + GTEST_FLAG_PREFIX_ + kFilterFlag + "=" + info->test_case_name() + "." + info->name(); const std::string internal_flag = std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + "=" + file_ + "|" + StreamableToString(line_) + "|" + StreamableToString(death_test_index) + "|" + StreamableToString(static_cast(::GetCurrentProcessId())) + // size_t has the same width as pointers on both 32-bit and 64-bit // Windows platforms. // See http://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx. "|" + StreamableToString(reinterpret_cast(write_handle)) + "|" + StreamableToString(reinterpret_cast(event_handle_.Get())); char executable_path[_MAX_PATH + 1]; // NOLINT GTEST_DEATH_TEST_CHECK_( _MAX_PATH + 1 != ::GetModuleFileNameA(NULL, executable_path, _MAX_PATH)); std::string command_line = std::string(::GetCommandLineA()) + " " + filter_flag + " \"" + internal_flag + "\""; 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(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) != FALSE); child_handle_.Reset(process_info.hProcess); ::CloseHandle(process_info.hThread); set_spawned(true); return OVERSEE_TEST; } # elif GTEST_OS_FUCHSIA class FuchsiaDeathTest : public DeathTestImpl { public: FuchsiaDeathTest(const char* a_statement, const RE* a_regex, const char* file, int line) : DeathTestImpl(a_statement, a_regex), file_(file), line_(line) {} // All of these virtual functions are inherited from DeathTest. virtual int Wait(); virtual TestRole AssumeRole(); private: // The name of the file in which the death test is located. const char* const file_; // The line number on which the death test is located. const int line_; zx_handle_t child_process_; }; // Utility class for accumulating command-line arguments. class Arguments { public: Arguments() { args_.push_back(NULL); } ~Arguments() { for (std::vector::iterator i = args_.begin(); i != args_.end(); ++i) { free(*i); } } void AddArgument(const char* argument) { args_.insert(args_.end() - 1, posix::StrDup(argument)); } template void AddArguments(const ::std::vector& arguments) { for (typename ::std::vector::const_iterator i = arguments.begin(); i != arguments.end(); ++i) { args_.insert(args_.end() - 1, posix::StrDup(i->c_str())); } } char* const* Argv() { return &args_[0]; } int size() { return args_.size() - 1; } private: std::vector args_; }; // Waits for the child in a death test to exit, returning its exit // status, or 0 if no child process exists. As a side effect, sets the // outcome data member. int FuchsiaDeathTest::Wait() { if (!spawned()) return 0; // Wait for child process to terminate. zx_status_t status_zx; zx_signals_t signals; status_zx = zx_object_wait_one( - child_process_, - ZX_PROCESS_TERMINATED, - ZX_TIME_INFINITE, - &signals); + child_process_, + ZX_PROCESS_TERMINATED, + ZX_TIME_INFINITE, + &signals); GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK); ReadAndInterpretStatusByte(); zx_info_process_t buffer; status_zx = zx_object_get_info( child_process_, ZX_INFO_PROCESS, &buffer, sizeof(buffer), nullptr, nullptr); GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK); GTEST_DEATH_TEST_CHECK_(buffer.exited); set_status(buffer.return_code); return status(); } // The AssumeRole process for a Fuchsia death test. It creates a child // process with the same executable as the current process to run the // death test. The child process is given the --gtest_filter and // --gtest_internal_run_death_test flags such that it knows to run the // current death test only. DeathTest::TestRole FuchsiaDeathTest::AssumeRole() { const UnitTestImpl* const impl = GetUnitTestImpl(); const InternalRunDeathTestFlag* const flag = impl->internal_run_death_test_flag(); const TestInfo* const info = impl->current_test_info(); const int death_test_index = info->result()->death_test_count(); if (flag != NULL) { // ParseInternalRunDeathTestFlag() has performed all the necessary // processing. set_write_fd(kFuchsiaReadPipeFd); return EXECUTE_TEST; } CaptureStderr(); // Flush the log buffers since the log streams are shared with the child. FlushInfoLog(); // Build the child process command line. const std::string filter_flag = std::string("--") + GTEST_FLAG_PREFIX_ + kFilterFlag + "=" + info->test_case_name() + "." + info->name(); const std::string internal_flag = std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + "=" + file_ + "|" + StreamableToString(line_) + "|" + StreamableToString(death_test_index); Arguments args; args.AddArguments(GetInjectableArgvs()); args.AddArgument(filter_flag.c_str()); args.AddArgument(internal_flag.c_str()); // Build the child process launcher. zx_status_t status; launchpad_t* lp; status = launchpad_create(ZX_HANDLE_INVALID, args.Argv()[0], &lp); GTEST_DEATH_TEST_CHECK_(status == ZX_OK); // Build the pipe for communication with the child. int read_fd; status = launchpad_add_pipe(lp, &read_fd, 3); GTEST_DEATH_TEST_CHECK_(status == ZX_OK); set_read_fd(read_fd); // Set the command line arguments. status = launchpad_load_from_file(lp, args.Argv()[0]); GTEST_DEATH_TEST_CHECK_(status == ZX_OK); status = launchpad_set_args(lp, args.size(), args.Argv()); GTEST_DEATH_TEST_CHECK_(status == ZX_OK); // Clone all the things (environment, stdio, namespace, ...). launchpad_clone(lp, LP_CLONE_ALL); // Launch the child process. status = launchpad_go(lp, &child_process_, nullptr); GTEST_DEATH_TEST_CHECK_(status == ZX_OK); set_spawned(true); return OVERSEE_TEST; } #else // We are neither on Windows, nor on Fuchsia. // ForkingDeathTest provides implementations for most of the abstract // methods of the DeathTest interface. Only the AssumeRole method is // left undefined. class ForkingDeathTest : public DeathTestImpl { public: ForkingDeathTest(const char* statement, const RE* regex); // All of these virtual functions are inherited from DeathTest. virtual int Wait(); protected: void set_child_pid(pid_t child_pid) { child_pid_ = child_pid; } private: // PID of child process during death test; 0 in the child process itself. pid_t child_pid_; }; // Constructs a ForkingDeathTest. ForkingDeathTest::ForkingDeathTest(const char* a_statement, const RE* a_regex) : DeathTestImpl(a_statement, a_regex), child_pid_(-1) {} // 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 (!spawned()) return 0; ReadAndInterpretStatusByte(); int status_value; GTEST_DEATH_TEST_CHECK_SYSCALL_(waitpid(child_pid_, &status_value, 0)); set_status(status_value); return status_value; } // A concrete death test class that forks, then immediately runs the test // in the child process. class NoExecDeathTest : public ForkingDeathTest { public: NoExecDeathTest(const char* a_statement, const RE* a_regex) : ForkingDeathTest(a_statement, a_regex) { } virtual TestRole AssumeRole(); }; // The AssumeRole process for a fork-and-run death test. It implements a // straightforward fork, with a simple pipe to transmit the status byte. DeathTest::TestRole NoExecDeathTest::AssumeRole() { const size_t thread_count = GetThreadCount(); if (thread_count != 1) { GTEST_LOG_(WARNING) << DeathTestThreadWarning(thread_count); } int pipe_fd[2]; GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1); 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 // the file descriptors in the child process doesn't throw off the // synchronization between descriptors and buffers in the parent process. // This is as close to the fork as possible to avoid a race condition in case // there are multiple threads running before the death test, and another // thread writes to the log file. FlushInfoLog(); const pid_t child_pid = fork(); GTEST_DEATH_TEST_CHECK_(child_pid != -1); set_child_pid(child_pid); if (child_pid == 0) { GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[0])); set_write_fd(pipe_fd[1]); // Redirects all logging to stderr in the child process to prevent // concurrent writes to the log files. We capture stderr in the parent // process and append the child process' output to a log. LogToStderr(); // Event forwarding to the listeners of event listener API mush be shut // down in death test subprocesses. GetUnitTestImpl()->listeners()->SuppressEventForwarding(); g_in_fast_death_test_child = true; return EXECUTE_TEST; } else { GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); set_read_fd(pipe_fd[0]); set_spawned(true); return OVERSEE_TEST; } } // A concrete death test class that forks and re-executes the main // program from the beginning, with command-line flags set that cause // only this specific death test to be run. class ExecDeathTest : public ForkingDeathTest { public: ExecDeathTest(const char* a_statement, const RE* a_regex, const char* file, int line) : ForkingDeathTest(a_statement, a_regex), file_(file), line_(line) { } virtual TestRole AssumeRole(); private: static ::std::vector GetArgvsForDeathTestChildProcess() { ::std::vector args = GetInjectableArgvs(); # if defined(GTEST_EXTRA_DEATH_TEST_COMMAND_LINE_ARGS_) ::std::vector extra_args = GTEST_EXTRA_DEATH_TEST_COMMAND_LINE_ARGS_(); args.insert(args.end(), extra_args.begin(), extra_args.end()); # endif // defined(GTEST_EXTRA_DEATH_TEST_COMMAND_LINE_ARGS_) return args; } // 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_; }; // Utility class for accumulating command-line arguments. class Arguments { public: Arguments() { args_.push_back(NULL); } ~Arguments() { for (std::vector::iterator i = args_.begin(); i != args_.end(); ++i) { free(*i); } } void AddArgument(const char* argument) { args_.insert(args_.end() - 1, posix::StrDup(argument)); } template void AddArguments(const ::std::vector& arguments) { for (typename ::std::vector::const_iterator i = arguments.begin(); i != arguments.end(); ++i) { args_.insert(args_.end() - 1, posix::StrDup(i->c_str())); } } char* const* Argv() { return &args_[0]; } private: std::vector args_; }; // A struct that encompasses the arguments to the child process of a // threadsafe-style death test process. struct ExecDeathTestArgs { char* const* argv; // Command-line arguments for the child's call to exec 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 // Some POSIX platforms expect you to declare environ. extern "C" makes // it reside in the global namespace. extern "C" char** environ; inline char** GetEnviron() { return environ; } # endif // GTEST_OS_MAC # if !GTEST_OS_QNX // 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. static int ExecDeathTestChildMain(void* child_arg) { ExecDeathTestArgs* const args = static_cast(child_arg); GTEST_DEATH_TEST_CHECK_SYSCALL_(close(args->close_fd)); // We need to execute the test program in the same environment where // it was originally invoked. Therefore we change to the original // working directory first. const char* const original_dir = UnitTest::GetInstance()->original_working_dir(); // We can safely call chdir() as it's a direct system call. if (chdir(original_dir) != 0) { DeathTestAbort(std::string("chdir(\"") + original_dir + "\") failed: " + GetLastErrnoDescription()); return EXIT_FAILURE; } // We can safely call execve() as it's a direct system call. We // cannot use execvp() as it's a libc function and thus potentially // 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, GetEnviron()); DeathTestAbort(std::string("execve(") + args->argv[0] + ", ...) in " + original_dir + " failed: " + GetLastErrnoDescription()); return EXIT_FAILURE; } # endif // !GTEST_OS_QNX # if GTEST_HAS_CLONE // Two utility routines that together determine the direction the stack // grows. // 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. // // GTEST_NO_INLINE_ is required to prevent GCC 4.6 from inlining // StackLowerThanAddress into StackGrowsDown, which then doesn't give // correct answer. static void StackLowerThanAddress(const void* ptr, bool* result) GTEST_NO_INLINE_; static void StackLowerThanAddress(const void* ptr, bool* result) { int dummy; *result = (&dummy < ptr); } // Make sure AddressSanitizer does not tamper with the stack here. GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ static bool StackGrowsDown() { int dummy; bool result; StackLowerThanAddress(&dummy, &result); return result; } # endif // GTEST_HAS_CLONE // Spawns a child process with the same executable as the current process in // a thread-safe manner and instructs it to run the death test. The // implementation uses fork(2) + exec. On systems where clone(2) is // available, it is used instead, being slightly more thread-safe. On QNX, // fork supports only single-threaded environments, so this function uses // spawn(2) there instead. The function dies with an error message if // anything goes wrong. static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) { ExecDeathTestArgs args = { argv, close_fd }; pid_t child_pid = -1; # if GTEST_OS_QNX // Obtains the current directory and sets it to be closed in the child // process. const int cwd_fd = open(".", O_RDONLY); GTEST_DEATH_TEST_CHECK_(cwd_fd != -1); GTEST_DEATH_TEST_CHECK_SYSCALL_(fcntl(cwd_fd, F_SETFD, FD_CLOEXEC)); // We need to execute the test program in the same environment where // it was originally invoked. Therefore we change to the original // working directory first. const char* const original_dir = UnitTest::GetInstance()->original_working_dir(); // We can safely call chdir() as it's a direct system call. if (chdir(original_dir) != 0) { DeathTestAbort(std::string("chdir(\"") + original_dir + "\") failed: " + GetLastErrnoDescription()); return EXIT_FAILURE; } int fd_flags; // Set close_fd to be closed after spawn. GTEST_DEATH_TEST_CHECK_SYSCALL_(fd_flags = fcntl(close_fd, F_GETFD)); GTEST_DEATH_TEST_CHECK_SYSCALL_(fcntl(close_fd, F_SETFD, fd_flags | FD_CLOEXEC)); struct inheritance inherit = {0}; // spawn is a system call. child_pid = spawn(args.argv[0], 0, NULL, &inherit, args.argv, GetEnviron()); // Restores the current working directory. GTEST_DEATH_TEST_CHECK_(fchdir(cwd_fd) != -1); GTEST_DEATH_TEST_CHECK_SYSCALL_(close(cwd_fd)); # else // GTEST_OS_QNX # if GTEST_OS_LINUX // When a SIGPROF signal is received while fork() or clone() are executing, // the process may hang. To avoid this, we ignore SIGPROF here and re-enable // it after the call to fork()/clone() is complete. struct sigaction saved_sigprof_action; struct sigaction ignore_sigprof_action; memset(&ignore_sigprof_action, 0, sizeof(ignore_sigprof_action)); sigemptyset(&ignore_sigprof_action.sa_mask); ignore_sigprof_action.sa_handler = SIG_IGN; GTEST_DEATH_TEST_CHECK_SYSCALL_(sigaction( SIGPROF, &ignore_sigprof_action, &saved_sigprof_action)); # endif // GTEST_OS_LINUX # 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); // Maximum stack alignment in bytes: For a downward-growing stack, this // amount is subtracted from size of the stack space to get an address // that is within the stack space and is aligned on all systems we care // about. As far as I know there is no ABI with stack alignment greater // than 64. We assume stack and stack_size already have alignment of // kMaxStackAlignment. const size_t kMaxStackAlignment = 64; void* const stack_top = static_cast(stack) + (stack_grows_down ? stack_size - kMaxStackAlignment : 0); GTEST_DEATH_TEST_CHECK_(stack_size > kMaxStackAlignment && reinterpret_cast(stack_top) % kMaxStackAlignment == 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); } # endif // GTEST_OS_QNX # if GTEST_OS_LINUX GTEST_DEATH_TEST_CHECK_SYSCALL_( sigaction(SIGPROF, &saved_sigprof_action, NULL)); # endif // GTEST_OS_LINUX GTEST_DEATH_TEST_CHECK_(child_pid != -1); return child_pid; } // The AssumeRole process for a fork-and-exec death test. It re-executes the // main program from the beginning, setting the --gtest_filter // and --gtest_internal_run_death_test flags to cause only the current // death test to be re-run. DeathTest::TestRole ExecDeathTest::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) { set_write_fd(flag->write_fd()); return EXECUTE_TEST; } int pipe_fd[2]; GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1); // Clear the close-on-exec flag on the write end of the pipe, lest // it be closed when the child process does an exec: GTEST_DEATH_TEST_CHECK_(fcntl(pipe_fd[1], F_SETFD, 0) != -1); const std::string filter_flag = std::string("--") + GTEST_FLAG_PREFIX_ + kFilterFlag + "=" + info->test_case_name() + "." + info->name(); const std::string internal_flag = std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + "=" + file_ + "|" + StreamableToString(line_) + "|" + StreamableToString(death_test_index) + "|" + StreamableToString(pipe_fd[1]); Arguments args; args.AddArguments(GetArgvsForDeathTestChildProcess()); args.AddArgument(filter_flag.c_str()); args.AddArgument(internal_flag.c_str()); DeathTest::set_last_death_test_message(""); CaptureStderr(); // See the comment in NoExecDeathTest::AssumeRole for why the next line // is necessary. FlushInfoLog(); const pid_t child_pid = ExecDeathTestSpawnChild(args.Argv(), pipe_fd[0]); GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); set_child_pid(child_pid); set_read_fd(pipe_fd[0]); 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 // skipped, sets that pointer to NULL. Returns true, unless the // flag is set to an invalid value. bool DefaultDeathTestFactory::Create(const char* statement, const RE* regex, const char* file, int line, DeathTest** test) { UnitTestImpl* const impl = GetUnitTestImpl(); const InternalRunDeathTestFlag* const flag = impl->internal_run_death_test_flag(); const int death_test_index = impl->current_test_info() ->increment_death_test_count(); if (flag != NULL) { if (death_test_index > flag->index()) { DeathTest::set_last_death_test_message( "Death test count (" + StreamableToString(death_test_index) + ") somehow exceeded expected maximum (" + StreamableToString(flag->index()) + ")"); return false; } 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); } # elif GTEST_OS_FUCHSIA if (GTEST_FLAG(death_test_style) == "threadsafe" || GTEST_FLAG(death_test_style) == "fast") { *test = new FuchsiaDeathTest(statement, regex, file, line); } # else if (GTEST_FLAG(death_test_style) == "threadsafe") { *test = new ExecDeathTest(statement, regex, file, line); } else if (GTEST_FLAG(death_test_style) == "fast") { *test = new NoExecDeathTest(statement, regex); } # endif // GTEST_OS_WINDOWS else { // NOLINT - this is more readable than unbalanced brackets inside #if. DeathTest::set_last_death_test_message( "Unknown death test style \"" + GTEST_FLAG(death_test_style) + "\" encountered"); return false; } return true; } # 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. static int GetStatusFileDescriptor(unsigned int parent_process_id, size_t write_handle_as_size_t, size_t event_handle_as_size_t) { AutoHandle parent_process_handle(::OpenProcess(PROCESS_DUP_HANDLE, FALSE, // Non-inheritable. parent_process_id)); if (parent_process_handle.Get() == INVALID_HANDLE_VALUE) { DeathTestAbort("Unable to open parent process " + StreamableToString(parent_process_id)); } // TODO(vladl@google.com): Replace the following check with a // compile-time assertion when available. GTEST_CHECK_(sizeof(HANDLE) <= sizeof(size_t)); const HANDLE write_handle = reinterpret_cast(write_handle_as_size_t); HANDLE dup_write_handle; // The newly initialized handle is accessible only in the parent // process. To obtain one accessible within the child, we need to use // DuplicateHandle. if (!::DuplicateHandle(parent_process_handle.Get(), write_handle, ::GetCurrentProcess(), &dup_write_handle, 0x0, // Requested privileges ignored since // DUPLICATE_SAME_ACCESS is used. FALSE, // Request non-inheritable handler. DUPLICATE_SAME_ACCESS)) { DeathTestAbort("Unable to duplicate the pipe handle " + StreamableToString(write_handle_as_size_t) + " from the parent process " + StreamableToString(parent_process_id)); } const HANDLE event_handle = reinterpret_cast(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("Unable to duplicate the event handle " + StreamableToString(event_handle_as_size_t) + " from the parent process " + StreamableToString(parent_process_id)); } const int write_fd = ::_open_osfhandle(reinterpret_cast(dup_write_handle), O_APPEND); if (write_fd == -1) { DeathTestAbort("Unable to convert pipe handle " + StreamableToString(write_handle_as_size_t) + " to a file descriptor"); } // 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 write_fd; } # endif // GTEST_OS_WINDOWS // Returns a newly created InternalRunDeathTestFlag object with fields // initialized from the GTEST_FLAG(internal_run_death_test) flag if // the flag is specified; otherwise returns NULL. InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() { if (GTEST_FLAG(internal_run_death_test) == "") return NULL; // 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); int write_fd = -1; # if GTEST_OS_WINDOWS unsigned int parent_process_id = 0; size_t write_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], &write_handle_as_size_t) || !ParseNaturalNumber(fields[5], &event_handle_as_size_t)) { DeathTestAbort("Bad --gtest_internal_run_death_test flag: " + GTEST_FLAG(internal_run_death_test)); } write_fd = GetStatusFileDescriptor(parent_process_id, write_handle_as_size_t, event_handle_as_size_t); # elif GTEST_OS_FUCHSIA if (fields.size() != 3 || !ParseNaturalNumber(fields[1], &line) || !ParseNaturalNumber(fields[2], &index)) { DeathTestAbort("Bad --gtest_internal_run_death_test flag: " + GTEST_FLAG(internal_run_death_test)); } # else if (fields.size() != 4 || !ParseNaturalNumber(fields[1], &line) || !ParseNaturalNumber(fields[2], &index) || !ParseNaturalNumber(fields[3], &write_fd)) { DeathTestAbort("Bad --gtest_internal_run_death_test flag: " + GTEST_FLAG(internal_run_death_test)); } # endif // GTEST_OS_WINDOWS return new InternalRunDeathTestFlag(fields[0], line, index, write_fd); } } // namespace internal #endif // GTEST_HAS_DEATH_TEST } // namespace testing diff --git a/googletest/src/gtest-port.cc b/googletest/src/gtest-port.cc index d6320894..ce59586f 100644 --- a/googletest/src/gtest-port.cc +++ b/googletest/src/gtest-port.cc @@ -1,1263 +1,1277 @@ // Copyright 2008, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) #include "gtest/internal/gtest-port.h" #include #include #include #include #include #if GTEST_OS_WINDOWS # include # include # include # include // Used in ThreadLocal. #else # include #endif // GTEST_OS_WINDOWS #if GTEST_OS_MAC # include # include # include #endif // GTEST_OS_MAC #if GTEST_OS_QNX # include # include # include #endif // GTEST_OS_QNX #if GTEST_OS_AIX # include # include #endif // GTEST_OS_AIX #if GTEST_OS_FUCHSIA +# include # include #endif #include "gtest/gtest-spi.h" #include "gtest/gtest-message.h" #include "gtest/internal/gtest-internal.h" #include "gtest/internal/gtest-string.h" #include "src/gtest-internal-inl.h" namespace testing { namespace internal { #if defined(_MSC_VER) || defined(__BORLANDC__) // MSVC and C++Builder do not provide a definition of STDERR_FILENO. const int kStdOutFileno = 1; const int kStdErrFileno = 2; #else const int kStdOutFileno = STDOUT_FILENO; const int kStdErrFileno = STDERR_FILENO; #endif // _MSC_VER #if GTEST_OS_LINUX namespace { template T ReadProcFileField(const std::string& filename, int field) { std::string dummy; std::ifstream file(filename.c_str()); while (field-- > 0) { file >> dummy; } T output = 0; file >> output; return output; } } // namespace // Returns the number of active threads, or 0 when there is an error. size_t GetThreadCount() { const std::string filename = (Message() << "/proc/" << getpid() << "/stat").GetString(); return ReadProcFileField(filename, 19); } #elif GTEST_OS_MAC size_t GetThreadCount() { const task_t task = mach_task_self(); mach_msg_type_number_t thread_count; thread_act_array_t thread_list; const kern_return_t status = task_threads(task, &thread_list, &thread_count); if (status == KERN_SUCCESS) { // task_threads allocates resources in thread_list and we need to free them // to avoid leaks. vm_deallocate(task, reinterpret_cast(thread_list), sizeof(thread_t) * thread_count); return static_cast(thread_count); } else { return 0; } } #elif GTEST_OS_QNX // Returns the number of threads running in the process, or 0 to indicate that // we cannot detect it. size_t GetThreadCount() { const int fd = open("/proc/self/as", O_RDONLY); if (fd < 0) { return 0; } procfs_info process_info; const int status = devctl(fd, DCMD_PROC_INFO, &process_info, sizeof(process_info), NULL); close(fd); if (status == EOK) { return static_cast(process_info.num_threads); } else { return 0; } } #elif GTEST_OS_AIX size_t GetThreadCount() { struct procentry64 entry; pid_t pid = getpid(); int status = getprocs64(&entry, sizeof(entry), NULL, 0, &pid, 1); if (status == 1) { return entry.pi_thcount; } else { return 0; } } #elif GTEST_OS_FUCHSIA size_t GetThreadCount() { - return static_cast(zx_system_get_num_cpus()); + int dummy_buffer; + size_t avail; + zx_status_t status = zx_object_get_info( + zx_process_self(), + ZX_INFO_PROCESS_THREADS, + &dummy_buffer, + 0, + nullptr, + &avail); + if(status == ZX_OK) { + return avail; + } else { + return 0; + } } #else size_t GetThreadCount() { // There's no portable way to detect the number of threads, so we just // return 0 to indicate that we cannot detect it. return 0; } #endif // GTEST_OS_LINUX #if GTEST_IS_THREADSAFE && GTEST_OS_WINDOWS void SleepMilliseconds(int n) { ::Sleep(n); } AutoHandle::AutoHandle() : handle_(INVALID_HANDLE_VALUE) {} AutoHandle::AutoHandle(Handle handle) : handle_(handle) {} AutoHandle::~AutoHandle() { Reset(); } AutoHandle::Handle AutoHandle::Get() const { return handle_; } void AutoHandle::Reset() { Reset(INVALID_HANDLE_VALUE); } void AutoHandle::Reset(HANDLE handle) { // Resetting with the same handle we already own is invalid. if (handle_ != handle) { if (IsCloseable()) { ::CloseHandle(handle_); } handle_ = handle; } else { GTEST_CHECK_(!IsCloseable()) << "Resetting a valid handle to itself is likely a programmer error " "and thus not allowed."; } } bool AutoHandle::IsCloseable() const { // Different Windows APIs may use either of these values to represent an // invalid handle. return handle_ != NULL && handle_ != INVALID_HANDLE_VALUE; } Notification::Notification() : event_(::CreateEvent(NULL, // Default security attributes. TRUE, // Do not reset automatically. FALSE, // Initially unset. NULL)) { // Anonymous event. GTEST_CHECK_(event_.Get() != NULL); } void Notification::Notify() { GTEST_CHECK_(::SetEvent(event_.Get()) != FALSE); } void Notification::WaitForNotification() { GTEST_CHECK_( ::WaitForSingleObject(event_.Get(), INFINITE) == WAIT_OBJECT_0); } Mutex::Mutex() : owner_thread_id_(0), type_(kDynamic), critical_section_init_phase_(0), critical_section_(new CRITICAL_SECTION) { ::InitializeCriticalSection(critical_section_); } Mutex::~Mutex() { // Static mutexes are leaked intentionally. It is not thread-safe to try // to clean them up. // TODO(yukawa): Switch to Slim Reader/Writer (SRW) Locks, which requires // nothing to clean it up but is available only on Vista and later. // http://msdn.microsoft.com/en-us/library/windows/desktop/aa904937.aspx if (type_ == kDynamic) { ::DeleteCriticalSection(critical_section_); delete critical_section_; critical_section_ = NULL; } } void Mutex::Lock() { ThreadSafeLazyInit(); ::EnterCriticalSection(critical_section_); owner_thread_id_ = ::GetCurrentThreadId(); } void Mutex::Unlock() { ThreadSafeLazyInit(); // We don't protect writing to owner_thread_id_ here, as it's the // caller's responsibility to ensure that the current thread holds the // mutex when this is called. owner_thread_id_ = 0; ::LeaveCriticalSection(critical_section_); } // Does nothing if the current thread holds the mutex. Otherwise, crashes // with high probability. void Mutex::AssertHeld() { ThreadSafeLazyInit(); GTEST_CHECK_(owner_thread_id_ == ::GetCurrentThreadId()) << "The current thread is not holding the mutex @" << this; } // Initializes owner_thread_id_ and critical_section_ in static mutexes. void Mutex::ThreadSafeLazyInit() { // Dynamic mutexes are initialized in the constructor. if (type_ == kStatic) { switch ( ::InterlockedCompareExchange(&critical_section_init_phase_, 1L, 0L)) { case 0: // If critical_section_init_phase_ was 0 before the exchange, we // are the first to test it and need to perform the initialization. owner_thread_id_ = 0; critical_section_ = new CRITICAL_SECTION; ::InitializeCriticalSection(critical_section_); // Updates the critical_section_init_phase_ to 2 to signal // initialization complete. GTEST_CHECK_(::InterlockedCompareExchange( &critical_section_init_phase_, 2L, 1L) == 1L); break; case 1: // Somebody else is already initializing the mutex; spin until they // are done. while (::InterlockedCompareExchange(&critical_section_init_phase_, 2L, 2L) != 2L) { // Possibly yields the rest of the thread's time slice to other // threads. ::Sleep(0); } break; case 2: break; // The mutex is already initialized and ready for use. default: GTEST_CHECK_(false) << "Unexpected value of critical_section_init_phase_ " << "while initializing a static mutex."; } } } namespace { class ThreadWithParamSupport : public ThreadWithParamBase { public: static HANDLE CreateThread(Runnable* runnable, Notification* thread_can_start) { ThreadMainParam* param = new ThreadMainParam(runnable, thread_can_start); DWORD thread_id; // TODO(yukawa): Consider to use _beginthreadex instead. HANDLE thread_handle = ::CreateThread( NULL, // Default security. 0, // Default stack size. &ThreadWithParamSupport::ThreadMain, param, // Parameter to ThreadMainStatic 0x0, // Default creation flags. &thread_id); // Need a valid pointer for the call to work under Win98. GTEST_CHECK_(thread_handle != NULL) << "CreateThread failed with error " << ::GetLastError() << "."; if (thread_handle == NULL) { delete param; } return thread_handle; } private: struct ThreadMainParam { ThreadMainParam(Runnable* runnable, Notification* thread_can_start) : runnable_(runnable), thread_can_start_(thread_can_start) { } scoped_ptr runnable_; // Does not own. Notification* thread_can_start_; }; static DWORD WINAPI ThreadMain(void* ptr) { // Transfers ownership. scoped_ptr param(static_cast(ptr)); if (param->thread_can_start_ != NULL) param->thread_can_start_->WaitForNotification(); param->runnable_->Run(); return 0; } // Prohibit instantiation. ThreadWithParamSupport(); GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParamSupport); }; } // namespace ThreadWithParamBase::ThreadWithParamBase(Runnable *runnable, Notification* thread_can_start) : thread_(ThreadWithParamSupport::CreateThread(runnable, thread_can_start)) { } ThreadWithParamBase::~ThreadWithParamBase() { Join(); } void ThreadWithParamBase::Join() { GTEST_CHECK_(::WaitForSingleObject(thread_.Get(), INFINITE) == WAIT_OBJECT_0) << "Failed to join the thread with error " << ::GetLastError() << "."; } // Maps a thread to a set of ThreadIdToThreadLocals that have values // instantiated on that thread and notifies them when the thread exits. A // ThreadLocal instance is expected to persist until all threads it has // values on have terminated. class ThreadLocalRegistryImpl { public: // Registers thread_local_instance as having value on the current thread. // Returns a value that can be used to identify the thread from other threads. static ThreadLocalValueHolderBase* GetValueOnCurrentThread( const ThreadLocalBase* thread_local_instance) { DWORD current_thread = ::GetCurrentThreadId(); MutexLock lock(&mutex_); ThreadIdToThreadLocals* const thread_to_thread_locals = GetThreadLocalsMapLocked(); ThreadIdToThreadLocals::iterator thread_local_pos = thread_to_thread_locals->find(current_thread); if (thread_local_pos == thread_to_thread_locals->end()) { thread_local_pos = thread_to_thread_locals->insert( std::make_pair(current_thread, ThreadLocalValues())).first; StartWatcherThreadFor(current_thread); } ThreadLocalValues& thread_local_values = thread_local_pos->second; ThreadLocalValues::iterator value_pos = thread_local_values.find(thread_local_instance); if (value_pos == thread_local_values.end()) { value_pos = thread_local_values .insert(std::make_pair( thread_local_instance, linked_ptr( thread_local_instance->NewValueForCurrentThread()))) .first; } return value_pos->second.get(); } static void OnThreadLocalDestroyed( const ThreadLocalBase* thread_local_instance) { std::vector > value_holders; // Clean up the ThreadLocalValues data structure while holding the lock, but // defer the destruction of the ThreadLocalValueHolderBases. { MutexLock lock(&mutex_); ThreadIdToThreadLocals* const thread_to_thread_locals = GetThreadLocalsMapLocked(); for (ThreadIdToThreadLocals::iterator it = thread_to_thread_locals->begin(); it != thread_to_thread_locals->end(); ++it) { ThreadLocalValues& thread_local_values = it->second; ThreadLocalValues::iterator value_pos = thread_local_values.find(thread_local_instance); if (value_pos != thread_local_values.end()) { value_holders.push_back(value_pos->second); thread_local_values.erase(value_pos); // This 'if' can only be successful at most once, so theoretically we // could break out of the loop here, but we don't bother doing so. } } } // Outside the lock, let the destructor for 'value_holders' deallocate the // ThreadLocalValueHolderBases. } static void OnThreadExit(DWORD thread_id) { GTEST_CHECK_(thread_id != 0) << ::GetLastError(); std::vector > value_holders; // Clean up the ThreadIdToThreadLocals data structure while holding the // lock, but defer the destruction of the ThreadLocalValueHolderBases. { MutexLock lock(&mutex_); ThreadIdToThreadLocals* const thread_to_thread_locals = GetThreadLocalsMapLocked(); ThreadIdToThreadLocals::iterator thread_local_pos = thread_to_thread_locals->find(thread_id); if (thread_local_pos != thread_to_thread_locals->end()) { ThreadLocalValues& thread_local_values = thread_local_pos->second; for (ThreadLocalValues::iterator value_pos = thread_local_values.begin(); value_pos != thread_local_values.end(); ++value_pos) { value_holders.push_back(value_pos->second); } thread_to_thread_locals->erase(thread_local_pos); } } // Outside the lock, let the destructor for 'value_holders' deallocate the // ThreadLocalValueHolderBases. } private: // In a particular thread, maps a ThreadLocal object to its value. typedef std::map > ThreadLocalValues; // Stores all ThreadIdToThreadLocals having values in a thread, indexed by // thread's ID. typedef std::map ThreadIdToThreadLocals; // Holds the thread id and thread handle that we pass from // StartWatcherThreadFor to WatcherThreadFunc. typedef std::pair ThreadIdAndHandle; static void StartWatcherThreadFor(DWORD thread_id) { // The returned handle will be kept in thread_map and closed by // watcher_thread in WatcherThreadFunc. HANDLE thread = ::OpenThread(SYNCHRONIZE | THREAD_QUERY_INFORMATION, FALSE, thread_id); GTEST_CHECK_(thread != NULL); // We need to pass a valid thread ID pointer into CreateThread for it // to work correctly under Win98. DWORD watcher_thread_id; HANDLE watcher_thread = ::CreateThread( NULL, // Default security. 0, // Default stack size &ThreadLocalRegistryImpl::WatcherThreadFunc, reinterpret_cast(new ThreadIdAndHandle(thread_id, thread)), CREATE_SUSPENDED, &watcher_thread_id); GTEST_CHECK_(watcher_thread != NULL); // Give the watcher thread the same priority as ours to avoid being // blocked by it. ::SetThreadPriority(watcher_thread, ::GetThreadPriority(::GetCurrentThread())); ::ResumeThread(watcher_thread); ::CloseHandle(watcher_thread); } // Monitors exit from a given thread and notifies those // ThreadIdToThreadLocals about thread termination. static DWORD WINAPI WatcherThreadFunc(LPVOID param) { const ThreadIdAndHandle* tah = reinterpret_cast(param); GTEST_CHECK_( ::WaitForSingleObject(tah->second, INFINITE) == WAIT_OBJECT_0); OnThreadExit(tah->first); ::CloseHandle(tah->second); delete tah; return 0; } // Returns map of thread local instances. static ThreadIdToThreadLocals* GetThreadLocalsMapLocked() { mutex_.AssertHeld(); static ThreadIdToThreadLocals* map = new ThreadIdToThreadLocals; return map; } // Protects access to GetThreadLocalsMapLocked() and its return value. static Mutex mutex_; // Protects access to GetThreadMapLocked() and its return value. static Mutex thread_map_mutex_; }; Mutex ThreadLocalRegistryImpl::mutex_(Mutex::kStaticMutex); Mutex ThreadLocalRegistryImpl::thread_map_mutex_(Mutex::kStaticMutex); ThreadLocalValueHolderBase* ThreadLocalRegistry::GetValueOnCurrentThread( const ThreadLocalBase* thread_local_instance) { return ThreadLocalRegistryImpl::GetValueOnCurrentThread( thread_local_instance); } void ThreadLocalRegistry::OnThreadLocalDestroyed( const ThreadLocalBase* thread_local_instance) { ThreadLocalRegistryImpl::OnThreadLocalDestroyed(thread_local_instance); } #endif // GTEST_IS_THREADSAFE && GTEST_OS_WINDOWS #if GTEST_USES_POSIX_RE // Implements RE. Currently only needed for death tests. RE::~RE() { if (is_valid_) { // regfree'ing an invalid regex might crash because the content // of the regex is undefined. Since the regex's are essentially // the same, one cannot be valid (or invalid) without the other // being so too. regfree(&partial_regex_); regfree(&full_regex_); } free(const_cast(pattern_)); } // Returns true iff regular expression re matches the entire str. bool RE::FullMatch(const char* str, const RE& re) { if (!re.is_valid_) return false; regmatch_t match; return regexec(&re.full_regex_, str, 1, &match, 0) == 0; } // Returns true iff regular expression re matches a substring of str // (including str itself). bool RE::PartialMatch(const char* str, const RE& re) { if (!re.is_valid_) return false; regmatch_t match; return regexec(&re.partial_regex_, str, 1, &match, 0) == 0; } // Initializes an RE from its string representation. void RE::Init(const char* regex) { pattern_ = posix::StrDup(regex); // Reserves enough bytes to hold the regular expression used for a // full match. const size_t full_regex_len = strlen(regex) + 10; char* const full_pattern = new char[full_regex_len]; snprintf(full_pattern, full_regex_len, "^(%s)$", regex); is_valid_ = regcomp(&full_regex_, full_pattern, REG_EXTENDED) == 0; // We want to call regcomp(&partial_regex_, ...) even if the // previous expression returns false. Otherwise partial_regex_ may // not be properly initialized can may cause trouble when it's // freed. // // 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. if (is_valid_) { const char* const partial_regex = (*regex == '\0') ? "()" : regex; is_valid_ = regcomp(&partial_regex_, partial_regex, REG_EXTENDED) == 0; } EXPECT_TRUE(is_valid_) << "Regular expression \"" << regex << "\" is not a valid POSIX Extended regular expression."; delete[] full_pattern; } #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 , these aren't affected by the // current locale. bool IsAsciiDigit(char ch) { return '0' <= ch && ch <= '9'; } bool IsAsciiPunct(char ch) { return IsInSet(ch, "^-!\"#$%&'()*+,./:;<=>?@[\\]_`{|}~"); } bool IsRepeat(char ch) { return IsInSet(ch, "?*+"); } bool IsAsciiWhiteSpace(char ch) { return IsInSet(ch, " \f\n\r\t\v"); } bool IsAsciiWordChar(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 (IsAsciiPunct(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 IsAsciiDigit(ch); case 'D': return !IsAsciiDigit(ch); case 'f': return ch == '\f'; case 'n': return ch == '\n'; case 'r': return ch == '\r'; case 's': return IsAsciiWhiteSpace(ch); case 'S': return !IsAsciiWhiteSpace(ch); case 't': return ch == '\t'; case 'v': return ch == '\v'; case 'w': return IsAsciiWordChar(ch); case 'W': return !IsAsciiWordChar(ch); } return IsAsciiPunct(pattern_char) && pattern_char == ch; } return (pattern_char == '.' && ch != '\n') || pattern_char == ch; } // Helper function used by ValidateRegex() to format error messages. static std::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(-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(pattern_)); free(const_cast(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) { pattern_ = posix::StrDup(regex); } 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(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 const char kUnknownFile[] = "unknown file"; // Formats a source file path and a line number as they would appear // in an error message from the compiler used to compile this code. GTEST_API_ ::std::string FormatFileLocation(const char* file, int line) { const std::string file_name(file == NULL ? kUnknownFile : file); if (line < 0) { return file_name + ":"; } #ifdef _MSC_VER return file_name + "(" + StreamableToString(line) + "):"; #else return file_name + ":" + StreamableToString(line) + ":"; #endif // _MSC_VER } // Formats a file location for compiler-independent XML output. // Although this function is not platform dependent, we put it next to // FormatFileLocation in order to contrast the two functions. // Note that FormatCompilerIndependentFileLocation() does NOT append colon // to the file location it produces, unlike FormatFileLocation(). GTEST_API_ ::std::string FormatCompilerIndependentFileLocation( const char* file, int line) { const std::string file_name(file == NULL ? kUnknownFile : file); if (line < 0) return file_name; else return file_name + ":" + StreamableToString(line); } GTestLog::GTestLog(GTestLogSeverity severity, const char* file, int line) : severity_(severity) { const char* const marker = severity == GTEST_INFO ? "[ INFO ]" : severity == GTEST_WARNING ? "[WARNING]" : severity == GTEST_ERROR ? "[ ERROR ]" : "[ FATAL ]"; GetStream() << ::std::endl << marker << " " << FormatFileLocation(file, line).c_str() << ": "; } // Flushes the buffers and, if severity is GTEST_FATAL, aborts the program. GTestLog::~GTestLog() { GetStream() << ::std::endl; if (severity_ == GTEST_FATAL) { fflush(stderr); posix::Abort(); } } // Disable Microsoft deprecation warnings for POSIX functions called from // this class (creat, dup, dup2, and close) GTEST_DISABLE_MSC_WARNINGS_PUSH_(4996) #if GTEST_HAS_STREAM_REDIRECTION // Object that captures an output stream (stdout/stderr). class CapturedStream { public: // The ctor redirects the stream to a temporary file. explicit CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) { # 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); const UINT success = ::GetTempFileNameA(temp_dir_path, "gtest_redir", 0, // Generate unique file name. temp_file_path); GTEST_CHECK_(success != 0) << "Unable to create a temporary file in " << temp_dir_path; const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE); GTEST_CHECK_(captured_fd != -1) << "Unable to open temporary file " << temp_file_path; 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. We use /tmp on most systems, and /sdcard on Android. // That's because Android doesn't have /tmp. # if GTEST_OS_LINUX_ANDROID // Note: Android applications are expected to call the framework's // Context.getExternalStorageDirectory() method through JNI to get // the location of the world-writable SD Card directory. However, // this requires a Context handle, which cannot be retrieved // globally from native code. Doing so also precludes running the // code as part of a regular standalone executable, which doesn't // run in a Dalvik process (e.g. when running it through 'adb shell'). // // The location /sdcard is directly accessible from native code // and is the only location (unofficially) supported by the Android // team. It's generally a symlink to the real SD Card mount point // which can be /mnt/sdcard, /mnt/sdcard0, /system/media/sdcard, or // other OEM-customized locations. Never rely on these, and always // use /sdcard. char name_template[] = "/sdcard/gtest_captured_stream.XXXXXX"; # else char name_template[] = "/tmp/captured_stream.XXXXXX"; # endif // GTEST_OS_LINUX_ANDROID const int captured_fd = mkstemp(name_template); filename_ = name_template; # endif // GTEST_OS_WINDOWS fflush(NULL); dup2(captured_fd, fd_); close(captured_fd); } ~CapturedStream() { remove(filename_.c_str()); } std::string GetCapturedString() { if (uncaptured_fd_ != -1) { // Restores the original stream. fflush(NULL); dup2(uncaptured_fd_, fd_); close(uncaptured_fd_); uncaptured_fd_ = -1; } FILE* const file = posix::FOpen(filename_.c_str(), "r"); const std::string content = ReadEntireFile(file); posix::FClose(file); return content; } private: const int fd_; // A stream to capture. int uncaptured_fd_; // Name of the temporary file holding the stderr output. ::std::string filename_; GTEST_DISALLOW_COPY_AND_ASSIGN_(CapturedStream); }; GTEST_DISABLE_MSC_WARNINGS_POP_() static CapturedStream* g_captured_stderr = NULL; static CapturedStream* g_captured_stdout = NULL; // Starts capturing an output stream (stdout/stderr). static void CaptureStream(int fd, const char* stream_name, CapturedStream** stream) { if (*stream != NULL) { GTEST_LOG_(FATAL) << "Only one " << stream_name << " capturer can exist at a time."; } *stream = new CapturedStream(fd); } // Stops capturing the output stream and returns the captured string. static std::string GetCapturedStream(CapturedStream** captured_stream) { const std::string content = (*captured_stream)->GetCapturedString(); delete *captured_stream; *captured_stream = NULL; return content; } // Starts capturing stdout. void CaptureStdout() { CaptureStream(kStdOutFileno, "stdout", &g_captured_stdout); } // Starts capturing stderr. void CaptureStderr() { CaptureStream(kStdErrFileno, "stderr", &g_captured_stderr); } // Stops capturing stdout and returns the captured string. std::string GetCapturedStdout() { return GetCapturedStream(&g_captured_stdout); } // Stops capturing stderr and returns the captured string. std::string GetCapturedStderr() { return GetCapturedStream(&g_captured_stderr); } #endif // GTEST_HAS_STREAM_REDIRECTION size_t GetFileSize(FILE* file) { fseek(file, 0, SEEK_END); return static_cast(ftell(file)); } std::string ReadEntireFile(FILE* file) { const size_t file_size = GetFileSize(file); char* const buffer = new char[file_size]; size_t bytes_last_read = 0; // # of bytes read in the last fread() size_t bytes_read = 0; // # of bytes read so far fseek(file, 0, SEEK_SET); // Keeps reading the file until we cannot read further or the // pre-determined file size is reached. do { bytes_last_read = fread(buffer+bytes_read, 1, file_size-bytes_read, file); bytes_read += bytes_last_read; } while (bytes_last_read > 0 && bytes_read < file_size); const std::string content(buffer, bytes_read); delete[] buffer; return content; } #if GTEST_HAS_DEATH_TEST static const std::vector* g_injected_test_argvs = NULL; // Owned. std::vector GetInjectableArgvs() { if (g_injected_test_argvs != NULL) { return *g_injected_test_argvs; } return GetArgvs(); } void SetInjectableArgvs(const std::vector* new_argvs) { if (g_injected_test_argvs != new_argvs) delete g_injected_test_argvs; g_injected_test_argvs = new_argvs; } void SetInjectableArgvs(const std::vector& new_argvs) { SetInjectableArgvs( new std::vector(new_argvs.begin(), new_argvs.end())); } #if GTEST_HAS_GLOBAL_STRING void SetInjectableArgvs(const std::vector< ::string>& new_argvs) { SetInjectableArgvs( new std::vector(new_argvs.begin(), new_argvs.end())); } #endif // GTEST_HAS_GLOBAL_STRING void ClearInjectableArgvs() { delete g_injected_test_argvs; g_injected_test_argvs = NULL; } #endif // GTEST_HAS_DEATH_TEST #if GTEST_OS_WINDOWS_MOBILE namespace posix { void Abort() { DebugBreak(); TerminateProcess(GetCurrentProcess(), 1); } } // namespace posix #endif // GTEST_OS_WINDOWS_MOBILE // Returns the name of the environment variable corresponding to the // given flag. For example, FlagToEnvVar("foo") will return // "GTEST_FOO" in the open-source version. static std::string FlagToEnvVar(const char* flag) { const std::string full_flag = (Message() << GTEST_FLAG_PREFIX_ << flag).GetString(); Message env_var; for (size_t i = 0; i != full_flag.length(); i++) { env_var << ToUpper(full_flag.c_str()[i]); } return env_var.GetString(); } // 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. bool ParseInt32(const Message& src_text, const char* str, Int32* value) { // Parses the environment variable as a decimal integer. char* end = NULL; const long long_value = strtol(str, &end, 10); // NOLINT // Has strtol() consumed all characters in the string? if (*end != '\0') { // No - an invalid character was encountered. Message msg; msg << "WARNING: " << src_text << " is expected to be a 32-bit integer, but actually" << " has value \"" << str << "\".\n"; printf("%s", msg.GetString().c_str()); fflush(stdout); return false; } // Is the parsed value in the range of an Int32? const Int32 result = static_cast(long_value); if (long_value == LONG_MAX || long_value == LONG_MIN || // The parsed value overflows as a long. (strtol() returns // LONG_MAX or LONG_MIN when the input overflows.) result != long_value // The parsed value overflows as an Int32. ) { Message msg; msg << "WARNING: " << src_text << " is expected to be a 32-bit integer, but actually" << " has value " << str << ", which overflows.\n"; printf("%s", msg.GetString().c_str()); fflush(stdout); return false; } *value = result; 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) { #if defined(GTEST_GET_BOOL_FROM_ENV_) return GTEST_GET_BOOL_FROM_ENV_(flag, default_value); #else const std::string env_var = FlagToEnvVar(flag); const char* const string_value = posix::GetEnv(env_var.c_str()); return string_value == NULL ? default_value : strcmp(string_value, "0") != 0; #endif // defined(GTEST_GET_BOOL_FROM_ENV_) } // Reads and returns a 32-bit integer stored in the environment // variable corresponding to the given flag; if it isn't set or // doesn't represent a valid 32-bit integer, returns default_value. Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) { #if defined(GTEST_GET_INT32_FROM_ENV_) return GTEST_GET_INT32_FROM_ENV_(flag, default_value); #else const std::string env_var = FlagToEnvVar(flag); const char* const string_value = posix::GetEnv(env_var.c_str()); if (string_value == NULL) { // The environment variable is not set. return default_value; } Int32 result = default_value; if (!ParseInt32(Message() << "Environment variable " << env_var, string_value, &result)) { printf("The default value %s is used.\n", (Message() << default_value).GetString().c_str()); fflush(stdout); return default_value; } return result; #endif // defined(GTEST_GET_INT32_FROM_ENV_) } // As a special case for the 'output' flag, if GTEST_OUTPUT is not // set, we look for XML_OUTPUT_FILE, which is set by the Bazel build // system. The value of XML_OUTPUT_FILE is a filename without the // "xml:" prefix of GTEST_OUTPUT. // Note that this is meant to be called at the call site so it does // not check that the flag is 'output' // In essence this checks an env variable called XML_OUTPUT_FILE // and if it is set we prepend "xml:" to its value, if it not set we return "" std::string OutputFlagAlsoCheckEnvVar(){ std::string default_value_for_output_flag = ""; const char* xml_output_file_env = posix::GetEnv("XML_OUTPUT_FILE"); if (NULL != xml_output_file_env) { default_value_for_output_flag = std::string("xml:") + xml_output_file_env; } return default_value_for_output_flag; } // Reads and returns the string environment variable corresponding to // the given flag; if it's not set, returns default_value. const char* StringFromGTestEnv(const char* flag, const char* default_value) { #if defined(GTEST_GET_STRING_FROM_ENV_) return GTEST_GET_STRING_FROM_ENV_(flag, default_value); #else const std::string env_var = FlagToEnvVar(flag); const char* const value = posix::GetEnv(env_var.c_str()); return value == NULL ? default_value : value; #endif // defined(GTEST_GET_STRING_FROM_ENV_) } } // namespace internal } // namespace testing diff --git a/googletest/test/gtest-death-test_test.cc b/googletest/test/gtest-death-test_test.cc index 21573c77..37261cb6 100644 --- a/googletest/test/gtest-death-test_test.cc +++ b/googletest/test/gtest-death-test_test.cc @@ -1,1423 +1,1424 @@ // Copyright 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) // // Tests for death tests. #include "gtest/gtest-death-test.h" #include "gtest/gtest.h" #include "gtest/internal/gtest-filepath.h" using testing::internal::AlwaysFalse; using testing::internal::AlwaysTrue; #if GTEST_HAS_DEATH_TEST # if GTEST_OS_WINDOWS # include // For chdir(). # else # include # include // For waitpid. # endif // GTEST_OS_WINDOWS # include # include # include # if GTEST_OS_LINUX # include # endif // GTEST_OS_LINUX # include "gtest/gtest-spi.h" # include "src/gtest-internal-inl.h" namespace posix = ::testing::internal::posix; using testing::Message; using testing::internal::DeathTest; using testing::internal::DeathTestFactory; using testing::internal::FilePath; using testing::internal::GetLastErrnoDescription; using testing::internal::GetUnitTestImpl; using testing::internal::InDeathTestChild; using testing::internal::ParseNaturalNumber; namespace testing { namespace internal { // A helper class whose objects replace the death test factory for a // single UnitTest object during their lifetimes. class ReplaceDeathTestFactory { public: explicit ReplaceDeathTestFactory(DeathTestFactory* new_factory) : unit_test_impl_(GetUnitTestImpl()) { old_factory_ = unit_test_impl_->death_test_factory_.release(); unit_test_impl_->death_test_factory_.reset(new_factory); } ~ReplaceDeathTestFactory() { unit_test_impl_->death_test_factory_.release(); unit_test_impl_->death_test_factory_.reset(old_factory_); } private: // Prevents copying ReplaceDeathTestFactory objects. ReplaceDeathTestFactory(const ReplaceDeathTestFactory&); void operator=(const ReplaceDeathTestFactory&); UnitTestImpl* unit_test_impl_; DeathTestFactory* old_factory_; }; } // namespace internal } // namespace testing void DieWithMessage(const ::std::string& message) { fprintf(stderr, "%s", message.c_str()); fflush(stderr); // Make sure the text is printed before the process exits. // We call _exit() instead of exit(), as the former is a direct // system call and thus safer in the presence of threads. exit() // will invoke user-defined exit-hooks, which may do dangerous // things that conflict with death tests. // // Some compilers can recognize that _exit() never returns and issue the // 'unreachable code' warning for code following this function, unless // fooled by a fake condition. if (AlwaysTrue()) _exit(1); } void DieInside(const ::std::string& function) { DieWithMessage("death inside " + function + "()."); } // Tests that death tests work. class TestForDeathTest : public testing::Test { protected: TestForDeathTest() : original_dir_(FilePath::GetCurrentDir()) {} virtual ~TestForDeathTest() { posix::ChDir(original_dir_.c_str()); } // A static member function that's expected to die. static void StaticMemberFunction() { DieInside("StaticMemberFunction"); } // A method of the test fixture that may die. void MemberFunction() { if (should_die_) DieInside("MemberFunction"); } // True iff MemberFunction() should die. bool should_die_; const FilePath original_dir_; }; // A class with a member function that may die. class MayDie { public: explicit MayDie(bool should_die) : should_die_(should_die) {} // A member function that may die. void MemberFunction() const { if (should_die_) DieInside("MayDie::MemberFunction"); } private: // True iff MemberFunction() should die. bool should_die_; }; // A global function that's expected to die. void GlobalFunction() { DieInside("GlobalFunction"); } // A non-void function that's expected to die. int NonVoidFunction() { DieInside("NonVoidFunction"); return 1; } // A unary function that may die. void DieIf(bool should_die) { if (should_die) DieInside("DieIf"); } // A binary function that may die. bool DieIfLessThan(int x, int y) { if (x < y) { DieInside("DieIfLessThan"); } return true; } // Tests that ASSERT_DEATH can be used outside a TEST, TEST_F, or test fixture. void DeathTestSubroutine() { EXPECT_DEATH(GlobalFunction(), "death.*GlobalFunction"); ASSERT_DEATH(GlobalFunction(), "death.*GlobalFunction"); } // Death in dbg, not opt. int DieInDebugElse12(int* sideeffect) { if (sideeffect) *sideeffect = 12; # ifndef NDEBUG DieInside("DieInDebugElse12"); # endif // NDEBUG return 12; } -# if GTEST_OS_WINDOWS +# if GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA // Tests the ExitedWithCode predicate. TEST(ExitStatusPredicateTest, ExitedWithCode) { // On Windows, the process's exit code is the same as its exit status, // so the predicate just compares the its input with its parameter. EXPECT_TRUE(testing::ExitedWithCode(0)(0)); EXPECT_TRUE(testing::ExitedWithCode(1)(1)); EXPECT_TRUE(testing::ExitedWithCode(42)(42)); EXPECT_FALSE(testing::ExitedWithCode(0)(1)); EXPECT_FALSE(testing::ExitedWithCode(1)(0)); } # else // Returns the exit status of a process that calls _exit(2) with a // given exit code. This is a helper function for the // ExitStatusPredicateTest test suite. static int NormalExitStatus(int exit_code) { pid_t child_pid = fork(); if (child_pid == 0) { _exit(exit_code); } int status; waitpid(child_pid, &status, 0); return status; } // Returns the exit status of a process that raises a given signal. // If the signal does not cause the process to die, then it returns // instead the exit status of a process that exits normally with exit // code 1. This is a helper function for the ExitStatusPredicateTest // test suite. static int KilledExitStatus(int signum) { pid_t child_pid = fork(); if (child_pid == 0) { raise(signum); _exit(1); } int status; waitpid(child_pid, &status, 0); return status; } // Tests the ExitedWithCode predicate. TEST(ExitStatusPredicateTest, ExitedWithCode) { const int status0 = NormalExitStatus(0); const int status1 = NormalExitStatus(1); const int status42 = NormalExitStatus(42); const testing::ExitedWithCode pred0(0); const testing::ExitedWithCode pred1(1); const testing::ExitedWithCode pred42(42); EXPECT_PRED1(pred0, status0); EXPECT_PRED1(pred1, status1); EXPECT_PRED1(pred42, status42); EXPECT_FALSE(pred0(status1)); EXPECT_FALSE(pred42(status0)); EXPECT_FALSE(pred1(status42)); } // Tests the KilledBySignal predicate. TEST(ExitStatusPredicateTest, KilledBySignal) { const int status_segv = KilledExitStatus(SIGSEGV); const int status_kill = KilledExitStatus(SIGKILL); const testing::KilledBySignal pred_segv(SIGSEGV); const testing::KilledBySignal pred_kill(SIGKILL); EXPECT_PRED1(pred_segv, status_segv); EXPECT_PRED1(pred_kill, status_kill); EXPECT_FALSE(pred_segv(status_kill)); EXPECT_FALSE(pred_kill(status_segv)); } -# endif // GTEST_OS_WINDOWS +# endif // GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA // Tests that the death test macros expand to code which may or may not // be followed by operator<<, and that in either case the complete text // comprises only a single C++ statement. TEST_F(TestForDeathTest, SingleStatement) { if (AlwaysFalse()) // This would fail if executed; this is a compilation test only ASSERT_DEATH(return, ""); if (AlwaysTrue()) EXPECT_DEATH(_exit(1), ""); else // This empty "else" branch is meant to ensure that EXPECT_DEATH // doesn't expand into an "if" statement without an "else" ; if (AlwaysFalse()) ASSERT_DEATH(return, "") << "did not die"; if (AlwaysFalse()) ; else EXPECT_DEATH(_exit(1), "") << 1 << 2 << 3; } void DieWithEmbeddedNul() { fprintf(stderr, "Hello%cmy null world.\n", '\0'); fflush(stderr); _exit(1); } # if GTEST_USES_PCRE // Tests that EXPECT_DEATH and ASSERT_DEATH work when the error // message has a NUL character in it. TEST_F(TestForDeathTest, EmbeddedNulInMessage) { EXPECT_DEATH(DieWithEmbeddedNul(), "my null world"); ASSERT_DEATH(DieWithEmbeddedNul(), "my null world"); } # endif // GTEST_USES_PCRE // Tests that death test macros expand to code which interacts well with switch // statements. TEST_F(TestForDeathTest, SwitchStatement) { // Microsoft compiler usually complains about switch statements without // case labels. We suppress that warning for this test. GTEST_DISABLE_MSC_WARNINGS_PUSH_(4065) switch (0) default: ASSERT_DEATH(_exit(1), "") << "exit in default switch handler"; switch (0) case 0: EXPECT_DEATH(_exit(1), "") << "exit in switch case"; GTEST_DISABLE_MSC_WARNINGS_POP_() } // Tests that a static member function can be used in a "fast" style // death test. TEST_F(TestForDeathTest, StaticMemberFunctionFastStyle) { testing::GTEST_FLAG(death_test_style) = "fast"; ASSERT_DEATH(StaticMemberFunction(), "death.*StaticMember"); } // Tests that a method of the test fixture can be used in a "fast" // style death test. TEST_F(TestForDeathTest, MemberFunctionFastStyle) { testing::GTEST_FLAG(death_test_style) = "fast"; should_die_ = true; EXPECT_DEATH(MemberFunction(), "inside.*MemberFunction"); } void ChangeToRootDir() { posix::ChDir(GTEST_PATH_SEP_); } // Tests that death tests work even if the current directory has been // changed. TEST_F(TestForDeathTest, FastDeathTestInChangedDir) { testing::GTEST_FLAG(death_test_style) = "fast"; ChangeToRootDir(); EXPECT_EXIT(_exit(1), testing::ExitedWithCode(1), ""); ChangeToRootDir(); ASSERT_DEATH(_exit(1), ""); } # if GTEST_OS_LINUX void SigprofAction(int, siginfo_t*, void*) { /* no op */ } // Sets SIGPROF action and ITIMER_PROF timer (interval: 1ms). void SetSigprofActionAndTimer() { struct itimerval timer; timer.it_interval.tv_sec = 0; timer.it_interval.tv_usec = 1; timer.it_value = timer.it_interval; ASSERT_EQ(0, setitimer(ITIMER_PROF, &timer, NULL)); struct sigaction signal_action; memset(&signal_action, 0, sizeof(signal_action)); sigemptyset(&signal_action.sa_mask); signal_action.sa_sigaction = SigprofAction; signal_action.sa_flags = SA_RESTART | SA_SIGINFO; ASSERT_EQ(0, sigaction(SIGPROF, &signal_action, NULL)); } // Disables ITIMER_PROF timer and ignores SIGPROF signal. void DisableSigprofActionAndTimer(struct sigaction* old_signal_action) { struct itimerval timer; timer.it_interval.tv_sec = 0; timer.it_interval.tv_usec = 0; timer.it_value = timer.it_interval; ASSERT_EQ(0, setitimer(ITIMER_PROF, &timer, NULL)); struct sigaction signal_action; memset(&signal_action, 0, sizeof(signal_action)); sigemptyset(&signal_action.sa_mask); signal_action.sa_handler = SIG_IGN; ASSERT_EQ(0, sigaction(SIGPROF, &signal_action, old_signal_action)); } // Tests that death tests work when SIGPROF handler and timer are set. TEST_F(TestForDeathTest, FastSigprofActionSet) { testing::GTEST_FLAG(death_test_style) = "fast"; SetSigprofActionAndTimer(); EXPECT_DEATH(_exit(1), ""); struct sigaction old_signal_action; DisableSigprofActionAndTimer(&old_signal_action); EXPECT_TRUE(old_signal_action.sa_sigaction == SigprofAction); } TEST_F(TestForDeathTest, ThreadSafeSigprofActionSet) { testing::GTEST_FLAG(death_test_style) = "threadsafe"; SetSigprofActionAndTimer(); EXPECT_DEATH(_exit(1), ""); struct sigaction old_signal_action; DisableSigprofActionAndTimer(&old_signal_action); EXPECT_TRUE(old_signal_action.sa_sigaction == SigprofAction); } # endif // GTEST_OS_LINUX // Repeats a representative sample of death tests in the "threadsafe" style: TEST_F(TestForDeathTest, StaticMemberFunctionThreadsafeStyle) { testing::GTEST_FLAG(death_test_style) = "threadsafe"; ASSERT_DEATH(StaticMemberFunction(), "death.*StaticMember"); } TEST_F(TestForDeathTest, MemberFunctionThreadsafeStyle) { testing::GTEST_FLAG(death_test_style) = "threadsafe"; should_die_ = true; EXPECT_DEATH(MemberFunction(), "inside.*MemberFunction"); } TEST_F(TestForDeathTest, ThreadsafeDeathTestInLoop) { testing::GTEST_FLAG(death_test_style) = "threadsafe"; for (int i = 0; i < 3; ++i) EXPECT_EXIT(_exit(i), testing::ExitedWithCode(i), "") << ": i = " << i; } TEST_F(TestForDeathTest, ThreadsafeDeathTestInChangedDir) { testing::GTEST_FLAG(death_test_style) = "threadsafe"; ChangeToRootDir(); EXPECT_EXIT(_exit(1), testing::ExitedWithCode(1), ""); ChangeToRootDir(); ASSERT_DEATH(_exit(1), ""); } TEST_F(TestForDeathTest, MixedStyles) { testing::GTEST_FLAG(death_test_style) = "threadsafe"; EXPECT_DEATH(_exit(1), ""); testing::GTEST_FLAG(death_test_style) = "fast"; EXPECT_DEATH(_exit(1), ""); } # if GTEST_HAS_CLONE && GTEST_HAS_PTHREAD namespace { bool pthread_flag; void SetPthreadFlag() { pthread_flag = true; } } // namespace TEST_F(TestForDeathTest, DoesNotExecuteAtforkHooks) { if (!testing::GTEST_FLAG(death_test_use_fork)) { testing::GTEST_FLAG(death_test_style) = "threadsafe"; pthread_flag = false; ASSERT_EQ(0, pthread_atfork(&SetPthreadFlag, NULL, NULL)); ASSERT_DEATH(_exit(1), ""); ASSERT_FALSE(pthread_flag); } } # endif // GTEST_HAS_CLONE && GTEST_HAS_PTHREAD // Tests that a method of another class can be used in a death test. TEST_F(TestForDeathTest, MethodOfAnotherClass) { const MayDie x(true); ASSERT_DEATH(x.MemberFunction(), "MayDie\\:\\:MemberFunction"); } // Tests that a global function can be used in a death test. TEST_F(TestForDeathTest, GlobalFunction) { EXPECT_DEATH(GlobalFunction(), "GlobalFunction"); } // Tests that any value convertible to an RE works as a second // argument to EXPECT_DEATH. TEST_F(TestForDeathTest, AcceptsAnythingConvertibleToRE) { static const char regex_c_str[] = "GlobalFunction"; EXPECT_DEATH(GlobalFunction(), regex_c_str); const testing::internal::RE regex(regex_c_str); EXPECT_DEATH(GlobalFunction(), regex); # if GTEST_HAS_GLOBAL_STRING const ::string regex_str(regex_c_str); EXPECT_DEATH(GlobalFunction(), regex_str); # endif // GTEST_HAS_GLOBAL_STRING # if !GTEST_USES_PCRE const ::std::string regex_std_str(regex_c_str); EXPECT_DEATH(GlobalFunction(), regex_std_str); # endif // !GTEST_USES_PCRE } // Tests that a non-void function can be used in a death test. TEST_F(TestForDeathTest, NonVoidFunction) { ASSERT_DEATH(NonVoidFunction(), "NonVoidFunction"); } // Tests that functions that take parameter(s) can be used in a death test. TEST_F(TestForDeathTest, FunctionWithParameter) { EXPECT_DEATH(DieIf(true), "DieIf\\(\\)"); EXPECT_DEATH(DieIfLessThan(2, 3), "DieIfLessThan"); } // Tests that ASSERT_DEATH can be used outside a TEST, TEST_F, or test fixture. TEST_F(TestForDeathTest, OutsideFixture) { DeathTestSubroutine(); } // Tests that death tests can be done inside a loop. TEST_F(TestForDeathTest, InsideLoop) { for (int i = 0; i < 5; i++) { EXPECT_DEATH(DieIfLessThan(-1, i), "DieIfLessThan") << "where i == " << i; } } // Tests that a compound statement can be used in a death test. TEST_F(TestForDeathTest, CompoundStatement) { EXPECT_DEATH({ // NOLINT const int x = 2; const int y = x + 1; DieIfLessThan(x, y); }, "DieIfLessThan"); } // Tests that code that doesn't die causes a death test to fail. TEST_F(TestForDeathTest, DoesNotDie) { EXPECT_NONFATAL_FAILURE(EXPECT_DEATH(DieIf(false), "DieIf"), "failed to die"); } // Tests that a death test fails when the error message isn't expected. TEST_F(TestForDeathTest, ErrorMessageMismatch) { EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_DEATH(DieIf(true), "DieIfLessThan") << "End of death test message."; }, "died but not with expected error"); } // On exit, *aborted will be true iff the EXPECT_DEATH() statement // aborted the function. void ExpectDeathTestHelper(bool* aborted) { *aborted = true; EXPECT_DEATH(DieIf(false), "DieIf"); // This assertion should fail. *aborted = false; } // Tests that EXPECT_DEATH doesn't abort the test on failure. TEST_F(TestForDeathTest, EXPECT_DEATH) { bool aborted = true; EXPECT_NONFATAL_FAILURE(ExpectDeathTestHelper(&aborted), "failed to die"); EXPECT_FALSE(aborted); } // Tests that ASSERT_DEATH does abort the test on failure. TEST_F(TestForDeathTest, ASSERT_DEATH) { static bool aborted; EXPECT_FATAL_FAILURE({ // NOLINT aborted = true; ASSERT_DEATH(DieIf(false), "DieIf"); // This assertion should fail. aborted = false; }, "failed to die"); EXPECT_TRUE(aborted); } // Tests that EXPECT_DEATH evaluates the arguments exactly once. TEST_F(TestForDeathTest, SingleEvaluation) { int x = 3; EXPECT_DEATH(DieIf((++x) == 4), "DieIf"); const char* regex = "DieIf"; const char* regex_save = regex; EXPECT_DEATH(DieIfLessThan(3, 4), regex++); EXPECT_EQ(regex_save + 1, regex); } // Tests that run-away death tests are reported as failures. TEST_F(TestForDeathTest, RunawayIsFailure) { EXPECT_NONFATAL_FAILURE(EXPECT_DEATH(static_cast(0), "Foo"), "failed to die."); } // Tests that death tests report executing 'return' in the statement as // failure. TEST_F(TestForDeathTest, ReturnIsFailure) { EXPECT_FATAL_FAILURE(ASSERT_DEATH(return, "Bar"), "illegal return in test statement."); } // Tests that EXPECT_DEBUG_DEATH works as expected, that is, you can stream a // message to it, and in debug mode it: // 1. Asserts on death. // 2. Has no side effect. // // And in opt mode, it: // 1. Has side effects but does not assert. TEST_F(TestForDeathTest, TestExpectDebugDeath) { int sideeffect = 0; // Put the regex in a local variable to make sure we don't get an "unused" // warning in opt mode. const char* regex = "death.*DieInDebugElse12"; EXPECT_DEBUG_DEATH(DieInDebugElse12(&sideeffect), regex) << "Must accept a streamed message"; # ifdef NDEBUG // Checks that the assignment occurs in opt mode (sideeffect). EXPECT_EQ(12, sideeffect); # else // Checks that the assignment does not occur in dbg mode (no sideeffect). EXPECT_EQ(0, sideeffect); # endif } // Tests that ASSERT_DEBUG_DEATH works as expected, that is, you can stream a // message to it, and in debug mode it: // 1. Asserts on death. // 2. Has no side effect. // // And in opt mode, it: // 1. Has side effects but does not assert. TEST_F(TestForDeathTest, TestAssertDebugDeath) { int sideeffect = 0; ASSERT_DEBUG_DEATH(DieInDebugElse12(&sideeffect), "death.*DieInDebugElse12") << "Must accept a streamed message"; # ifdef NDEBUG // Checks that the assignment occurs in opt mode (sideeffect). EXPECT_EQ(12, sideeffect); # else // Checks that the assignment does not occur in dbg mode (no sideeffect). EXPECT_EQ(0, sideeffect); # endif } # ifndef NDEBUG void ExpectDebugDeathHelper(bool* aborted) { *aborted = true; EXPECT_DEBUG_DEATH(return, "") << "This is expected to fail."; *aborted = false; } # if GTEST_OS_WINDOWS TEST(PopUpDeathTest, DoesNotShowPopUpOnAbort) { printf("This test should be considered failing if it shows " "any pop-up dialogs.\n"); fflush(stdout); EXPECT_DEATH({ testing::GTEST_FLAG(catch_exceptions) = false; abort(); }, ""); } # endif // GTEST_OS_WINDOWS // Tests that EXPECT_DEBUG_DEATH in debug mode does not abort // the function. TEST_F(TestForDeathTest, ExpectDebugDeathDoesNotAbort) { bool aborted = true; EXPECT_NONFATAL_FAILURE(ExpectDebugDeathHelper(&aborted), ""); EXPECT_FALSE(aborted); } void AssertDebugDeathHelper(bool* aborted) { *aborted = true; GTEST_LOG_(INFO) << "Before ASSERT_DEBUG_DEATH"; ASSERT_DEBUG_DEATH(GTEST_LOG_(INFO) << "In ASSERT_DEBUG_DEATH"; return, "") << "This is expected to fail."; GTEST_LOG_(INFO) << "After ASSERT_DEBUG_DEATH"; *aborted = false; } // Tests that ASSERT_DEBUG_DEATH in debug mode aborts the function on // failure. TEST_F(TestForDeathTest, AssertDebugDeathAborts) { static bool aborted; aborted = false; EXPECT_FATAL_FAILURE(AssertDebugDeathHelper(&aborted), ""); EXPECT_TRUE(aborted); } TEST_F(TestForDeathTest, AssertDebugDeathAborts2) { static bool aborted; aborted = false; EXPECT_FATAL_FAILURE(AssertDebugDeathHelper(&aborted), ""); EXPECT_TRUE(aborted); } TEST_F(TestForDeathTest, AssertDebugDeathAborts3) { static bool aborted; aborted = false; EXPECT_FATAL_FAILURE(AssertDebugDeathHelper(&aborted), ""); EXPECT_TRUE(aborted); } TEST_F(TestForDeathTest, AssertDebugDeathAborts4) { static bool aborted; aborted = false; EXPECT_FATAL_FAILURE(AssertDebugDeathHelper(&aborted), ""); EXPECT_TRUE(aborted); } TEST_F(TestForDeathTest, AssertDebugDeathAborts5) { static bool aborted; aborted = false; EXPECT_FATAL_FAILURE(AssertDebugDeathHelper(&aborted), ""); EXPECT_TRUE(aborted); } TEST_F(TestForDeathTest, AssertDebugDeathAborts6) { static bool aborted; aborted = false; EXPECT_FATAL_FAILURE(AssertDebugDeathHelper(&aborted), ""); EXPECT_TRUE(aborted); } TEST_F(TestForDeathTest, AssertDebugDeathAborts7) { static bool aborted; aborted = false; EXPECT_FATAL_FAILURE(AssertDebugDeathHelper(&aborted), ""); EXPECT_TRUE(aborted); } TEST_F(TestForDeathTest, AssertDebugDeathAborts8) { static bool aborted; aborted = false; EXPECT_FATAL_FAILURE(AssertDebugDeathHelper(&aborted), ""); EXPECT_TRUE(aborted); } TEST_F(TestForDeathTest, AssertDebugDeathAborts9) { static bool aborted; aborted = false; EXPECT_FATAL_FAILURE(AssertDebugDeathHelper(&aborted), ""); EXPECT_TRUE(aborted); } TEST_F(TestForDeathTest, AssertDebugDeathAborts10) { static bool aborted; aborted = false; EXPECT_FATAL_FAILURE(AssertDebugDeathHelper(&aborted), ""); EXPECT_TRUE(aborted); } # endif // _NDEBUG // Tests the *_EXIT family of macros, using a variety of predicates. static void TestExitMacros() { EXPECT_EXIT(_exit(1), testing::ExitedWithCode(1), ""); ASSERT_EXIT(_exit(42), testing::ExitedWithCode(42), ""); # if GTEST_OS_WINDOWS // Of all signals effects on the process exit code, only those of SIGABRT // are documented on Windows. // See http://msdn.microsoft.com/en-us/library/dwwzkt4c(VS.71).aspx. EXPECT_EXIT(raise(SIGABRT), testing::ExitedWithCode(3), "") << "b_ar"; -# else +# elif !GTEST_OS_FUCHSIA + // Fuchsia has no unix signals. EXPECT_EXIT(raise(SIGKILL), testing::KilledBySignal(SIGKILL), "") << "foo"; ASSERT_EXIT(raise(SIGUSR2), testing::KilledBySignal(SIGUSR2), "") << "bar"; EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_EXIT(_exit(0), testing::KilledBySignal(SIGSEGV), "") << "This failure is expected, too."; }, "This failure is expected, too."); # endif // GTEST_OS_WINDOWS EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_EXIT(raise(SIGSEGV), testing::ExitedWithCode(0), "") << "This failure is expected."; }, "This failure is expected."); } TEST_F(TestForDeathTest, ExitMacros) { TestExitMacros(); } TEST_F(TestForDeathTest, ExitMacrosUsingFork) { testing::GTEST_FLAG(death_test_use_fork) = true; TestExitMacros(); } TEST_F(TestForDeathTest, InvalidStyle) { testing::GTEST_FLAG(death_test_style) = "rococo"; EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_DEATH(_exit(0), "") << "This failure is expected."; }, "This failure is expected."); } TEST_F(TestForDeathTest, DeathTestFailedOutput) { testing::GTEST_FLAG(death_test_style) = "fast"; EXPECT_NONFATAL_FAILURE( EXPECT_DEATH(DieWithMessage("death\n"), "expected message"), "Actual msg:\n" "[ DEATH ] death\n"); } TEST_F(TestForDeathTest, DeathTestUnexpectedReturnOutput) { testing::GTEST_FLAG(death_test_style) = "fast"; EXPECT_NONFATAL_FAILURE( EXPECT_DEATH({ fprintf(stderr, "returning\n"); fflush(stderr); return; }, ""), " Result: illegal return in test statement.\n" " Error msg:\n" "[ DEATH ] returning\n"); } TEST_F(TestForDeathTest, DeathTestBadExitCodeOutput) { testing::GTEST_FLAG(death_test_style) = "fast"; EXPECT_NONFATAL_FAILURE( EXPECT_EXIT(DieWithMessage("exiting with rc 1\n"), testing::ExitedWithCode(3), "expected message"), " Result: died but not with expected exit code:\n" " Exited with exit status 1\n" "Actual msg:\n" "[ DEATH ] exiting with rc 1\n"); } TEST_F(TestForDeathTest, DeathTestMultiLineMatchFail) { testing::GTEST_FLAG(death_test_style) = "fast"; EXPECT_NONFATAL_FAILURE( EXPECT_DEATH(DieWithMessage("line 1\nline 2\nline 3\n"), "line 1\nxyz\nline 3\n"), "Actual msg:\n" "[ DEATH ] line 1\n" "[ DEATH ] line 2\n" "[ DEATH ] line 3\n"); } TEST_F(TestForDeathTest, DeathTestMultiLineMatchPass) { testing::GTEST_FLAG(death_test_style) = "fast"; EXPECT_DEATH(DieWithMessage("line 1\nline 2\nline 3\n"), "line 1\nline 2\nline 3\n"); } // A DeathTestFactory that returns MockDeathTests. class MockDeathTestFactory : public DeathTestFactory { public: MockDeathTestFactory(); virtual bool Create(const char* statement, const ::testing::internal::RE* regex, const char* file, int line, DeathTest** test); // Sets the parameters for subsequent calls to Create. void SetParameters(bool create, DeathTest::TestRole role, int status, bool passed); // Accessors. int AssumeRoleCalls() const { return assume_role_calls_; } int WaitCalls() const { return wait_calls_; } size_t PassedCalls() const { return passed_args_.size(); } bool PassedArgument(int n) const { return passed_args_[n]; } size_t AbortCalls() const { return abort_args_.size(); } DeathTest::AbortReason AbortArgument(int n) const { return abort_args_[n]; } bool TestDeleted() const { return test_deleted_; } private: friend class MockDeathTest; // If true, Create will return a MockDeathTest; otherwise it returns // NULL. bool create_; // The value a MockDeathTest will return from its AssumeRole method. DeathTest::TestRole role_; // The value a MockDeathTest will return from its Wait method. int status_; // The value a MockDeathTest will return from its Passed method. bool passed_; // Number of times AssumeRole was called. int assume_role_calls_; // Number of times Wait was called. int wait_calls_; // The arguments to the calls to Passed since the last call to // SetParameters. std::vector passed_args_; // The arguments to the calls to Abort since the last call to // SetParameters. std::vector abort_args_; // True if the last MockDeathTest returned by Create has been // deleted. bool test_deleted_; }; // A DeathTest implementation useful in testing. It returns values set // at its creation from its various inherited DeathTest methods, and // reports calls to those methods to its parent MockDeathTestFactory // object. class MockDeathTest : public DeathTest { public: MockDeathTest(MockDeathTestFactory *parent, TestRole role, int status, bool passed) : parent_(parent), role_(role), status_(status), passed_(passed) { } virtual ~MockDeathTest() { parent_->test_deleted_ = true; } virtual TestRole AssumeRole() { ++parent_->assume_role_calls_; return role_; } virtual int Wait() { ++parent_->wait_calls_; return status_; } virtual bool Passed(bool exit_status_ok) { parent_->passed_args_.push_back(exit_status_ok); return passed_; } virtual void Abort(AbortReason reason) { parent_->abort_args_.push_back(reason); } private: MockDeathTestFactory* const parent_; const TestRole role_; const int status_; const bool passed_; }; // MockDeathTestFactory constructor. MockDeathTestFactory::MockDeathTestFactory() : create_(true), role_(DeathTest::OVERSEE_TEST), status_(0), passed_(true), assume_role_calls_(0), wait_calls_(0), passed_args_(), abort_args_() { } // Sets the parameters for subsequent calls to Create. void MockDeathTestFactory::SetParameters(bool create, DeathTest::TestRole role, int status, bool passed) { create_ = create; role_ = role; status_ = status; passed_ = passed; assume_role_calls_ = 0; wait_calls_ = 0; passed_args_.clear(); abort_args_.clear(); } // Sets test to NULL (if create_ is false) or to the address of a new // MockDeathTest object with parameters taken from the last call // to SetParameters (if create_ is true). Always returns true. bool MockDeathTestFactory::Create(const char* /*statement*/, const ::testing::internal::RE* /*regex*/, const char* /*file*/, int /*line*/, DeathTest** test) { test_deleted_ = false; if (create_) { *test = new MockDeathTest(this, role_, status_, passed_); } else { *test = NULL; } return true; } // A test fixture for testing the logic of the GTEST_DEATH_TEST_ macro. // It installs a MockDeathTestFactory that is used for the duration // of the test case. class MacroLogicDeathTest : public testing::Test { protected: static testing::internal::ReplaceDeathTestFactory* replacer_; static MockDeathTestFactory* factory_; static void SetUpTestCase() { factory_ = new MockDeathTestFactory; replacer_ = new testing::internal::ReplaceDeathTestFactory(factory_); } static void TearDownTestCase() { delete replacer_; replacer_ = NULL; delete factory_; factory_ = NULL; } // Runs a death test that breaks the rules by returning. Such a death // test cannot be run directly from a test routine that uses a // MockDeathTest, or the remainder of the routine will not be executed. static void RunReturningDeathTest(bool* flag) { ASSERT_DEATH({ // NOLINT *flag = true; return; }, ""); } }; testing::internal::ReplaceDeathTestFactory* MacroLogicDeathTest::replacer_ = NULL; MockDeathTestFactory* MacroLogicDeathTest::factory_ = NULL; // Test that nothing happens when the factory doesn't return a DeathTest: TEST_F(MacroLogicDeathTest, NothingHappens) { bool flag = false; factory_->SetParameters(false, DeathTest::OVERSEE_TEST, 0, true); EXPECT_DEATH(flag = true, ""); EXPECT_FALSE(flag); EXPECT_EQ(0, factory_->AssumeRoleCalls()); EXPECT_EQ(0, factory_->WaitCalls()); EXPECT_EQ(0U, factory_->PassedCalls()); EXPECT_EQ(0U, factory_->AbortCalls()); EXPECT_FALSE(factory_->TestDeleted()); } // Test that the parent process doesn't run the death test code, // and that the Passed method returns false when the (simulated) // child process exits with status 0: TEST_F(MacroLogicDeathTest, ChildExitsSuccessfully) { bool flag = false; factory_->SetParameters(true, DeathTest::OVERSEE_TEST, 0, true); EXPECT_DEATH(flag = true, ""); EXPECT_FALSE(flag); EXPECT_EQ(1, factory_->AssumeRoleCalls()); EXPECT_EQ(1, factory_->WaitCalls()); ASSERT_EQ(1U, factory_->PassedCalls()); EXPECT_FALSE(factory_->PassedArgument(0)); EXPECT_EQ(0U, factory_->AbortCalls()); EXPECT_TRUE(factory_->TestDeleted()); } // Tests that the Passed method was given the argument "true" when // the (simulated) child process exits with status 1: TEST_F(MacroLogicDeathTest, ChildExitsUnsuccessfully) { bool flag = false; factory_->SetParameters(true, DeathTest::OVERSEE_TEST, 1, true); EXPECT_DEATH(flag = true, ""); EXPECT_FALSE(flag); EXPECT_EQ(1, factory_->AssumeRoleCalls()); EXPECT_EQ(1, factory_->WaitCalls()); ASSERT_EQ(1U, factory_->PassedCalls()); EXPECT_TRUE(factory_->PassedArgument(0)); EXPECT_EQ(0U, factory_->AbortCalls()); EXPECT_TRUE(factory_->TestDeleted()); } // Tests that the (simulated) child process executes the death test // code, and is aborted with the correct AbortReason if it // executes a return statement. TEST_F(MacroLogicDeathTest, ChildPerformsReturn) { bool flag = false; factory_->SetParameters(true, DeathTest::EXECUTE_TEST, 0, true); RunReturningDeathTest(&flag); EXPECT_TRUE(flag); EXPECT_EQ(1, factory_->AssumeRoleCalls()); EXPECT_EQ(0, factory_->WaitCalls()); EXPECT_EQ(0U, factory_->PassedCalls()); EXPECT_EQ(1U, factory_->AbortCalls()); EXPECT_EQ(DeathTest::TEST_ENCOUNTERED_RETURN_STATEMENT, factory_->AbortArgument(0)); EXPECT_TRUE(factory_->TestDeleted()); } // Tests that the (simulated) child process is aborted with the // correct AbortReason if it does not die. TEST_F(MacroLogicDeathTest, ChildDoesNotDie) { bool flag = false; factory_->SetParameters(true, DeathTest::EXECUTE_TEST, 0, true); EXPECT_DEATH(flag = true, ""); EXPECT_TRUE(flag); EXPECT_EQ(1, factory_->AssumeRoleCalls()); EXPECT_EQ(0, factory_->WaitCalls()); EXPECT_EQ(0U, factory_->PassedCalls()); // This time there are two calls to Abort: one since the test didn't // die, and another from the ReturnSentinel when it's destroyed. The // sentinel normally isn't destroyed if a test doesn't die, since // _exit(2) is called in that case by ForkingDeathTest, but not by // our MockDeathTest. ASSERT_EQ(2U, factory_->AbortCalls()); EXPECT_EQ(DeathTest::TEST_DID_NOT_DIE, factory_->AbortArgument(0)); EXPECT_EQ(DeathTest::TEST_ENCOUNTERED_RETURN_STATEMENT, factory_->AbortArgument(1)); EXPECT_TRUE(factory_->TestDeleted()); } // Tests that a successful death test does not register a successful // test part. TEST(SuccessRegistrationDeathTest, NoSuccessPart) { EXPECT_DEATH(_exit(1), ""); EXPECT_EQ(0, GetUnitTestImpl()->current_test_result()->total_part_count()); } TEST(StreamingAssertionsDeathTest, DeathTest) { EXPECT_DEATH(_exit(1), "") << "unexpected failure"; ASSERT_DEATH(_exit(1), "") << "unexpected failure"; EXPECT_NONFATAL_FAILURE({ // NOLINT EXPECT_DEATH(_exit(0), "") << "expected failure"; }, "expected failure"); EXPECT_FATAL_FAILURE({ // NOLINT ASSERT_DEATH(_exit(0), "") << "expected failure"; }, "expected failure"); } // Tests that GetLastErrnoDescription returns an empty string when the // last error is 0 and non-empty string when it is non-zero. TEST(GetLastErrnoDescription, GetLastErrnoDescriptionWorks) { errno = ENOENT; EXPECT_STRNE("", GetLastErrnoDescription().c_str()); errno = 0; EXPECT_STREQ("", GetLastErrnoDescription().c_str()); } # if GTEST_OS_WINDOWS TEST(AutoHandleTest, AutoHandleWorks) { HANDLE handle = ::CreateEvent(NULL, FALSE, FALSE, NULL); ASSERT_NE(INVALID_HANDLE_VALUE, handle); // Tests that the AutoHandle is correctly initialized with a handle. testing::internal::AutoHandle auto_handle(handle); EXPECT_EQ(handle, auto_handle.Get()); // Tests that Reset assigns INVALID_HANDLE_VALUE. // Note that this cannot verify whether the original handle is closed. auto_handle.Reset(); EXPECT_EQ(INVALID_HANDLE_VALUE, auto_handle.Get()); // Tests that Reset assigns the new handle. // Note that this cannot verify whether the original handle is closed. handle = ::CreateEvent(NULL, FALSE, FALSE, NULL); ASSERT_NE(INVALID_HANDLE_VALUE, handle); auto_handle.Reset(handle); EXPECT_EQ(handle, auto_handle.Get()); // Tests that AutoHandle contains INVALID_HANDLE_VALUE by default. testing::internal::AutoHandle auto_handle2; EXPECT_EQ(INVALID_HANDLE_VALUE, auto_handle2.Get()); } # endif // GTEST_OS_WINDOWS # if GTEST_OS_WINDOWS typedef unsigned __int64 BiggestParsable; typedef signed __int64 BiggestSignedParsable; # else typedef unsigned long long BiggestParsable; typedef signed long long BiggestSignedParsable; # endif // GTEST_OS_WINDOWS // We cannot use std::numeric_limits::max() as it clashes with the // max() macro defined by . const BiggestParsable kBiggestParsableMax = ULLONG_MAX; const BiggestSignedParsable kBiggestSignedParsableMax = LLONG_MAX; TEST(ParseNaturalNumberTest, RejectsInvalidFormat) { BiggestParsable result = 0; // Rejects non-numbers. EXPECT_FALSE(ParseNaturalNumber("non-number string", &result)); // Rejects numbers with whitespace prefix. EXPECT_FALSE(ParseNaturalNumber(" 123", &result)); // Rejects negative numbers. EXPECT_FALSE(ParseNaturalNumber("-123", &result)); // Rejects numbers starting with a plus sign. EXPECT_FALSE(ParseNaturalNumber("+123", &result)); errno = 0; } TEST(ParseNaturalNumberTest, RejectsOverflownNumbers) { BiggestParsable result = 0; EXPECT_FALSE(ParseNaturalNumber("99999999999999999999999", &result)); signed char char_result = 0; EXPECT_FALSE(ParseNaturalNumber("200", &char_result)); errno = 0; } TEST(ParseNaturalNumberTest, AcceptsValidNumbers) { BiggestParsable result = 0; result = 0; ASSERT_TRUE(ParseNaturalNumber("123", &result)); EXPECT_EQ(123U, result); // Check 0 as an edge case. result = 1; ASSERT_TRUE(ParseNaturalNumber("0", &result)); EXPECT_EQ(0U, result); result = 1; ASSERT_TRUE(ParseNaturalNumber("00000", &result)); EXPECT_EQ(0U, result); } TEST(ParseNaturalNumberTest, AcceptsTypeLimits) { Message msg; msg << kBiggestParsableMax; BiggestParsable result = 0; EXPECT_TRUE(ParseNaturalNumber(msg.GetString(), &result)); EXPECT_EQ(kBiggestParsableMax, result); Message msg2; msg2 << kBiggestSignedParsableMax; BiggestSignedParsable signed_result = 0; EXPECT_TRUE(ParseNaturalNumber(msg2.GetString(), &signed_result)); EXPECT_EQ(kBiggestSignedParsableMax, signed_result); Message msg3; msg3 << INT_MAX; int int_result = 0; EXPECT_TRUE(ParseNaturalNumber(msg3.GetString(), &int_result)); EXPECT_EQ(INT_MAX, int_result); Message msg4; msg4 << UINT_MAX; unsigned int uint_result = 0; EXPECT_TRUE(ParseNaturalNumber(msg4.GetString(), &uint_result)); EXPECT_EQ(UINT_MAX, uint_result); } TEST(ParseNaturalNumberTest, WorksForShorterIntegers) { short short_result = 0; ASSERT_TRUE(ParseNaturalNumber("123", &short_result)); EXPECT_EQ(123, short_result); signed char char_result = 0; ASSERT_TRUE(ParseNaturalNumber("123", &char_result)); EXPECT_EQ(123, char_result); } # if GTEST_OS_WINDOWS TEST(EnvironmentTest, HandleFitsIntoSizeT) { // TODO(vladl@google.com): Remove this test after this condition is verified // in a static assertion in gtest-death-test.cc in the function // GetStatusFileDescriptor. ASSERT_TRUE(sizeof(HANDLE) <= sizeof(size_t)); } # endif // GTEST_OS_WINDOWS // Tests that EXPECT_DEATH_IF_SUPPORTED/ASSERT_DEATH_IF_SUPPORTED trigger // failures when death tests are available on the system. TEST(ConditionalDeathMacrosDeathTest, ExpectsDeathWhenDeathTestsAvailable) { EXPECT_DEATH_IF_SUPPORTED(DieInside("CondDeathTestExpectMacro"), "death inside CondDeathTestExpectMacro"); ASSERT_DEATH_IF_SUPPORTED(DieInside("CondDeathTestAssertMacro"), "death inside CondDeathTestAssertMacro"); // Empty statement will not crash, which must trigger a failure. EXPECT_NONFATAL_FAILURE(EXPECT_DEATH_IF_SUPPORTED(;, ""), ""); EXPECT_FATAL_FAILURE(ASSERT_DEATH_IF_SUPPORTED(;, ""), ""); } TEST(InDeathTestChildDeathTest, ReportsDeathTestCorrectlyInFastStyle) { testing::GTEST_FLAG(death_test_style) = "fast"; EXPECT_FALSE(InDeathTestChild()); EXPECT_DEATH({ fprintf(stderr, InDeathTestChild() ? "Inside" : "Outside"); fflush(stderr); _exit(1); }, "Inside"); } TEST(InDeathTestChildDeathTest, ReportsDeathTestCorrectlyInThreadSafeStyle) { testing::GTEST_FLAG(death_test_style) = "threadsafe"; EXPECT_FALSE(InDeathTestChild()); EXPECT_DEATH({ fprintf(stderr, InDeathTestChild() ? "Inside" : "Outside"); fflush(stderr); _exit(1); }, "Inside"); } #else // !GTEST_HAS_DEATH_TEST follows using testing::internal::CaptureStderr; using testing::internal::GetCapturedStderr; // Tests that EXPECT_DEATH_IF_SUPPORTED/ASSERT_DEATH_IF_SUPPORTED are still // defined but do not trigger failures when death tests are not available on // the system. TEST(ConditionalDeathMacrosTest, WarnsWhenDeathTestsNotAvailable) { // Empty statement will not crash, but that should not trigger a failure // when death tests are not supported. CaptureStderr(); EXPECT_DEATH_IF_SUPPORTED(;, ""); std::string output = GetCapturedStderr(); ASSERT_TRUE(NULL != strstr(output.c_str(), "Death tests are not supported on this platform")); ASSERT_TRUE(NULL != strstr(output.c_str(), ";")); // The streamed message should not be printed as there is no test failure. CaptureStderr(); EXPECT_DEATH_IF_SUPPORTED(;, "") << "streamed message"; output = GetCapturedStderr(); ASSERT_TRUE(NULL == strstr(output.c_str(), "streamed message")); CaptureStderr(); ASSERT_DEATH_IF_SUPPORTED(;, ""); // NOLINT output = GetCapturedStderr(); ASSERT_TRUE(NULL != strstr(output.c_str(), "Death tests are not supported on this platform")); ASSERT_TRUE(NULL != strstr(output.c_str(), ";")); CaptureStderr(); ASSERT_DEATH_IF_SUPPORTED(;, "") << "streamed message"; // NOLINT output = GetCapturedStderr(); ASSERT_TRUE(NULL == strstr(output.c_str(), "streamed message")); } void FuncWithAssert(int* n) { ASSERT_DEATH_IF_SUPPORTED(return;, ""); (*n)++; } // Tests that ASSERT_DEATH_IF_SUPPORTED does not return from the current // function (as ASSERT_DEATH does) if death tests are not supported. TEST(ConditionalDeathMacrosTest, AssertDeatDoesNotReturnhIfUnsupported) { int n = 0; FuncWithAssert(&n); EXPECT_EQ(1, n); } #endif // !GTEST_HAS_DEATH_TEST // Tests that the death test macros expand to code which may or may not // be followed by operator<<, and that in either case the complete text // comprises only a single C++ statement. // // The syntax should work whether death tests are available or not. TEST(ConditionalDeathMacrosSyntaxDeathTest, SingleStatement) { if (AlwaysFalse()) // This would fail if executed; this is a compilation test only ASSERT_DEATH_IF_SUPPORTED(return, ""); if (AlwaysTrue()) EXPECT_DEATH_IF_SUPPORTED(_exit(1), ""); else // This empty "else" branch is meant to ensure that EXPECT_DEATH // doesn't expand into an "if" statement without an "else" ; // NOLINT if (AlwaysFalse()) ASSERT_DEATH_IF_SUPPORTED(return, "") << "did not die"; if (AlwaysFalse()) ; // NOLINT else EXPECT_DEATH_IF_SUPPORTED(_exit(1), "") << 1 << 2 << 3; } // Tests that conditional death test macros expand to code which interacts // well with switch statements. TEST(ConditionalDeathMacrosSyntaxDeathTest, SwitchStatement) { // Microsoft compiler usually complains about switch statements without // case labels. We suppress that warning for this test. GTEST_DISABLE_MSC_WARNINGS_PUSH_(4065) switch (0) default: ASSERT_DEATH_IF_SUPPORTED(_exit(1), "") << "exit in default switch handler"; switch (0) case 0: EXPECT_DEATH_IF_SUPPORTED(_exit(1), "") << "exit in switch case"; GTEST_DISABLE_MSC_WARNINGS_POP_() } // Tests that a test case whose name ends with "DeathTest" works fine // on Windows. TEST(NotADeathTest, Test) { SUCCEED(); } diff --git a/googletest/test/gtest-options_test.cc b/googletest/test/gtest-options_test.cc index 25c9f394..10cb1df7 100644 --- a/googletest/test/gtest-options_test.cc +++ b/googletest/test/gtest-options_test.cc @@ -1,207 +1,213 @@ // Copyright 2008, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // // Google Test UnitTestOptions tests // // This file tests classes and functions used internally by // Google Test. They are subject to change without notice. // // This file is #included from gtest.cc, to avoid changing build or // make-files on Windows and other platforms. Do not #include this file // anywhere else! #include "gtest/gtest.h" #if GTEST_OS_WINDOWS_MOBILE # include #elif GTEST_OS_WINDOWS # include #endif // GTEST_OS_WINDOWS_MOBILE #include "src/gtest-internal-inl.h" namespace testing { namespace internal { namespace { // Turns the given relative path into an absolute path. FilePath GetAbsolutePathOf(const FilePath& relative_path) { return FilePath::ConcatPaths(FilePath::GetCurrentDir(), relative_path); } // Testing UnitTestOptions::GetOutputFormat/GetOutputFile. TEST(XmlOutputTest, GetOutputFormatDefault) { GTEST_FLAG(output) = ""; EXPECT_STREQ("", UnitTestOptions::GetOutputFormat().c_str()); } TEST(XmlOutputTest, GetOutputFormat) { GTEST_FLAG(output) = "xml:filename"; EXPECT_STREQ("xml", UnitTestOptions::GetOutputFormat().c_str()); } TEST(XmlOutputTest, GetOutputFileDefault) { GTEST_FLAG(output) = ""; EXPECT_EQ(GetAbsolutePathOf(FilePath("test_detail.xml")).string(), UnitTestOptions::GetAbsolutePathToOutputFile()); } TEST(XmlOutputTest, GetOutputFileSingleFile) { GTEST_FLAG(output) = "xml:filename.abc"; EXPECT_EQ(GetAbsolutePathOf(FilePath("filename.abc")).string(), UnitTestOptions::GetAbsolutePathToOutputFile()); } TEST(XmlOutputTest, GetOutputFileFromDirectoryPath) { GTEST_FLAG(output) = "xml:path" GTEST_PATH_SEP_; const std::string expected_output_file = GetAbsolutePathOf( FilePath(std::string("path") + GTEST_PATH_SEP_ + GetCurrentExecutableName().string() + ".xml")).string(); const std::string& output_file = UnitTestOptions::GetAbsolutePathToOutputFile(); #if GTEST_OS_WINDOWS EXPECT_STRCASEEQ(expected_output_file.c_str(), output_file.c_str()); #else EXPECT_EQ(expected_output_file, output_file.c_str()); #endif } TEST(OutputFileHelpersTest, GetCurrentExecutableName) { const std::string exe_str = GetCurrentExecutableName().string(); #if GTEST_OS_WINDOWS const bool success = _strcmpi("gtest-options_test", exe_str.c_str()) == 0 || _strcmpi("gtest-options-ex_test", exe_str.c_str()) == 0 || _strcmpi("gtest_all_test", exe_str.c_str()) == 0 || _strcmpi("gtest_dll_test", exe_str.c_str()) == 0; +#elif GTEST_OS_FUCHSIA + const bool success = exe_str == "app"; #else // TODO(wan@google.com): remove the hard-coded "lt-" prefix when // Chandler Carruth's libtool replacement is ready. const bool success = exe_str == "gtest-options_test" || exe_str == "gtest_all_test" || exe_str == "lt-gtest_all_test" || exe_str == "gtest_dll_test"; #endif // GTEST_OS_WINDOWS if (!success) FAIL() << "GetCurrentExecutableName() returns " << exe_str; } +#if !GTEST_OS_FUCHSIA + class XmlOutputChangeDirTest : public Test { protected: virtual void SetUp() { original_working_dir_ = FilePath::GetCurrentDir(); posix::ChDir(".."); // This will make the test fail if run from the root directory. EXPECT_NE(original_working_dir_.string(), FilePath::GetCurrentDir().string()); } virtual void TearDown() { posix::ChDir(original_working_dir_.string().c_str()); } FilePath original_working_dir_; }; TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithDefault) { GTEST_FLAG(output) = ""; EXPECT_EQ(FilePath::ConcatPaths(original_working_dir_, FilePath("test_detail.xml")).string(), UnitTestOptions::GetAbsolutePathToOutputFile()); } TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithDefaultXML) { GTEST_FLAG(output) = "xml"; EXPECT_EQ(FilePath::ConcatPaths(original_working_dir_, FilePath("test_detail.xml")).string(), UnitTestOptions::GetAbsolutePathToOutputFile()); } TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithRelativeFile) { GTEST_FLAG(output) = "xml:filename.abc"; EXPECT_EQ(FilePath::ConcatPaths(original_working_dir_, FilePath("filename.abc")).string(), UnitTestOptions::GetAbsolutePathToOutputFile()); } TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithRelativePath) { GTEST_FLAG(output) = "xml:path" GTEST_PATH_SEP_; const std::string expected_output_file = FilePath::ConcatPaths( original_working_dir_, FilePath(std::string("path") + GTEST_PATH_SEP_ + GetCurrentExecutableName().string() + ".xml")).string(); const std::string& output_file = UnitTestOptions::GetAbsolutePathToOutputFile(); #if GTEST_OS_WINDOWS EXPECT_STRCASEEQ(expected_output_file.c_str(), output_file.c_str()); #else EXPECT_EQ(expected_output_file, output_file.c_str()); #endif } TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithAbsoluteFile) { #if GTEST_OS_WINDOWS GTEST_FLAG(output) = "xml:c:\\tmp\\filename.abc"; EXPECT_EQ(FilePath("c:\\tmp\\filename.abc").string(), UnitTestOptions::GetAbsolutePathToOutputFile()); #else GTEST_FLAG(output) ="xml:/tmp/filename.abc"; EXPECT_EQ(FilePath("/tmp/filename.abc").string(), UnitTestOptions::GetAbsolutePathToOutputFile()); #endif } TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithAbsolutePath) { #if GTEST_OS_WINDOWS const std::string path = "c:\\tmp\\"; #else const std::string path = "/tmp/"; #endif GTEST_FLAG(output) = "xml:" + path; const std::string expected_output_file = path + GetCurrentExecutableName().string() + ".xml"; const std::string& output_file = UnitTestOptions::GetAbsolutePathToOutputFile(); #if GTEST_OS_WINDOWS EXPECT_STRCASEEQ(expected_output_file.c_str(), output_file.c_str()); #else EXPECT_EQ(expected_output_file, output_file.c_str()); #endif } +#endif // !GTEST_OS_FUCHSIA + } // namespace } // namespace internal } // namespace testing diff --git a/googletest/test/gtest-port_test.cc b/googletest/test/gtest-port_test.cc index 51956f05..3801e5ee 100644 --- a/googletest/test/gtest-port_test.cc +++ b/googletest/test/gtest-port_test.cc @@ -1,1303 +1,1303 @@ // Copyright 2008, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Authors: vladl@google.com (Vlad Losev), wan@google.com (Zhanyong Wan) // // This file tests the internal cross-platform support utilities. #include "gtest/internal/gtest-port.h" #include #if GTEST_OS_MAC # include #endif // GTEST_OS_MAC #include #include // For std::pair and std::make_pair. #include #include "gtest/gtest.h" #include "gtest/gtest-spi.h" #include "src/gtest-internal-inl.h" using std::make_pair; using std::pair; namespace testing { namespace internal { TEST(IsXDigitTest, WorksForNarrowAscii) { EXPECT_TRUE(IsXDigit('0')); EXPECT_TRUE(IsXDigit('9')); EXPECT_TRUE(IsXDigit('A')); EXPECT_TRUE(IsXDigit('F')); EXPECT_TRUE(IsXDigit('a')); EXPECT_TRUE(IsXDigit('f')); EXPECT_FALSE(IsXDigit('-')); EXPECT_FALSE(IsXDigit('g')); EXPECT_FALSE(IsXDigit('G')); } TEST(IsXDigitTest, ReturnsFalseForNarrowNonAscii) { EXPECT_FALSE(IsXDigit(static_cast('\x80'))); EXPECT_FALSE(IsXDigit(static_cast('0' | '\x80'))); } TEST(IsXDigitTest, WorksForWideAscii) { EXPECT_TRUE(IsXDigit(L'0')); EXPECT_TRUE(IsXDigit(L'9')); EXPECT_TRUE(IsXDigit(L'A')); EXPECT_TRUE(IsXDigit(L'F')); EXPECT_TRUE(IsXDigit(L'a')); EXPECT_TRUE(IsXDigit(L'f')); EXPECT_FALSE(IsXDigit(L'-')); EXPECT_FALSE(IsXDigit(L'g')); EXPECT_FALSE(IsXDigit(L'G')); } TEST(IsXDigitTest, ReturnsFalseForWideNonAscii) { EXPECT_FALSE(IsXDigit(static_cast(0x80))); EXPECT_FALSE(IsXDigit(static_cast(L'0' | 0x80))); EXPECT_FALSE(IsXDigit(static_cast(L'0' | 0x100))); } class Base { public: // Copy constructor and assignment operator do exactly what we need, so we // use them. Base() : member_(0) {} explicit Base(int n) : member_(n) {} virtual ~Base() {} int member() { return member_; } private: int member_; }; class Derived : public Base { public: explicit Derived(int n) : Base(n) {} }; TEST(ImplicitCastTest, ConvertsPointers) { Derived derived(0); EXPECT_TRUE(&derived == ::testing::internal::ImplicitCast_(&derived)); } TEST(ImplicitCastTest, CanUseInheritance) { Derived derived(1); Base base = ::testing::internal::ImplicitCast_(derived); EXPECT_EQ(derived.member(), base.member()); } class Castable { public: explicit Castable(bool* converted) : converted_(converted) {} operator Base() { *converted_ = true; return Base(); } private: bool* converted_; }; TEST(ImplicitCastTest, CanUseNonConstCastOperator) { bool converted = false; Castable castable(&converted); Base base = ::testing::internal::ImplicitCast_(castable); EXPECT_TRUE(converted); } class ConstCastable { public: explicit ConstCastable(bool* converted) : converted_(converted) {} operator Base() const { *converted_ = true; return Base(); } private: bool* converted_; }; TEST(ImplicitCastTest, CanUseConstCastOperatorOnConstValues) { bool converted = false; const ConstCastable const_castable(&converted); Base base = ::testing::internal::ImplicitCast_(const_castable); EXPECT_TRUE(converted); } class ConstAndNonConstCastable { public: ConstAndNonConstCastable(bool* converted, bool* const_converted) : converted_(converted), const_converted_(const_converted) {} operator Base() { *converted_ = true; return Base(); } operator Base() const { *const_converted_ = true; return Base(); } private: bool* converted_; bool* const_converted_; }; TEST(ImplicitCastTest, CanSelectBetweenConstAndNonConstCasrAppropriately) { bool converted = false; bool const_converted = false; ConstAndNonConstCastable castable(&converted, &const_converted); Base base = ::testing::internal::ImplicitCast_(castable); EXPECT_TRUE(converted); EXPECT_FALSE(const_converted); converted = false; const_converted = false; const ConstAndNonConstCastable const_castable(&converted, &const_converted); base = ::testing::internal::ImplicitCast_(const_castable); EXPECT_FALSE(converted); EXPECT_TRUE(const_converted); } class To { public: To(bool* converted) { *converted = true; } // NOLINT }; TEST(ImplicitCastTest, CanUseImplicitConstructor) { bool converted = false; To to = ::testing::internal::ImplicitCast_(&converted); (void)to; EXPECT_TRUE(converted); } TEST(IteratorTraitsTest, WorksForSTLContainerIterators) { StaticAssertTypeEq::const_iterator>::value_type>(); StaticAssertTypeEq::iterator>::value_type>(); } TEST(IteratorTraitsTest, WorksForPointerToNonConst) { StaticAssertTypeEq::value_type>(); StaticAssertTypeEq::value_type>(); } TEST(IteratorTraitsTest, WorksForPointerToConst) { StaticAssertTypeEq::value_type>(); StaticAssertTypeEq::value_type>(); } // Tests that the element_type typedef is available in scoped_ptr and refers // to the parameter type. TEST(ScopedPtrTest, DefinesElementType) { StaticAssertTypeEq::element_type>(); } // TODO(vladl@google.com): Implement THE REST of scoped_ptr tests. TEST(GtestCheckSyntaxTest, BehavesLikeASingleStatement) { if (AlwaysFalse()) GTEST_CHECK_(false) << "This should never be executed; " "It's a compilation test only."; if (AlwaysTrue()) GTEST_CHECK_(true); else ; // NOLINT if (AlwaysFalse()) ; // NOLINT else GTEST_CHECK_(true) << ""; } TEST(GtestCheckSyntaxTest, WorksWithSwitch) { switch (0) { case 1: break; default: GTEST_CHECK_(true); } switch (0) case 0: GTEST_CHECK_(true) << "Check failed in switch case"; } // Verifies behavior of FormatFileLocation. TEST(FormatFileLocationTest, FormatsFileLocation) { EXPECT_PRED_FORMAT2(IsSubstring, "foo.cc", FormatFileLocation("foo.cc", 42)); EXPECT_PRED_FORMAT2(IsSubstring, "42", FormatFileLocation("foo.cc", 42)); } TEST(FormatFileLocationTest, FormatsUnknownFile) { EXPECT_PRED_FORMAT2( IsSubstring, "unknown file", FormatFileLocation(NULL, 42)); EXPECT_PRED_FORMAT2(IsSubstring, "42", FormatFileLocation(NULL, 42)); } TEST(FormatFileLocationTest, FormatsUknownLine) { EXPECT_EQ("foo.cc:", FormatFileLocation("foo.cc", -1)); } TEST(FormatFileLocationTest, FormatsUknownFileAndLine) { EXPECT_EQ("unknown file:", FormatFileLocation(NULL, -1)); } // Verifies behavior of FormatCompilerIndependentFileLocation. TEST(FormatCompilerIndependentFileLocationTest, FormatsFileLocation) { EXPECT_EQ("foo.cc:42", FormatCompilerIndependentFileLocation("foo.cc", 42)); } TEST(FormatCompilerIndependentFileLocationTest, FormatsUknownFile) { EXPECT_EQ("unknown file:42", FormatCompilerIndependentFileLocation(NULL, 42)); } TEST(FormatCompilerIndependentFileLocationTest, FormatsUknownLine) { EXPECT_EQ("foo.cc", FormatCompilerIndependentFileLocation("foo.cc", -1)); } TEST(FormatCompilerIndependentFileLocationTest, FormatsUknownFileAndLine) { EXPECT_EQ("unknown file", FormatCompilerIndependentFileLocation(NULL, -1)); } -#if GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_QNX +#if GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_QNX || GTEST_OS_FUCHSIA void* ThreadFunc(void* data) { internal::Mutex* mutex = static_cast(data); mutex->Lock(); mutex->Unlock(); return NULL; } TEST(GetThreadCountTest, ReturnsCorrectValue) { const size_t starting_count = GetThreadCount(); pthread_t thread_id; internal::Mutex mutex; { internal::MutexLock lock(&mutex); pthread_attr_t attr; ASSERT_EQ(0, pthread_attr_init(&attr)); ASSERT_EQ(0, pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE)); const int status = pthread_create(&thread_id, &attr, &ThreadFunc, &mutex); ASSERT_EQ(0, pthread_attr_destroy(&attr)); ASSERT_EQ(0, status); EXPECT_EQ(starting_count + 1, GetThreadCount()); } void* dummy; ASSERT_EQ(0, pthread_join(thread_id, &dummy)); // The OS may not immediately report the updated thread count after // joining a thread, causing flakiness in this test. To counter that, we // wait for up to .5 seconds for the OS to report the correct value. for (int i = 0; i < 5; ++i) { if (GetThreadCount() == starting_count) break; SleepMilliseconds(100); } EXPECT_EQ(starting_count, GetThreadCount()); } #else TEST(GetThreadCountTest, ReturnsZeroWhenUnableToCountThreads) { EXPECT_EQ(0U, GetThreadCount()); } -#endif // GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_QNX +#endif // GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_QNX || GTEST_OS_FUCHSIA TEST(GtestCheckDeathTest, DiesWithCorrectOutputOnFailure) { const bool a_false_condition = false; const char regex[] = #ifdef _MSC_VER "gtest-port_test\\.cc\\(\\d+\\):" #elif GTEST_USES_POSIX_RE "gtest-port_test\\.cc:[0-9]+" #else "gtest-port_test\\.cc:\\d+" #endif // _MSC_VER ".*a_false_condition.*Extra info.*"; EXPECT_DEATH_IF_SUPPORTED(GTEST_CHECK_(a_false_condition) << "Extra info", regex); } #if GTEST_HAS_DEATH_TEST TEST(GtestCheckDeathTest, LivesSilentlyOnSuccess) { EXPECT_EXIT({ GTEST_CHECK_(true) << "Extra info"; ::std::cerr << "Success\n"; exit(0); }, ::testing::ExitedWithCode(0), "Success"); } #endif // GTEST_HAS_DEATH_TEST // Verifies that Google Test choose regular expression engine appropriate to // the platform. The test will produce compiler errors in case of failure. // For simplicity, we only cover the most important platforms here. TEST(RegexEngineSelectionTest, SelectsCorrectRegexEngine) { #if !GTEST_USES_PCRE # if GTEST_HAS_POSIX_RE EXPECT_TRUE(GTEST_USES_POSIX_RE); # else EXPECT_TRUE(GTEST_USES_SIMPLE_RE); # endif #endif // !GTEST_USES_PCRE } #if GTEST_USES_POSIX_RE # if GTEST_HAS_TYPED_TEST template class RETest : public ::testing::Test {}; // Defines StringTypes as the list of all string types that class RE // supports. typedef testing::Types< ::std::string, # if GTEST_HAS_GLOBAL_STRING ::string, # endif // GTEST_HAS_GLOBAL_STRING const char*> StringTypes; TYPED_TEST_CASE(RETest, StringTypes); // Tests RE's implicit constructors. TYPED_TEST(RETest, ImplicitConstructorWorks) { const RE empty(TypeParam("")); EXPECT_STREQ("", empty.pattern()); const RE simple(TypeParam("hello")); EXPECT_STREQ("hello", simple.pattern()); const RE normal(TypeParam(".*(\\w+)")); EXPECT_STREQ(".*(\\w+)", normal.pattern()); } // Tests that RE's constructors reject invalid regular expressions. TYPED_TEST(RETest, RejectsInvalidRegex) { EXPECT_NONFATAL_FAILURE({ const RE invalid(TypeParam("?")); }, "\"?\" is not a valid POSIX Extended regular expression."); } // Tests RE::FullMatch(). TYPED_TEST(RETest, FullMatchWorks) { const RE empty(TypeParam("")); EXPECT_TRUE(RE::FullMatch(TypeParam(""), empty)); EXPECT_FALSE(RE::FullMatch(TypeParam("a"), empty)); const RE re(TypeParam("a.*z")); EXPECT_TRUE(RE::FullMatch(TypeParam("az"), re)); EXPECT_TRUE(RE::FullMatch(TypeParam("axyz"), re)); EXPECT_FALSE(RE::FullMatch(TypeParam("baz"), re)); EXPECT_FALSE(RE::FullMatch(TypeParam("azy"), re)); } // Tests RE::PartialMatch(). TYPED_TEST(RETest, PartialMatchWorks) { const RE empty(TypeParam("")); EXPECT_TRUE(RE::PartialMatch(TypeParam(""), empty)); EXPECT_TRUE(RE::PartialMatch(TypeParam("a"), empty)); const RE re(TypeParam("a.*z")); EXPECT_TRUE(RE::PartialMatch(TypeParam("az"), re)); EXPECT_TRUE(RE::PartialMatch(TypeParam("axyz"), re)); EXPECT_TRUE(RE::PartialMatch(TypeParam("baz"), re)); EXPECT_TRUE(RE::PartialMatch(TypeParam("azy"), re)); EXPECT_FALSE(RE::PartialMatch(TypeParam("zza"), re)); } # endif // GTEST_HAS_TYPED_TEST #elif GTEST_USES_SIMPLE_RE TEST(IsInSetTest, NulCharIsNotInAnySet) { EXPECT_FALSE(IsInSet('\0', "")); EXPECT_FALSE(IsInSet('\0', "\0")); EXPECT_FALSE(IsInSet('\0', "a")); } TEST(IsInSetTest, WorksForNonNulChars) { EXPECT_FALSE(IsInSet('a', "Ab")); EXPECT_FALSE(IsInSet('c', "")); EXPECT_TRUE(IsInSet('b', "bcd")); EXPECT_TRUE(IsInSet('b', "ab")); } TEST(IsAsciiDigitTest, IsFalseForNonDigit) { EXPECT_FALSE(IsAsciiDigit('\0')); EXPECT_FALSE(IsAsciiDigit(' ')); EXPECT_FALSE(IsAsciiDigit('+')); EXPECT_FALSE(IsAsciiDigit('-')); EXPECT_FALSE(IsAsciiDigit('.')); EXPECT_FALSE(IsAsciiDigit('a')); } TEST(IsAsciiDigitTest, IsTrueForDigit) { EXPECT_TRUE(IsAsciiDigit('0')); EXPECT_TRUE(IsAsciiDigit('1')); EXPECT_TRUE(IsAsciiDigit('5')); EXPECT_TRUE(IsAsciiDigit('9')); } TEST(IsAsciiPunctTest, IsFalseForNonPunct) { EXPECT_FALSE(IsAsciiPunct('\0')); EXPECT_FALSE(IsAsciiPunct(' ')); EXPECT_FALSE(IsAsciiPunct('\n')); EXPECT_FALSE(IsAsciiPunct('a')); EXPECT_FALSE(IsAsciiPunct('0')); } TEST(IsAsciiPunctTest, IsTrueForPunct) { for (const char* p = "^-!\"#$%&'()*+,./:;<=>?@[\\]_`{|}~"; *p; p++) { EXPECT_PRED1(IsAsciiPunct, *p); } } TEST(IsRepeatTest, IsFalseForNonRepeatChar) { EXPECT_FALSE(IsRepeat('\0')); EXPECT_FALSE(IsRepeat(' ')); EXPECT_FALSE(IsRepeat('a')); EXPECT_FALSE(IsRepeat('1')); EXPECT_FALSE(IsRepeat('-')); } TEST(IsRepeatTest, IsTrueForRepeatChar) { EXPECT_TRUE(IsRepeat('?')); EXPECT_TRUE(IsRepeat('*')); EXPECT_TRUE(IsRepeat('+')); } TEST(IsAsciiWhiteSpaceTest, IsFalseForNonWhiteSpace) { EXPECT_FALSE(IsAsciiWhiteSpace('\0')); EXPECT_FALSE(IsAsciiWhiteSpace('a')); EXPECT_FALSE(IsAsciiWhiteSpace('1')); EXPECT_FALSE(IsAsciiWhiteSpace('+')); EXPECT_FALSE(IsAsciiWhiteSpace('_')); } TEST(IsAsciiWhiteSpaceTest, IsTrueForWhiteSpace) { EXPECT_TRUE(IsAsciiWhiteSpace(' ')); EXPECT_TRUE(IsAsciiWhiteSpace('\n')); EXPECT_TRUE(IsAsciiWhiteSpace('\r')); EXPECT_TRUE(IsAsciiWhiteSpace('\t')); EXPECT_TRUE(IsAsciiWhiteSpace('\v')); EXPECT_TRUE(IsAsciiWhiteSpace('\f')); } TEST(IsAsciiWordCharTest, IsFalseForNonWordChar) { EXPECT_FALSE(IsAsciiWordChar('\0')); EXPECT_FALSE(IsAsciiWordChar('+')); EXPECT_FALSE(IsAsciiWordChar('.')); EXPECT_FALSE(IsAsciiWordChar(' ')); EXPECT_FALSE(IsAsciiWordChar('\n')); } TEST(IsAsciiWordCharTest, IsTrueForLetter) { EXPECT_TRUE(IsAsciiWordChar('a')); EXPECT_TRUE(IsAsciiWordChar('b')); EXPECT_TRUE(IsAsciiWordChar('A')); EXPECT_TRUE(IsAsciiWordChar('Z')); } TEST(IsAsciiWordCharTest, IsTrueForDigit) { EXPECT_TRUE(IsAsciiWordChar('0')); EXPECT_TRUE(IsAsciiWordChar('1')); EXPECT_TRUE(IsAsciiWordChar('7')); EXPECT_TRUE(IsAsciiWordChar('9')); } TEST(IsAsciiWordCharTest, IsTrueForUnderscore) { EXPECT_TRUE(IsAsciiWordChar('_')); } TEST(IsValidEscapeTest, IsFalseForNonPrintable) { EXPECT_FALSE(IsValidEscape('\0')); EXPECT_FALSE(IsValidEscape('\007')); } TEST(IsValidEscapeTest, IsFalseForDigit) { EXPECT_FALSE(IsValidEscape('0')); EXPECT_FALSE(IsValidEscape('9')); } TEST(IsValidEscapeTest, IsFalseForWhiteSpace) { EXPECT_FALSE(IsValidEscape(' ')); EXPECT_FALSE(IsValidEscape('\n')); } TEST(IsValidEscapeTest, IsFalseForSomeLetter) { EXPECT_FALSE(IsValidEscape('a')); EXPECT_FALSE(IsValidEscape('Z')); } TEST(IsValidEscapeTest, IsTrueForPunct) { EXPECT_TRUE(IsValidEscape('.')); EXPECT_TRUE(IsValidEscape('-')); EXPECT_TRUE(IsValidEscape('^')); EXPECT_TRUE(IsValidEscape('$')); EXPECT_TRUE(IsValidEscape('(')); EXPECT_TRUE(IsValidEscape(']')); EXPECT_TRUE(IsValidEscape('{')); EXPECT_TRUE(IsValidEscape('|')); } TEST(IsValidEscapeTest, IsTrueForSomeLetter) { EXPECT_TRUE(IsValidEscape('d')); EXPECT_TRUE(IsValidEscape('D')); EXPECT_TRUE(IsValidEscape('s')); EXPECT_TRUE(IsValidEscape('S')); EXPECT_TRUE(IsValidEscape('w')); EXPECT_TRUE(IsValidEscape('W')); } TEST(AtomMatchesCharTest, EscapedPunct) { EXPECT_FALSE(AtomMatchesChar(true, '\\', '\0')); EXPECT_FALSE(AtomMatchesChar(true, '\\', ' ')); EXPECT_FALSE(AtomMatchesChar(true, '_', '.')); EXPECT_FALSE(AtomMatchesChar(true, '.', 'a')); EXPECT_TRUE(AtomMatchesChar(true, '\\', '\\')); EXPECT_TRUE(AtomMatchesChar(true, '_', '_')); EXPECT_TRUE(AtomMatchesChar(true, '+', '+')); EXPECT_TRUE(AtomMatchesChar(true, '.', '.')); } TEST(AtomMatchesCharTest, Escaped_d) { EXPECT_FALSE(AtomMatchesChar(true, 'd', '\0')); EXPECT_FALSE(AtomMatchesChar(true, 'd', 'a')); EXPECT_FALSE(AtomMatchesChar(true, 'd', '.')); EXPECT_TRUE(AtomMatchesChar(true, 'd', '0')); EXPECT_TRUE(AtomMatchesChar(true, 'd', '9')); } TEST(AtomMatchesCharTest, Escaped_D) { EXPECT_FALSE(AtomMatchesChar(true, 'D', '0')); EXPECT_FALSE(AtomMatchesChar(true, 'D', '9')); EXPECT_TRUE(AtomMatchesChar(true, 'D', '\0')); EXPECT_TRUE(AtomMatchesChar(true, 'D', 'a')); EXPECT_TRUE(AtomMatchesChar(true, 'D', '-')); } TEST(AtomMatchesCharTest, Escaped_s) { EXPECT_FALSE(AtomMatchesChar(true, 's', '\0')); EXPECT_FALSE(AtomMatchesChar(true, 's', 'a')); EXPECT_FALSE(AtomMatchesChar(true, 's', '.')); EXPECT_FALSE(AtomMatchesChar(true, 's', '9')); EXPECT_TRUE(AtomMatchesChar(true, 's', ' ')); EXPECT_TRUE(AtomMatchesChar(true, 's', '\n')); EXPECT_TRUE(AtomMatchesChar(true, 's', '\t')); } TEST(AtomMatchesCharTest, Escaped_S) { EXPECT_FALSE(AtomMatchesChar(true, 'S', ' ')); EXPECT_FALSE(AtomMatchesChar(true, 'S', '\r')); EXPECT_TRUE(AtomMatchesChar(true, 'S', '\0')); EXPECT_TRUE(AtomMatchesChar(true, 'S', 'a')); EXPECT_TRUE(AtomMatchesChar(true, 'S', '9')); } TEST(AtomMatchesCharTest, Escaped_w) { EXPECT_FALSE(AtomMatchesChar(true, 'w', '\0')); EXPECT_FALSE(AtomMatchesChar(true, 'w', '+')); EXPECT_FALSE(AtomMatchesChar(true, 'w', ' ')); EXPECT_FALSE(AtomMatchesChar(true, 'w', '\n')); EXPECT_TRUE(AtomMatchesChar(true, 'w', '0')); EXPECT_TRUE(AtomMatchesChar(true, 'w', 'b')); EXPECT_TRUE(AtomMatchesChar(true, 'w', 'C')); EXPECT_TRUE(AtomMatchesChar(true, 'w', '_')); } TEST(AtomMatchesCharTest, Escaped_W) { EXPECT_FALSE(AtomMatchesChar(true, 'W', 'A')); EXPECT_FALSE(AtomMatchesChar(true, 'W', 'b')); EXPECT_FALSE(AtomMatchesChar(true, 'W', '9')); EXPECT_FALSE(AtomMatchesChar(true, 'W', '_')); EXPECT_TRUE(AtomMatchesChar(true, 'W', '\0')); EXPECT_TRUE(AtomMatchesChar(true, 'W', '*')); EXPECT_TRUE(AtomMatchesChar(true, 'W', '\n')); } TEST(AtomMatchesCharTest, EscapedWhiteSpace) { EXPECT_FALSE(AtomMatchesChar(true, 'f', '\0')); EXPECT_FALSE(AtomMatchesChar(true, 'f', '\n')); EXPECT_FALSE(AtomMatchesChar(true, 'n', '\0')); EXPECT_FALSE(AtomMatchesChar(true, 'n', '\r')); EXPECT_FALSE(AtomMatchesChar(true, 'r', '\0')); EXPECT_FALSE(AtomMatchesChar(true, 'r', 'a')); EXPECT_FALSE(AtomMatchesChar(true, 't', '\0')); EXPECT_FALSE(AtomMatchesChar(true, 't', 't')); EXPECT_FALSE(AtomMatchesChar(true, 'v', '\0')); EXPECT_FALSE(AtomMatchesChar(true, 'v', '\f')); EXPECT_TRUE(AtomMatchesChar(true, 'f', '\f')); EXPECT_TRUE(AtomMatchesChar(true, 'n', '\n')); EXPECT_TRUE(AtomMatchesChar(true, 'r', '\r')); EXPECT_TRUE(AtomMatchesChar(true, 't', '\t')); EXPECT_TRUE(AtomMatchesChar(true, 'v', '\v')); } TEST(AtomMatchesCharTest, UnescapedDot) { EXPECT_FALSE(AtomMatchesChar(false, '.', '\n')); EXPECT_TRUE(AtomMatchesChar(false, '.', '\0')); EXPECT_TRUE(AtomMatchesChar(false, '.', '.')); EXPECT_TRUE(AtomMatchesChar(false, '.', 'a')); EXPECT_TRUE(AtomMatchesChar(false, '.', ' ')); } TEST(AtomMatchesCharTest, UnescapedChar) { EXPECT_FALSE(AtomMatchesChar(false, 'a', '\0')); EXPECT_FALSE(AtomMatchesChar(false, 'a', 'b')); EXPECT_FALSE(AtomMatchesChar(false, '$', 'a')); EXPECT_TRUE(AtomMatchesChar(false, '$', '$')); EXPECT_TRUE(AtomMatchesChar(false, '5', '5')); EXPECT_TRUE(AtomMatchesChar(false, 'Z', 'Z')); } TEST(ValidateRegexTest, GeneratesFailureAndReturnsFalseForInvalid) { EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex(NULL)), "NULL is not a valid simple regular expression"); EXPECT_NONFATAL_FAILURE( ASSERT_FALSE(ValidateRegex("a\\")), "Syntax error at index 1 in simple regular expression \"a\\\": "); EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("a\\")), "'\\' cannot appear at the end"); EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("\\n\\")), "'\\' cannot appear at the end"); EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("\\s\\hb")), "invalid escape sequence \"\\h\""); EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("^^")), "'^' can only appear at the beginning"); EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex(".*^b")), "'^' can only appear at the beginning"); EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("$$")), "'$' can only appear at the end"); EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("^$a")), "'$' can only appear at the end"); EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("a(b")), "'(' is unsupported"); EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("ab)")), "')' is unsupported"); EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("[ab")), "'[' is unsupported"); EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("a{2")), "'{' is unsupported"); EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("?")), "'?' can only follow a repeatable token"); EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("^*")), "'*' can only follow a repeatable token"); EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("5*+")), "'+' can only follow a repeatable token"); } TEST(ValidateRegexTest, ReturnsTrueForValid) { EXPECT_TRUE(ValidateRegex("")); EXPECT_TRUE(ValidateRegex("a")); EXPECT_TRUE(ValidateRegex(".*")); EXPECT_TRUE(ValidateRegex("^a_+")); EXPECT_TRUE(ValidateRegex("^a\\t\\&?")); EXPECT_TRUE(ValidateRegex("09*$")); EXPECT_TRUE(ValidateRegex("^Z$")); EXPECT_TRUE(ValidateRegex("a\\^Z\\$\\(\\)\\|\\[\\]\\{\\}")); } TEST(MatchRepetitionAndRegexAtHeadTest, WorksForZeroOrOne) { EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, 'a', '?', "a", "ba")); // Repeating more than once. EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, 'a', '?', "b", "aab")); // Repeating zero times. EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, 'a', '?', "b", "ba")); // Repeating once. EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, 'a', '?', "b", "ab")); EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, '#', '?', ".", "##")); } TEST(MatchRepetitionAndRegexAtHeadTest, WorksForZeroOrMany) { EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, '.', '*', "a$", "baab")); // Repeating zero times. EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, '.', '*', "b", "bc")); // Repeating once. EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, '.', '*', "b", "abc")); // Repeating more than once. EXPECT_TRUE(MatchRepetitionAndRegexAtHead(true, 'w', '*', "-", "ab_1-g")); } TEST(MatchRepetitionAndRegexAtHeadTest, WorksForOneOrMany) { EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, '.', '+', "a$", "baab")); // Repeating zero times. EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, '.', '+', "b", "bc")); // Repeating once. EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, '.', '+', "b", "abc")); // Repeating more than once. EXPECT_TRUE(MatchRepetitionAndRegexAtHead(true, 'w', '+', "-", "ab_1-g")); } TEST(MatchRegexAtHeadTest, ReturnsTrueForEmptyRegex) { EXPECT_TRUE(MatchRegexAtHead("", "")); EXPECT_TRUE(MatchRegexAtHead("", "ab")); } TEST(MatchRegexAtHeadTest, WorksWhenDollarIsInRegex) { EXPECT_FALSE(MatchRegexAtHead("$", "a")); EXPECT_TRUE(MatchRegexAtHead("$", "")); EXPECT_TRUE(MatchRegexAtHead("a$", "a")); } TEST(MatchRegexAtHeadTest, WorksWhenRegexStartsWithEscapeSequence) { EXPECT_FALSE(MatchRegexAtHead("\\w", "+")); EXPECT_FALSE(MatchRegexAtHead("\\W", "ab")); EXPECT_TRUE(MatchRegexAtHead("\\sa", "\nab")); EXPECT_TRUE(MatchRegexAtHead("\\d", "1a")); } TEST(MatchRegexAtHeadTest, WorksWhenRegexStartsWithRepetition) { EXPECT_FALSE(MatchRegexAtHead(".+a", "abc")); EXPECT_FALSE(MatchRegexAtHead("a?b", "aab")); EXPECT_TRUE(MatchRegexAtHead(".*a", "bc12-ab")); EXPECT_TRUE(MatchRegexAtHead("a?b", "b")); EXPECT_TRUE(MatchRegexAtHead("a?b", "ab")); } TEST(MatchRegexAtHeadTest, WorksWhenRegexStartsWithRepetionOfEscapeSequence) { EXPECT_FALSE(MatchRegexAtHead("\\.+a", "abc")); EXPECT_FALSE(MatchRegexAtHead("\\s?b", " b")); EXPECT_TRUE(MatchRegexAtHead("\\(*a", "((((ab")); EXPECT_TRUE(MatchRegexAtHead("\\^?b", "^b")); EXPECT_TRUE(MatchRegexAtHead("\\\\?b", "b")); EXPECT_TRUE(MatchRegexAtHead("\\\\?b", "\\b")); } TEST(MatchRegexAtHeadTest, MatchesSequentially) { EXPECT_FALSE(MatchRegexAtHead("ab.*c", "acabc")); EXPECT_TRUE(MatchRegexAtHead("ab.*c", "ab-fsc")); } TEST(MatchRegexAnywhereTest, ReturnsFalseWhenStringIsNull) { EXPECT_FALSE(MatchRegexAnywhere("", NULL)); } TEST(MatchRegexAnywhereTest, WorksWhenRegexStartsWithCaret) { EXPECT_FALSE(MatchRegexAnywhere("^a", "ba")); EXPECT_FALSE(MatchRegexAnywhere("^$", "a")); EXPECT_TRUE(MatchRegexAnywhere("^a", "ab")); EXPECT_TRUE(MatchRegexAnywhere("^", "ab")); EXPECT_TRUE(MatchRegexAnywhere("^$", "")); } TEST(MatchRegexAnywhereTest, ReturnsFalseWhenNoMatch) { EXPECT_FALSE(MatchRegexAnywhere("a", "bcde123")); EXPECT_FALSE(MatchRegexAnywhere("a.+a", "--aa88888888")); } TEST(MatchRegexAnywhereTest, ReturnsTrueWhenMatchingPrefix) { EXPECT_TRUE(MatchRegexAnywhere("\\w+", "ab1_ - 5")); EXPECT_TRUE(MatchRegexAnywhere(".*=", "=")); EXPECT_TRUE(MatchRegexAnywhere("x.*ab?.*bc", "xaaabc")); } TEST(MatchRegexAnywhereTest, ReturnsTrueWhenMatchingNonPrefix) { EXPECT_TRUE(MatchRegexAnywhere("\\w+", "$$$ ab1_ - 5")); EXPECT_TRUE(MatchRegexAnywhere("\\.+=", "= ...=")); } // Tests RE's implicit constructors. TEST(RETest, ImplicitConstructorWorks) { const RE empty(""); EXPECT_STREQ("", empty.pattern()); const RE simple("hello"); EXPECT_STREQ("hello", simple.pattern()); } // Tests that RE's constructors reject invalid regular expressions. TEST(RETest, RejectsInvalidRegex) { EXPECT_NONFATAL_FAILURE({ const RE normal(NULL); }, "NULL is not a valid simple regular expression"); EXPECT_NONFATAL_FAILURE({ const RE normal(".*(\\w+"); }, "'(' is unsupported"); EXPECT_NONFATAL_FAILURE({ const RE invalid("^?"); }, "'?' can only follow a repeatable token"); } // Tests RE::FullMatch(). TEST(RETest, FullMatchWorks) { const RE empty(""); EXPECT_TRUE(RE::FullMatch("", empty)); EXPECT_FALSE(RE::FullMatch("a", empty)); const RE re1("a"); EXPECT_TRUE(RE::FullMatch("a", re1)); const RE re("a.*z"); EXPECT_TRUE(RE::FullMatch("az", re)); EXPECT_TRUE(RE::FullMatch("axyz", re)); EXPECT_FALSE(RE::FullMatch("baz", re)); EXPECT_FALSE(RE::FullMatch("azy", re)); } // Tests RE::PartialMatch(). TEST(RETest, PartialMatchWorks) { const RE empty(""); EXPECT_TRUE(RE::PartialMatch("", empty)); EXPECT_TRUE(RE::PartialMatch("a", empty)); const RE re("a.*z"); EXPECT_TRUE(RE::PartialMatch("az", re)); EXPECT_TRUE(RE::PartialMatch("axyz", re)); EXPECT_TRUE(RE::PartialMatch("baz", re)); EXPECT_TRUE(RE::PartialMatch("azy", re)); EXPECT_FALSE(RE::PartialMatch("zza", re)); } #endif // GTEST_USES_POSIX_RE #if !GTEST_OS_WINDOWS_MOBILE TEST(CaptureTest, CapturesStdout) { CaptureStdout(); fprintf(stdout, "abc"); EXPECT_STREQ("abc", GetCapturedStdout().c_str()); CaptureStdout(); fprintf(stdout, "def%cghi", '\0'); EXPECT_EQ(::std::string("def\0ghi", 7), ::std::string(GetCapturedStdout())); } TEST(CaptureTest, CapturesStderr) { CaptureStderr(); fprintf(stderr, "jkl"); EXPECT_STREQ("jkl", GetCapturedStderr().c_str()); CaptureStderr(); fprintf(stderr, "jkl%cmno", '\0'); EXPECT_EQ(::std::string("jkl\0mno", 7), ::std::string(GetCapturedStderr())); } // Tests that stdout and stderr capture don't interfere with each other. TEST(CaptureTest, CapturesStdoutAndStderr) { CaptureStdout(); CaptureStderr(); fprintf(stdout, "pqr"); fprintf(stderr, "stu"); EXPECT_STREQ("pqr", GetCapturedStdout().c_str()); EXPECT_STREQ("stu", GetCapturedStderr().c_str()); } TEST(CaptureDeathTest, CannotReenterStdoutCapture) { CaptureStdout(); EXPECT_DEATH_IF_SUPPORTED(CaptureStdout(), "Only one stdout capturer can exist at a time"); GetCapturedStdout(); // We cannot test stderr capturing using death tests as they use it // themselves. } #endif // !GTEST_OS_WINDOWS_MOBILE TEST(ThreadLocalTest, DefaultConstructorInitializesToDefaultValues) { ThreadLocal t1; EXPECT_EQ(0, t1.get()); ThreadLocal t2; EXPECT_TRUE(t2.get() == NULL); } TEST(ThreadLocalTest, SingleParamConstructorInitializesToParam) { ThreadLocal t1(123); EXPECT_EQ(123, t1.get()); int i = 0; ThreadLocal t2(&i); EXPECT_EQ(&i, t2.get()); } class NoDefaultContructor { public: explicit NoDefaultContructor(const char*) {} NoDefaultContructor(const NoDefaultContructor&) {} }; TEST(ThreadLocalTest, ValueDefaultContructorIsNotRequiredForParamVersion) { ThreadLocal bar(NoDefaultContructor("foo")); bar.pointer(); } TEST(ThreadLocalTest, GetAndPointerReturnSameValue) { ThreadLocal thread_local_string; EXPECT_EQ(thread_local_string.pointer(), &(thread_local_string.get())); // Verifies the condition still holds after calling set. thread_local_string.set("foo"); EXPECT_EQ(thread_local_string.pointer(), &(thread_local_string.get())); } TEST(ThreadLocalTest, PointerAndConstPointerReturnSameValue) { ThreadLocal thread_local_string; const ThreadLocal& const_thread_local_string = thread_local_string; EXPECT_EQ(thread_local_string.pointer(), const_thread_local_string.pointer()); thread_local_string.set("foo"); EXPECT_EQ(thread_local_string.pointer(), const_thread_local_string.pointer()); } #if GTEST_IS_THREADSAFE void AddTwo(int* param) { *param += 2; } TEST(ThreadWithParamTest, ConstructorExecutesThreadFunc) { int i = 40; ThreadWithParam thread(&AddTwo, &i, NULL); thread.Join(); EXPECT_EQ(42, i); } TEST(MutexDeathTest, AssertHeldShouldAssertWhenNotLocked) { // AssertHeld() is flaky only in the presence of multiple threads accessing // the lock. In this case, the test is robust. EXPECT_DEATH_IF_SUPPORTED({ Mutex m; { MutexLock lock(&m); } m.AssertHeld(); }, "thread .*hold"); } TEST(MutexTest, AssertHeldShouldNotAssertWhenLocked) { Mutex m; MutexLock lock(&m); m.AssertHeld(); } class AtomicCounterWithMutex { public: explicit AtomicCounterWithMutex(Mutex* mutex) : value_(0), mutex_(mutex), random_(42) {} void Increment() { MutexLock lock(mutex_); int temp = value_; { // We need to put up a memory barrier to prevent reads and writes to // value_ rearranged with the call to SleepMilliseconds when observed // from other threads. #if GTEST_HAS_PTHREAD // On POSIX, locking a mutex puts up a memory barrier. We cannot use // Mutex and MutexLock here or rely on their memory barrier // functionality as we are testing them here. pthread_mutex_t memory_barrier_mutex; GTEST_CHECK_POSIX_SUCCESS_( pthread_mutex_init(&memory_barrier_mutex, NULL)); GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&memory_barrier_mutex)); SleepMilliseconds(random_.Generate(30)); GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_unlock(&memory_barrier_mutex)); GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_destroy(&memory_barrier_mutex)); #elif GTEST_OS_WINDOWS // On Windows, performing an interlocked access puts up a memory barrier. volatile LONG dummy = 0; ::InterlockedIncrement(&dummy); SleepMilliseconds(random_.Generate(30)); ::InterlockedIncrement(&dummy); #else # error "Memory barrier not implemented on this platform." #endif // GTEST_HAS_PTHREAD } value_ = temp + 1; } int value() const { return value_; } private: volatile int value_; Mutex* const mutex_; // Protects value_. Random random_; }; void CountingThreadFunc(pair param) { for (int i = 0; i < param.second; ++i) param.first->Increment(); } // Tests that the mutex only lets one thread at a time to lock it. TEST(MutexTest, OnlyOneThreadCanLockAtATime) { Mutex mutex; AtomicCounterWithMutex locked_counter(&mutex); typedef ThreadWithParam > ThreadType; const int kCycleCount = 20; const int kThreadCount = 7; scoped_ptr counting_threads[kThreadCount]; Notification threads_can_start; // Creates and runs kThreadCount threads that increment locked_counter // kCycleCount times each. for (int i = 0; i < kThreadCount; ++i) { counting_threads[i].reset(new ThreadType(&CountingThreadFunc, make_pair(&locked_counter, kCycleCount), &threads_can_start)); } threads_can_start.Notify(); for (int i = 0; i < kThreadCount; ++i) counting_threads[i]->Join(); // If the mutex lets more than one thread to increment the counter at a // time, they are likely to encounter a race condition and have some // increments overwritten, resulting in the lower then expected counter // value. EXPECT_EQ(kCycleCount * kThreadCount, locked_counter.value()); } template void RunFromThread(void (func)(T), T param) { ThreadWithParam thread(func, param, NULL); thread.Join(); } void RetrieveThreadLocalValue( pair*, std::string*> param) { *param.second = param.first->get(); } TEST(ThreadLocalTest, ParameterizedConstructorSetsDefault) { ThreadLocal thread_local_string("foo"); EXPECT_STREQ("foo", thread_local_string.get().c_str()); thread_local_string.set("bar"); EXPECT_STREQ("bar", thread_local_string.get().c_str()); std::string result; RunFromThread(&RetrieveThreadLocalValue, make_pair(&thread_local_string, &result)); EXPECT_STREQ("foo", result.c_str()); } // Keeps track of whether of destructors being called on instances of // DestructorTracker. On Windows, waits for the destructor call reports. class DestructorCall { public: DestructorCall() { invoked_ = false; #if GTEST_OS_WINDOWS wait_event_.Reset(::CreateEvent(NULL, TRUE, FALSE, NULL)); GTEST_CHECK_(wait_event_.Get() != NULL); #endif } bool CheckDestroyed() const { #if GTEST_OS_WINDOWS if (::WaitForSingleObject(wait_event_.Get(), 1000) != WAIT_OBJECT_0) return false; #endif return invoked_; } void ReportDestroyed() { invoked_ = true; #if GTEST_OS_WINDOWS ::SetEvent(wait_event_.Get()); #endif } static std::vector& List() { return *list_; } static void ResetList() { for (size_t i = 0; i < list_->size(); ++i) { delete list_->at(i); } list_->clear(); } private: bool invoked_; #if GTEST_OS_WINDOWS AutoHandle wait_event_; #endif static std::vector* const list_; GTEST_DISALLOW_COPY_AND_ASSIGN_(DestructorCall); }; std::vector* const DestructorCall::list_ = new std::vector; // DestructorTracker keeps track of whether its instances have been // destroyed. class DestructorTracker { public: DestructorTracker() : index_(GetNewIndex()) {} DestructorTracker(const DestructorTracker& /* rhs */) : index_(GetNewIndex()) {} ~DestructorTracker() { // We never access DestructorCall::List() concurrently, so we don't need // to protect this access with a mutex. DestructorCall::List()[index_]->ReportDestroyed(); } private: static size_t GetNewIndex() { DestructorCall::List().push_back(new DestructorCall); return DestructorCall::List().size() - 1; } const size_t index_; GTEST_DISALLOW_ASSIGN_(DestructorTracker); }; typedef ThreadLocal* ThreadParam; void CallThreadLocalGet(ThreadParam thread_local_param) { thread_local_param->get(); } // Tests that when a ThreadLocal object dies in a thread, it destroys // the managed object for that thread. TEST(ThreadLocalTest, DestroysManagedObjectForOwnThreadWhenDying) { DestructorCall::ResetList(); { ThreadLocal thread_local_tracker; ASSERT_EQ(0U, DestructorCall::List().size()); // This creates another DestructorTracker object for the main thread. thread_local_tracker.get(); ASSERT_EQ(1U, DestructorCall::List().size()); ASSERT_FALSE(DestructorCall::List()[0]->CheckDestroyed()); } // Now thread_local_tracker has died. ASSERT_EQ(1U, DestructorCall::List().size()); EXPECT_TRUE(DestructorCall::List()[0]->CheckDestroyed()); DestructorCall::ResetList(); } // Tests that when a thread exits, the thread-local object for that // thread is destroyed. TEST(ThreadLocalTest, DestroysManagedObjectAtThreadExit) { DestructorCall::ResetList(); { ThreadLocal thread_local_tracker; ASSERT_EQ(0U, DestructorCall::List().size()); // This creates another DestructorTracker object in the new thread. ThreadWithParam thread( &CallThreadLocalGet, &thread_local_tracker, NULL); thread.Join(); // The thread has exited, and we should have a DestroyedTracker // instance created for it. But it may not have been destroyed yet. ASSERT_EQ(1U, DestructorCall::List().size()); } // The thread has exited and thread_local_tracker has died. ASSERT_EQ(1U, DestructorCall::List().size()); EXPECT_TRUE(DestructorCall::List()[0]->CheckDestroyed()); DestructorCall::ResetList(); } TEST(ThreadLocalTest, ThreadLocalMutationsAffectOnlyCurrentThread) { ThreadLocal thread_local_string; thread_local_string.set("Foo"); EXPECT_STREQ("Foo", thread_local_string.get().c_str()); std::string result; RunFromThread(&RetrieveThreadLocalValue, make_pair(&thread_local_string, &result)); EXPECT_TRUE(result.empty()); } #endif // GTEST_IS_THREADSAFE #if GTEST_OS_WINDOWS TEST(WindowsTypesTest, HANDLEIsVoidStar) { StaticAssertTypeEq(); } #if GTEST_OS_WINDOWS_MINGW && !defined(__MINGW64_VERSION_MAJOR) TEST(WindowsTypesTest, _CRITICAL_SECTIONIs_CRITICAL_SECTION) { StaticAssertTypeEq(); } #else TEST(WindowsTypesTest, CRITICAL_SECTIONIs_RTL_CRITICAL_SECTION) { StaticAssertTypeEq(); } #endif #endif // GTEST_OS_WINDOWS } // namespace internal } // namespace testing