michael@0: // Copyright 2005, Google Inc. michael@0: // All rights reserved. michael@0: // michael@0: // Redistribution and use in source and binary forms, with or without michael@0: // modification, are permitted provided that the following conditions are michael@0: // met: michael@0: // michael@0: // * Redistributions of source code must retain the above copyright michael@0: // notice, this list of conditions and the following disclaimer. michael@0: // * Redistributions in binary form must reproduce the above michael@0: // copyright notice, this list of conditions and the following disclaimer michael@0: // in the documentation and/or other materials provided with the michael@0: // distribution. michael@0: // * Neither the name of Google Inc. nor the names of its michael@0: // contributors may be used to endorse or promote products derived from michael@0: // this software without specific prior written permission. michael@0: // michael@0: // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS michael@0: // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT michael@0: // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR michael@0: // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT michael@0: // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, michael@0: // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT michael@0: // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, michael@0: // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY michael@0: // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT michael@0: // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE michael@0: // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. michael@0: michael@0: // Utility functions and classes used by the Google C++ testing framework. michael@0: // michael@0: // Author: wan@google.com (Zhanyong Wan) michael@0: // michael@0: // This file contains purely Google Test's internal implementation. Please michael@0: // DO NOT #INCLUDE IT IN A USER PROGRAM. michael@0: michael@0: #ifndef GTEST_SRC_GTEST_INTERNAL_INL_H_ michael@0: #define GTEST_SRC_GTEST_INTERNAL_INL_H_ michael@0: michael@0: // GTEST_IMPLEMENTATION_ is defined to 1 iff the current translation unit is michael@0: // part of Google Test's implementation; otherwise it's undefined. michael@0: #if !GTEST_IMPLEMENTATION_ michael@0: // A user is trying to include this from his code - just say no. michael@0: # error "gtest-internal-inl.h is part of Google Test's internal implementation." michael@0: # error "It must not be included except by Google Test itself." michael@0: #endif // GTEST_IMPLEMENTATION_ michael@0: michael@0: #ifndef _WIN32_WCE michael@0: # include michael@0: #endif // !_WIN32_WCE michael@0: #include michael@0: #include // For strtoll/_strtoul64/malloc/free. michael@0: #include // For memmove. michael@0: michael@0: #include michael@0: #include michael@0: #include michael@0: michael@0: #include "gtest/internal/gtest-port.h" michael@0: michael@0: #if GTEST_OS_WINDOWS michael@0: # include // NOLINT michael@0: #endif // GTEST_OS_WINDOWS michael@0: michael@0: #include "gtest/gtest.h" // NOLINT michael@0: #include "gtest/gtest-spi.h" michael@0: michael@0: namespace testing { michael@0: michael@0: // Declares the flags. michael@0: // michael@0: // We don't want the users to modify this flag in the code, but want michael@0: // Google Test's own unit tests to be able to access it. Therefore we michael@0: // declare it here as opposed to in gtest.h. michael@0: GTEST_DECLARE_bool_(death_test_use_fork); michael@0: michael@0: namespace internal { michael@0: michael@0: // The value of GetTestTypeId() as seen from within the Google Test michael@0: // library. This is solely for testing GetTestTypeId(). michael@0: GTEST_API_ extern const TypeId kTestTypeIdInGoogleTest; michael@0: michael@0: // Names of the flags (needed for parsing Google Test flags). michael@0: const char kAlsoRunDisabledTestsFlag[] = "also_run_disabled_tests"; michael@0: const char kBreakOnFailureFlag[] = "break_on_failure"; michael@0: const char kCatchExceptionsFlag[] = "catch_exceptions"; michael@0: const char kColorFlag[] = "color"; michael@0: const char kFilterFlag[] = "filter"; michael@0: const char kListTestsFlag[] = "list_tests"; michael@0: const char kOutputFlag[] = "output"; michael@0: const char kPrintTimeFlag[] = "print_time"; michael@0: const char kRandomSeedFlag[] = "random_seed"; michael@0: const char kRepeatFlag[] = "repeat"; michael@0: const char kShuffleFlag[] = "shuffle"; michael@0: const char kStackTraceDepthFlag[] = "stack_trace_depth"; michael@0: const char kStreamResultToFlag[] = "stream_result_to"; michael@0: const char kThrowOnFailureFlag[] = "throw_on_failure"; michael@0: michael@0: // A valid random seed must be in [1, kMaxRandomSeed]. michael@0: const int kMaxRandomSeed = 99999; michael@0: michael@0: // g_help_flag is true iff the --help flag or an equivalent form is michael@0: // specified on the command line. michael@0: GTEST_API_ extern bool g_help_flag; michael@0: michael@0: // Returns the current time in milliseconds. michael@0: GTEST_API_ TimeInMillis GetTimeInMillis(); michael@0: michael@0: // Returns true iff Google Test should use colors in the output. michael@0: GTEST_API_ bool ShouldUseColor(bool stdout_is_tty); michael@0: michael@0: // Formats the given time in milliseconds as seconds. michael@0: GTEST_API_ std::string FormatTimeInMillisAsSeconds(TimeInMillis ms); michael@0: michael@0: // Converts the given time in milliseconds to a date string in the ISO 8601 michael@0: // format, without the timezone information. N.B.: due to the use the michael@0: // non-reentrant localtime() function, this function is not thread safe. Do michael@0: // not use it in any code that can be called from multiple threads. michael@0: GTEST_API_ std::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms); michael@0: michael@0: // Parses a string for an Int32 flag, in the form of "--flag=value". michael@0: // michael@0: // On success, stores the value of the flag in *value, and returns michael@0: // true. On failure, returns false without changing *value. michael@0: GTEST_API_ bool ParseInt32Flag( michael@0: const char* str, const char* flag, Int32* value); michael@0: michael@0: // Returns a random seed in range [1, kMaxRandomSeed] based on the michael@0: // given --gtest_random_seed flag value. michael@0: inline int GetRandomSeedFromFlag(Int32 random_seed_flag) { michael@0: const unsigned int raw_seed = (random_seed_flag == 0) ? michael@0: static_cast(GetTimeInMillis()) : michael@0: static_cast(random_seed_flag); michael@0: michael@0: // Normalizes the actual seed to range [1, kMaxRandomSeed] such that michael@0: // it's easy to type. michael@0: const int normalized_seed = michael@0: static_cast((raw_seed - 1U) % michael@0: static_cast(kMaxRandomSeed)) + 1; michael@0: return normalized_seed; michael@0: } michael@0: michael@0: // Returns the first valid random seed after 'seed'. The behavior is michael@0: // undefined if 'seed' is invalid. The seed after kMaxRandomSeed is michael@0: // considered to be 1. michael@0: inline int GetNextRandomSeed(int seed) { michael@0: GTEST_CHECK_(1 <= seed && seed <= kMaxRandomSeed) michael@0: << "Invalid random seed " << seed << " - must be in [1, " michael@0: << kMaxRandomSeed << "]."; michael@0: const int next_seed = seed + 1; michael@0: return (next_seed > kMaxRandomSeed) ? 1 : next_seed; michael@0: } michael@0: michael@0: // This class saves the values of all Google Test flags in its c'tor, and michael@0: // restores them in its d'tor. michael@0: class GTestFlagSaver { michael@0: public: michael@0: // The c'tor. michael@0: GTestFlagSaver() { michael@0: also_run_disabled_tests_ = GTEST_FLAG(also_run_disabled_tests); michael@0: break_on_failure_ = GTEST_FLAG(break_on_failure); michael@0: catch_exceptions_ = GTEST_FLAG(catch_exceptions); michael@0: color_ = GTEST_FLAG(color); michael@0: death_test_style_ = GTEST_FLAG(death_test_style); michael@0: death_test_use_fork_ = GTEST_FLAG(death_test_use_fork); michael@0: filter_ = GTEST_FLAG(filter); michael@0: internal_run_death_test_ = GTEST_FLAG(internal_run_death_test); michael@0: list_tests_ = GTEST_FLAG(list_tests); michael@0: output_ = GTEST_FLAG(output); michael@0: print_time_ = GTEST_FLAG(print_time); michael@0: random_seed_ = GTEST_FLAG(random_seed); michael@0: repeat_ = GTEST_FLAG(repeat); michael@0: shuffle_ = GTEST_FLAG(shuffle); michael@0: stack_trace_depth_ = GTEST_FLAG(stack_trace_depth); michael@0: stream_result_to_ = GTEST_FLAG(stream_result_to); michael@0: throw_on_failure_ = GTEST_FLAG(throw_on_failure); michael@0: } michael@0: michael@0: // The d'tor is not virtual. DO NOT INHERIT FROM THIS CLASS. michael@0: ~GTestFlagSaver() { michael@0: GTEST_FLAG(also_run_disabled_tests) = also_run_disabled_tests_; michael@0: GTEST_FLAG(break_on_failure) = break_on_failure_; michael@0: GTEST_FLAG(catch_exceptions) = catch_exceptions_; michael@0: GTEST_FLAG(color) = color_; michael@0: GTEST_FLAG(death_test_style) = death_test_style_; michael@0: GTEST_FLAG(death_test_use_fork) = death_test_use_fork_; michael@0: GTEST_FLAG(filter) = filter_; michael@0: GTEST_FLAG(internal_run_death_test) = internal_run_death_test_; michael@0: GTEST_FLAG(list_tests) = list_tests_; michael@0: GTEST_FLAG(output) = output_; michael@0: GTEST_FLAG(print_time) = print_time_; michael@0: GTEST_FLAG(random_seed) = random_seed_; michael@0: GTEST_FLAG(repeat) = repeat_; michael@0: GTEST_FLAG(shuffle) = shuffle_; michael@0: GTEST_FLAG(stack_trace_depth) = stack_trace_depth_; michael@0: GTEST_FLAG(stream_result_to) = stream_result_to_; michael@0: GTEST_FLAG(throw_on_failure) = throw_on_failure_; michael@0: } michael@0: michael@0: private: michael@0: // Fields for saving the original values of flags. michael@0: bool also_run_disabled_tests_; michael@0: bool break_on_failure_; michael@0: bool catch_exceptions_; michael@0: String color_; michael@0: String death_test_style_; michael@0: bool death_test_use_fork_; michael@0: String filter_; michael@0: String internal_run_death_test_; michael@0: bool list_tests_; michael@0: String output_; michael@0: bool print_time_; michael@0: bool pretty_; michael@0: internal::Int32 random_seed_; michael@0: internal::Int32 repeat_; michael@0: bool shuffle_; michael@0: internal::Int32 stack_trace_depth_; michael@0: String stream_result_to_; michael@0: bool throw_on_failure_; michael@0: } GTEST_ATTRIBUTE_UNUSED_; michael@0: michael@0: // Converts a Unicode code point to a narrow string in UTF-8 encoding. michael@0: // code_point parameter is of type UInt32 because wchar_t may not be michael@0: // wide enough to contain a code point. michael@0: // The output buffer str must containt at least 32 characters. michael@0: // The function returns the address of the output buffer. michael@0: // If the code_point is not a valid Unicode code point michael@0: // (i.e. outside of Unicode range U+0 to U+10FFFF) it will be output michael@0: // as '(Invalid Unicode 0xXXXXXXXX)'. michael@0: GTEST_API_ char* CodePointToUtf8(UInt32 code_point, char* str); michael@0: michael@0: // Converts a wide string to a narrow string in UTF-8 encoding. michael@0: // The wide string is assumed to have the following encoding: michael@0: // UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin, Symbian OS) michael@0: // UTF-32 if sizeof(wchar_t) == 4 (on Linux) michael@0: // Parameter str points to a null-terminated wide string. michael@0: // Parameter num_chars may additionally limit the number michael@0: // of wchar_t characters processed. -1 is used when the entire string michael@0: // should be processed. michael@0: // If the string contains code points that are not valid Unicode code points michael@0: // (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output michael@0: // as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding michael@0: // and contains invalid UTF-16 surrogate pairs, values in those pairs michael@0: // will be encoded as individual Unicode characters from Basic Normal Plane. michael@0: GTEST_API_ String WideStringToUtf8(const wchar_t* str, int num_chars); michael@0: michael@0: // Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file michael@0: // if the variable is present. If a file already exists at this location, this michael@0: // function will write over it. If the variable is present, but the file cannot michael@0: // be created, prints an error and exits. michael@0: void WriteToShardStatusFileIfNeeded(); michael@0: michael@0: // Checks whether sharding is enabled by examining the relevant michael@0: // environment variable values. If the variables are present, michael@0: // but inconsistent (e.g., shard_index >= total_shards), prints michael@0: // an error and exits. If in_subprocess_for_death_test, sharding is michael@0: // disabled because it must only be applied to the original test michael@0: // process. Otherwise, we could filter out death tests we intended to execute. michael@0: GTEST_API_ bool ShouldShard(const char* total_shards_str, michael@0: const char* shard_index_str, michael@0: bool in_subprocess_for_death_test); michael@0: michael@0: // Parses the environment variable var as an Int32. If it is unset, michael@0: // returns default_val. If it is not an Int32, prints an error and michael@0: // and aborts. michael@0: GTEST_API_ Int32 Int32FromEnvOrDie(const char* env_var, Int32 default_val); michael@0: michael@0: // Given the total number of shards, the shard index, and the test id, michael@0: // returns true iff the test should be run on this shard. The test id is michael@0: // some arbitrary but unique non-negative integer assigned to each test michael@0: // method. Assumes that 0 <= shard_index < total_shards. michael@0: GTEST_API_ bool ShouldRunTestOnShard( michael@0: int total_shards, int shard_index, int test_id); michael@0: michael@0: // STL container utilities. michael@0: michael@0: // Returns the number of elements in the given container that satisfy michael@0: // the given predicate. michael@0: template michael@0: inline int CountIf(const Container& c, Predicate predicate) { michael@0: // Implemented as an explicit loop since std::count_if() in libCstd on michael@0: // Solaris has a non-standard signature. michael@0: int count = 0; michael@0: for (typename Container::const_iterator it = c.begin(); it != c.end(); ++it) { michael@0: if (predicate(*it)) michael@0: ++count; michael@0: } michael@0: return count; michael@0: } michael@0: michael@0: // Applies a function/functor to each element in the container. michael@0: template michael@0: void ForEach(const Container& c, Functor functor) { michael@0: std::for_each(c.begin(), c.end(), functor); michael@0: } michael@0: michael@0: // Returns the i-th element of the vector, or default_value if i is not michael@0: // in range [0, v.size()). michael@0: template michael@0: inline E GetElementOr(const std::vector& v, int i, E default_value) { michael@0: return (i < 0 || i >= static_cast(v.size())) ? default_value : v[i]; michael@0: } michael@0: michael@0: // Performs an in-place shuffle of a range of the vector's elements. michael@0: // 'begin' and 'end' are element indices as an STL-style range; michael@0: // i.e. [begin, end) are shuffled, where 'end' == size() means to michael@0: // shuffle to the end of the vector. michael@0: template michael@0: void ShuffleRange(internal::Random* random, int begin, int end, michael@0: std::vector* v) { michael@0: const int size = static_cast(v->size()); michael@0: GTEST_CHECK_(0 <= begin && begin <= size) michael@0: << "Invalid shuffle range start " << begin << ": must be in range [0, " michael@0: << size << "]."; michael@0: GTEST_CHECK_(begin <= end && end <= size) michael@0: << "Invalid shuffle range finish " << end << ": must be in range [" michael@0: << begin << ", " << size << "]."; michael@0: michael@0: // Fisher-Yates shuffle, from michael@0: // http://en.wikipedia.org/wiki/Fisher-Yates_shuffle michael@0: for (int range_width = end - begin; range_width >= 2; range_width--) { michael@0: const int last_in_range = begin + range_width - 1; michael@0: const int selected = begin + random->Generate(range_width); michael@0: std::swap((*v)[selected], (*v)[last_in_range]); michael@0: } michael@0: } michael@0: michael@0: // Performs an in-place shuffle of the vector's elements. michael@0: template michael@0: inline void Shuffle(internal::Random* random, std::vector* v) { michael@0: ShuffleRange(random, 0, static_cast(v->size()), v); michael@0: } michael@0: michael@0: // A function for deleting an object. Handy for being used as a michael@0: // functor. michael@0: template michael@0: static void Delete(T* x) { michael@0: delete x; michael@0: } michael@0: michael@0: // A predicate that checks the key of a TestProperty against a known key. michael@0: // michael@0: // TestPropertyKeyIs is copyable. michael@0: class TestPropertyKeyIs { michael@0: public: michael@0: // Constructor. michael@0: // michael@0: // TestPropertyKeyIs has NO default constructor. michael@0: explicit TestPropertyKeyIs(const char* key) michael@0: : key_(key) {} michael@0: michael@0: // Returns true iff the test name of test property matches on key_. michael@0: bool operator()(const TestProperty& test_property) const { michael@0: return String(test_property.key()).Compare(key_) == 0; michael@0: } michael@0: michael@0: private: michael@0: String key_; michael@0: }; michael@0: michael@0: // Class UnitTestOptions. michael@0: // michael@0: // This class contains functions for processing options the user michael@0: // specifies when running the tests. It has only static members. michael@0: // michael@0: // In most cases, the user can specify an option using either an michael@0: // environment variable or a command line flag. E.g. you can set the michael@0: // test filter using either GTEST_FILTER or --gtest_filter. If both michael@0: // the variable and the flag are present, the latter overrides the michael@0: // former. michael@0: class GTEST_API_ UnitTestOptions { michael@0: public: michael@0: // Functions for processing the gtest_output flag. michael@0: michael@0: // Returns the output format, or "" for normal printed output. michael@0: static String GetOutputFormat(); michael@0: michael@0: // Returns the absolute path of the requested output file, or the michael@0: // default (test_detail.xml in the original working directory) if michael@0: // none was explicitly specified. michael@0: static String GetAbsolutePathToOutputFile(); michael@0: michael@0: // Functions for processing the gtest_filter flag. michael@0: michael@0: // Returns true iff the wildcard pattern matches the string. The michael@0: // first ':' or '\0' character in pattern marks the end of it. michael@0: // michael@0: // This recursive algorithm isn't very efficient, but is clear and michael@0: // works well enough for matching test names, which are short. michael@0: static bool PatternMatchesString(const char *pattern, const char *str); michael@0: michael@0: // Returns true iff the user-specified filter matches the test case michael@0: // name and the test name. michael@0: static bool FilterMatchesTest(const String &test_case_name, michael@0: const String &test_name); michael@0: michael@0: #if GTEST_OS_WINDOWS michael@0: // Function for supporting the gtest_catch_exception flag. michael@0: michael@0: // Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the michael@0: // given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise. michael@0: // This function is useful as an __except condition. michael@0: static int GTestShouldProcessSEH(DWORD exception_code); michael@0: #endif // GTEST_OS_WINDOWS michael@0: michael@0: // Returns true if "name" matches the ':' separated list of glob-style michael@0: // filters in "filter". michael@0: static bool MatchesFilter(const String& name, const char* filter); michael@0: }; michael@0: michael@0: // Returns the current application's name, removing directory path if that michael@0: // is present. Used by UnitTestOptions::GetOutputFile. michael@0: GTEST_API_ FilePath GetCurrentExecutableName(); michael@0: michael@0: // The role interface for getting the OS stack trace as a string. michael@0: class OsStackTraceGetterInterface { michael@0: public: michael@0: OsStackTraceGetterInterface() {} michael@0: virtual ~OsStackTraceGetterInterface() {} michael@0: michael@0: // Returns the current OS stack trace as a String. Parameters: michael@0: // michael@0: // max_depth - the maximum number of stack frames to be included michael@0: // in the trace. michael@0: // skip_count - the number of top frames to be skipped; doesn't count michael@0: // against max_depth. michael@0: virtual String CurrentStackTrace(int max_depth, int skip_count) = 0; michael@0: michael@0: // UponLeavingGTest() should be called immediately before Google Test calls michael@0: // user code. It saves some information about the current stack that michael@0: // CurrentStackTrace() will use to find and hide Google Test stack frames. michael@0: virtual void UponLeavingGTest() = 0; michael@0: michael@0: private: michael@0: GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetterInterface); michael@0: }; michael@0: michael@0: // A working implementation of the OsStackTraceGetterInterface interface. michael@0: class OsStackTraceGetter : public OsStackTraceGetterInterface { michael@0: public: michael@0: OsStackTraceGetter() : caller_frame_(NULL) {} michael@0: michael@0: virtual String CurrentStackTrace(int max_depth, int skip_count) michael@0: GTEST_LOCK_EXCLUDED_(mutex_); michael@0: michael@0: virtual void UponLeavingGTest() GTEST_LOCK_EXCLUDED_(mutex_); michael@0: michael@0: // This string is inserted in place of stack frames that are part of michael@0: // Google Test's implementation. michael@0: static const char* const kElidedFramesMarker; michael@0: michael@0: private: michael@0: Mutex mutex_; // protects all internal state michael@0: michael@0: // We save the stack frame below the frame that calls user code. michael@0: // We do this because the address of the frame immediately below michael@0: // the user code changes between the call to UponLeavingGTest() michael@0: // and any calls to CurrentStackTrace() from within the user code. michael@0: void* caller_frame_; michael@0: michael@0: GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetter); michael@0: }; michael@0: michael@0: // Information about a Google Test trace point. michael@0: struct TraceInfo { michael@0: const char* file; michael@0: int line; michael@0: String message; michael@0: }; michael@0: michael@0: // This is the default global test part result reporter used in UnitTestImpl. michael@0: // This class should only be used by UnitTestImpl. michael@0: class DefaultGlobalTestPartResultReporter michael@0: : public TestPartResultReporterInterface { michael@0: public: michael@0: explicit DefaultGlobalTestPartResultReporter(UnitTestImpl* unit_test); michael@0: // Implements the TestPartResultReporterInterface. Reports the test part michael@0: // result in the current test. michael@0: virtual void ReportTestPartResult(const TestPartResult& result); michael@0: michael@0: private: michael@0: UnitTestImpl* const unit_test_; michael@0: michael@0: GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultGlobalTestPartResultReporter); michael@0: }; michael@0: michael@0: // This is the default per thread test part result reporter used in michael@0: // UnitTestImpl. This class should only be used by UnitTestImpl. michael@0: class DefaultPerThreadTestPartResultReporter michael@0: : public TestPartResultReporterInterface { michael@0: public: michael@0: explicit DefaultPerThreadTestPartResultReporter(UnitTestImpl* unit_test); michael@0: // Implements the TestPartResultReporterInterface. The implementation just michael@0: // delegates to the current global test part result reporter of *unit_test_. michael@0: virtual void ReportTestPartResult(const TestPartResult& result); michael@0: michael@0: private: michael@0: UnitTestImpl* const unit_test_; michael@0: michael@0: GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultPerThreadTestPartResultReporter); michael@0: }; michael@0: michael@0: // The private implementation of the UnitTest class. We don't protect michael@0: // the methods under a mutex, as this class is not accessible by a michael@0: // user and the UnitTest class that delegates work to this class does michael@0: // proper locking. michael@0: class GTEST_API_ UnitTestImpl { michael@0: public: michael@0: explicit UnitTestImpl(UnitTest* parent); michael@0: virtual ~UnitTestImpl(); michael@0: michael@0: // There are two different ways to register your own TestPartResultReporter. michael@0: // You can register your own repoter to listen either only for test results michael@0: // from the current thread or for results from all threads. michael@0: // By default, each per-thread test result repoter just passes a new michael@0: // TestPartResult to the global test result reporter, which registers the michael@0: // test part result for the currently running test. michael@0: michael@0: // Returns the global test part result reporter. michael@0: TestPartResultReporterInterface* GetGlobalTestPartResultReporter(); michael@0: michael@0: // Sets the global test part result reporter. michael@0: void SetGlobalTestPartResultReporter( michael@0: TestPartResultReporterInterface* reporter); michael@0: michael@0: // Returns the test part result reporter for the current thread. michael@0: TestPartResultReporterInterface* GetTestPartResultReporterForCurrentThread(); michael@0: michael@0: // Sets the test part result reporter for the current thread. michael@0: void SetTestPartResultReporterForCurrentThread( michael@0: TestPartResultReporterInterface* reporter); michael@0: michael@0: // Gets the number of successful test cases. michael@0: int successful_test_case_count() const; michael@0: michael@0: // Gets the number of failed test cases. michael@0: int failed_test_case_count() const; michael@0: michael@0: // Gets the number of all test cases. michael@0: int total_test_case_count() const; michael@0: michael@0: // Gets the number of all test cases that contain at least one test michael@0: // that should run. michael@0: int test_case_to_run_count() const; michael@0: michael@0: // Gets the number of successful tests. michael@0: int successful_test_count() const; michael@0: michael@0: // Gets the number of failed tests. michael@0: int failed_test_count() const; michael@0: michael@0: // Gets the number of disabled tests. michael@0: int disabled_test_count() const; michael@0: michael@0: // Gets the number of all tests. michael@0: int total_test_count() const; michael@0: michael@0: // Gets the number of tests that should run. michael@0: int test_to_run_count() const; michael@0: michael@0: // Gets the time of the test program start, in ms from the start of the michael@0: // UNIX epoch. michael@0: TimeInMillis start_timestamp() const { return start_timestamp_; } michael@0: michael@0: // Gets the elapsed time, in milliseconds. michael@0: TimeInMillis elapsed_time() const { return elapsed_time_; } michael@0: michael@0: // Returns true iff the unit test passed (i.e. all test cases passed). michael@0: bool Passed() const { return !Failed(); } michael@0: michael@0: // Returns true iff the unit test failed (i.e. some test case failed michael@0: // or something outside of all tests failed). michael@0: bool Failed() const { michael@0: return failed_test_case_count() > 0 || ad_hoc_test_result()->Failed(); michael@0: } michael@0: michael@0: // Gets the i-th test case among all the test cases. i can range from 0 to michael@0: // total_test_case_count() - 1. If i is not in that range, returns NULL. michael@0: const TestCase* GetTestCase(int i) const { michael@0: const int index = GetElementOr(test_case_indices_, i, -1); michael@0: return index < 0 ? NULL : test_cases_[i]; michael@0: } michael@0: michael@0: // Gets the i-th test case among all the test cases. i can range from 0 to michael@0: // total_test_case_count() - 1. If i is not in that range, returns NULL. michael@0: TestCase* GetMutableTestCase(int i) { michael@0: const int index = GetElementOr(test_case_indices_, i, -1); michael@0: return index < 0 ? NULL : test_cases_[index]; michael@0: } michael@0: michael@0: // Provides access to the event listener list. michael@0: TestEventListeners* listeners() { return &listeners_; } michael@0: michael@0: // Returns the TestResult for the test that's currently running, or michael@0: // the TestResult for the ad hoc test if no test is running. michael@0: TestResult* current_test_result(); michael@0: michael@0: // Returns the TestResult for the ad hoc test. michael@0: const TestResult* ad_hoc_test_result() const { return &ad_hoc_test_result_; } michael@0: michael@0: // Sets the OS stack trace getter. michael@0: // michael@0: // Does nothing if the input and the current OS stack trace getter michael@0: // are the same; otherwise, deletes the old getter and makes the michael@0: // input the current getter. michael@0: void set_os_stack_trace_getter(OsStackTraceGetterInterface* getter); michael@0: michael@0: // Returns the current OS stack trace getter if it is not NULL; michael@0: // otherwise, creates an OsStackTraceGetter, makes it the current michael@0: // getter, and returns it. michael@0: OsStackTraceGetterInterface* os_stack_trace_getter(); michael@0: michael@0: // Returns the current OS stack trace as a String. michael@0: // michael@0: // The maximum number of stack frames to be included is specified by michael@0: // the gtest_stack_trace_depth flag. The skip_count parameter michael@0: // specifies the number of top frames to be skipped, which doesn't michael@0: // count against the number of frames to be included. michael@0: // michael@0: // For example, if Foo() calls Bar(), which in turn calls michael@0: // CurrentOsStackTraceExceptTop(1), Foo() will be included in the michael@0: // trace but Bar() and CurrentOsStackTraceExceptTop() won't. michael@0: String CurrentOsStackTraceExceptTop(int skip_count) GTEST_NO_INLINE_; michael@0: michael@0: // Finds and returns a TestCase with the given name. If one doesn't michael@0: // exist, creates one and returns it. michael@0: // michael@0: // Arguments: michael@0: // michael@0: // test_case_name: name of the test case michael@0: // type_param: the name of the test's type parameter, or NULL if michael@0: // this is not a typed or a type-parameterized test. michael@0: // set_up_tc: pointer to the function that sets up the test case michael@0: // tear_down_tc: pointer to the function that tears down the test case michael@0: TestCase* GetTestCase(const char* test_case_name, michael@0: const char* type_param, michael@0: Test::SetUpTestCaseFunc set_up_tc, michael@0: Test::TearDownTestCaseFunc tear_down_tc); michael@0: michael@0: // Adds a TestInfo to the unit test. michael@0: // michael@0: // Arguments: michael@0: // michael@0: // set_up_tc: pointer to the function that sets up the test case michael@0: // tear_down_tc: pointer to the function that tears down the test case michael@0: // test_info: the TestInfo object michael@0: void AddTestInfo(Test::SetUpTestCaseFunc set_up_tc, michael@0: Test::TearDownTestCaseFunc tear_down_tc, michael@0: TestInfo* test_info) { michael@0: // In order to support thread-safe death tests, we need to michael@0: // remember the original working directory when the test program michael@0: // was first invoked. We cannot do this in RUN_ALL_TESTS(), as michael@0: // the user may have changed the current directory before calling michael@0: // RUN_ALL_TESTS(). Therefore we capture the current directory in michael@0: // AddTestInfo(), which is called to register a TEST or TEST_F michael@0: // before main() is reached. michael@0: if (original_working_dir_.IsEmpty()) { michael@0: original_working_dir_.Set(FilePath::GetCurrentDir()); michael@0: GTEST_CHECK_(!original_working_dir_.IsEmpty()) michael@0: << "Failed to get the current working directory."; michael@0: } michael@0: michael@0: GetTestCase(test_info->test_case_name(), michael@0: test_info->type_param(), michael@0: set_up_tc, michael@0: tear_down_tc)->AddTestInfo(test_info); michael@0: } michael@0: michael@0: #if GTEST_HAS_PARAM_TEST michael@0: // Returns ParameterizedTestCaseRegistry object used to keep track of michael@0: // value-parameterized tests and instantiate and register them. michael@0: internal::ParameterizedTestCaseRegistry& parameterized_test_registry() { michael@0: return parameterized_test_registry_; michael@0: } michael@0: #endif // GTEST_HAS_PARAM_TEST michael@0: michael@0: // Sets the TestCase object for the test that's currently running. michael@0: void set_current_test_case(TestCase* a_current_test_case) { michael@0: current_test_case_ = a_current_test_case; michael@0: } michael@0: michael@0: // Sets the TestInfo object for the test that's currently running. If michael@0: // current_test_info is NULL, the assertion results will be stored in michael@0: // ad_hoc_test_result_. michael@0: void set_current_test_info(TestInfo* a_current_test_info) { michael@0: current_test_info_ = a_current_test_info; michael@0: } michael@0: michael@0: // Registers all parameterized tests defined using TEST_P and michael@0: // INSTANTIATE_TEST_CASE_P, creating regular tests for each test/parameter michael@0: // combination. This method can be called more then once; it has guards michael@0: // protecting from registering the tests more then once. If michael@0: // value-parameterized tests are disabled, RegisterParameterizedTests is michael@0: // present but does nothing. michael@0: void RegisterParameterizedTests(); michael@0: michael@0: // Runs all tests in this UnitTest object, prints the result, and michael@0: // returns true if all tests are successful. If any exception is michael@0: // thrown during a test, this test is considered to be failed, but michael@0: // the rest of the tests will still be run. michael@0: bool RunAllTests(); michael@0: michael@0: // Clears the results of all tests, except the ad hoc tests. michael@0: void ClearNonAdHocTestResult() { michael@0: ForEach(test_cases_, TestCase::ClearTestCaseResult); michael@0: } michael@0: michael@0: // Clears the results of ad-hoc test assertions. michael@0: void ClearAdHocTestResult() { michael@0: ad_hoc_test_result_.Clear(); michael@0: } michael@0: michael@0: enum ReactionToSharding { michael@0: HONOR_SHARDING_PROTOCOL, michael@0: IGNORE_SHARDING_PROTOCOL michael@0: }; michael@0: michael@0: // Matches the full name of each test against the user-specified michael@0: // filter to decide whether the test should run, then records the michael@0: // result in each TestCase and TestInfo object. michael@0: // If shard_tests == HONOR_SHARDING_PROTOCOL, further filters tests michael@0: // based on sharding variables in the environment. michael@0: // Returns the number of tests that should run. michael@0: int FilterTests(ReactionToSharding shard_tests); michael@0: michael@0: // Prints the names of the tests matching the user-specified filter flag. michael@0: void ListTestsMatchingFilter(); michael@0: michael@0: const TestCase* current_test_case() const { return current_test_case_; } michael@0: TestInfo* current_test_info() { return current_test_info_; } michael@0: const TestInfo* current_test_info() const { return current_test_info_; } michael@0: michael@0: // Returns the vector of environments that need to be set-up/torn-down michael@0: // before/after the tests are run. michael@0: std::vector& environments() { return environments_; } michael@0: michael@0: // Getters for the per-thread Google Test trace stack. michael@0: std::vector& gtest_trace_stack() { michael@0: return *(gtest_trace_stack_.pointer()); michael@0: } michael@0: const std::vector& gtest_trace_stack() const { michael@0: return gtest_trace_stack_.get(); michael@0: } michael@0: michael@0: #if GTEST_HAS_DEATH_TEST michael@0: void InitDeathTestSubprocessControlInfo() { michael@0: internal_run_death_test_flag_.reset(ParseInternalRunDeathTestFlag()); michael@0: } michael@0: // Returns a pointer to the parsed --gtest_internal_run_death_test michael@0: // flag, or NULL if that flag was not specified. michael@0: // This information is useful only in a death test child process. michael@0: // Must not be called before a call to InitGoogleTest. michael@0: const InternalRunDeathTestFlag* internal_run_death_test_flag() const { michael@0: return internal_run_death_test_flag_.get(); michael@0: } michael@0: michael@0: // Returns a pointer to the current death test factory. michael@0: internal::DeathTestFactory* death_test_factory() { michael@0: return death_test_factory_.get(); michael@0: } michael@0: michael@0: void SuppressTestEventsIfInSubprocess(); michael@0: michael@0: friend class ReplaceDeathTestFactory; michael@0: #endif // GTEST_HAS_DEATH_TEST michael@0: michael@0: // Initializes the event listener performing XML output as specified by michael@0: // UnitTestOptions. Must not be called before InitGoogleTest. michael@0: void ConfigureXmlOutput(); michael@0: michael@0: #if GTEST_CAN_STREAM_RESULTS_ michael@0: // Initializes the event listener for streaming test results to a socket. michael@0: // Must not be called before InitGoogleTest. michael@0: void ConfigureStreamingOutput(); michael@0: #endif michael@0: michael@0: // Performs initialization dependent upon flag values obtained in michael@0: // ParseGoogleTestFlagsOnly. Is called from InitGoogleTest after the call to michael@0: // ParseGoogleTestFlagsOnly. In case a user neglects to call InitGoogleTest michael@0: // this function is also called from RunAllTests. Since this function can be michael@0: // called more than once, it has to be idempotent. michael@0: void PostFlagParsingInit(); michael@0: michael@0: // Gets the random seed used at the start of the current test iteration. michael@0: int random_seed() const { return random_seed_; } michael@0: michael@0: // Gets the random number generator. michael@0: internal::Random* random() { return &random_; } michael@0: michael@0: // Shuffles all test cases, and the tests within each test case, michael@0: // making sure that death tests are still run first. michael@0: void ShuffleTests(); michael@0: michael@0: // Restores the test cases and tests to their order before the first shuffle. michael@0: void UnshuffleTests(); michael@0: michael@0: // Returns the value of GTEST_FLAG(catch_exceptions) at the moment michael@0: // UnitTest::Run() starts. michael@0: bool catch_exceptions() const { return catch_exceptions_; } michael@0: michael@0: private: michael@0: friend class ::testing::UnitTest; michael@0: michael@0: // Used by UnitTest::Run() to capture the state of michael@0: // GTEST_FLAG(catch_exceptions) at the moment it starts. michael@0: void set_catch_exceptions(bool value) { catch_exceptions_ = value; } michael@0: michael@0: // The UnitTest object that owns this implementation object. michael@0: UnitTest* const parent_; michael@0: michael@0: // The working directory when the first TEST() or TEST_F() was michael@0: // executed. michael@0: internal::FilePath original_working_dir_; michael@0: michael@0: // The default test part result reporters. michael@0: DefaultGlobalTestPartResultReporter default_global_test_part_result_reporter_; michael@0: DefaultPerThreadTestPartResultReporter michael@0: default_per_thread_test_part_result_reporter_; michael@0: michael@0: // Points to (but doesn't own) the global test part result reporter. michael@0: TestPartResultReporterInterface* global_test_part_result_repoter_; michael@0: michael@0: // Protects read and write access to global_test_part_result_reporter_. michael@0: internal::Mutex global_test_part_result_reporter_mutex_; michael@0: michael@0: // Points to (but doesn't own) the per-thread test part result reporter. michael@0: internal::ThreadLocal michael@0: per_thread_test_part_result_reporter_; michael@0: michael@0: // The vector of environments that need to be set-up/torn-down michael@0: // before/after the tests are run. michael@0: std::vector environments_; michael@0: michael@0: // The vector of TestCases in their original order. It owns the michael@0: // elements in the vector. michael@0: std::vector test_cases_; michael@0: michael@0: // Provides a level of indirection for the test case list to allow michael@0: // easy shuffling and restoring the test case order. The i-th michael@0: // element of this vector is the index of the i-th test case in the michael@0: // shuffled order. michael@0: std::vector test_case_indices_; michael@0: michael@0: #if GTEST_HAS_PARAM_TEST michael@0: // ParameterizedTestRegistry object used to register value-parameterized michael@0: // tests. michael@0: internal::ParameterizedTestCaseRegistry parameterized_test_registry_; michael@0: michael@0: // Indicates whether RegisterParameterizedTests() has been called already. michael@0: bool parameterized_tests_registered_; michael@0: #endif // GTEST_HAS_PARAM_TEST michael@0: michael@0: // Index of the last death test case registered. Initially -1. michael@0: int last_death_test_case_; michael@0: michael@0: // This points to the TestCase for the currently running test. It michael@0: // changes as Google Test goes through one test case after another. michael@0: // When no test is running, this is set to NULL and Google Test michael@0: // stores assertion results in ad_hoc_test_result_. Initially NULL. michael@0: TestCase* current_test_case_; michael@0: michael@0: // This points to the TestInfo for the currently running test. It michael@0: // changes as Google Test goes through one test after another. When michael@0: // no test is running, this is set to NULL and Google Test stores michael@0: // assertion results in ad_hoc_test_result_. Initially NULL. michael@0: TestInfo* current_test_info_; michael@0: michael@0: // Normally, a user only writes assertions inside a TEST or TEST_F, michael@0: // or inside a function called by a TEST or TEST_F. Since Google michael@0: // Test keeps track of which test is current running, it can michael@0: // associate such an assertion with the test it belongs to. michael@0: // michael@0: // If an assertion is encountered when no TEST or TEST_F is running, michael@0: // Google Test attributes the assertion result to an imaginary "ad hoc" michael@0: // test, and records the result in ad_hoc_test_result_. michael@0: TestResult ad_hoc_test_result_; michael@0: michael@0: // The list of event listeners that can be used to track events inside michael@0: // Google Test. michael@0: TestEventListeners listeners_; michael@0: michael@0: // The OS stack trace getter. Will be deleted when the UnitTest michael@0: // object is destructed. By default, an OsStackTraceGetter is used, michael@0: // but the user can set this field to use a custom getter if that is michael@0: // desired. michael@0: OsStackTraceGetterInterface* os_stack_trace_getter_; michael@0: michael@0: // True iff PostFlagParsingInit() has been called. michael@0: bool post_flag_parse_init_performed_; michael@0: michael@0: // The random number seed used at the beginning of the test run. michael@0: int random_seed_; michael@0: michael@0: // Our random number generator. michael@0: internal::Random random_; michael@0: michael@0: // The time of the test program start, in ms from the start of the michael@0: // UNIX epoch. michael@0: TimeInMillis start_timestamp_; michael@0: michael@0: // How long the test took to run, in milliseconds. michael@0: TimeInMillis elapsed_time_; michael@0: michael@0: #if GTEST_HAS_DEATH_TEST michael@0: // The decomposed components of the gtest_internal_run_death_test flag, michael@0: // parsed when RUN_ALL_TESTS is called. michael@0: internal::scoped_ptr internal_run_death_test_flag_; michael@0: internal::scoped_ptr death_test_factory_; michael@0: #endif // GTEST_HAS_DEATH_TEST michael@0: michael@0: // A per-thread stack of traces created by the SCOPED_TRACE() macro. michael@0: internal::ThreadLocal > gtest_trace_stack_; michael@0: michael@0: // The value of GTEST_FLAG(catch_exceptions) at the moment RunAllTests() michael@0: // starts. michael@0: bool catch_exceptions_; michael@0: michael@0: GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTestImpl); michael@0: }; // class UnitTestImpl michael@0: michael@0: // Convenience function for accessing the global UnitTest michael@0: // implementation object. michael@0: inline UnitTestImpl* GetUnitTestImpl() { michael@0: return UnitTest::GetInstance()->impl(); michael@0: } michael@0: michael@0: #if GTEST_USES_SIMPLE_RE michael@0: michael@0: // Internal helper functions for implementing the simple regular michael@0: // expression matcher. michael@0: GTEST_API_ bool IsInSet(char ch, const char* str); michael@0: GTEST_API_ bool IsAsciiDigit(char ch); michael@0: GTEST_API_ bool IsAsciiPunct(char ch); michael@0: GTEST_API_ bool IsRepeat(char ch); michael@0: GTEST_API_ bool IsAsciiWhiteSpace(char ch); michael@0: GTEST_API_ bool IsAsciiWordChar(char ch); michael@0: GTEST_API_ bool IsValidEscape(char ch); michael@0: GTEST_API_ bool AtomMatchesChar(bool escaped, char pattern, char ch); michael@0: GTEST_API_ bool ValidateRegex(const char* regex); michael@0: GTEST_API_ bool MatchRegexAtHead(const char* regex, const char* str); michael@0: GTEST_API_ bool MatchRepetitionAndRegexAtHead( michael@0: bool escaped, char ch, char repeat, const char* regex, const char* str); michael@0: GTEST_API_ bool MatchRegexAnywhere(const char* regex, const char* str); michael@0: michael@0: #endif // GTEST_USES_SIMPLE_RE michael@0: michael@0: // Parses the command line for Google Test flags, without initializing michael@0: // other parts of Google Test. michael@0: GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, char** argv); michael@0: GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv); michael@0: michael@0: #if GTEST_HAS_DEATH_TEST michael@0: michael@0: // Returns the message describing the last system error, regardless of the michael@0: // platform. michael@0: GTEST_API_ String GetLastErrnoDescription(); michael@0: michael@0: # if GTEST_OS_WINDOWS michael@0: // Provides leak-safe Windows kernel handle ownership. michael@0: class AutoHandle { michael@0: public: michael@0: AutoHandle() : handle_(INVALID_HANDLE_VALUE) {} michael@0: explicit AutoHandle(HANDLE handle) : handle_(handle) {} michael@0: michael@0: ~AutoHandle() { Reset(); } michael@0: michael@0: HANDLE Get() const { return handle_; } michael@0: void Reset() { Reset(INVALID_HANDLE_VALUE); } michael@0: void Reset(HANDLE handle) { michael@0: if (handle != handle_) { michael@0: if (handle_ != INVALID_HANDLE_VALUE) michael@0: ::CloseHandle(handle_); michael@0: handle_ = handle; michael@0: } michael@0: } michael@0: michael@0: private: michael@0: HANDLE handle_; michael@0: michael@0: GTEST_DISALLOW_COPY_AND_ASSIGN_(AutoHandle); michael@0: }; michael@0: # endif // GTEST_OS_WINDOWS michael@0: michael@0: // Attempts to parse a string into a positive integer pointed to by the michael@0: // number parameter. Returns true if that is possible. michael@0: // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we can use michael@0: // it here. michael@0: template michael@0: bool ParseNaturalNumber(const ::std::string& str, Integer* number) { michael@0: // Fail fast if the given string does not begin with a digit; michael@0: // this bypasses strtoXXX's "optional leading whitespace and plus michael@0: // or minus sign" semantics, which are undesirable here. michael@0: if (str.empty() || !IsDigit(str[0])) { michael@0: return false; michael@0: } michael@0: errno = 0; michael@0: michael@0: char* end; michael@0: // BiggestConvertible is the largest integer type that system-provided michael@0: // string-to-number conversion routines can return. michael@0: michael@0: # if GTEST_OS_WINDOWS && !defined(__GNUC__) michael@0: michael@0: // MSVC and C++ Builder define __int64 instead of the standard long long. michael@0: typedef unsigned __int64 BiggestConvertible; michael@0: const BiggestConvertible parsed = _strtoui64(str.c_str(), &end, 10); michael@0: michael@0: # else michael@0: michael@0: typedef unsigned long long BiggestConvertible; // NOLINT michael@0: const BiggestConvertible parsed = strtoull(str.c_str(), &end, 10); michael@0: michael@0: # endif // GTEST_OS_WINDOWS && !defined(__GNUC__) michael@0: michael@0: const bool parse_success = *end == '\0' && errno == 0; michael@0: michael@0: // TODO(vladl@google.com): Convert this to compile time assertion when it is michael@0: // available. michael@0: GTEST_CHECK_(sizeof(Integer) <= sizeof(parsed)); michael@0: michael@0: const Integer result = static_cast(parsed); michael@0: if (parse_success && static_cast(result) == parsed) { michael@0: *number = result; michael@0: return true; michael@0: } michael@0: return false; michael@0: } michael@0: #endif // GTEST_HAS_DEATH_TEST michael@0: michael@0: // TestResult contains some private methods that should be hidden from michael@0: // Google Test user but are required for testing. This class allow our tests michael@0: // to access them. michael@0: // michael@0: // This class is supplied only for the purpose of testing Google Test's own michael@0: // constructs. Do not use it in user tests, either directly or indirectly. michael@0: class TestResultAccessor { michael@0: public: michael@0: static void RecordProperty(TestResult* test_result, michael@0: const TestProperty& property) { michael@0: test_result->RecordProperty(property); michael@0: } michael@0: michael@0: static void ClearTestPartResults(TestResult* test_result) { michael@0: test_result->ClearTestPartResults(); michael@0: } michael@0: michael@0: static const std::vector& test_part_results( michael@0: const TestResult& test_result) { michael@0: return test_result.test_part_results(); michael@0: } michael@0: }; michael@0: michael@0: } // namespace internal michael@0: } // namespace testing michael@0: michael@0: #endif // GTEST_SRC_GTEST_INTERNAL_INL_H_