blob: e76ed5af214cd93cc2b171ac308accdb806a6153 [file] [log] [blame]
// Copyright (c) 2012 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.
#include "content/public/test/render_view_fake_resources_test.h"
#include <string.h>
#include "base/command_line.h"
#include "base/memory/shared_memory.h"
#include "base/process/process.h"
#include "base/run_loop.h"
#include "base/time/time.h"
#include "content/common/dom_storage/dom_storage_types.h"
#include "content/common/resource_messages.h"
#include "content/common/view_messages.h"
#include "content/public/common/resource_response.h"
#include "content/public/renderer/history_item_serialization.h"
#include "content/renderer/render_thread_impl.h"
#include "content/renderer/render_view_impl.h"
#include "content/renderer/renderer_webkitplatformsupport_impl.h"
#include "content/test/mock_render_process.h"
#include "net/base/net_errors.h"
#include "net/base/upload_data.h"
#include "net/http/http_response_headers.h"
#include "net/url_request/url_request_status.h"
#include "third_party/WebKit/public/platform/WebString.h"
#include "third_party/WebKit/public/platform/WebURLRequest.h"
#include "third_party/WebKit/public/web/WebFrame.h"
#include "third_party/WebKit/public/web/WebHistoryItem.h"
#include "third_party/WebKit/public/web/WebView.h"
#include "ui/base/ui_base_switches.h"
#include "url/gurl.h"
#include "webkit/glue/webkit_glue.h"
namespace content {
const int32 RenderViewFakeResourcesTest::kViewId = 5;
RenderViewFakeResourcesTest::RenderViewFakeResourcesTest() {}
RenderViewFakeResourcesTest::~RenderViewFakeResourcesTest() {}
bool RenderViewFakeResourcesTest::OnMessageReceived(
const IPC::Message& message) {
IPC_BEGIN_MESSAGE_MAP(RenderViewFakeResourcesTest, message)
IPC_MESSAGE_HANDLER(ViewHostMsg_RenderViewReady, OnRenderViewReady)
IPC_MESSAGE_HANDLER(ViewHostMsg_DidStopLoading, OnDidStopLoading)
IPC_MESSAGE_HANDLER(ResourceHostMsg_RequestResource, OnRequestResource)
IPC_END_MESSAGE_MAP()
return true;
}
bool RenderViewFakeResourcesTest::Visit(RenderView* render_view) {
view_ = render_view;
return false;
}
void RenderViewFakeResourcesTest::SetUp() {
// Set up the renderer. This code is largely adapted from
// render_view_test.cc and renderer_main.cc. Note that we use a
// MockRenderProcess (because we don't need to use IPC for painting),
// but we use a real RenderThread so that we can use the ResourceDispatcher
// to fetch network resources. These are then served canned content
// in OnRequestResource().
SetRendererClientForTesting(&content_renderer_client_);
// Generate a unique channel id so that multiple instances of the test can
// run in parallel.
std::string channel_id = IPC::Channel::GenerateVerifiedChannelID(
std::string());
channel_.reset(new IPC::Channel(channel_id,
IPC::Channel::MODE_SERVER, this));
ASSERT_TRUE(channel_->Connect());
CommandLine& command_line = *CommandLine::ForCurrentProcess();
command_line.AppendSwitchASCII(switches::kLang, "en-us");
webkit_glue::SetJavaScriptFlags("--expose-gc");
mock_process_.reset(new MockRenderProcess);
sandbox_was_enabled_ =
RendererWebKitPlatformSupportImpl::SetSandboxEnabledForTesting(false);
render_thread_ = new RenderThreadImpl(channel_id);
// Tell the renderer to create a view, then wait until it's ready.
// We can't call View::Create() directly here or else we won't get
// RenderProcess's lazy initialization of WebKit.
view_ = NULL;
ViewMsg_New_Params params;
params.view_id = kViewId;
params.opener_route_id = MSG_ROUTING_NONE;
params.session_storage_namespace_id = kInvalidSessionStorageNamespaceId;
ASSERT_TRUE(channel_->Send(new ViewMsg_New(params)));
message_loop_.Run();
}
void RenderViewFakeResourcesTest::TearDown() {
// Try very hard to collect garbage before shutting down.
GetMainFrame()->collectGarbage();
GetMainFrame()->collectGarbage();
ASSERT_TRUE(channel_->Send(new ViewMsg_Close(kViewId)));
do {
base::RunLoop().RunUntilIdle();
view_ = NULL;
RenderView::ForEach(this);
} while (view_);
mock_process_.reset();
RendererWebKitPlatformSupportImpl::SetSandboxEnabledForTesting(
sandbox_was_enabled_);
}
RenderView* RenderViewFakeResourcesTest::view() {
return view_;
}
WebKit::WebFrame* RenderViewFakeResourcesTest::GetMainFrame() {
return view_->GetWebView()->mainFrame();
}
void RenderViewFakeResourcesTest::LoadURL(const std::string& url) {
GURL g_url(url);
GetMainFrame()->loadRequest(WebKit::WebURLRequest(g_url));
message_loop_.Run();
}
void RenderViewFakeResourcesTest::LoadURLWithPost(const std::string& url) {
GURL g_url(url);
WebKit::WebURLRequest request(g_url);
request.setHTTPMethod(WebKit::WebString::fromUTF8("POST"));
GetMainFrame()->loadRequest(request);
message_loop_.Run();
}
void RenderViewFakeResourcesTest::GoBack() {
GoToOffset(-1, GetMainFrame()->previousHistoryItem());
}
void RenderViewFakeResourcesTest::GoForward(
const WebKit::WebHistoryItem& history_item) {
GoToOffset(1, history_item);
}
void RenderViewFakeResourcesTest::OnDidStopLoading() {
message_loop_.Quit();
}
void RenderViewFakeResourcesTest::OnRequestResource(
const IPC::Message& message,
int request_id,
const ResourceHostMsg_Request& request_data) {
std::string headers, body;
std::map<std::string, std::string>::const_iterator it =
responses_.find(request_data.url.spec());
if (it == responses_.end()) {
headers = "HTTP/1.1 404 Not Found\0Content-Type:text/html\0\0";
body = "content not found";
} else {
headers = "HTTP/1.1 200 OK\0Content-Type:text/html\0\0";
body = it->second;
}
ResourceResponseHead response_head;
response_head.headers = new net::HttpResponseHeaders(headers);
response_head.mime_type = "text/html";
ASSERT_TRUE(channel_->Send(new ResourceMsg_ReceivedResponse(
request_id, response_head)));
base::SharedMemory shared_memory;
ASSERT_TRUE(shared_memory.CreateAndMapAnonymous(body.size()));
memcpy(shared_memory.memory(), body.data(), body.size());
base::SharedMemoryHandle handle;
ASSERT_TRUE(shared_memory.GiveToProcess(base::Process::Current().handle(),
&handle));
ASSERT_TRUE(channel_->Send(new ResourceMsg_SetDataBuffer(
request_id,
handle,
body.size(),
0)));
ASSERT_TRUE(channel_->Send(new ResourceMsg_DataReceived(
request_id,
0,
body.size(),
body.size())));
ASSERT_TRUE(channel_->Send(new ResourceMsg_RequestComplete(
request_id,
net::OK,
false,
std::string(),
base::TimeTicks())));
}
void RenderViewFakeResourcesTest::OnRenderViewReady() {
// Grab a pointer to the new view using RenderViewVisitor.
ASSERT_TRUE(!view_);
RenderView::ForEach(this);
ASSERT_TRUE(view_);
message_loop_.Quit();
}
void RenderViewFakeResourcesTest::GoToOffset(
int offset,
const WebKit::WebHistoryItem& history_item) {
RenderViewImpl* impl = static_cast<RenderViewImpl*>(view_);
ViewMsg_Navigate_Params params;
params.page_id = impl->GetPageId() + offset;
params.pending_history_list_offset =
impl->history_list_offset() + offset;
params.current_history_list_offset = impl->history_list_offset();
params.current_history_list_length = (impl->historyBackListCount() +
impl->historyForwardListCount() + 1);
params.url = GURL(history_item.urlString());
params.transition = PAGE_TRANSITION_FORWARD_BACK;
params.page_state = HistoryItemToPageState(history_item);
params.navigation_type = ViewMsg_Navigate_Type::NORMAL;
params.request_time = base::Time::Now();
channel_->Send(new ViewMsg_Navigate(impl->routing_id(), params));
message_loop_.Run();
}
} // namespace content