summaryrefslogtreecommitdiffstats
path: root/chrome/common/resource_dispatcher_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/common/resource_dispatcher_unittest.cc')
-rw-r--r--chrome/common/resource_dispatcher_unittest.cc325
1 files changed, 325 insertions, 0 deletions
diff --git a/chrome/common/resource_dispatcher_unittest.cc b/chrome/common/resource_dispatcher_unittest.cc
new file mode 100644
index 0000000..323a6e4
--- /dev/null
+++ b/chrome/common/resource_dispatcher_unittest.cc
@@ -0,0 +1,325 @@
+// Copyright (c) 2010 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 <string>
+#include <vector>
+
+#include "base/message_loop.h"
+#include "base/process.h"
+#include "base/process_util.h"
+#include "base/scoped_ptr.h"
+#include "chrome/common/render_messages.h"
+#include "chrome/common/resource_dispatcher.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "webkit/appcache/appcache_interfaces.h"
+
+using webkit_glue::ResourceLoaderBridge;
+
+static const char test_page_url[] = "http://www.google.com/";
+static const char test_page_headers[] =
+ "HTTP/1.1 200 OK\nContent-Type:text/html\n\n";
+static const char test_page_mime_type[] = "text/html";
+static const char test_page_charset[] = "";
+static const char test_page_contents[] =
+ "<html><head><title>Google</title></head><body><h1>Google</h1></body></html>";
+static const uint32 test_page_contents_len = arraysize(test_page_contents) - 1;
+
+// Listens for request response data and stores it so that it can be compared
+// to the reference data.
+class TestRequestCallback : public ResourceLoaderBridge::Peer {
+ public:
+ TestRequestCallback() : complete_(false) {
+ }
+
+ virtual bool OnReceivedRedirect(
+ const GURL& new_url,
+ const ResourceLoaderBridge::ResponseInfo& info,
+ bool* has_new_first_party_for_cookies,
+ GURL* new_first_party_for_cookies) {
+ *has_new_first_party_for_cookies = false;
+ return true;
+ }
+
+ virtual void OnReceivedResponse(
+ const ResourceLoaderBridge::ResponseInfo& info,
+ bool content_filtered) {
+ }
+
+ virtual void OnReceivedData(const char* data, int len) {
+ EXPECT_FALSE(complete_);
+ data_.append(data, len);
+ }
+
+ virtual void OnUploadProgress(uint64 position, uint64 size) {
+ }
+
+ virtual void OnCompletedRequest(const URLRequestStatus& status,
+ const std::string& security_info) {
+ EXPECT_FALSE(complete_);
+ complete_ = true;
+ }
+
+ virtual GURL GetURLForDebugging() const {
+ return GURL();
+ }
+
+ const std::string& data() const {
+ return data_;
+ }
+ bool complete() const {
+ return complete_;
+ }
+
+ private:
+ bool complete_;
+ std::string data_;
+};
+
+
+// Sets up the message sender override for the unit test
+class ResourceDispatcherTest : public testing::Test,
+ public IPC::Message::Sender {
+ public:
+ // Emulates IPC send operations (IPC::Message::Sender) by adding
+ // pending messages to the queue.
+ virtual bool Send(IPC::Message* msg) {
+ message_queue_.push_back(IPC::Message(*msg));
+ delete msg;
+ return true;
+ }
+
+ // Emulates the browser process and processes the pending IPC messages,
+ // returning the hardcoded file contents.
+ void ProcessMessages() {
+ while (!message_queue_.empty()) {
+ int request_id;
+ ViewHostMsg_Resource_Request request;
+ ASSERT_TRUE(ViewHostMsg_RequestResource::Read(
+ &message_queue_[0], &request_id, &request));
+
+ // check values
+ EXPECT_EQ(test_page_url, request.url.spec());
+
+ // received response message
+ ResourceResponseHead response;
+ std::string raw_headers(test_page_headers);
+ std::replace(raw_headers.begin(), raw_headers.end(), '\n', '\0');
+ response.headers = new net::HttpResponseHeaders(raw_headers);
+ response.mime_type = test_page_mime_type;
+ response.charset = test_page_charset;
+ dispatcher_->OnReceivedResponse(request_id, response);
+
+ // received data message with the test contents
+ base::SharedMemory shared_mem;
+ EXPECT_TRUE(shared_mem.Create(std::wstring(),
+ false, false, test_page_contents_len));
+ EXPECT_TRUE(shared_mem.Map(test_page_contents_len));
+ char* put_data_here = static_cast<char*>(shared_mem.memory());
+ memcpy(put_data_here, test_page_contents, test_page_contents_len);
+ base::SharedMemoryHandle dup_handle;
+ EXPECT_TRUE(shared_mem.GiveToProcess(
+ base::Process::Current().handle(), &dup_handle));
+ dispatcher_->OnReceivedData(
+ message_queue_[0], request_id, dup_handle, test_page_contents_len);
+
+ message_queue_.erase(message_queue_.begin());
+
+ // read the ack message.
+ Tuple1<int> request_ack;
+ ASSERT_TRUE(ViewHostMsg_DataReceived_ACK::Read(
+ &message_queue_[0], &request_ack));
+
+ ASSERT_EQ(request_ack.a, request_id);
+
+ message_queue_.erase(message_queue_.begin());
+ }
+ }
+
+ protected:
+ // testing::Test
+ virtual void SetUp() {
+ dispatcher_.reset(new ResourceDispatcher(this));
+ }
+ virtual void TearDown() {
+ dispatcher_.reset();
+ }
+
+ ResourceLoaderBridge* CreateBridge() {
+ webkit_glue::ResourceLoaderBridge::RequestInfo request_info;
+ request_info.method = "GET";
+ request_info.url = GURL(test_page_url);
+ request_info.first_party_for_cookies = GURL(test_page_url);
+ request_info.referrer = GURL();
+ request_info.frame_origin = "null";
+ request_info.main_frame_origin = "null";
+ request_info.headers = std::string();
+ request_info.load_flags = 0;
+ request_info.requestor_pid = 0;
+ request_info.request_type = ResourceType::SUB_RESOURCE;
+ request_info.appcache_host_id = appcache::kNoHostId;
+ request_info.routing_id = 0;
+
+ return dispatcher_->CreateBridge(request_info, -1, -1);
+ }
+
+ std::vector<IPC::Message> message_queue_;
+ static scoped_ptr<ResourceDispatcher> dispatcher_;
+};
+
+/*static*/
+scoped_ptr<ResourceDispatcher> ResourceDispatcherTest::dispatcher_;
+
+// Does a simple request and tests that the correct data is received.
+TEST_F(ResourceDispatcherTest, RoundTrip) {
+ TestRequestCallback callback;
+ ResourceLoaderBridge* bridge = CreateBridge();
+
+ bridge->Start(&callback);
+
+ ProcessMessages();
+
+ // FIXME(brettw) when the request complete messages are actually handledo
+ // and dispatched, uncomment this.
+ //EXPECT_TRUE(callback.complete());
+ //EXPECT_STREQ(test_page_contents, callback.data().c_str());
+
+ delete bridge;
+}
+
+// Tests that the request IDs are straight when there are multiple requests.
+TEST_F(ResourceDispatcherTest, MultipleRequests) {
+ // FIXME
+}
+
+// Tests that the cancel method prevents other messages from being received
+TEST_F(ResourceDispatcherTest, Cancel) {
+ // FIXME
+}
+
+TEST_F(ResourceDispatcherTest, Cookies) {
+ // FIXME
+}
+
+TEST_F(ResourceDispatcherTest, SerializedPostData) {
+ // FIXME
+}
+
+// This class provides functionality to validate whether the ResourceDispatcher
+// object honors the deferred loading contract correctly, i.e. if deferred
+// loading is enabled it should queue up any responses received. If deferred
+// loading is enabled/disabled in the context of a dispatched message, other
+// queued messages should not be dispatched until deferred load is turned off.
+class DeferredResourceLoadingTest : public ResourceDispatcherTest,
+ public ResourceLoaderBridge::Peer {
+ public:
+ DeferredResourceLoadingTest()
+ : defer_loading_(false) {
+ }
+
+ virtual bool Send(IPC::Message* msg) {
+ delete msg;
+ return true;
+ }
+
+ void InitMessages() {
+ set_defer_loading(true);
+
+ ResourceResponseHead response_head;
+ response_head.status.set_status(URLRequestStatus::SUCCESS);
+
+ IPC::Message* response_message =
+ new ViewMsg_Resource_ReceivedResponse(0, 0, response_head);
+
+ dispatcher_->OnMessageReceived(*response_message);
+
+ delete response_message;
+
+ // Duplicate the shared memory handle so both the test and the callee can
+ // close their copy.
+ base::SharedMemoryHandle duplicated_handle;
+ EXPECT_TRUE(shared_handle_.ShareToProcess(base::GetCurrentProcessHandle(),
+ &duplicated_handle));
+
+ response_message =
+ new ViewMsg_Resource_DataReceived(0, 0, duplicated_handle, 100);
+
+ dispatcher_->OnMessageReceived(*response_message);
+
+ delete response_message;
+
+ set_defer_loading(false);
+ }
+
+ // ResourceLoaderBridge::Peer methods.
+ virtual void OnReceivedResponse(
+ const ResourceLoaderBridge::ResponseInfo& info,
+ bool content_filtered) {
+ EXPECT_EQ(defer_loading_, false);
+ set_defer_loading(true);
+ }
+
+ virtual bool OnReceivedRedirect(
+ const GURL& new_url,
+ const ResourceLoaderBridge::ResponseInfo& info,
+ bool* has_new_first_party_for_cookies,
+ GURL* new_first_party_for_cookies) {
+ *has_new_first_party_for_cookies = false;
+ return true;
+ }
+
+ virtual void OnReceivedData(const char* data, int len) {
+ EXPECT_EQ(defer_loading_, false);
+ set_defer_loading(false);
+ }
+
+ virtual void OnUploadProgress(uint64 position, uint64 size) {
+ }
+
+ virtual void OnCompletedRequest(const URLRequestStatus& status,
+ const std::string& security_info) {
+ }
+
+ virtual GURL GetURLForDebugging() const {
+ return GURL();
+ }
+
+ protected:
+ virtual void SetUp() {
+ EXPECT_EQ(true, shared_handle_.Create(L"DeferredResourceLoaderTest", false,
+ false, 100));
+ ResourceDispatcherTest::SetUp();
+ }
+
+ virtual void TearDown() {
+ shared_handle_.Close();
+ ResourceDispatcherTest::TearDown();
+ }
+
+ private:
+ void set_defer_loading(bool defer) {
+ defer_loading_ = defer;
+ dispatcher_->SetDefersLoading(0, defer);
+ }
+
+ bool defer_loading() const {
+ return defer_loading_;
+ }
+
+ bool defer_loading_;
+ base::SharedMemory shared_handle_;
+};
+
+TEST_F(DeferredResourceLoadingTest, DeferredLoadTest) {
+ MessageLoop message_loop(MessageLoop::TYPE_IO);
+
+ ResourceLoaderBridge* bridge = CreateBridge();
+
+ bridge->Start(this);
+ InitMessages();
+
+ // Dispatch deferred messages.
+ message_loop.RunAllPending();
+ delete bridge;
+}
+