15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file.
45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Browser tests targeted at the RenderView that run in browser context.
65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Note that these tests rely on single-process mode, and hence may be
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// disabled in some configurations (check gyp files).
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/basictypes.h"
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/bind.h"
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/callback.h"
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/command_line.h"
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/browser/browser_context.h"
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/browser/render_frame_host.h"
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/browser/render_process_host.h"
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/browser/web_contents.h"
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/common/content_switches.h"
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/renderer/render_view.h"
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/test/browser_test_utils.h"
22effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "content/public/test/content_browser_test.h"
23effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "content/public/test/content_browser_test_utils.h"
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/test/test_utils.h"
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/shell/browser/shell.h"
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/shell/browser/shell_browser_context.h"
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/shell/browser/shell_content_browser_client.h"
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/shell/common/shell_content_client.h"
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/shell/renderer/shell_content_renderer_client.h"
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/base/net_errors.h"
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/disk_cache/disk_cache.h"
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/http/failing_http_transaction_factory.h"
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/http/http_cache.h"
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/url_request/url_request_context.h"
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/url_request/url_request_context_getter.h"
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebURLError.h"
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebURLRequest.h"
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "third_party/WebKit/public/web/WebFrame.h"
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace content {
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace {
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class TestShellContentRendererClient : public ShellContentRendererClient {
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  TestShellContentRendererClient()
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      : latest_error_valid_(false),
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        latest_error_reason_(0),
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        latest_error_stale_copy_in_cache_(false) {}
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void GetNavigationErrorStrings(
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      content::RenderView* render_view,
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      blink::WebFrame* frame,
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const blink::WebURLRequest& failed_request,
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const blink::WebURLError& error,
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      std::string* error_html,
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::string16* error_description) OVERRIDE {
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (error_html)
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      *error_html = "A suffusion of yellow.";
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    latest_error_valid_ = true;
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    latest_error_reason_ = error.reason;
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    latest_error_stale_copy_in_cache_ = error.staleCopyInCache;
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool GetLatestError(int* error_code, bool* stale_cache_entry_present) {
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (latest_error_valid_) {
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      *error_code = latest_error_reason_;
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      *stale_cache_entry_present = latest_error_stale_copy_in_cache_;
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return latest_error_valid_;
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool latest_error_valid_;
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int latest_error_reason_;
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool latest_error_stale_copy_in_cache_;
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Must be called on IO thread.
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void InterceptNetworkTransactions(net::URLRequestContextGetter* getter,
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                  net::Error error) {
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(content::BrowserThread::CurrentlyOn(BrowserThread::IO));
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  net::HttpCache* cache(
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      getter->GetURLRequestContext()->http_transaction_factory()->GetCache());
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(cache);
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<net::FailingHttpTransactionFactory> factory(
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      new net::FailingHttpTransactionFactory(cache->GetSession(), error));
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Throw away old version; since this is a browser test, there is no
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // need to restore the old state.
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  cache->SetHttpNetworkTransactionFactoryForTesting(
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      factory.PassAs<net::HttpTransactionFactory>());
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void CallOnUIThreadValidatingReturn(const base::Closure& callback,
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                    int rv) {
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK_EQ(net::OK, rv);
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  BrowserThread::PostTask(
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      BrowserThread::UI, FROM_HERE, callback);
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Must be called on IO thread.  The callback will be called on
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// completion of cache clearing on the UI thread.
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void BackendClearCache(scoped_ptr<disk_cache::Backend*> backend,
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                       const base::Closure& callback,
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                       int rv) {
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(*backend);
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK_EQ(net::OK, rv);
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  (*backend)->DoomAllEntries(
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&CallOnUIThreadValidatingReturn, callback));
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Must be called on IO thread.  The callback will be called on
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// completion of cache clearing on the UI thread.
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ClearCache(net::URLRequestContextGetter* getter,
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                const base::Closure& callback) {
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(content::BrowserThread::CurrentlyOn(BrowserThread::IO));
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  net::HttpCache* cache(
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      getter->GetURLRequestContext()->http_transaction_factory()->GetCache());
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(cache);
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<disk_cache::Backend*> backend(new disk_cache::Backend*);
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  *backend = NULL;
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  disk_cache::Backend** backend_ptr = backend.get();
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  net::CompletionCallback backend_callback(
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&BackendClearCache, base::Passed(backend.Pass()), callback));
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // backend_ptr is valid until all copies of backend_callback go out
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // of scope.
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (net::OK == cache->GetBackend(backend_ptr, backend_callback)) {
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // The call completed synchronously, so GetBackend didn't run the callback.
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    backend_callback.Run(net::OK);
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class RenderViewBrowserTest : public ContentBrowserTest {
1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
14023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  RenderViewBrowserTest() {}
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // This method is needed to allow interaction with in-process renderer
1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // and use of a test ContentRendererClient.
1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    command_line->AppendSwitch(switches::kSingleProcess);
1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
14823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  virtual void SetUpOnMainThread() OVERRIDE {
1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Override setting of renderer client.
1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    renderer_client_ = new TestShellContentRendererClient();
15123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    // Explicitly leaks ownership; this object will remain alive
15223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    // until process death.  We don't deleted the returned value,
15323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    // since some contexts set the pointer to a non-heap address.
15423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    SetRendererClientForTesting(renderer_client_);
1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Navigates to the given URL and waits for |num_navigations| to occur, and
1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // the title to change to |expected_title|.
1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void NavigateToURLAndWaitForTitle(const GURL& url,
1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                    const std::string& expected_title,
1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                    int num_navigations) {
1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    content::TitleWatcher title_watcher(
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        shell()->web_contents(), base::ASCIIToUTF16(expected_title));
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    content::NavigateToURLBlockUntilNavigationsComplete(
1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        shell(), url, num_navigations);
1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(base::ASCIIToUTF16(expected_title),
1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              title_watcher.WaitAndGetTitle());
1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Returns true if there is a valid error stored; in this case
1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // |*error_code| and |*stale_cache_entry_present| will be updated
1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // appropriately.
1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Must be called after the renderer thread is created.
1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool GetLatestErrorFromRendererClient(
1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      int* error_code, bool* stale_cache_entry_present) {
1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    bool result = false;
1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    PostTaskToInProcessRendererAndWait(
1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        base::Bind(&RenderViewBrowserTest::GetLatestErrorFromRendererClient0,
1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                   renderer_client_, &result, error_code,
1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                   stale_cache_entry_present));
1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return result;
1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Must be run on renderer thread.
1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  static void GetLatestErrorFromRendererClient0(
1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      TestShellContentRendererClient* renderer_client,
1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      bool* result, int* error_code, bool* stale_cache_entry_present) {
1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    *result = renderer_client->GetLatestError(
1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        error_code, stale_cache_entry_present);
1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  TestShellContentRendererClient* renderer_client_;
1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
19923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(RenderViewBrowserTest, ConfirmCacheInformationPlumbed) {
2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(test_server()->Start());
2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Load URL with "nocache" set, to create stale cache.
2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  GURL test_url(test_server()->GetURL("files/nocache.html"));
2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  NavigateToURLAndWaitForTitle(test_url, "Nocache Test Page", 1);
2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Reload same URL after forcing an error from the the network layer;
2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // confirm that the error page is told the cached copy exists.
2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int renderer_id =
2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      shell()->web_contents()->GetMainFrame()->GetProcess()->GetID();
2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_refptr<net::URLRequestContextGetter> url_request_context_getter =
2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ShellContentBrowserClient::Get()->browser_context()->
2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          GetRequestContextForRenderProcess(renderer_id);
2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  BrowserThread::PostTask(
2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      BrowserThread::IO, FROM_HERE,
2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&InterceptNetworkTransactions, url_request_context_getter,
2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 net::ERR_FAILED));
2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // An error results in one completed navigation.
2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 1);
2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int error_code = net::OK;
2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool stale_cache_entry_present = false;
2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(GetLatestErrorFromRendererClient(
2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      &error_code, &stale_cache_entry_present));
2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(net::ERR_FAILED, error_code);
2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(stale_cache_entry_present);
2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Clear the cache and repeat; confirm lack of entry in cache reported.
2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_refptr<MessageLoopRunner> runner = new MessageLoopRunner;
2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  BrowserThread::PostTask(
2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      BrowserThread::IO, FROM_HERE,
2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&ClearCache, url_request_context_getter,
2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 runner->QuitClosure()));
2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  runner->Run();
2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  content::NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 1);
2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  error_code = net::OK;
2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  stale_cache_entry_present = true;
2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(GetLatestErrorFromRendererClient(
2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      &error_code, &stale_cache_entry_present));
2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(net::ERR_FAILED, error_code);
2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(stale_cache_entry_present);
2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace content
246