diff --git a/api/BUILD.gn b/api/BUILD.gn index ebd22c6b43..70caec62f8 100644 --- a/api/BUILD.gn +++ b/api/BUILD.gn @@ -407,7 +407,7 @@ rtc_library("test_dependency_factory") { deps = [ ":video_quality_test_fixture_api", "../rtc_base:checks", - "../rtc_base:thread_checker", + "../rtc_base:platform_thread_types", ] } diff --git a/api/test/test_dependency_factory.cc b/api/test/test_dependency_factory.cc index e72f55aab5..41ad70cc3f 100644 --- a/api/test/test_dependency_factory.cc +++ b/api/test/test_dependency_factory.cc @@ -14,22 +14,24 @@ #include #include "rtc_base/checks.h" -#include "rtc_base/thread_checker.h" +#include "rtc_base/platform_thread_types.h" namespace webrtc { +namespace { // This checks everything in this file gets called on the same thread. It's // static because it needs to look at the static methods too. -rtc::ThreadChecker* GetThreadChecker() { - static rtc::ThreadChecker checker; - return &checker; +bool IsValidTestDependencyFactoryThread() { + const rtc::PlatformThreadRef main_thread = rtc::CurrentThreadRef(); + return rtc::IsThreadRefEqual(main_thread, rtc::CurrentThreadRef()); } +} // namespace std::unique_ptr TestDependencyFactory::instance_ = nullptr; const TestDependencyFactory& TestDependencyFactory::GetInstance() { - RTC_DCHECK(GetThreadChecker()->IsCurrent()); + RTC_DCHECK(IsValidTestDependencyFactoryThread()); if (instance_ == nullptr) { instance_ = std::make_unique(); } @@ -38,14 +40,14 @@ const TestDependencyFactory& TestDependencyFactory::GetInstance() { void TestDependencyFactory::SetInstance( std::unique_ptr instance) { - RTC_DCHECK(GetThreadChecker()->IsCurrent()); + RTC_DCHECK(IsValidTestDependencyFactoryThread()); RTC_CHECK(instance_ == nullptr); instance_ = std::move(instance); } std::unique_ptr TestDependencyFactory::CreateComponents() const { - RTC_DCHECK(GetThreadChecker()->IsCurrent()); + RTC_DCHECK(IsValidTestDependencyFactoryThread()); return nullptr; } diff --git a/call/rampup_tests.cc b/call/rampup_tests.cc index 64eab050cb..89fbe3dde7 100644 --- a/call/rampup_tests.cc +++ b/call/rampup_tests.cc @@ -362,14 +362,14 @@ void RampUpTester::AccumulateStats(const VideoSendStream::StreamStats& stream, void RampUpTester::TriggerTestDone() { RTC_DCHECK_GE(test_start_ms_, 0); - // TODO(holmer): Add audio send stats here too when those APIs are available. - if (!send_stream_) - return; - // Stop polling stats. // Corner case for field_trials=WebRTC-QuickPerfTest/Enabled/ SendTask(RTC_FROM_HERE, task_queue_, [this] { pending_task_.Stop(); }); + // TODO(holmer): Add audio send stats here too when those APIs are available. + if (!send_stream_) + return; + VideoSendStream::Stats send_stats = send_stream_->GetStats(); send_stream_ = nullptr; // To avoid dereferencing a bad pointer. diff --git a/test/test_main_lib.cc b/test/test_main_lib.cc index 15318b49e1..1fd62301e2 100644 --- a/test/test_main_lib.cc +++ b/test/test_main_lib.cc @@ -100,6 +100,40 @@ namespace { class TestMainImpl : public TestMain { public: + // In order to set up a fresh rtc::Thread state for each test and avoid + // accidentally carrying over pending tasks that might be sent from one test + // and executed while another test is running, we inject a TestListener + // that sets up a new rtc::Thread instance for the main thread, per test. + class TestListener : public ::testing::EmptyTestEventListener { + public: + TestListener() = default; + + private: + void OnTestStart(const ::testing::TestInfo& test_info) override { + // Ensure that main thread gets wrapped as an rtc::Thread. + // TODO(bugs.webrtc.org/9714): It might be better to avoid wrapping the + // main thread, or leave it to individual tests that need it. But as long + // as we have automatic thread wrapping, we need this to avoid that some + // other random thread (which one depending on which tests are run) gets + // automatically wrapped. + thread_ = rtc::Thread::CreateWithSocketServer(); + thread_->WrapCurrent(); + RTC_DCHECK_EQ(rtc::Thread::Current(), thread_.get()); + } + + void OnTestEnd(const ::testing::TestInfo& test_info) override { + // Terminate the message loop. Note that if the test failed to clean + // up pending messages, this may execute part of the test. Ideally we + // should print a warning message here, or even fail the test if it leaks. + thread_->Quit(); // Signal quit. + thread_->Run(); // Flush + process Quit signal. + thread_->UnwrapCurrent(); + thread_ = nullptr; + } + + std::unique_ptr thread_; + }; + int Init(int* argc, char* argv[]) override { ::testing::InitGoogleMock(argc, argv); absl::ParseCommandLine(*argc, argv); @@ -134,14 +168,7 @@ class TestMainImpl : public TestMain { rtc::InitializeSSL(); rtc::SSLStreamAdapter::EnableTimeCallbackForTesting(); - // Ensure that main thread gets wrapped as an rtc::Thread. - // TODO(bugs.webrt.org/9714): It might be better to avoid wrapping the main - // thread, or leave it to individual tests that need it. But as long as we - // have automatic thread wrapping, we need this to avoid that some other - // random thread (which one depending on which tests are run) gets - // automatically wrapped. - rtc::ThreadManager::Instance()->WrapCurrentThread(); - RTC_CHECK(rtc::Thread::Current()); + ::testing::UnitTest::GetInstance()->listeners().Append(new TestListener()); return 0; }