aboutsummaryrefslogtreecommitdiff
path: root/tests/gtest/src/gtest-internal-inl.h
diff options
context:
space:
mode:
Diffstat (limited to 'tests/gtest/src/gtest-internal-inl.h')
-rw-r--r--tests/gtest/src/gtest-internal-inl.h270
1 files changed, 212 insertions, 58 deletions
diff --git a/tests/gtest/src/gtest-internal-inl.h b/tests/gtest/src/gtest-internal-inl.h
index 65a2101a4..0ac7a109b 100644
--- a/tests/gtest/src/gtest-internal-inl.h
+++ b/tests/gtest/src/gtest-internal-inl.h
@@ -40,7 +40,7 @@
// GTEST_IMPLEMENTATION_ is defined to 1 iff the current translation unit is
// part of Google Test's implementation; otherwise it's undefined.
#if !GTEST_IMPLEMENTATION_
-// A user is trying to include this from his code - just say no.
+// If this file is included from the user's code, just say no.
# error "gtest-internal-inl.h is part of Google Test's internal implementation."
# error "It must not be included except by Google Test itself."
#endif // GTEST_IMPLEMENTATION_
@@ -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
@@ -112,6 +117,12 @@ GTEST_API_ bool ShouldUseColor(bool stdout_is_tty);
// Formats the given time in milliseconds as seconds.
GTEST_API_ std::string FormatTimeInMillisAsSeconds(TimeInMillis ms);
+// Converts the given time in milliseconds to a date string in the ISO 8601
+// format, without the timezone information. N.B.: due to the use the
+// non-reentrant localtime() function, this function is not thread safe. Do
+// not use it in any code that can be called from multiple threads.
+GTEST_API_ std::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms);
+
// Parses a string for an Int32 flag, in the form of "--flag=value".
//
// On success, stores the value of the flag in *value, and returns
@@ -190,37 +201,35 @@ class GTestFlagSaver {
GTEST_FLAG(stream_result_to) = stream_result_to_;
GTEST_FLAG(throw_on_failure) = throw_on_failure_;
}
+
private:
// Fields for saving the original values of flags.
bool also_run_disabled_tests_;
bool break_on_failure_;
bool catch_exceptions_;
- String color_;
- String death_test_style_;
+ 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:
@@ -235,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
@@ -339,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.
@@ -366,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.
@@ -384,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.
@@ -398,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
@@ -411,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
@@ -432,8 +440,11 @@ class OsStackTraceGetterInterface {
class OsStackTraceGetter : public OsStackTraceGetterInterface {
public:
OsStackTraceGetter() : caller_frame_(NULL) {}
- virtual String CurrentStackTrace(int max_depth, int skip_count);
- virtual void UponLeavingGTest();
+
+ virtual string CurrentStackTrace(int max_depth, int skip_count)
+ GTEST_LOCK_EXCLUDED_(mutex_);
+
+ virtual void UponLeavingGTest() GTEST_LOCK_EXCLUDED_(mutex_);
// This string is inserted in place of stack frames that are part of
// Google Test's implementation.
@@ -455,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.
@@ -539,15 +550,25 @@ 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;
// Gets the number of tests that should run.
int test_to_run_count() const;
+ // Gets the time of the test program start, in ms from the start of the
+ // UNIX epoch.
+ TimeInMillis start_timestamp() const { return start_timestamp_; }
+
// Gets the elapsed time, in milliseconds.
TimeInMillis elapsed_time() const { return elapsed_time_; }
@@ -596,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
@@ -606,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);
+ 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.
@@ -696,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
@@ -880,6 +907,10 @@ class GTEST_API_ UnitTestImpl {
// Our random number generator.
internal::Random random_;
+ // The time of the test program start, in ms from the start of the
+ // UNIX epoch.
+ TimeInMillis start_timestamp_;
+
// How long the test took to run, in milliseconds.
TimeInMillis elapsed_time_;
@@ -935,33 +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();
-
-# if GTEST_OS_WINDOWS
-// Provides leak-safe Windows kernel handle ownership.
-class AutoHandle {
- public:
- AutoHandle() : handle_(INVALID_HANDLE_VALUE) {}
- explicit AutoHandle(HANDLE handle) : handle_(handle) {}
-
- ~AutoHandle() { Reset(); }
-
- HANDLE Get() const { return handle_; }
- void Reset() { Reset(INVALID_HANDLE_VALUE); }
- void Reset(HANDLE handle) {
- if (handle != handle_) {
- if (handle_ != INVALID_HANDLE_VALUE)
- ::CloseHandle(handle_);
- handle_ = handle;
- }
- }
-
- private:
- HANDLE handle_;
-
- GTEST_DISALLOW_COPY_AND_ASSIGN_(AutoHandle);
-};
-# endif // GTEST_OS_WINDOWS
+GTEST_API_ std::string GetLastErrnoDescription();
// Attempts to parse a string into a positive integer pointed to by the
// number parameter. Returns true if that is possible.
@@ -1018,8 +1023,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) {
@@ -1032,6 +1038,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