172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/net/connection_tester.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
74a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "chrome/test/testing_pref_service.h"
8dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browser_thread.h"
921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "net/base/cert_verifier.h"
1021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "net/base/cookie_monster.h"
1121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "net/base/dnsrr_resolver.h"
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/mock_host_resolver.h"
1321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "net/base/ssl_config_service_defaults.h"
1421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "net/ftp/ftp_network_layer.h"
1521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "net/http/http_auth_handler_factory.h"
1621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "net/http/http_network_layer.h"
1772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "net/http/http_network_session.h"
1821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "net/proxy/proxy_config_service_fixed.h"
193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "net/test/test_server.h"
2021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "net/url_request/url_request_context.h"
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "testing/gtest/include/gtest/gtest.h"
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "testing/platform_test.h"
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace {
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// This is a testing delegate which simply counts how many times each of
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// the delegate's methods were invoked.
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass ConnectionTesterDelegate : public ConnectionTester::Delegate {
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ConnectionTesterDelegate()
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch     : start_connection_test_suite_count_(0),
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       start_connection_test_experiment_count_(0),
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       completed_connection_test_experiment_count_(0),
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       completed_connection_test_suite_count_(0) {
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void OnStartConnectionTestSuite() {
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    start_connection_test_suite_count_++;
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void OnStartConnectionTestExperiment(
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      const ConnectionTester::Experiment& experiment) {
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    start_connection_test_experiment_count_++;
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void OnCompletedConnectionTestExperiment(
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      const ConnectionTester::Experiment& experiment,
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      int result) {
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    completed_connection_test_experiment_count_++;
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void OnCompletedConnectionTestSuite() {
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    completed_connection_test_suite_count_++;
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    MessageLoop::current()->Quit();
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int start_connection_test_suite_count() const {
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return start_connection_test_suite_count_;
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int start_connection_test_experiment_count() const {
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return start_connection_test_experiment_count_;
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int completed_connection_test_experiment_count() const {
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return completed_connection_test_experiment_count_;
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int completed_connection_test_suite_count() const {
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return completed_connection_test_suite_count_;
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int start_connection_test_suite_count_;
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int start_connection_test_experiment_count_;
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int completed_connection_test_experiment_count_;
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int completed_connection_test_suite_count_;
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The test fixture is responsible for:
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//   - Making sure each test has an IO loop running
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//   - Catching any host resolve requests and mapping them to localhost
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//     (so the test doesn't use any external network dependencies).
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass ConnectionTesterTest : public PlatformTest {
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ConnectionTesterTest()
87ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      : message_loop_(MessageLoop::TYPE_IO),
88ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        io_thread_(BrowserThread::IO, &message_loop_),
89ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        test_server_(net::TestServer::TYPE_HTTP,
903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest"))),
91ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        proxy_script_fetcher_context_(new net::URLRequestContext) {
9221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    InitializeRequestContext();
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch protected:
96ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Destroy last the MessageLoop last to give a chance for objects like
97ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // ObserverListThreadSave to shut down properly.  For example,
98ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // SSLClientAuthCache calls RemoveObserver when destroyed, but if the
99ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // MessageLoop is already destroyed, then the RemoveObserver will be a
100ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // no-op, and the ObserverList will contain invalid entries.
101ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  MessageLoop message_loop_;
102ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  BrowserThread io_thread_;
1033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  net::TestServer test_server_;
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ConnectionTesterDelegate test_delegate_;
10521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  net::MockHostResolver host_resolver_;
10621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  net::CertVerifier cert_verifier_;
10721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  net::DnsRRResolver dnsrr_resolver_;
10821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  scoped_refptr<net::ProxyService> proxy_service_;
10921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  scoped_refptr<net::SSLConfigService> ssl_config_service_;
11021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  scoped_ptr<net::HttpTransactionFactory> http_transaction_factory_;
11121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  net::HttpAuthHandlerRegistryFactory http_auth_handler_factory_;
11272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  scoped_refptr<net::URLRequestContext> proxy_script_fetcher_context_;
11321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
11421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen private:
11521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  void InitializeRequestContext() {
11621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    proxy_script_fetcher_context_->set_host_resolver(&host_resolver_);
11721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    proxy_script_fetcher_context_->set_cert_verifier(&cert_verifier_);
11821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    proxy_script_fetcher_context_->set_dnsrr_resolver(&dnsrr_resolver_);
11921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    proxy_script_fetcher_context_->set_http_auth_handler_factory(
12021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        &http_auth_handler_factory_);
12121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    proxy_service_ = net::ProxyService::CreateDirect();
12221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    proxy_script_fetcher_context_->set_proxy_service(proxy_service_);
12321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    ssl_config_service_ = net::SSLConfigService::CreateSystemSSLConfigService();
12472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    net::HttpNetworkSession::Params session_params;
12572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    session_params.host_resolver = &host_resolver_;
12672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    session_params.cert_verifier = &cert_verifier_;
12772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    session_params.dnsrr_resolver = &dnsrr_resolver_;
12872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    session_params.http_auth_handler_factory = &http_auth_handler_factory_;
12972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    session_params.ssl_config_service = ssl_config_service_;
13072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    session_params.proxy_service = proxy_service_;
13172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    scoped_refptr<net::HttpNetworkSession> network_session(
13272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        new net::HttpNetworkSession(session_params));
13321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    http_transaction_factory_.reset(
13472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        new net::HttpNetworkLayer(network_session));
13521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    proxy_script_fetcher_context_->set_http_transaction_factory(
13621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        http_transaction_factory_.get());
13721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // In-memory cookie store.
13821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    proxy_script_fetcher_context_->set_cookie_store(
13921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        new net::CookieMonster(NULL, NULL));
14021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ConnectionTesterTest, RunAllTests) {
1443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ASSERT_TRUE(test_server_.Start());
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
14621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ConnectionTester tester(&test_delegate_, proxy_script_fetcher_context_);
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Start the test suite on URL "echoall".
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TODO(eroman): Is this URL right?
1503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  tester.RunAllTests(test_server_.GetURL("echoall"));
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Wait for all the tests to complete.
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->Run();
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const int kNumExperiments =
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ConnectionTester::PROXY_EXPERIMENT_COUNT *
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ConnectionTester::HOST_RESOLVER_EXPERIMENT_COUNT;
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, test_delegate_.start_connection_test_suite_count());
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(kNumExperiments,
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            test_delegate_.start_connection_test_experiment_count());
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(kNumExperiments,
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            test_delegate_.completed_connection_test_experiment_count());
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, test_delegate_.completed_connection_test_suite_count());
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ConnectionTesterTest, DeleteWhileInProgress) {
1683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ASSERT_TRUE(test_server_.Start());
169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
170731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<ConnectionTester> tester(
17121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      new ConnectionTester(&test_delegate_, proxy_script_fetcher_context_));
172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Start the test suite on URL "echoall".
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TODO(eroman): Is this URL right?
1753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  tester->RunAllTests(test_server_.GetURL("echoall"));
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->RunAllPending();
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, test_delegate_.start_connection_test_suite_count());
180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1, test_delegate_.start_connection_test_experiment_count());
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(0, test_delegate_.completed_connection_test_experiment_count());
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(0, test_delegate_.completed_connection_test_suite_count());
183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Delete the ConnectionTester while it is in progress.
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tester.reset();
186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Drain the tasks on the message loop.
188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //
189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Note that we cannot simply stop the message loop, since that will delete
190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // any pending tasks instead of running them. This causes a problem with
191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // net::ClientSocketPoolBaseHelper, since the "Group" holds a pointer
192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // |backup_task| that it will try to deref during the destructor, but
193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // depending on the order that pending tasks were deleted in, it might
194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // already be invalid! See http://crbug.com/43291.
195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->Run();
197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace
200