| Index: chrome/browser/errorpage_browsertest.cc
|
| diff --git a/chrome/browser/errorpage_browsertest.cc b/chrome/browser/errorpage_browsertest.cc
|
| index f7555be4c066a7d448c507a9006f491aa4496b6c..240b68301f1053912e19dad157f3f9ed707b4373 100644
|
| --- a/chrome/browser/errorpage_browsertest.cc
|
| +++ b/chrome/browser/errorpage_browsertest.cc
|
| @@ -3,6 +3,9 @@
|
| // found in the LICENSE file.
|
|
|
| #include "base/bind.h"
|
| +#include "base/command_line.h"
|
| +#include "base/logging.h"
|
| +#include "base/memory/scoped_ptr.h"
|
| #include "base/prefs/pref_service.h"
|
| #include "base/strings/stringprintf.h"
|
| #include "base/strings/utf_string_conversions.h"
|
| @@ -14,6 +17,7 @@
|
| #include "chrome/browser/ui/browser.h"
|
| #include "chrome/browser/ui/browser_commands.h"
|
| #include "chrome/browser/ui/tabs/tab_strip_model.h"
|
| +#include "chrome/common/chrome_switches.h"
|
| #include "chrome/common/pref_names.h"
|
| #include "chrome/test/base/in_process_browser_test.h"
|
| #include "chrome/test/base/ui_test_utils.h"
|
| @@ -33,14 +37,69 @@
|
| #include "net/url_request/url_request_context.h"
|
| #include "net/url_request/url_request_context_getter.h"
|
| #include "net/url_request/url_request_filter.h"
|
| +#include "net/url_request/url_request_job.h"
|
| #include "net/url_request/url_request_job_factory.h"
|
| +#include "net/url_request/url_request_test_job.h"
|
| +#include "net/url_request/url_request_test_util.h"
|
|
|
| using content::BrowserThread;
|
| using content::NavigationController;
|
| using content::URLRequestFailedJob;
|
| +using net::URLRequestJobFactory;
|
| +using net::URLRequestTestJob;
|
|
|
| namespace {
|
|
|
| +// A protocol handler that fails a configurable number of requests, then
|
| +// succeeds all requests after that, keeping count of failures and successes.
|
| +class FailFirstNRequestsProtocolHandler
|
| + : public URLRequestJobFactory::ProtocolHandler {
|
| + public:
|
| + FailFirstNRequestsProtocolHandler(const GURL& url, int requests_to_fail)
|
| + : url_(url), requests_(0), failures_(0),
|
| + requests_to_fail_(requests_to_fail) {}
|
| + virtual ~FailFirstNRequestsProtocolHandler() {}
|
| +
|
| + void AddUrlHandler() {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + scoped_ptr<URLRequestJobFactory::ProtocolHandler> scoped_handler(this);
|
| + net::URLRequestFilter::GetInstance()->AddUrlProtocolHandler(
|
| + url_,
|
| + scoped_handler.Pass());
|
| + }
|
| +
|
| + virtual net::URLRequestJob* MaybeCreateJob(
|
| + net::URLRequest* request,
|
| + net::NetworkDelegate* network_delegate) OVERRIDE const {
|
| + DCHECK_EQ(url_, request->url());
|
| + requests_++;
|
| + if (failures_ < requests_to_fail_) {
|
| + failures_++;
|
| + // Note: net::ERR_CONNECTION_RESET does not summon the Link Doctor; see
|
| + // NetErrorHelperCore::GetErrorPageURL.
|
| + return new URLRequestFailedJob(request,
|
| + network_delegate,
|
| + net::ERR_CONNECTION_RESET);
|
| + } else {
|
| + return new URLRequestTestJob(request, network_delegate,
|
| + URLRequestTestJob::test_headers(),
|
| + URLRequestTestJob::test_data_1(),
|
| + true);
|
| + }
|
| + }
|
| +
|
| + int requests() const { return requests_; }
|
| + int failures() const { return failures_; }
|
| +
|
| + private:
|
| + const GURL url_;
|
| + // These are mutable because MaybeCreateJob is const but we want this state
|
| + // for testing.
|
| + mutable int requests_;
|
| + mutable int failures_;
|
| + int requests_to_fail_;
|
| +};
|
| +
|
| class ErrorPageTest : public InProcessBrowserTest {
|
| public:
|
| enum HistoryNavigationDirection {
|
| @@ -442,6 +501,65 @@ IN_PROC_BROWSER_TEST_F(ErrorPageTest, StaleCacheStatus) {
|
| EXPECT_TRUE(ProbeStaleCopyValue(false));
|
| }
|
|
|
| +class ErrorPageAutoReloadTest : public InProcessBrowserTest {
|
| + public:
|
| + virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
|
| + command_line->AppendSwitch(switches::kEnableOfflineAutoReload);
|
| + }
|
| +
|
| + void InstallProtocolHandler(const GURL& url, int requests_to_fail) {
|
| + protocol_handler_ = new FailFirstNRequestsProtocolHandler(
|
| + url,
|
| + requests_to_fail);
|
| + // Tests don't need to wait for this task to complete before using the
|
| + // filter; any requests that might be affected by it will end up in the IO
|
| + // thread's message loop after this posted task anyway.
|
| + BrowserThread::PostTask(
|
| + BrowserThread::IO, FROM_HERE,
|
| + base::Bind(&ErrorPageAutoReloadTest::AddFilters,
|
| + base::Unretained(this)));
|
| + }
|
| +
|
| + void NavigateToURLAndWaitForTitle(const GURL& url,
|
| + const std::string& expected_title,
|
| + int num_navigations) {
|
| + content::TitleWatcher title_watcher(
|
| + browser()->tab_strip_model()->GetActiveWebContents(),
|
| + base::ASCIIToUTF16(expected_title));
|
| +
|
| + ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
|
| + browser(), url, num_navigations);
|
| +
|
| + EXPECT_EQ(base::ASCIIToUTF16(expected_title),
|
| + title_watcher.WaitAndGetTitle());
|
| + }
|
| +
|
| + FailFirstNRequestsProtocolHandler* protocol_handler() {
|
| + return protocol_handler_;
|
| + }
|
| +
|
| + private:
|
| + void AddFilters() {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + protocol_handler_->AddUrlHandler();
|
| + }
|
| +
|
| + FailFirstNRequestsProtocolHandler* protocol_handler_;
|
| +};
|
| +
|
| +IN_PROC_BROWSER_TEST_F(ErrorPageAutoReloadTest, AutoReload) {
|
| + GURL test_url("http://error.page.auto.reload");
|
| + const int kRequestsToFail = 2;
|
| + InstallProtocolHandler(test_url, kRequestsToFail);
|
| + NavigateToURLAndWaitForTitle(test_url, "Test One", kRequestsToFail + 1);
|
| + // Note that the protocol handler updates these variables on the IO thread,
|
| + // but this function reads them on the main thread. The requests have to be
|
| + // created (on the IO thread) before NavigateToURLAndWaitForTitle returns or
|
| + // this becomes racey.
|
| + EXPECT_EQ(kRequestsToFail, protocol_handler()->failures());
|
| + EXPECT_EQ(kRequestsToFail + 1, protocol_handler()->requests());
|
| +}
|
| +
|
| // Returns Javascript code that executes plain text search for the page.
|
| // Pass into content::ExecuteScriptAndExtractBool as |script| parameter.
|
| std::string GetTextContentContainsStringScript(
|
|
|