blob: 3ede586d0e3a4ea9f362d0ead4676ed01162e580 [file] [log] [blame]
[email protected]8a58f9a2010-05-18 18:38:091// Copyright (c) 2010 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
5#include <string>
6#include <vector>
7
[email protected]2602087e2009-08-24 23:12:168#include "base/message_loop.h"
[email protected]4003d7142009-01-12 12:56:209#include "base/process.h"
[email protected]a68114f72009-11-30 23:32:4910#include "base/process_util.h"
[email protected]1fec8402009-03-13 19:11:5911#include "base/scoped_ptr.h"
[email protected]e09ba552009-02-05 03:26:2912#include "chrome/common/render_messages.h"
[email protected]939856a2010-08-24 20:29:0213#include "chrome/common/render_messages_params.h"
initial.commit09911bf2008-07-26 23:55:2914#include "chrome/common/resource_dispatcher.h"
[email protected]939856a2010-08-24 20:29:0215#include "net/base/upload_data.h"
[email protected]7a4de7a62010-08-17 18:38:2416#include "net/http/http_response_headers.h"
initial.commit09911bf2008-07-26 23:55:2917#include "testing/gtest/include/gtest/gtest.h"
[email protected]f430b5712009-08-21 21:46:3118#include "webkit/appcache/appcache_interfaces.h"
initial.commit09911bf2008-07-26 23:55:2919
20using webkit_glue::ResourceLoaderBridge;
21
22static const char test_page_url[] = "http://www.google.com/";
23static const char test_page_headers[] =
24 "HTTP/1.1 200 OK\nContent-Type:text/html\n\n";
25static const char test_page_mime_type[] = "text/html";
26static const char test_page_charset[] = "";
27static const char test_page_contents[] =
28 "<html><head><title>Google</title></head><body><h1>Google</h1></body></html>";
[email protected]b5ab3982010-02-16 23:58:2729static const uint32 test_page_contents_len = arraysize(test_page_contents) - 1;
initial.commit09911bf2008-07-26 23:55:2930
31// Listens for request response data and stores it so that it can be compared
32// to the reference data.
33class TestRequestCallback : public ResourceLoaderBridge::Peer {
34 public:
35 TestRequestCallback() : complete_(false) {
36 }
37
[email protected]bb551622010-07-22 20:52:4938 virtual void OnUploadProgress(uint64 position, uint64 size) {
39 }
40
[email protected]6568a9e32009-07-30 18:01:3941 virtual bool OnReceivedRedirect(
42 const GURL& new_url,
[email protected]2581e572009-11-13 21:54:5543 const ResourceLoaderBridge::ResponseInfo& info,
[email protected]041b0bbb2009-11-18 02:27:3444 bool* has_new_first_party_for_cookies,
[email protected]2581e572009-11-13 21:54:5545 GURL* new_first_party_for_cookies) {
[email protected]041b0bbb2009-11-18 02:27:3446 *has_new_first_party_for_cookies = false;
[email protected]6568a9e32009-07-30 18:01:3947 return true;
initial.commit09911bf2008-07-26 23:55:2948 }
49
50 virtual void OnReceivedResponse(
[email protected]8a3422c92008-09-24 17:42:4251 const ResourceLoaderBridge::ResponseInfo& info,
52 bool content_filtered) {
initial.commit09911bf2008-07-26 23:55:2953 }
54
[email protected]bb551622010-07-22 20:52:4955 virtual void OnDownloadedData(int len) {
56 }
57
initial.commit09911bf2008-07-26 23:55:2958 virtual void OnReceivedData(const char* data, int len) {
59 EXPECT_FALSE(complete_);
60 data_.append(data, len);
61 }
62
[email protected]c4891b32009-03-08 07:41:3163 virtual void OnCompletedRequest(const URLRequestStatus& status,
64 const std::string& security_info) {
initial.commit09911bf2008-07-26 23:55:2965 EXPECT_FALSE(complete_);
66 complete_ = true;
67 }
68
[email protected]9ee9a76a2009-10-28 21:02:5969 virtual GURL GetURLForDebugging() const {
70 return GURL();
initial.commit09911bf2008-07-26 23:55:2971 }
72
73 const std::string& data() const {
74 return data_;
75 }
[email protected]52120702010-03-09 21:44:4476 bool complete() const {
initial.commit09911bf2008-07-26 23:55:2977 return complete_;
78 }
79
80 private:
81 bool complete_;
82 std::string data_;
83};
84
85
86// Sets up the message sender override for the unit test
87class ResourceDispatcherTest : public testing::Test,
88 public IPC::Message::Sender {
89 public:
90 // Emulates IPC send operations (IPC::Message::Sender) by adding
91 // pending messages to the queue.
92 virtual bool Send(IPC::Message* msg) {
93 message_queue_.push_back(IPC::Message(*msg));
94 delete msg;
95 return true;
96 }
97
98 // Emulates the browser process and processes the pending IPC messages,
99 // returning the hardcoded file contents.
100 void ProcessMessages() {
101 while (!message_queue_.empty()) {
initial.commit09911bf2008-07-26 23:55:29102 int request_id;
initial.commit09911bf2008-07-26 23:55:29103 ViewHostMsg_Resource_Request request;
[email protected]eb9989092009-03-12 21:42:52104 ASSERT_TRUE(ViewHostMsg_RequestResource::Read(
105 &message_queue_[0], &request_id, &request));
initial.commit09911bf2008-07-26 23:55:29106
107 // check values
108 EXPECT_EQ(test_page_url, request.url.spec());
109
110 // received response message
[email protected]e09ba552009-02-05 03:26:29111 ResourceResponseHead response;
initial.commit09911bf2008-07-26 23:55:29112 std::string raw_headers(test_page_headers);
113 std::replace(raw_headers.begin(), raw_headers.end(), '\n', '\0');
114 response.headers = new net::HttpResponseHeaders(raw_headers);
115 response.mime_type = test_page_mime_type;
116 response.charset = test_page_charset;
initial.commit09911bf2008-07-26 23:55:29117 dispatcher_->OnReceivedResponse(request_id, response);
118
119 // received data message with the test contents
[email protected]176aa482008-11-14 03:25:15120 base::SharedMemory shared_mem;
initial.commit09911bf2008-07-26 23:55:29121 EXPECT_TRUE(shared_mem.Create(std::wstring(),
122 false, false, test_page_contents_len));
123 EXPECT_TRUE(shared_mem.Map(test_page_contents_len));
124 char* put_data_here = static_cast<char*>(shared_mem.memory());
125 memcpy(put_data_here, test_page_contents, test_page_contents_len);
[email protected]176aa482008-11-14 03:25:15126 base::SharedMemoryHandle dup_handle;
[email protected]4003d7142009-01-12 12:56:20127 EXPECT_TRUE(shared_mem.GiveToProcess(
128 base::Process::Current().handle(), &dup_handle));
[email protected]eb9989092009-03-12 21:42:52129 dispatcher_->OnReceivedData(
130 message_queue_[0], request_id, dup_handle, test_page_contents_len);
initial.commit09911bf2008-07-26 23:55:29131
132 message_queue_.erase(message_queue_.begin());
133
134 // read the ack message.
[email protected]c2fe31542009-05-20 18:24:14135 Tuple1<int> request_ack;
[email protected]eb9989092009-03-12 21:42:52136 ASSERT_TRUE(ViewHostMsg_DataReceived_ACK::Read(
137 &message_queue_[0], &request_ack));
initial.commit09911bf2008-07-26 23:55:29138
[email protected]c2fe31542009-05-20 18:24:14139 ASSERT_EQ(request_ack.a, request_id);
initial.commit09911bf2008-07-26 23:55:29140
141 message_queue_.erase(message_queue_.begin());
142 }
143 }
144
145 protected:
initial.commit09911bf2008-07-26 23:55:29146 // testing::Test
147 virtual void SetUp() {
[email protected]eb9989092009-03-12 21:42:52148 dispatcher_.reset(new ResourceDispatcher(this));
initial.commit09911bf2008-07-26 23:55:29149 }
150 virtual void TearDown() {
[email protected]eb9989092009-03-12 21:42:52151 dispatcher_.reset();
initial.commit09911bf2008-07-26 23:55:29152 }
153
[email protected]2602087e2009-08-24 23:12:16154 ResourceLoaderBridge* CreateBridge() {
[email protected]46b0d4a2009-12-19 00:46:33155 webkit_glue::ResourceLoaderBridge::RequestInfo request_info;
156 request_info.method = "GET";
157 request_info.url = GURL(test_page_url);
158 request_info.first_party_for_cookies = GURL(test_page_url);
159 request_info.referrer = GURL();
160 request_info.frame_origin = "null";
161 request_info.main_frame_origin = "null";
162 request_info.headers = std::string();
163 request_info.load_flags = 0;
164 request_info.requestor_pid = 0;
165 request_info.request_type = ResourceType::SUB_RESOURCE;
[email protected]52bbcd932010-01-06 18:56:12166 request_info.appcache_host_id = appcache::kNoHostId;
167 request_info.routing_id = 0;
[email protected]46b0d4a2009-12-19 00:46:33168
169 return dispatcher_->CreateBridge(request_info, -1, -1);
[email protected]2602087e2009-08-24 23:12:16170 }
171
initial.commit09911bf2008-07-26 23:55:29172 std::vector<IPC::Message> message_queue_;
[email protected]eb9989092009-03-12 21:42:52173 static scoped_ptr<ResourceDispatcher> dispatcher_;
initial.commit09911bf2008-07-26 23:55:29174};
175
176/*static*/
[email protected]eb9989092009-03-12 21:42:52177scoped_ptr<ResourceDispatcher> ResourceDispatcherTest::dispatcher_;
initial.commit09911bf2008-07-26 23:55:29178
179// Does a simple request and tests that the correct data is received.
180TEST_F(ResourceDispatcherTest, RoundTrip) {
181 TestRequestCallback callback;
[email protected]2602087e2009-08-24 23:12:16182 ResourceLoaderBridge* bridge = CreateBridge();
initial.commit09911bf2008-07-26 23:55:29183
184 bridge->Start(&callback);
185
186 ProcessMessages();
187
188 // FIXME(brettw) when the request complete messages are actually handledo
189 // and dispatched, uncomment this.
190 //EXPECT_TRUE(callback.complete());
191 //EXPECT_STREQ(test_page_contents, callback.data().c_str());
192
193 delete bridge;
194}
195
196// Tests that the request IDs are straight when there are multiple requests.
197TEST_F(ResourceDispatcherTest, MultipleRequests) {
198 // FIXME
199}
200
201// Tests that the cancel method prevents other messages from being received
202TEST_F(ResourceDispatcherTest, Cancel) {
203 // FIXME
204}
205
206TEST_F(ResourceDispatcherTest, Cookies) {
207 // FIXME
208}
209
210TEST_F(ResourceDispatcherTest, SerializedPostData) {
211 // FIXME
212}
[email protected]2602087e2009-08-24 23:12:16213
214// This class provides functionality to validate whether the ResourceDispatcher
215// object honors the deferred loading contract correctly, i.e. if deferred
216// loading is enabled it should queue up any responses received. If deferred
217// loading is enabled/disabled in the context of a dispatched message, other
218// queued messages should not be dispatched until deferred load is turned off.
219class DeferredResourceLoadingTest : public ResourceDispatcherTest,
220 public ResourceLoaderBridge::Peer {
221 public:
222 DeferredResourceLoadingTest()
223 : defer_loading_(false) {
224 }
225
226 virtual bool Send(IPC::Message* msg) {
227 delete msg;
228 return true;
229 }
230
231 void InitMessages() {
232 set_defer_loading(true);
233
234 ResourceResponseHead response_head;
235 response_head.status.set_status(URLRequestStatus::SUCCESS);
236
237 IPC::Message* response_message =
238 new ViewMsg_Resource_ReceivedResponse(0, 0, response_head);
239
240 dispatcher_->OnMessageReceived(*response_message);
241
242 delete response_message;
243
[email protected]a68114f72009-11-30 23:32:49244 // Duplicate the shared memory handle so both the test and the callee can
245 // close their copy.
246 base::SharedMemoryHandle duplicated_handle;
247 EXPECT_TRUE(shared_handle_.ShareToProcess(base::GetCurrentProcessHandle(),
248 &duplicated_handle));
249
[email protected]2602087e2009-08-24 23:12:16250 response_message =
[email protected]a68114f72009-11-30 23:32:49251 new ViewMsg_Resource_DataReceived(0, 0, duplicated_handle, 100);
[email protected]2602087e2009-08-24 23:12:16252
253 dispatcher_->OnMessageReceived(*response_message);
254
255 delete response_message;
256
257 set_defer_loading(false);
258 }
259
260 // ResourceLoaderBridge::Peer methods.
[email protected]bb551622010-07-22 20:52:49261 virtual void OnUploadProgress(uint64 position, uint64 size) {
[email protected]2602087e2009-08-24 23:12:16262 }
263
264 virtual bool OnReceivedRedirect(
265 const GURL& new_url,
[email protected]2581e572009-11-13 21:54:55266 const ResourceLoaderBridge::ResponseInfo& info,
[email protected]041b0bbb2009-11-18 02:27:34267 bool* has_new_first_party_for_cookies,
[email protected]2581e572009-11-13 21:54:55268 GURL* new_first_party_for_cookies) {
[email protected]041b0bbb2009-11-18 02:27:34269 *has_new_first_party_for_cookies = false;
[email protected]2602087e2009-08-24 23:12:16270 return true;
271 }
272
[email protected]bb551622010-07-22 20:52:49273 virtual void OnReceivedResponse(
274 const ResourceLoaderBridge::ResponseInfo& info,
275 bool content_filtered) {
276 EXPECT_EQ(defer_loading_, false);
277 set_defer_loading(true);
278 }
279
280 virtual void OnDownloadedData(int len) {
281 }
282
[email protected]2602087e2009-08-24 23:12:16283 virtual void OnReceivedData(const char* data, int len) {
284 EXPECT_EQ(defer_loading_, false);
285 set_defer_loading(false);
286 }
287
[email protected]2602087e2009-08-24 23:12:16288 virtual void OnCompletedRequest(const URLRequestStatus& status,
289 const std::string& security_info) {
290 }
291
[email protected]9ee9a76a2009-10-28 21:02:59292 virtual GURL GetURLForDebugging() const {
293 return GURL();
[email protected]2602087e2009-08-24 23:12:16294 }
295
296 protected:
297 virtual void SetUp() {
298 EXPECT_EQ(true, shared_handle_.Create(L"DeferredResourceLoaderTest", false,
299 false, 100));
300 ResourceDispatcherTest::SetUp();
301 }
302
303 virtual void TearDown() {
304 shared_handle_.Close();
305 ResourceDispatcherTest::TearDown();
306 }
307
308 private:
309 void set_defer_loading(bool defer) {
310 defer_loading_ = defer;
311 dispatcher_->SetDefersLoading(0, defer);
312 }
313
314 bool defer_loading() const {
315 return defer_loading_;
316 }
317
318 bool defer_loading_;
319 base::SharedMemory shared_handle_;
320};
321
322TEST_F(DeferredResourceLoadingTest, DeferredLoadTest) {
323 MessageLoop message_loop(MessageLoop::TYPE_IO);
324
325 ResourceLoaderBridge* bridge = CreateBridge();
326
327 bridge->Start(this);
328 InitMessages();
329
330 // Dispatch deferred messages.
331 message_loop.RunAllPending();
332 delete bridge;
333}
334