Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#4178 Event Listener callback for scope enter / exit #4590

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions docs/reference/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -1038,6 +1038,20 @@ int iteration)`

Fired after each iteration of tests finishes.


##### OnScopedTraceEnter {#TestEventListener::OnScopedTraceEnter}

`virtual void TestEventListener::OnScopedTraceEnter(const UnitTest& unit_test, const char* file,
int line, std::string message)`

Fired before the test scope enter.

##### OnScopedTraceExit {#TestEventListener::OnScopedTraceExit}

`virtual void TestEventListener::OnScopedTraceExit(const UnitTest& unit_test)`

Fired after the test scope exit.

##### OnTestProgramEnd {#TestEventListener::OnTestProgramEnd}

`virtual void TestEventListener::OnTestProgramEnd(const UnitTest& unit_test)`
Expand Down
9 changes: 9 additions & 0 deletions googletest/include/gtest/gtest.h
Original file line number Diff line number Diff line change
Expand Up @@ -982,6 +982,14 @@ class TestEventListener {

// Fired after all test activities have ended.
virtual void OnTestProgramEnd(const UnitTest& unit_test) = 0;

// Fired before the test scope enter.
virtual void OnScopedTraceEnter(const UnitTest& /*unit_test*/,
const char* /*file*/, int /*line*/,
std::string /*message*/) {}

// Fired after the test scope exit.
virtual void OnScopedTraceExit(const UnitTest& /*unit_test*/) {}
};

// The convenience class for users who need to override just one or two
Expand Down Expand Up @@ -1061,6 +1069,7 @@ class GTEST_API_ TestEventListeners {
private:
friend class TestSuite;
friend class TestInfo;
friend class UnitTest;
friend class internal::DefaultGlobalTestPartResultReporter;
friend class internal::NoExecDeathTest;
friend class internal::TestEventListenersAccessor;
Expand Down
20 changes: 20 additions & 0 deletions googletest/src/gtest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3817,6 +3817,9 @@ class TestEventRepeater : public TestEventListener {
void OnEnvironmentsTearDownEnd(const UnitTest& parameter) override;
void OnTestIterationEnd(const UnitTest& unit_test, int iteration) override;
void OnTestProgramEnd(const UnitTest& parameter) override;
void OnScopedTraceEnter(const UnitTest& unit_test, const char* file, int line,
std::string message) override;
void OnScopedTraceExit(const UnitTest& unit_test) override;

private:
// Controls whether events will be forwarded to listeners_. Set to false
Expand Down Expand Up @@ -3911,6 +3914,20 @@ void TestEventRepeater::OnTestIterationEnd(const UnitTest& unit_test,
}
}

void TestEventRepeater::OnScopedTraceEnter(const UnitTest& unit_test,
const char* file, int line,
std::string message) {
for (size_t i = 0; i < listeners_.size(); i++) {
listeners_[i]->OnScopedTraceEnter(unit_test, file, line, message);
}
}

void TestEventRepeater::OnScopedTraceExit(const UnitTest& unit_test) {
for (size_t i = listeners_.size(); i > 0; i--) {
listeners_[i - 1]->OnScopedTraceExit(unit_test);
}
}

// End TestEventRepeater

#if GTEST_HAS_FILE_SYSTEM
Expand Down Expand Up @@ -5603,12 +5620,15 @@ UnitTest::~UnitTest() { delete impl_; }
// Google Test trace stack.
void UnitTest::PushGTestTrace(const internal::TraceInfo& trace)
GTEST_LOCK_EXCLUDED_(mutex_) {
impl_->listeners()->repeater()->OnScopedTraceEnter(*this, trace.file,
trace.line, trace.message);
internal::MutexLock lock(&mutex_);
impl_->gtest_trace_stack().push_back(trace);
}

// Pops a trace from the per-thread Google Test trace stack.
void UnitTest::PopGTestTrace() GTEST_LOCK_EXCLUDED_(mutex_) {
impl_->listeners()->repeater()->OnScopedTraceExit(*this);
internal::MutexLock lock(&mutex_);
impl_->gtest_trace_stack().pop_back();
}
Expand Down
42 changes: 42 additions & 0 deletions googletest/test/googletest-output-test_.cc
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,48 @@ TEST(SCOPED_TRACETest, CanBeRepeated) {
<< "contain trace point A, B, and D.";
}

class MyScopedTraceTestListener : public ::testing::EmptyTestEventListener {
void OnScopedTraceEnter(const testing::UnitTest& unit_test, const char* file,
int line, std::string message) override {
const auto* test_info = unit_test.current_test_info();
printf("scoped trace enter test: %s line: %d message: %s.\n",
test_info->name(), line, message.c_str());
}

void OnScopedTraceExit(const testing::UnitTest& unit_test) override {
printf("scoped trace exit test: %s.\n",
unit_test.current_test_info()->name());
}
};

// Tests that multiple SCOPED_TRACEs can be used in the same scope.
TEST(SCOPED_TRACEWithListenerTest, CanBeRepeated) {
MyScopedTraceTestListener* listener = new MyScopedTraceTestListener;
::testing::UnitTest::GetInstance()->listeners().Append(listener);
{
printf("(expected to fail)\n");
SCOPED_TRACE("A");
ADD_FAILURE()
<< "This failure is expected, and should contain trace point A.";

SCOPED_TRACE("B");
ADD_FAILURE()
<< "This failure is expected, and should contain trace point A and B.";

{
SCOPED_TRACE("C");
ADD_FAILURE() << "This failure is expected, and should "
<< "contain trace point A, B, and C.";
}

SCOPED_TRACE("D");
ADD_FAILURE() << "This failure is expected, and should "
<< "contain trace point A, B, and D.";
};
::testing::UnitTest::GetInstance()->listeners().Release(listener);
delete listener;
}

#ifdef GTEST_IS_THREADSAFE
// Tests that SCOPED_TRACE()s can be used concurrently from multiple
// threads. Namely, an assertion should be affected by
Expand Down