Event Listener callback for scope enter / exit

This commit is contained in:
Denis Hananein 2024-08-06 20:15:13 +02:00
parent ff233bdd4c
commit a6b70a685d
4 changed files with 85 additions and 0 deletions

View file

@ -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)`

View file

@ -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
@ -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;

View file

@ -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
@ -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
@ -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();
}

View file

@ -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 trace: %s:%d message: %s.\n",
test_info->name(), file, 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