blob: 89c690063e80c93db3f3b7498bf66423143dc0a0 [file] [log] [blame]
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001// 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.
4
5#include "content/public/test/render_view_fake_resources_test.h"
6
7#include <string.h>
8
Ben Murdocheb525c52013-07-10 11:40:50 +01009#include "base/command_line.h"
Ben Murdochca12bfa2013-07-23 11:17:05 +010010#include "base/memory/shared_memory.h"
Ben Murdoch58e6fbe2013-07-26 10:20:38 +010011#include "base/process/process.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000012#include "base/run_loop.h"
Ben Murdocheb525c52013-07-10 11:40:50 +010013#include "base/time/time.h"
Ben Murdochbb1529c2013-08-08 10:24:53 +010014#include "content/common/dom_storage/dom_storage_types.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000015#include "content/common/resource_messages.h"
16#include "content/common/view_messages.h"
17#include "content/public/common/resource_response.h"
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +010018#include "content/public/renderer/history_item_serialization.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000019#include "content/renderer/render_thread_impl.h"
20#include "content/renderer/render_view_impl.h"
21#include "content/renderer/renderer_webkitplatformsupport_impl.h"
22#include "content/test/mock_render_process.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000023#include "net/base/net_errors.h"
24#include "net/base/upload_data.h"
25#include "net/http/http_response_headers.h"
26#include "net/url_request/url_request_status.h"
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010027#include "third_party/WebKit/public/platform/WebString.h"
28#include "third_party/WebKit/public/platform/WebURLRequest.h"
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +010029#include "third_party/WebKit/public/web/WebFrame.h"
30#include "third_party/WebKit/public/web/WebHistoryItem.h"
31#include "third_party/WebKit/public/web/WebView.h"
Ben Murdocheb525c52013-07-10 11:40:50 +010032#include "ui/base/ui_base_switches.h"
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010033#include "url/gurl.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000034#include "webkit/glue/webkit_glue.h"
35
36namespace content {
37
38const int32 RenderViewFakeResourcesTest::kViewId = 5;
39
40RenderViewFakeResourcesTest::RenderViewFakeResourcesTest() {}
41RenderViewFakeResourcesTest::~RenderViewFakeResourcesTest() {}
42
43bool RenderViewFakeResourcesTest::OnMessageReceived(
44 const IPC::Message& message) {
45 IPC_BEGIN_MESSAGE_MAP(RenderViewFakeResourcesTest, message)
46 IPC_MESSAGE_HANDLER(ViewHostMsg_RenderViewReady, OnRenderViewReady)
47 IPC_MESSAGE_HANDLER(ViewHostMsg_DidStopLoading, OnDidStopLoading)
48 IPC_MESSAGE_HANDLER(ResourceHostMsg_RequestResource, OnRequestResource)
49 IPC_END_MESSAGE_MAP()
50 return true;
51}
52
53bool RenderViewFakeResourcesTest::Visit(RenderView* render_view) {
54 view_ = render_view;
55 return false;
56}
57
58void RenderViewFakeResourcesTest::SetUp() {
59 // Set up the renderer. This code is largely adapted from
60 // render_view_test.cc and renderer_main.cc. Note that we use a
61 // MockRenderProcess (because we don't need to use IPC for painting),
62 // but we use a real RenderThread so that we can use the ResourceDispatcher
63 // to fetch network resources. These are then served canned content
64 // in OnRequestResource().
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010065 SetRendererClientForTesting(&content_renderer_client_);
Torne (Richard Coles)58218062012-11-14 11:43:16 +000066 // Generate a unique channel id so that multiple instances of the test can
67 // run in parallel.
68 std::string channel_id = IPC::Channel::GenerateVerifiedChannelID(
69 std::string());
70 channel_.reset(new IPC::Channel(channel_id,
71 IPC::Channel::MODE_SERVER, this));
72 ASSERT_TRUE(channel_->Connect());
73
Ben Murdocheb525c52013-07-10 11:40:50 +010074 CommandLine& command_line = *CommandLine::ForCurrentProcess();
75 command_line.AppendSwitchASCII(switches::kLang, "en-us");
76
Torne (Richard Coles)58218062012-11-14 11:43:16 +000077 webkit_glue::SetJavaScriptFlags("--expose-gc");
78 mock_process_.reset(new MockRenderProcess);
79 sandbox_was_enabled_ =
80 RendererWebKitPlatformSupportImpl::SetSandboxEnabledForTesting(false);
81 render_thread_ = new RenderThreadImpl(channel_id);
82
83 // Tell the renderer to create a view, then wait until it's ready.
84 // We can't call View::Create() directly here or else we won't get
85 // RenderProcess's lazy initialization of WebKit.
86 view_ = NULL;
87 ViewMsg_New_Params params;
88 params.view_id = kViewId;
89 params.opener_route_id = MSG_ROUTING_NONE;
Ben Murdochbb1529c2013-08-08 10:24:53 +010090 params.session_storage_namespace_id = kInvalidSessionStorageNamespaceId;
Torne (Richard Coles)58218062012-11-14 11:43:16 +000091 ASSERT_TRUE(channel_->Send(new ViewMsg_New(params)));
92 message_loop_.Run();
93}
94
95void RenderViewFakeResourcesTest::TearDown() {
96 // Try very hard to collect garbage before shutting down.
97 GetMainFrame()->collectGarbage();
98 GetMainFrame()->collectGarbage();
99
100 ASSERT_TRUE(channel_->Send(new ViewMsg_Close(kViewId)));
101 do {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000102 base::RunLoop().RunUntilIdle();
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000103 view_ = NULL;
104 RenderView::ForEach(this);
105 } while (view_);
106
107 mock_process_.reset();
108 RendererWebKitPlatformSupportImpl::SetSandboxEnabledForTesting(
109 sandbox_was_enabled_);
110}
111
112RenderView* RenderViewFakeResourcesTest::view() {
113 return view_;
114}
115
116WebKit::WebFrame* RenderViewFakeResourcesTest::GetMainFrame() {
117 return view_->GetWebView()->mainFrame();
118}
119
120void RenderViewFakeResourcesTest::LoadURL(const std::string& url) {
121 GURL g_url(url);
122 GetMainFrame()->loadRequest(WebKit::WebURLRequest(g_url));
123 message_loop_.Run();
124}
125
126void RenderViewFakeResourcesTest::LoadURLWithPost(const std::string& url) {
127 GURL g_url(url);
128 WebKit::WebURLRequest request(g_url);
129 request.setHTTPMethod(WebKit::WebString::fromUTF8("POST"));
130 GetMainFrame()->loadRequest(request);
131 message_loop_.Run();
132}
133
134void RenderViewFakeResourcesTest::GoBack() {
135 GoToOffset(-1, GetMainFrame()->previousHistoryItem());
136}
137
138void RenderViewFakeResourcesTest::GoForward(
139 const WebKit::WebHistoryItem& history_item) {
140 GoToOffset(1, history_item);
141}
142
143void RenderViewFakeResourcesTest::OnDidStopLoading() {
144 message_loop_.Quit();
145}
146
147void RenderViewFakeResourcesTest::OnRequestResource(
148 const IPC::Message& message,
149 int request_id,
150 const ResourceHostMsg_Request& request_data) {
151 std::string headers, body;
152 std::map<std::string, std::string>::const_iterator it =
153 responses_.find(request_data.url.spec());
154 if (it == responses_.end()) {
155 headers = "HTTP/1.1 404 Not Found\0Content-Type:text/html\0\0";
156 body = "content not found";
157 } else {
158 headers = "HTTP/1.1 200 OK\0Content-Type:text/html\0\0";
159 body = it->second;
160 }
161
162 ResourceResponseHead response_head;
163 response_head.headers = new net::HttpResponseHeaders(headers);
164 response_head.mime_type = "text/html";
165 ASSERT_TRUE(channel_->Send(new ResourceMsg_ReceivedResponse(
166 message.routing_id(), request_id, response_head)));
167
168 base::SharedMemory shared_memory;
169 ASSERT_TRUE(shared_memory.CreateAndMapAnonymous(body.size()));
170 memcpy(shared_memory.memory(), body.data(), body.size());
171
172 base::SharedMemoryHandle handle;
173 ASSERT_TRUE(shared_memory.GiveToProcess(base::Process::Current().handle(),
174 &handle));
175
176 ASSERT_TRUE(channel_->Send(new ResourceMsg_SetDataBuffer(
177 message.routing_id(),
178 request_id,
179 handle,
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000180 body.size(),
181 0)));
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000182
183 ASSERT_TRUE(channel_->Send(new ResourceMsg_DataReceived(
184 message.routing_id(),
185 request_id,
186 0,
187 body.size(),
188 body.size())));
189
190 ASSERT_TRUE(channel_->Send(new ResourceMsg_RequestComplete(
191 message.routing_id(),
192 request_id,
193 net::OK,
194 false,
195 std::string(),
196 base::TimeTicks())));
197}
198
199void RenderViewFakeResourcesTest::OnRenderViewReady() {
200 // Grab a pointer to the new view using RenderViewVisitor.
201 ASSERT_TRUE(!view_);
202 RenderView::ForEach(this);
203 ASSERT_TRUE(view_);
204 message_loop_.Quit();
205}
206
207void RenderViewFakeResourcesTest::GoToOffset(
208 int offset,
209 const WebKit::WebHistoryItem& history_item) {
210 RenderViewImpl* impl = static_cast<RenderViewImpl*>(view_);
211 ViewMsg_Navigate_Params params;
212 params.page_id = impl->GetPageId() + offset;
213 params.pending_history_list_offset =
214 impl->history_list_offset() + offset;
215 params.current_history_list_offset = impl->history_list_offset();
216 params.current_history_list_length = (impl->historyBackListCount() +
217 impl->historyForwardListCount() + 1);
218 params.url = GURL(history_item.urlString());
219 params.transition = PAGE_TRANSITION_FORWARD_BACK;
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +0100220 params.page_state = HistoryItemToPageState(history_item);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000221 params.navigation_type = ViewMsg_Navigate_Type::NORMAL;
222 params.request_time = base::Time::Now();
223 channel_->Send(new ViewMsg_Navigate(impl->routing_id(), params));
224 message_loop_.Run();
225}
226
227} // namespace content