diff options
Diffstat (limited to 'lib/gtest/src/gtest-internal-inl.h')
-rw-r--r-- | lib/gtest/src/gtest-internal-inl.h | 222 |
1 files changed, 192 insertions, 30 deletions
diff --git a/lib/gtest/src/gtest-internal-inl.h b/lib/gtest/src/gtest-internal-inl.h index 350ade076f..35df303cca 100644 --- a/lib/gtest/src/gtest-internal-inl.h +++ b/lib/gtest/src/gtest-internal-inl.h @@ -58,6 +58,11 @@ #include "gtest/internal/gtest-port.h" +#if GTEST_CAN_STREAM_RESULTS_ +# include <arpa/inet.h> // NOLINT +# include <netdb.h> // NOLINT +#endif + #if GTEST_OS_WINDOWS # include <windows.h> // NOLINT #endif // GTEST_OS_WINDOWS @@ -202,32 +207,29 @@ class GTestFlagSaver { bool also_run_disabled_tests_; bool break_on_failure_; bool catch_exceptions_; - String color_; - String death_test_style_; + std::string color_; + std::string death_test_style_; bool death_test_use_fork_; - String filter_; - String internal_run_death_test_; + std::string filter_; + std::string internal_run_death_test_; bool list_tests_; - String output_; + std::string output_; bool print_time_; - bool pretty_; internal::Int32 random_seed_; internal::Int32 repeat_; bool shuffle_; internal::Int32 stack_trace_depth_; - String stream_result_to_; + std::string stream_result_to_; bool throw_on_failure_; } GTEST_ATTRIBUTE_UNUSED_; // Converts a Unicode code point to a narrow string in UTF-8 encoding. // code_point parameter is of type UInt32 because wchar_t may not be // wide enough to contain a code point. -// The output buffer str must containt at least 32 characters. -// The function returns the address of the output buffer. // If the code_point is not a valid Unicode code point -// (i.e. outside of Unicode range U+0 to U+10FFFF) it will be output -// as '(Invalid Unicode 0xXXXXXXXX)'. -GTEST_API_ char* CodePointToUtf8(UInt32 code_point, char* str); +// (i.e. outside of Unicode range U+0 to U+10FFFF) it will be converted +// to "(Invalid Unicode 0xXXXXXXXX)". +GTEST_API_ std::string CodePointToUtf8(UInt32 code_point); // Converts a wide string to a narrow string in UTF-8 encoding. // The wide string is assumed to have the following encoding: @@ -242,7 +244,7 @@ GTEST_API_ char* CodePointToUtf8(UInt32 code_point, char* str); // as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding // and contains invalid UTF-16 surrogate pairs, values in those pairs // will be encoded as individual Unicode characters from Basic Normal Plane. -GTEST_API_ String WideStringToUtf8(const wchar_t* str, int num_chars); +GTEST_API_ std::string WideStringToUtf8(const wchar_t* str, int num_chars); // Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file // if the variable is present. If a file already exists at this location, this @@ -346,16 +348,15 @@ class TestPropertyKeyIs { // Constructor. // // TestPropertyKeyIs has NO default constructor. - explicit TestPropertyKeyIs(const char* key) - : key_(key) {} + explicit TestPropertyKeyIs(const std::string& key) : key_(key) {} // Returns true iff the test name of test property matches on key_. bool operator()(const TestProperty& test_property) const { - return String(test_property.key()).Compare(key_) == 0; + return test_property.key() == key_; } private: - String key_; + std::string key_; }; // Class UnitTestOptions. @@ -373,12 +374,12 @@ class GTEST_API_ UnitTestOptions { // Functions for processing the gtest_output flag. // Returns the output format, or "" for normal printed output. - static String GetOutputFormat(); + static std::string GetOutputFormat(); // Returns the absolute path of the requested output file, or the // default (test_detail.xml in the original working directory) if // none was explicitly specified. - static String GetAbsolutePathToOutputFile(); + static std::string GetAbsolutePathToOutputFile(); // Functions for processing the gtest_filter flag. @@ -391,8 +392,8 @@ class GTEST_API_ UnitTestOptions { // Returns true iff the user-specified filter matches the test case // name and the test name. - static bool FilterMatchesTest(const String &test_case_name, - const String &test_name); + static bool FilterMatchesTest(const std::string &test_case_name, + const std::string &test_name); #if GTEST_OS_WINDOWS // Function for supporting the gtest_catch_exception flag. @@ -405,7 +406,7 @@ class GTEST_API_ UnitTestOptions { // Returns true if "name" matches the ':' separated list of glob-style // filters in "filter". - static bool MatchesFilter(const String& name, const char* filter); + static bool MatchesFilter(const std::string& name, const char* filter); }; // Returns the current application's name, removing directory path if that @@ -418,13 +419,13 @@ class OsStackTraceGetterInterface { OsStackTraceGetterInterface() {} virtual ~OsStackTraceGetterInterface() {} - // Returns the current OS stack trace as a String. Parameters: + // Returns the current OS stack trace as an std::string. Parameters: // // max_depth - the maximum number of stack frames to be included // in the trace. // skip_count - the number of top frames to be skipped; doesn't count // against max_depth. - virtual String CurrentStackTrace(int max_depth, int skip_count) = 0; + virtual string CurrentStackTrace(int max_depth, int skip_count) = 0; // UponLeavingGTest() should be called immediately before Google Test calls // user code. It saves some information about the current stack that @@ -440,7 +441,7 @@ class OsStackTraceGetter : public OsStackTraceGetterInterface { public: OsStackTraceGetter() : caller_frame_(NULL) {} - virtual String CurrentStackTrace(int max_depth, int skip_count) + virtual string CurrentStackTrace(int max_depth, int skip_count) GTEST_LOCK_EXCLUDED_(mutex_); virtual void UponLeavingGTest() GTEST_LOCK_EXCLUDED_(mutex_); @@ -465,7 +466,7 @@ class OsStackTraceGetter : public OsStackTraceGetterInterface { struct TraceInfo { const char* file; int line; - String message; + std::string message; }; // This is the default global test part result reporter used in UnitTestImpl. @@ -549,9 +550,15 @@ class GTEST_API_ UnitTestImpl { // Gets the number of failed tests. int failed_test_count() const; + // Gets the number of disabled tests that will be reported in the XML report. + int reportable_disabled_test_count() const; + // Gets the number of disabled tests. int disabled_test_count() const; + // Gets the number of tests to be printed in the XML report. + int reportable_test_count() const; + // Gets the number of all tests. int total_test_count() const; @@ -610,7 +617,7 @@ class GTEST_API_ UnitTestImpl { // getter, and returns it. OsStackTraceGetterInterface* os_stack_trace_getter(); - // Returns the current OS stack trace as a String. + // Returns the current OS stack trace as an std::string. // // The maximum number of stack frames to be included is specified by // the gtest_stack_trace_depth flag. The skip_count parameter @@ -620,7 +627,7 @@ class GTEST_API_ UnitTestImpl { // For example, if Foo() calls Bar(), which in turn calls // CurrentOsStackTraceExceptTop(1), Foo() will be included in the // trace but Bar() and CurrentOsStackTraceExceptTop() won't. - String CurrentOsStackTraceExceptTop(int skip_count) GTEST_NO_INLINE_; + std::string CurrentOsStackTraceExceptTop(int skip_count) GTEST_NO_INLINE_; // Finds and returns a TestCase with the given name. If one doesn't // exist, creates one and returns it. @@ -710,6 +717,12 @@ class GTEST_API_ UnitTestImpl { ad_hoc_test_result_.Clear(); } + // Adds a TestProperty to the current TestResult object when invoked in a + // context of a test or a test case, or to the global property set. If the + // result already contains a property with the same key, the value will be + // updated. + void RecordProperty(const TestProperty& test_property); + enum ReactionToSharding { HONOR_SHARDING_PROTOCOL, IGNORE_SHARDING_PROTOCOL @@ -953,7 +966,7 @@ GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv); // Returns the message describing the last system error, regardless of the // platform. -GTEST_API_ String GetLastErrnoDescription(); +GTEST_API_ std::string GetLastErrnoDescription(); # if GTEST_OS_WINDOWS // Provides leak-safe Windows kernel handle ownership. @@ -1036,8 +1049,9 @@ bool ParseNaturalNumber(const ::std::string& str, Integer* number) { class TestResultAccessor { public: static void RecordProperty(TestResult* test_result, + const std::string& xml_element, const TestProperty& property) { - test_result->RecordProperty(property); + test_result->RecordProperty(xml_element, property); } static void ClearTestPartResults(TestResult* test_result) { @@ -1050,6 +1064,154 @@ class TestResultAccessor { } }; +#if GTEST_CAN_STREAM_RESULTS_ + +// Streams test results to the given port on the given host machine. +class StreamingListener : public EmptyTestEventListener { + public: + // Abstract base class for writing strings to a socket. + class AbstractSocketWriter { + public: + virtual ~AbstractSocketWriter() {} + + // Sends a string to the socket. + virtual void Send(const string& message) = 0; + + // Closes the socket. + virtual void CloseConnection() {} + + // Sends a string and a newline to the socket. + void SendLn(const string& message) { + Send(message + "\n"); + } + }; + + // Concrete class for actually writing strings to a socket. + class SocketWriter : public AbstractSocketWriter { + public: + SocketWriter(const string& host, const string& port) + : sockfd_(-1), host_name_(host), port_num_(port) { + MakeConnection(); + } + + virtual ~SocketWriter() { + if (sockfd_ != -1) + CloseConnection(); + } + + // Sends a string to the socket. + virtual void Send(const string& message) { + GTEST_CHECK_(sockfd_ != -1) + << "Send() can be called only when there is a connection."; + + const int len = static_cast<int>(message.length()); + if (write(sockfd_, message.c_str(), len) != len) { + GTEST_LOG_(WARNING) + << "stream_result_to: failed to stream to " + << host_name_ << ":" << port_num_; + } + } + + private: + // Creates a client socket and connects to the server. + void MakeConnection(); + + // Closes the socket. + void CloseConnection() { + GTEST_CHECK_(sockfd_ != -1) + << "CloseConnection() can be called only when there is a connection."; + + close(sockfd_); + sockfd_ = -1; + } + + int sockfd_; // socket file descriptor + const string host_name_; + const string port_num_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(SocketWriter); + }; // class SocketWriter + + // Escapes '=', '&', '%', and '\n' characters in str as "%xx". + static string UrlEncode(const char* str); + + StreamingListener(const string& host, const string& port) + : socket_writer_(new SocketWriter(host, port)) { Start(); } + + explicit StreamingListener(AbstractSocketWriter* socket_writer) + : socket_writer_(socket_writer) { Start(); } + + void OnTestProgramStart(const UnitTest& /* unit_test */) { + SendLn("event=TestProgramStart"); + } + + void OnTestProgramEnd(const UnitTest& unit_test) { + // Note that Google Test current only report elapsed time for each + // test iteration, not for the entire test program. + SendLn("event=TestProgramEnd&passed=" + FormatBool(unit_test.Passed())); + + // Notify the streaming server to stop. + socket_writer_->CloseConnection(); + } + + void OnTestIterationStart(const UnitTest& /* unit_test */, int iteration) { + SendLn("event=TestIterationStart&iteration=" + + StreamableToString(iteration)); + } + + void OnTestIterationEnd(const UnitTest& unit_test, int /* iteration */) { + SendLn("event=TestIterationEnd&passed=" + + FormatBool(unit_test.Passed()) + "&elapsed_time=" + + StreamableToString(unit_test.elapsed_time()) + "ms"); + } + + void OnTestCaseStart(const TestCase& test_case) { + SendLn(std::string("event=TestCaseStart&name=") + test_case.name()); + } + + void OnTestCaseEnd(const TestCase& test_case) { + SendLn("event=TestCaseEnd&passed=" + FormatBool(test_case.Passed()) + + "&elapsed_time=" + StreamableToString(test_case.elapsed_time()) + + "ms"); + } + + void OnTestStart(const TestInfo& test_info) { + SendLn(std::string("event=TestStart&name=") + test_info.name()); + } + + void OnTestEnd(const TestInfo& test_info) { + SendLn("event=TestEnd&passed=" + + FormatBool((test_info.result())->Passed()) + + "&elapsed_time=" + + StreamableToString((test_info.result())->elapsed_time()) + "ms"); + } + + void OnTestPartResult(const TestPartResult& test_part_result) { + const char* file_name = test_part_result.file_name(); + if (file_name == NULL) + file_name = ""; + SendLn("event=TestPartResult&file=" + UrlEncode(file_name) + + "&line=" + StreamableToString(test_part_result.line_number()) + + "&message=" + UrlEncode(test_part_result.message())); + } + + private: + // Sends the given message and a newline to the socket. + void SendLn(const string& message) { socket_writer_->SendLn(message); } + + // Called at the start of streaming to notify the receiver what + // protocol we are using. + void Start() { SendLn("gtest_streaming_protocol_version=1.0"); } + + string FormatBool(bool value) { return value ? "1" : "0"; } + + const scoped_ptr<AbstractSocketWriter> socket_writer_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(StreamingListener); +}; // class StreamingListener + +#endif // GTEST_CAN_STREAM_RESULTS_ + } // namespace internal } // namespace testing |