13f50c38dc070f4bb515c1b64450dae14f316474eKristian 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#ifndef CHROME_BROWSER_NET_CONNECTION_TESTER_H_ 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define CHROME_BROWSER_NET_CONNECTION_TESTER_H_ 73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <vector> 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/basictypes.h" 12ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h" 13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "googleurl/src/gurl.h" 14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/completion_callback.h" 15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 163f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsennamespace net { 1721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenclass URLRequestContext; 183f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen} // namespace net 19731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ConnectionTester runs a suite of tests (also called "experiments"), 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// to try and discover why loading a particular URL is failing with an error 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// code. 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// For example, one reason why the URL might have failed, is that the 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// network requires the URL to be routed through a proxy, however chrome is 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// not configured for that. 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The above issue might be detected by running test that fetches the URL using 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// auto-detect and seeing if it works this time. Or even by retrieving the 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// settings from another installed browser and trying with those. 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// USAGE: 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// To run the test suite, create an instance of ConnectionTester and then call 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// RunAllTests(). 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// This starts a sequence of tests, which will complete asynchronously. 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The ConnectionTester object can be deleted at any time, and it will abort 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// any of the in-progress tests. 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// As tests are started or completed, notification will be sent through the 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// "Delegate" object. 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass ConnectionTester { 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This enum lists the possible proxy settings configurations. 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch enum ProxySettingsExperiment { 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Do not use any proxy. 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PROXY_EXPERIMENT_USE_DIRECT = 0, 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Use the system proxy settings. 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PROXY_EXPERIMENT_USE_SYSTEM_SETTINGS, 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Use Firefox's proxy settings if they are available. 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PROXY_EXPERIMENT_USE_FIREFOX_SETTINGS, 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Use proxy auto-detect. 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PROXY_EXPERIMENT_USE_AUTO_DETECT, 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PROXY_EXPERIMENT_COUNT, 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This enum lists the possible host resolving configurations. 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch enum HostResolverExperiment { 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Use a default host resolver implementation. 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HOST_RESOLVER_EXPERIMENT_PLAIN = 0, 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Disable IPv6 host resolving. 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HOST_RESOLVER_EXPERIMENT_DISABLE_IPV6, 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Probe for IPv6 support. 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HOST_RESOLVER_EXPERIMENT_IPV6_PROBE, 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HOST_RESOLVER_EXPERIMENT_COUNT, 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The "Experiment" structure describes an individual test to run. 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch struct Experiment { 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Experiment(const GURL& url, 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ProxySettingsExperiment proxy_settings_experiment, 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HostResolverExperiment host_resolver_experiment) 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : url(url), 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch proxy_settings_experiment(proxy_settings_experiment), 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch host_resolver_experiment(host_resolver_experiment) { 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The URL to try and fetch. 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL url; 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The proxy settings to use. 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ProxySettingsExperiment proxy_settings_experiment; 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The host resolver settings to use. 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HostResolverExperiment host_resolver_experiment; 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch typedef std::vector<Experiment> ExperimentList; 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // "Delegate" is an interface for receiving start and completion notification 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // of individual tests that are run by the ConnectionTester. 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // NOTE: do not delete the ConnectionTester when executing within one of the 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // delegate methods. 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch class Delegate { 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual ~Delegate() {} 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Called once the test suite is about to start. 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void OnStartConnectionTestSuite() = 0; 110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Called when an individual experiment is about to be started. 112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void OnStartConnectionTestExperiment( 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const Experiment& experiment) = 0; 114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Called when an individual experiment has completed. 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // |experiment| - the experiment that has completed. 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // |result| - the net error that the experiment completed with 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // (or net::OK if it was success). 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void OnCompletedConnectionTestExperiment( 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const Experiment& experiment, 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int result) = 0; 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Called once ALL tests have completed. 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void OnCompletedConnectionTestSuite() = 0; 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Constructs a ConnectionTester that notifies test progress to |delegate|. 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // |delegate| is owned by the caller, and must remain valid for the lifetime 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // of ConnectionTester. 13021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen ConnectionTester(Delegate* delegate, 1313f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen net::URLRequestContext* proxy_request_context); 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Note that destruction cancels any in-progress tests. 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ~ConnectionTester(); 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Starts running the test suite on |url|. Notification of progress is sent to 137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // |delegate_|. 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void RunAllTests(const GURL& url); 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Returns a text string explaining what |experiment| is testing. 141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static string16 ProxySettingsExperimentDescription( 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ProxySettingsExperiment experiment); 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static string16 HostResolverExperimentDescription( 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HostResolverExperiment experiment); 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Internally each experiment run by ConnectionTester is handled by a 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // "TestRunner" instance. 149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch class TestRunner; 150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch friend class TestRunner; 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Fills |list| with the set of all possible experiments for |url|. 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static void GetAllPossibleExperimentCombinations(const GURL& url, 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ExperimentList* list); 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Starts the next experiment from |remaining_experiments_|. 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void StartNextExperiment(); 158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Callback for when |current_test_runner_| finishes. 160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void OnExperimentCompleted(int result); 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Returns the experiment at the front of our list. 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const Experiment& current_experiment() const { 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return remaining_experiments_.front(); 165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The object to notify test progress to. 168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Delegate* delegate_; 169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The current in-progress test, or NULL if there is no active test. 171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<TestRunner> current_test_runner_; 172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The ordered list of experiments to try next. The experiment at the front 174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // of the list is the one currently in progress. 175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ExperimentList remaining_experiments_; 176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1773f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen const scoped_refptr<net::URLRequestContext> proxy_request_context_; 178731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DISALLOW_COPY_AND_ASSIGN(ConnectionTester); 180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif // CHROME_BROWSER_NET_CONNECTION_TESTER_H_ 183