Index: chromeos/dbus/services/proxy_resolution_service_provider_unittest.cc |
diff --git a/chromeos/dbus/services/proxy_resolution_service_provider_unittest.cc b/chromeos/dbus/services/proxy_resolution_service_provider_unittest.cc |
index bbd935bfe7d8d0b6103493f7d63a6ba2249b635a..336d0171928831e32df91be58cf796ee0f755056 100644 |
--- a/chromeos/dbus/services/proxy_resolution_service_provider_unittest.cc |
+++ b/chromeos/dbus/services/proxy_resolution_service_provider_unittest.cc |
@@ -5,10 +5,14 @@ |
#include "chromeos/dbus/services/proxy_resolution_service_provider.h" |
#include "base/bind.h" |
+#include "base/bind_helpers.h" |
+#include "base/logging.h" |
#include "base/macros.h" |
#include "base/memory/ptr_util.h" |
#include "base/run_loop.h" |
#include "base/single_thread_task_runner.h" |
+#include "base/test/thread_test_helper.h" |
+#include "base/threading/thread.h" |
#include "base/threading/thread_task_runner_handle.h" |
#include "chromeos/dbus/services/service_provider_test_helper.h" |
#include "dbus/message.h" |
@@ -30,6 +34,13 @@ namespace { |
const char kReturnSignalInterface[] = "org.chromium.TestInterface"; |
const char kReturnSignalName[] = "TestSignal"; |
+// Runs all tasks on |task_runner|. |
+void RunAllTasks(scoped_refptr<base::SingleThreadTaskRunner> task_runner) { |
+ scoped_refptr<base::ThreadTestHelper> helper = |
+ new base::ThreadTestHelper(task_runner); |
+ ASSERT_TRUE(helper->Run()); |
+} |
+ |
// Trivial net::ProxyResolver implementation that returns canned data either |
// synchronously or asynchronously. |
class TestProxyResolver : public net::ProxyResolver { |
@@ -110,6 +121,33 @@ class TestDelegate : public ProxyResolutionServiceProvider::Delegate { |
: proxy_resolver_(proxy_resolver), |
context_getter_( |
new net::TestURLRequestContextGetter(network_task_runner)) { |
+ // NetworkProxy derives from base::NonThreadSafe, so it needs to be created |
+ // on the network thread so it won't blow up when it's called from there |
+ // later. |
+ network_task_runner->PostTask( |
+ FROM_HERE, base::Bind(&TestDelegate::CreateProxyServiceOnNetworkThread, |
+ base::Unretained(this))); |
+ RunAllTasks(network_task_runner); |
Daniel Erat
2017/04/01 00:19:19
yuck.
James Cook
2017/04/03 15:30:23
lol
|
+ } |
+ |
+ ~TestDelegate() override { |
+ context_getter_->GetNetworkTaskRunner()->PostTask( |
+ FROM_HERE, base::Bind(&TestDelegate::DeleteProxyServiceOnNetworkThread, |
+ base::Unretained(this))); |
+ RunAllTasks(context_getter_->GetNetworkTaskRunner()); |
Daniel Erat
2017/04/01 00:19:19
yuck again.
|
+ } |
+ |
+ // ProxyResolutionServiceProvider::Delegate: |
+ scoped_refptr<net::URLRequestContextGetter> GetRequestContext() override { |
+ return context_getter_; |
+ } |
+ |
+ private: |
+ // Helper method for the constructor that initializes |proxy_service_| and |
+ // injects it into |context_getter_|'s context. |
+ void CreateProxyServiceOnNetworkThread() { |
+ CHECK(context_getter_->GetNetworkTaskRunner()->BelongsToCurrentThread()); |
+ |
// The config's autodetect property needs to be set in order for |
// net::ProxyService to send requests to our resolver. |
net::ProxyConfig config = net::ProxyConfig::CreateAutoDetect(); |
@@ -120,14 +158,13 @@ class TestDelegate : public ProxyResolutionServiceProvider::Delegate { |
context_getter_->GetURLRequestContext()->set_proxy_service( |
proxy_service_.get()); |
} |
- ~TestDelegate() override = default; |
- // ProxyResolutionServiceProvider::Delegate: |
- scoped_refptr<net::URLRequestContextGetter> GetRequestContext() override { |
- return context_getter_; |
+ // Helper method for the destructor that resets |proxy_service_|. |
+ void DeleteProxyServiceOnNetworkThread() { |
+ CHECK(context_getter_->GetNetworkTaskRunner()->BelongsToCurrentThread()); |
+ proxy_service_.reset(); |
} |
- private: |
net::ProxyResolver* proxy_resolver_; // Not owned. |
std::unique_ptr<net::ProxyService> proxy_service_; |
James Cook
2017/04/03 15:30:23
optional: comment that it lives on network thread?
Daniel Erat
2017/04/04 00:01:37
Done.
|
scoped_refptr<net::TestURLRequestContextGetter> context_getter_; |
@@ -139,20 +176,26 @@ class TestDelegate : public ProxyResolutionServiceProvider::Delegate { |
class ProxyResolutionServiceProviderTest : public testing::Test { |
public: |
- ProxyResolutionServiceProviderTest() = default; |
- ~ProxyResolutionServiceProviderTest() override = default; |
+ ProxyResolutionServiceProviderTest() : network_thread_("NetworkThread") { |
+ CHECK(network_thread_.Start()); |
- // testing::Test: |
- void SetUp() override { |
- proxy_resolver_ = base::MakeUnique<TestProxyResolver>( |
- base::ThreadTaskRunnerHandle::Get()); |
+ proxy_resolver_ = |
+ base::MakeUnique<TestProxyResolver>(network_thread_.task_runner()); |
service_provider_ = base::MakeUnique<ProxyResolutionServiceProvider>( |
- base::MakeUnique<TestDelegate>(base::ThreadTaskRunnerHandle::Get(), |
+ base::MakeUnique<TestDelegate>(network_thread_.task_runner(), |
proxy_resolver_.get())); |
test_helper_.SetUp(kResolveNetworkProxy, service_provider_.get()); |
} |
- void TearDown() override { |
+ |
+ ~ProxyResolutionServiceProviderTest() override { |
test_helper_.TearDown(); |
+ |
+ // URLRequestContextGetter posts a task to delete itself to its task runner, |
+ // so give it a chance to do that. |
+ service_provider_.reset(); |
+ RunAllTasks(network_thread_.task_runner()); |
+ |
+ network_thread_.Stop(); |
} |
protected: |
@@ -216,10 +259,19 @@ class ProxyResolutionServiceProviderTest : public testing::Test { |
} |
*response_out = test_helper_.CallMethod(&method_call); |
+ |
+ // Let the main thread perform work on the network thread and then send the |
+ // response. |
base::RunLoop().RunUntilIdle(); |
+ RunAllTasks(network_thread_.task_runner()); |
+ base::RunLoop().RunUntilIdle(); |
Daniel Erat
2017/04/04 00:01:37
sigh, it turns out there's a tricky race here. i t
|
+ |
*signal_out = std::move(signal_); |
} |
+ // Thread used to perform network operations. |
+ base::Thread network_thread_; |
+ |
// Information about the last D-Bus signal received by OnSignalReceived(). |
std::unique_ptr<SignalInfo> signal_; |