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 #ifndef CHROME_BROWSER_NET_CONNECTION_TESTER_H_
6 #define CHROME_BROWSER_NET_CONNECTION_TESTER_H_
10 #include "base/basictypes.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "net/base/completion_callback.h"
17 class URLRequestContext
;
20 // ConnectionTester runs a suite of tests (also called "experiments"),
21 // to try and discover why loading a particular URL is failing with an error
24 // For example, one reason why the URL might have failed, is that the
25 // network requires the URL to be routed through a proxy, however chrome is
26 // not configured for that.
28 // The above issue might be detected by running test that fetches the URL using
29 // auto-detect and seeing if it works this time. Or even by retrieving the
30 // settings from another installed browser and trying with those.
34 // To run the test suite, create an instance of ConnectionTester and then call
37 // This starts a sequence of tests, which will complete asynchronously.
38 // The ConnectionTester object can be deleted at any time, and it will abort
39 // any of the in-progress tests.
41 // As tests are started or completed, notification will be sent through the
44 class ConnectionTester
{
46 // This enum lists the possible proxy settings configurations.
47 enum ProxySettingsExperiment
{
48 // Do not use any proxy.
49 PROXY_EXPERIMENT_USE_DIRECT
= 0,
51 // Use the system proxy settings.
52 PROXY_EXPERIMENT_USE_SYSTEM_SETTINGS
,
54 // Use Firefox's proxy settings if they are available.
55 PROXY_EXPERIMENT_USE_FIREFOX_SETTINGS
,
57 // Use proxy auto-detect.
58 PROXY_EXPERIMENT_USE_AUTO_DETECT
,
60 PROXY_EXPERIMENT_COUNT
,
63 // This enum lists the possible host resolving configurations.
64 enum HostResolverExperiment
{
65 // Use a default host resolver implementation.
66 HOST_RESOLVER_EXPERIMENT_PLAIN
= 0,
68 // Disable IPv6 host resolving.
69 HOST_RESOLVER_EXPERIMENT_DISABLE_IPV6
,
71 // Probe for IPv6 support.
72 HOST_RESOLVER_EXPERIMENT_IPV6_PROBE
,
74 HOST_RESOLVER_EXPERIMENT_COUNT
,
77 // The "Experiment" structure describes an individual test to run.
79 Experiment(const GURL
& url
,
80 ProxySettingsExperiment proxy_settings_experiment
,
81 HostResolverExperiment host_resolver_experiment
)
83 proxy_settings_experiment(proxy_settings_experiment
),
84 host_resolver_experiment(host_resolver_experiment
) {
87 // The URL to try and fetch.
90 // The proxy settings to use.
91 ProxySettingsExperiment proxy_settings_experiment
;
93 // The host resolver settings to use.
94 HostResolverExperiment host_resolver_experiment
;
97 typedef std::vector
<Experiment
> ExperimentList
;
99 // "Delegate" is an interface for receiving start and completion notification
100 // of individual tests that are run by the ConnectionTester.
102 // NOTE: do not delete the ConnectionTester when executing within one of the
106 // Called once the test suite is about to start.
107 virtual void OnStartConnectionTestSuite() = 0;
109 // Called when an individual experiment is about to be started.
110 virtual void OnStartConnectionTestExperiment(
111 const Experiment
& experiment
) = 0;
113 // Called when an individual experiment has completed.
114 // |experiment| - the experiment that has completed.
115 // |result| - the net error that the experiment completed with
116 // (or net::OK if it was success).
117 virtual void OnCompletedConnectionTestExperiment(
118 const Experiment
& experiment
,
121 // Called once ALL tests have completed.
122 virtual void OnCompletedConnectionTestSuite() = 0;
125 virtual ~Delegate() {}
128 // Constructs a ConnectionTester that notifies test progress to |delegate|.
129 // |delegate| is owned by the caller, and must remain valid for the lifetime
130 // of ConnectionTester.
131 ConnectionTester(Delegate
* delegate
,
132 net::URLRequestContext
* proxy_request_context
,
133 net::NetLog
* net_log
);
135 // Note that destruction cancels any in-progress tests.
138 // Starts running the test suite on |url|. Notification of progress is sent to
140 void RunAllTests(const GURL
& url
);
142 // Returns a text string explaining what |experiment| is testing.
143 static base::string16
ProxySettingsExperimentDescription(
144 ProxySettingsExperiment experiment
);
145 static base::string16
HostResolverExperimentDescription(
146 HostResolverExperiment experiment
);
149 // Internally each experiment run by ConnectionTester is handled by a
150 // "TestRunner" instance.
152 friend class TestRunner
;
154 // Fills |list| with the set of all possible experiments for |url|.
155 static void GetAllPossibleExperimentCombinations(const GURL
& url
,
156 ExperimentList
* list
);
158 // Starts the next experiment from |remaining_experiments_|.
159 void StartNextExperiment();
161 // Callback for when |current_test_runner_| finishes.
162 void OnExperimentCompleted(int result
);
164 // Returns the experiment at the front of our list.
165 const Experiment
& current_experiment() const {
166 return remaining_experiments_
.front();
169 // The object to notify test progress to.
172 // The current in-progress test, or NULL if there is no active test.
173 scoped_ptr
<TestRunner
> current_test_runner_
;
175 // The ordered list of experiments to try next. The experiment at the front
176 // of the list is the one currently in progress.
177 ExperimentList remaining_experiments_
;
179 net::URLRequestContext
* const proxy_request_context_
;
181 net::NetLog
* net_log_
;
183 DISALLOW_COPY_AND_ASSIGN(ConnectionTester
);
186 #endif // CHROME_BROWSER_NET_CONNECTION_TESTER_H_