Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1852)

Unified Diff: content/renderer/render_view_browsertest.cc

Issue 138513002: Plumb network stack information about existence of cached copy (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Incorporated comments from Matt & Ricardo. Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/renderer/render_view_browsertest.cc
diff --git a/content/renderer/render_view_browsertest.cc b/content/renderer/render_view_browsertest.cc
index 7ffa3fa224bdf5fc290403450f776f3d1c7a39ab..df4b8d6c9c44f23707b70336ec82d676284970bf 100644
--- a/content/renderer/render_view_browsertest.cc
+++ b/content/renderer/render_view_browsertest.cc
@@ -4,28 +4,48 @@
#include "base/basictypes.h"
+#include "base/bind.h"
+#include "base/callback.h"
#include "base/memory/shared_memory.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/win/windows_version.h"
#include "content/common/ssl_status_serialization.h"
#include "content/common/view_messages.h"
+#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_thread.h"
#include "content/public/browser/native_web_keyboard_event.h"
+#include "content/public/browser/render_frame_host.h"
+#include "content/public/browser/render_process_host.h"
+#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_ui_controller_factory.h"
#include "content/public/common/bindings_policy.h"
+#include "content/public/common/content_switches.h"
#include "content/public/common/page_zoom.h"
#include "content/public/common/url_constants.h"
#include "content/public/common/url_utils.h"
#include "content/public/renderer/document_state.h"
#include "content/public/renderer/history_item_serialization.h"
#include "content/public/renderer/navigation_state.h"
+#include "content/public/test/browser_test_utils.h"
#include "content/public/test/render_view_test.h"
+#include "content/public/test/test_utils.h"
#include "content/renderer/render_view_impl.h"
+#include "content/shell/browser/shell.h"
+#include "content/shell/browser/shell_browser_context.h"
#include "content/shell/browser/shell_content_browser_client.h"
#include "content/shell/common/shell_content_client.h"
+#include "content/shell/renderer/shell_content_renderer_client.h"
+#include "content/test/content_browser_test.h"
+#include "content/test/content_browser_test_utils.h"
#include "content/test/mock_keyboard.h"
#include "net/base/net_errors.h"
#include "net/cert/cert_status_flags.h"
+#include "net/disk_cache/disk_cache.h"
+#include "net/http/failing_http_transaction_factory.h"
+#include "net/http/http_cache.h"
+#include "net/url_request/url_request_context.h"
+#include "net/url_request/url_request_context_getter.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/WebKit/public/platform/WebData.h"
#include "third_party/WebKit/public/platform/WebHTTPBody.h"
@@ -117,8 +137,6 @@ class WebUITestWebUIControllerFactory : public WebUIControllerFactory {
}
};
-} // namespace
-
class RenderViewImplTest : public RenderViewTest {
public:
RenderViewImplTest() {
@@ -304,6 +322,167 @@ class RenderViewImplTest : public RenderViewTest {
scoped_ptr<MockKeyboard> mock_keyboard_;
};
+class TestShellContentRendererClient : public ShellContentRendererClient {
+ public:
+ TestShellContentRendererClient()
+ : latest_error_valid_(false),
+ latest_error_reason_(0),
+ latest_error_stale_copy_in_cache_(false) {}
+
+ virtual bool ShouldSuppressErrorPage(RenderFrame* render_frame,
+ const GURL& url) OVERRIDE {
+ return url == GURL("http://example.com/suppress");
+ }
+
+ virtual void GetNavigationErrorStrings(
+ content::RenderView* render_view,
+ blink::WebFrame* frame,
+ const blink::WebURLRequest& failed_request,
+ const blink::WebURLError& error,
+ std::string* error_html,
+ base::string16* error_description) OVERRIDE {
+ if (error_html)
+ *error_html = "A suffusion of yellow.";
+ latest_error_valid_ = true;
+ latest_error_reason_ = error.reason;
+ latest_error_stale_copy_in_cache_ = error.staleCopyInCache;
+ }
+
+ bool GetLatestError(int* error_code, bool* stale_cache_entry_present) {
+ if (latest_error_valid_) {
+ *error_code = latest_error_reason_;
+ *stale_cache_entry_present = latest_error_stale_copy_in_cache_;
+ }
+ return latest_error_valid_;
+ }
+
+ private:
+ bool latest_error_valid_;
+ int latest_error_reason_;
+ bool latest_error_stale_copy_in_cache_;
+};
+
+
+// For actual, browser side tests targetting code in RenderView
+// or RenderViewImpl.
+class RenderViewBrowserTest : public ContentBrowserTest {
+ public:
+ RenderViewBrowserTest() : renderer_client_(NULL) {}
+
+ virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
+ // To allow interaction with in-process renderer and use
+ // of a test ContentRendererClient.
+ command_line->AppendSwitch(switches::kSingleProcess);
+ }
+
+ virtual void SetUp() OVERRIDE {
+ // Override setting of renderer client.
+ renderer_client_ = new TestShellContentRendererClient();
+ SetContentRendererClient(
+ scoped_ptr<ContentRendererClient>(renderer_client_).Pass());
+
+ ContentBrowserTest::SetUp();
+ }
+
+ // Navigates to the given URL and waits for |num_navigations| to occur, and
+ // the title to change to |expected_title|.
+ void NavigateToURLAndWaitForTitle(const GURL& url,
+ const std::string& expected_title,
+ int num_navigations) {
+ content::TitleWatcher title_watcher(
+ shell()->web_contents(), base::ASCIIToUTF16(expected_title));
+
+ content::NavigateToURLBlockUntilNavigationsComplete(
+ shell(), url, num_navigations);
+
+ EXPECT_EQ(base::ASCIIToUTF16(expected_title),
+ title_watcher.WaitAndGetTitle());
+ }
+
+ // Returns true if there is a valid error stored; in this case
+ // |*error| will be set to that value.
+ // Must be called after the renderer thread is created.
+ bool GetLatestErrorFromRendererClient(
+ int* error_code, bool* stale_cache_entry_present) {
+ bool result = false;
+
+ PostTaskToInProcessRendererAndWait(
+ base::Bind(&RenderViewBrowserTest::GetLatestErrorFromRendererClient0,
+ renderer_client_, &result, error_code,
+ stale_cache_entry_present));
+ return result;
+ }
+
+ private:
+ // Must be run on renderer thread.
+ static void GetLatestErrorFromRendererClient0(
+ TestShellContentRendererClient* renderer_client,
+ bool* result, int* error_code, bool* stale_cache_entry_present) {
+ *result = renderer_client->GetLatestError(
+ error_code, stale_cache_entry_present);
+ }
+
+ // Actually owned by our superclass, so safe to keep a bare pointer.
+ TestShellContentRendererClient* renderer_client_;
+};
+
+// Must be called on IO thread.
+void InterceptNetworkTransactions(net::URLRequestContextGetter* getter,
+ net::Error error) {
+ DCHECK(content::BrowserThread::CurrentlyOn(BrowserThread::IO));
+ net::HttpCache* cache(
+ getter->GetURLRequestContext()->http_transaction_factory()->GetCache());
+ DCHECK(cache);
+ scoped_ptr<net::FailingHttpTransactionFactory> factory(
+ new net::FailingHttpTransactionFactory(cache->GetSession(), error));
+ // Throw away old version; since we're a browser test, we don't
+ // need to restore the old state.
+ cache->SetHttpNetworkTransactionFactoryForTesting(
+ factory.PassAs<net::HttpTransactionFactory>());
+}
+
+void CallOnUIThreadValidatingReturn(const base::Closure& callback,
+ int rv) {
+ DCHECK_EQ(net::OK, rv);
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE, callback);
+}
+
+// Must be called on IO thread. The callback will be called on
+// completion of cache clearing on the UI thread.
+void BackendClearCache(disk_cache::Backend** backend,
+ const base::Closure& callback,
+ int rv) {
+ DCHECK(*backend);
+ DCHECK_EQ(net::OK, rv);
+ (*backend)->DoomAllEntries(
+ base::Bind(&CallOnUIThreadValidatingReturn, callback));
+ // Not deleting the backend, just the spot allocated for storing
+ // the pointer.
+ delete backend;
+ return;
+}
+
+// Must be called on IO thread. The callback will be called on
+// completion of cache clearing on the UI thread.
+void ClearCache(net::URLRequestContextGetter* getter,
+ const base::Closure& callback) {
+ DCHECK(content::BrowserThread::CurrentlyOn(BrowserThread::IO));
+ net::HttpCache* cache(
+ getter->GetURLRequestContext()->http_transaction_factory()->GetCache());
+ DCHECK(cache);
+ disk_cache::Backend** backend = new disk_cache::Backend*;
+ *backend = NULL;
+ if (net::OK == cache->GetBackend(
+ backend, base::Bind(&BackendClearCache, backend, callback))) {
+ // Completed synchronously, so our job to call the callback.
+ BackendClearCache(backend, callback, net::OK);
+ // *backend has been deleted.
+ }
+}
+
+} // namespace
+
// Test that we get form state change notifications when input fields change.
TEST_F(RenderViewImplTest, DISABLED_OnNavStateChanged) {
// Don't want any delay for form state sync changes. This will still post a
@@ -2240,4 +2419,51 @@ TEST_F(RenderViewImplTest, FocusElementCallsFocusedNodeChanged) {
render_thread_->sink().ClearMessages();
}
+IN_PROC_BROWSER_TEST_F(RenderViewBrowserTest, ConfirmCacheInformationPlumbed) {
+ ASSERT_TRUE(test_server()->Start());
+
+ // Load cache with entry with "nocache" set, to create stale
+ // cache.
+ GURL test_url(test_server()->GetURL("files/nocache.html"));
+ NavigateToURLAndWaitForTitle(test_url, "Nocache Test Page", 1);
+
+ // Reload same URL after forcing an error from the the network layer;
+ // confirm that the error page is told the cached copy exists.
+ int renderer_id =
+ shell()->web_contents()->GetMainFrame()->GetProcess()->GetID();
+ scoped_refptr<net::URLRequestContextGetter> url_request_context_getter =
+ ShellContentBrowserClient::Get()->browser_context()->
+ GetRequestContextForRenderProcess(renderer_id);
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&InterceptNetworkTransactions, url_request_context_getter,
+ net::ERR_FAILED));
+
+ // An error results in one completed navigation.
+ content::NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 1);
+ int error_code = net::OK;
+ bool stale_cache_entry_present = false;
+ ASSERT_TRUE(GetLatestErrorFromRendererClient(
+ &error_code, &stale_cache_entry_present));
+ ASSERT_EQ(net::ERR_FAILED, error_code);
+ ASSERT_TRUE(stale_cache_entry_present);
+
+ // Clear the cache and repeat; confirm lack of entry in cache reported.
+ scoped_refptr<MessageLoopRunner> runner = new MessageLoopRunner;
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&ClearCache, url_request_context_getter,
+ runner->QuitClosure()));
+ runner->Run();
+
+ content::NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 1);
+
+ error_code = net::OK;
+ stale_cache_entry_present = true;
+ ASSERT_TRUE(GetLatestErrorFromRendererClient(
+ &error_code, &stale_cache_entry_present));
+ ASSERT_EQ(net::ERR_FAILED, error_code);
+ ASSERT_FALSE(stale_cache_entry_present);
+}
+
} // namespace content

Powered by Google App Engine
This is Rietveld 408576698