| // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CHROME_BROWSER_NET_CONNECTION_TESTER_H_ |
| #define CHROME_BROWSER_NET_CONNECTION_TESTER_H_ |
| #pragma once |
| |
| #include <vector> |
| |
| #include "base/basictypes.h" |
| #include "base/memory/scoped_ptr.h" |
| #include "googleurl/src/gurl.h" |
| #include "net/base/completion_callback.h" |
| |
| namespace net { |
| class URLRequestContext; |
| } // namespace net |
| |
| // ConnectionTester runs a suite of tests (also called "experiments"), |
| // to try and discover why loading a particular URL is failing with an error |
| // code. |
| // |
| // For example, one reason why the URL might have failed, is that the |
| // network requires the URL to be routed through a proxy, however chrome is |
| // not configured for that. |
| // |
| // The above issue might be detected by running test that fetches the URL using |
| // auto-detect and seeing if it works this time. Or even by retrieving the |
| // settings from another installed browser and trying with those. |
| // |
| // USAGE: |
| // |
| // To run the test suite, create an instance of ConnectionTester and then call |
| // RunAllTests(). |
| // |
| // This starts a sequence of tests, which will complete asynchronously. |
| // The ConnectionTester object can be deleted at any time, and it will abort |
| // any of the in-progress tests. |
| // |
| // As tests are started or completed, notification will be sent through the |
| // "Delegate" object. |
| |
| class ConnectionTester { |
| public: |
| // This enum lists the possible proxy settings configurations. |
| enum ProxySettingsExperiment { |
| // Do not use any proxy. |
| PROXY_EXPERIMENT_USE_DIRECT = 0, |
| |
| // Use the system proxy settings. |
| PROXY_EXPERIMENT_USE_SYSTEM_SETTINGS, |
| |
| // Use Firefox's proxy settings if they are available. |
| PROXY_EXPERIMENT_USE_FIREFOX_SETTINGS, |
| |
| // Use proxy auto-detect. |
| PROXY_EXPERIMENT_USE_AUTO_DETECT, |
| |
| PROXY_EXPERIMENT_COUNT, |
| }; |
| |
| // This enum lists the possible host resolving configurations. |
| enum HostResolverExperiment { |
| // Use a default host resolver implementation. |
| HOST_RESOLVER_EXPERIMENT_PLAIN = 0, |
| |
| // Disable IPv6 host resolving. |
| HOST_RESOLVER_EXPERIMENT_DISABLE_IPV6, |
| |
| // Probe for IPv6 support. |
| HOST_RESOLVER_EXPERIMENT_IPV6_PROBE, |
| |
| HOST_RESOLVER_EXPERIMENT_COUNT, |
| }; |
| |
| // The "Experiment" structure describes an individual test to run. |
| struct Experiment { |
| Experiment(const GURL& url, |
| ProxySettingsExperiment proxy_settings_experiment, |
| HostResolverExperiment host_resolver_experiment) |
| : url(url), |
| proxy_settings_experiment(proxy_settings_experiment), |
| host_resolver_experiment(host_resolver_experiment) { |
| } |
| |
| // The URL to try and fetch. |
| GURL url; |
| |
| // The proxy settings to use. |
| ProxySettingsExperiment proxy_settings_experiment; |
| |
| // The host resolver settings to use. |
| HostResolverExperiment host_resolver_experiment; |
| }; |
| |
| typedef std::vector<Experiment> ExperimentList; |
| |
| // "Delegate" is an interface for receiving start and completion notification |
| // of individual tests that are run by the ConnectionTester. |
| // |
| // NOTE: do not delete the ConnectionTester when executing within one of the |
| // delegate methods. |
| class Delegate { |
| public: |
| virtual ~Delegate() {} |
| |
| // Called once the test suite is about to start. |
| virtual void OnStartConnectionTestSuite() = 0; |
| |
| // Called when an individual experiment is about to be started. |
| virtual void OnStartConnectionTestExperiment( |
| const Experiment& experiment) = 0; |
| |
| // Called when an individual experiment has completed. |
| // |experiment| - the experiment that has completed. |
| // |result| - the net error that the experiment completed with |
| // (or net::OK if it was success). |
| virtual void OnCompletedConnectionTestExperiment( |
| const Experiment& experiment, |
| int result) = 0; |
| |
| // Called once ALL tests have completed. |
| virtual void OnCompletedConnectionTestSuite() = 0; |
| }; |
| |
| // Constructs a ConnectionTester that notifies test progress to |delegate|. |
| // |delegate| is owned by the caller, and must remain valid for the lifetime |
| // of ConnectionTester. |
| ConnectionTester(Delegate* delegate, |
| net::URLRequestContext* proxy_request_context); |
| |
| // Note that destruction cancels any in-progress tests. |
| ~ConnectionTester(); |
| |
| // Starts running the test suite on |url|. Notification of progress is sent to |
| // |delegate_|. |
| void RunAllTests(const GURL& url); |
| |
| // Returns a text string explaining what |experiment| is testing. |
| static string16 ProxySettingsExperimentDescription( |
| ProxySettingsExperiment experiment); |
| static string16 HostResolverExperimentDescription( |
| HostResolverExperiment experiment); |
| |
| private: |
| // Internally each experiment run by ConnectionTester is handled by a |
| // "TestRunner" instance. |
| class TestRunner; |
| friend class TestRunner; |
| |
| // Fills |list| with the set of all possible experiments for |url|. |
| static void GetAllPossibleExperimentCombinations(const GURL& url, |
| ExperimentList* list); |
| |
| // Starts the next experiment from |remaining_experiments_|. |
| void StartNextExperiment(); |
| |
| // Callback for when |current_test_runner_| finishes. |
| void OnExperimentCompleted(int result); |
| |
| // Returns the experiment at the front of our list. |
| const Experiment& current_experiment() const { |
| return remaining_experiments_.front(); |
| } |
| |
| // The object to notify test progress to. |
| Delegate* delegate_; |
| |
| // The current in-progress test, or NULL if there is no active test. |
| scoped_ptr<TestRunner> current_test_runner_; |
| |
| // The ordered list of experiments to try next. The experiment at the front |
| // of the list is the one currently in progress. |
| ExperimentList remaining_experiments_; |
| |
| const scoped_refptr<net::URLRequestContext> proxy_request_context_; |
| |
| DISALLOW_COPY_AND_ASSIGN(ConnectionTester); |
| }; |
| |
| #endif // CHROME_BROWSER_NET_CONNECTION_TESTER_H_ |