Expose ScopedTrace utility in public interface

This commit is contained in:
Fedor Trushkin 2018-01-17 16:41:59 +01:00
parent 1b077667bd
commit 9c82e7745c
6 changed files with 94 additions and 70 deletions

View File

@ -1299,9 +1299,9 @@ class GTEST_API_ UnitTest {
// These classes and functions are friends as they need to access private
// members of UnitTest.
friend class ScopedTrace;
friend class Test;
friend class internal::AssertHelper;
friend class internal::ScopedTrace;
friend class internal::StreamingListenerTest;
friend class internal::UnitTestRecordPropertyTestHelper;
friend Environment* AddGlobalTestEnvironment(Environment* env);
@ -2102,6 +2102,57 @@ GTEST_API_ AssertionResult DoubleLE(const char* expr1, const char* expr2,
#define EXPECT_NO_FATAL_FAILURE(statement) \
GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_NONFATAL_FAILURE_)
// Causes a trace (including the given source file path and line number,
// and the given message) to be included in every test failure message generated
// by code in the scope of the lifetime of an instance of this class. The effect
// is undone with the destruction of the instance.
//
// The message argument can be anything streamable to std::ostream.
//
// Example:
// testing::ScopedTrace trace("file.cc", 123, "message");
//
class GTEST_API_ ScopedTrace {
public:
// The c'tor pushes the given source file location and message onto
// a trace stack maintained by Google Test.
// Template version. Uses Message() to convert the values into strings.
// Slow, but flexible.
template <typename T>
ScopedTrace(const char* file, int line, const T& message) {
PushTrace(file, line, (Message() << message).GetString());
}
// Optimize for some known types.
ScopedTrace(const char* file, int line, const char* message) {
PushTrace(file, line, message ? message : "(null)");
}
#if GTEST_HAS_GLOBAL_STRING
ScopedTrace(const char* file, int line, const ::string& message) {
PushTrace(file, line, message);
}
#endif
ScopedTrace(const char* file, int line, const std::string& message) {
PushTrace(file, line, message);
}
// The d'tor pops the info pushed by the c'tor.
//
// Note that the d'tor is not virtual in order to be efficient.
// Don't inherit from ScopedTrace!
~ScopedTrace();
private:
void PushTrace(const char* file, int line, std::string message);
GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedTrace);
} GTEST_ATTRIBUTE_UNUSED_; // A ScopedTrace object does its job in its
// c'tor and d'tor. Therefore it doesn't
// need to be used otherwise.
// Causes a trace (including the source file path, the current line
// number, and the given message) to be included in every test failure
// message generated by code in the current scope. The effect is
@ -2118,7 +2169,7 @@ GTEST_API_ AssertionResult DoubleLE(const char* expr1, const char* expr2,
// Therefore, a SCOPED_TRACE() would (correctly) only affect the
// assertions in its own thread.
#define SCOPED_TRACE(message) \
::testing::internal::ScopedTrace GTEST_CONCAT_TOKEN_(gtest_trace_, __LINE__)(\
::testing::ScopedTrace GTEST_CONCAT_TOKEN_(gtest_trace_, __LINE__)(\
__FILE__, __LINE__, (message))

View File

@ -95,7 +95,6 @@ template <typename T>
namespace internal {
struct TraceInfo; // Information about a trace point.
class ScopedTrace; // Implements scoped trace.
class TestInfoImpl; // Opaque implementation of TestInfo
class UnitTestImpl; // Opaque implementation of UnitTest
@ -151,48 +150,6 @@ class GTEST_API_ GoogleTestFailureException : public ::std::runtime_error {
#endif // GTEST_HAS_EXCEPTIONS
// A helper class for creating scoped traces in user programs.
class GTEST_API_ ScopedTrace {
public:
// The c'tor pushes the given source file location and message onto
// a trace stack maintained by Google Test.
// Template version. Uses Message() to convert the values into strings.
// Slow, but flexible.
template <typename T>
ScopedTrace(const char* file, int line, const T& message) {
PushTrace(file, line, (Message() << message).GetString());
}
// Optimize for some known types.
ScopedTrace(const char* file, int line, const char* message) {
PushTrace(file, line, message ? message : "(null)");
}
#if GTEST_HAS_GLOBAL_STRING
ScopedTrace(const char* file, int line, const ::string& message) {
PushTrace(file, line, message);
}
#endif
ScopedTrace(const char* file, int line, const std::string& message) {
PushTrace(file, line, message);
}
// The d'tor pops the info pushed by the c'tor.
//
// Note that the d'tor is not virtual in order to be efficient.
// Don't inherit from ScopedTrace!
~ScopedTrace();
private:
void PushTrace(const char* file, int line, std::string message);
GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedTrace);
} GTEST_ATTRIBUTE_UNUSED_; // A ScopedTrace object does its job in its
// c'tor and d'tor. Therefore it doesn't
// need to be used otherwise.
namespace edit_distance {
// Returns the optimal edits to go from 'left' to 'right'.
// All edits cost the same, with replace having lower priority than

View File

@ -3835,26 +3835,6 @@ void StreamingListener::SocketWriter::MakeConnection() {
// End of class Streaming Listener
#endif // GTEST_CAN_STREAM_RESULTS__
// Class ScopedTrace
// Pushes the given source file location and message onto a per-thread
// trace stack maintained by Google Test.
void ScopedTrace::PushTrace(const char* file, int line, std::string message) {
TraceInfo trace;
trace.file = file;
trace.line = line;
trace.message.swap(message);
UnitTest::GetInstance()->PushGTestTrace(trace);
}
// Pops the info pushed by the c'tor.
ScopedTrace::~ScopedTrace()
GTEST_LOCK_EXCLUDED_(&UnitTest::mutex_) {
UnitTest::GetInstance()->PopGTestTrace();
}
// class OsStackTraceGetter
const char* const OsStackTraceGetterInterface::kElidedFramesMarker =
@ -5415,4 +5395,23 @@ std::string TempDir() {
#endif // GTEST_OS_WINDOWS_MOBILE
}
// Class ScopedTrace
// Pushes the given source file location and message onto a per-thread
// trace stack maintained by Google Test.
void ScopedTrace::PushTrace(const char* file, int line, std::string message) {
internal::TraceInfo trace;
trace.file = file;
trace.line = line;
trace.message.swap(message);
UnitTest::GetInstance()->PushGTestTrace(trace);
}
// Pops the info pushed by the c'tor.
ScopedTrace::~ScopedTrace()
GTEST_LOCK_EXCLUDED_(&UnitTest::mutex_) {
UnitTest::GetInstance()->PopGTestTrace();
}
} // namespace testing

View File

@ -99,7 +99,8 @@ def RemoveLocations(test_output):
'FILE_NAME:#: '.
"""
return re.sub(r'.*[/\\](.+)(\:\d+|\(\d+\))\: ', r'\1:#: ', test_output)
return re.sub(r'.*[/\\]((gtest_output_test_|gtest).cc)(\:\d+|\(\d+\))\: ',
r'\1:#: ', test_output)
def RemoveStackTraceDetails(output):

View File

@ -315,6 +315,13 @@ TEST(SCOPED_TRACETest, WorksConcurrently) {
}
#endif // GTEST_IS_THREADSAFE
// Tests basic functionality of the ScopedTrace utility (most of its features
// are already tested in SCOPED_TRACETest).
TEST(ScopedTraceTest, WithExplicitFileAndLine) {
testing::ScopedTrace trace("explicit_file.cc", 123, "expected trace message");
ADD_FAILURE() << "Check that the trace is attached to a particular location.";
}
TEST(DisabledTestsWarningTest,
DISABLED_AlsoRunDisabledTestsFlagSuppressesWarning) {
// This test body is intentionally empty. Its sole purpose is for

View File

@ -8,7 +8,7 @@ gtest_output_test_.cc:#: Failure
Expected equality of these values:
2
3
[==========] Running 66 tests from 29 test cases.
[==========] Running 67 tests from 30 test cases.
[----------] Global test environment set-up.
FooEnvironment::SetUp() called.
BarEnvironment::SetUp() called.
@ -212,6 +212,14 @@ gtest_output_test_.cc:#: Failure
Failed
Expected failure #6 (in thread A, no trace alive).
[ FAILED ] SCOPED_TRACETest.WorksConcurrently
[----------] 1 test from ScopedTraceTest
[ RUN ] ScopedTraceTest.WithExplicitFileAndLine
gtest_output_test_.cc:#: Failure
Failed
Check that the trace is attached to a particular location.
Google Test trace:
explicit_file.cc:123: expected trace message
[ FAILED ] ScopedTraceTest.WithExplicitFileAndLine
[----------] 1 test from NonFatalFailureInFixtureConstructorTest
[ RUN ] NonFatalFailureInFixtureConstructorTest.FailureInConstructor
(expecting 5 failures)
@ -636,9 +644,9 @@ FooEnvironment::TearDown() called.
gtest_output_test_.cc:#: Failure
Failed
Expected fatal failure.
[==========] 66 tests from 29 test cases ran.
[==========] 67 tests from 30 test cases ran.
[ PASSED ] 22 tests.
[ FAILED ] 44 tests, listed below:
[ FAILED ] 45 tests, listed below:
[ FAILED ] NonfatalFailureTest.EscapesStringOperands
[ FAILED ] NonfatalFailureTest.DiffForLongStrings
[ FAILED ] FatalFailureTest.FatalFailureInSubroutine
@ -651,6 +659,7 @@ Expected fatal failure.
[ FAILED ] SCOPED_TRACETest.CanBeNested
[ FAILED ] SCOPED_TRACETest.CanBeRepeated
[ FAILED ] SCOPED_TRACETest.WorksConcurrently
[ FAILED ] ScopedTraceTest.WithExplicitFileAndLine
[ FAILED ] NonFatalFailureInFixtureConstructorTest.FailureInConstructor
[ FAILED ] FatalFailureInFixtureConstructorTest.FailureInConstructor
[ FAILED ] NonFatalFailureInSetUpTest.FailureInSetUp
@ -684,7 +693,7 @@ Expected fatal failure.
[ FAILED ] PrintingFailingParams/FailingParamTest.Fails/0, where GetParam() = 2
[ FAILED ] PrintingStrings/ParamTest.Failure/a, where GetParam() = "a"
44 FAILED TESTS
45 FAILED TESTS
 YOU HAVE 1 DISABLED TEST
Note: Google Test filter = FatalFailureTest.*:LoggingTest.*