1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/net/connection_tester.h"
7 #include "base/prefs/testing_pref_service.h"
8 #include "content/public/browser/cookie_store_factory.h"
9 #include "content/public/test/test_browser_thread.h"
10 #include "content/public/browser/cookie_store_factory.h"
11 #include "net/cert/mock_cert_verifier.h"
12 #include "net/dns/mock_host_resolver.h"
13 #include "net/ftp/ftp_network_layer.h"
14 #include "net/http/http_auth_handler_factory.h"
15 #include "net/http/http_network_layer.h"
16 #include "net/http/http_network_session.h"
17 #include "net/http/http_server_properties_impl.h"
18 #include "net/http/transport_security_state.h"
19 #include "net/proxy/proxy_config_service_fixed.h"
20 #include "net/proxy/proxy_service.h"
21 #include "net/ssl/ssl_config_service_defaults.h"
22 #include "net/test/spawned_test_server/spawned_test_server.h"
23 #include "net/url_request/url_request_context.h"
24 #include "testing/gtest/include/gtest/gtest.h"
25 #include "testing/platform_test.h"
27 using content::BrowserThread
;
31 // This is a testing delegate which simply counts how many times each of
32 // the delegate's methods were invoked.
33 class ConnectionTesterDelegate
: public ConnectionTester::Delegate
{
35 ConnectionTesterDelegate()
36 : start_connection_test_suite_count_(0),
37 start_connection_test_experiment_count_(0),
38 completed_connection_test_experiment_count_(0),
39 completed_connection_test_suite_count_(0) {
42 virtual void OnStartConnectionTestSuite() OVERRIDE
{
43 start_connection_test_suite_count_
++;
46 virtual void OnStartConnectionTestExperiment(
47 const ConnectionTester::Experiment
& experiment
) OVERRIDE
{
48 start_connection_test_experiment_count_
++;
51 virtual void OnCompletedConnectionTestExperiment(
52 const ConnectionTester::Experiment
& experiment
,
53 int result
) OVERRIDE
{
54 completed_connection_test_experiment_count_
++;
57 virtual void OnCompletedConnectionTestSuite() OVERRIDE
{
58 completed_connection_test_suite_count_
++;
59 base::MessageLoop::current()->Quit();
62 int start_connection_test_suite_count() const {
63 return start_connection_test_suite_count_
;
66 int start_connection_test_experiment_count() const {
67 return start_connection_test_experiment_count_
;
70 int completed_connection_test_experiment_count() const {
71 return completed_connection_test_experiment_count_
;
74 int completed_connection_test_suite_count() const {
75 return completed_connection_test_suite_count_
;
79 int start_connection_test_suite_count_
;
80 int start_connection_test_experiment_count_
;
81 int completed_connection_test_experiment_count_
;
82 int completed_connection_test_suite_count_
;
85 // The test fixture is responsible for:
86 // - Making sure each test has an IO loop running
87 // - Catching any host resolve requests and mapping them to localhost
88 // (so the test doesn't use any external network dependencies).
89 class ConnectionTesterTest
: public PlatformTest
{
91 ConnectionTesterTest()
92 : io_thread_(BrowserThread::IO
, &message_loop_
),
93 test_server_(net::SpawnedTestServer::TYPE_HTTP
,
94 net::SpawnedTestServer::kLocalhost
,
95 // Nothing is read in this directory.
96 base::FilePath(FILE_PATH_LITERAL("chrome"))),
97 proxy_script_fetcher_context_(new net::URLRequestContext
) {
98 InitializeRequestContext();
102 // Destroy last the MessageLoop last to give a chance for objects like
103 // ObserverListThreadSave to shut down properly. For example,
104 // SSLClientAuthCache calls RemoveObserver when destroyed, but if the
105 // MessageLoop is already destroyed, then the RemoveObserver will be a
106 // no-op, and the ObserverList will contain invalid entries.
107 base::MessageLoopForIO message_loop_
;
108 content::TestBrowserThread io_thread_
;
109 net::SpawnedTestServer test_server_
;
110 ConnectionTesterDelegate test_delegate_
;
111 net::MockHostResolver host_resolver_
;
112 scoped_ptr
<net::CertVerifier
> cert_verifier_
;
113 scoped_ptr
<net::TransportSecurityState
> transport_security_state_
;
114 scoped_ptr
<net::ProxyService
> proxy_service_
;
115 scoped_refptr
<net::SSLConfigService
> ssl_config_service_
;
116 scoped_ptr
<net::HttpTransactionFactory
> http_transaction_factory_
;
117 net::HttpAuthHandlerRegistryFactory http_auth_handler_factory_
;
118 net::HttpServerPropertiesImpl http_server_properties_impl_
;
119 scoped_ptr
<net::URLRequestContext
> proxy_script_fetcher_context_
;
122 void InitializeRequestContext() {
123 proxy_script_fetcher_context_
->set_host_resolver(&host_resolver_
);
124 cert_verifier_
.reset(new net::MockCertVerifier
);
125 transport_security_state_
.reset(new net::TransportSecurityState
);
126 proxy_script_fetcher_context_
->set_cert_verifier(cert_verifier_
.get());
127 proxy_script_fetcher_context_
->set_transport_security_state(
128 transport_security_state_
.get());
129 proxy_script_fetcher_context_
->set_http_auth_handler_factory(
130 &http_auth_handler_factory_
);
131 proxy_service_
.reset(net::ProxyService::CreateDirect());
132 proxy_script_fetcher_context_
->set_proxy_service(proxy_service_
.get());
133 ssl_config_service_
= new net::SSLConfigServiceDefaults
;
134 net::HttpNetworkSession::Params session_params
;
135 session_params
.host_resolver
= &host_resolver_
;
136 session_params
.cert_verifier
= cert_verifier_
.get();
137 session_params
.transport_security_state
= transport_security_state_
.get();
138 session_params
.http_auth_handler_factory
= &http_auth_handler_factory_
;
139 session_params
.ssl_config_service
= ssl_config_service_
.get();
140 session_params
.proxy_service
= proxy_service_
.get();
141 session_params
.http_server_properties
=
142 http_server_properties_impl_
.GetWeakPtr();
143 scoped_refptr
<net::HttpNetworkSession
> network_session(
144 new net::HttpNetworkSession(session_params
));
145 http_transaction_factory_
.reset(
146 new net::HttpNetworkLayer(network_session
.get()));
147 proxy_script_fetcher_context_
->set_http_transaction_factory(
148 http_transaction_factory_
.get());
149 // In-memory cookie store.
150 proxy_script_fetcher_context_
->set_cookie_store(
151 content::CreateCookieStore(content::CookieStoreConfig()));
155 TEST_F(ConnectionTesterTest
, RunAllTests
) {
156 ASSERT_TRUE(test_server_
.Start());
158 ConnectionTester
tester(&test_delegate_
,
159 proxy_script_fetcher_context_
.get(),
162 // Start the test suite on URL "echoall".
163 // TODO(eroman): Is this URL right?
164 tester
.RunAllTests(test_server_
.GetURL("echoall"));
166 // Wait for all the tests to complete.
167 base::MessageLoop::current()->Run();
169 const int kNumExperiments
=
170 ConnectionTester::PROXY_EXPERIMENT_COUNT
*
171 ConnectionTester::HOST_RESOLVER_EXPERIMENT_COUNT
;
173 EXPECT_EQ(1, test_delegate_
.start_connection_test_suite_count());
174 EXPECT_EQ(kNumExperiments
,
175 test_delegate_
.start_connection_test_experiment_count());
176 EXPECT_EQ(kNumExperiments
,
177 test_delegate_
.completed_connection_test_experiment_count());
178 EXPECT_EQ(1, test_delegate_
.completed_connection_test_suite_count());
181 TEST_F(ConnectionTesterTest
, DeleteWhileInProgress
) {
182 ASSERT_TRUE(test_server_
.Start());
184 scoped_ptr
<ConnectionTester
> tester(
185 new ConnectionTester(&test_delegate_
,
186 proxy_script_fetcher_context_
.get(),
189 // Start the test suite on URL "echoall".
190 // TODO(eroman): Is this URL right?
191 tester
->RunAllTests(test_server_
.GetURL("echoall"));
193 // Don't run the message loop at all. Otherwise the experiment's request may
194 // complete and post a task to run the next experiment before we quit the
197 EXPECT_EQ(1, test_delegate_
.start_connection_test_suite_count());
198 EXPECT_EQ(1, test_delegate_
.start_connection_test_experiment_count());
199 EXPECT_EQ(0, test_delegate_
.completed_connection_test_experiment_count());
200 EXPECT_EQ(0, test_delegate_
.completed_connection_test_suite_count());
202 // Delete the ConnectionTester while it is in progress.
205 // Drain the tasks on the message loop.
207 // Note that we cannot simply stop the message loop, since that will delete
208 // any pending tasks instead of running them. This causes a problem with
209 // net::ClientSocketPoolBaseHelper, since the "Group" holds a pointer
210 // |backup_task| that it will try to deref during the destructor, but
211 // depending on the order that pending tasks were deleted in, it might
212 // already be invalid! See http://crbug.com/43291.
213 base::MessageLoop::current()->PostTask(FROM_HERE
,
214 base::MessageLoop::QuitClosure());
215 base::MessageLoop::current()->Run();