blob: 3e76678803d904b1ebfb1ba3d9fb246973d02411 [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"
initial.commit09911bf2008-07-26 23:55:2913#include "chrome/common/resource_dispatcher.h"
initial.commit09911bf2008-07-26 23:55:2914#include "testing/gtest/include/gtest/gtest.h"
[email protected]f430b5712009-08-21 21:46:3115#include "webkit/appcache/appcache_interfaces.h"
initial.commit09911bf2008-07-26 23:55:2916
17using webkit_glue::ResourceLoaderBridge;
18
19static const char test_page_url[] = "http://www.google.com/";
20static const char test_page_headers[] =
21 "HTTP/1.1 200 OK\nContent-Type:text/html\n\n";
22static const char test_page_mime_type[] = "text/html";
23static const char test_page_charset[] = "";
24static const char test_page_contents[] =
25 "<html><head><title>Google</title></head><body><h1>Google</h1></body></html>";
[email protected]b5ab3982010-02-16 23:58:2726static const uint32 test_page_contents_len = arraysize(test_page_contents) - 1;
initial.commit09911bf2008-07-26 23:55:2927
28// Listens for request response data and stores it so that it can be compared
29// to the reference data.
30class TestRequestCallback : public ResourceLoaderBridge::Peer {
31 public:
32 TestRequestCallback() : complete_(false) {
33 }
34
[email protected]bb551622010-07-22 20:52:4935 virtual void OnUploadProgress(uint64 position, uint64 size) {
36 }
37
[email protected]6568a9e32009-07-30 18:01:3938 virtual bool OnReceivedRedirect(
39 const GURL& new_url,
[email protected]2581e572009-11-13 21:54:5540 const ResourceLoaderBridge::ResponseInfo& info,
[email protected]041b0bbb2009-11-18 02:27:3441 bool* has_new_first_party_for_cookies,
[email protected]2581e572009-11-13 21:54:5542 GURL* new_first_party_for_cookies) {
[email protected]041b0bbb2009-11-18 02:27:3443 *has_new_first_party_for_cookies = false;
[email protected]6568a9e32009-07-30 18:01:3944 return true;
initial.commit09911bf2008-07-26 23:55:2945 }
46
47 virtual void OnReceivedResponse(
[email protected]8a3422c92008-09-24 17:42:4248 const ResourceLoaderBridge::ResponseInfo& info,
49 bool content_filtered) {
initial.commit09911bf2008-07-26 23:55:2950 }
51
[email protected]bb551622010-07-22 20:52:4952 virtual void OnDownloadedData(int len) {
53 }
54
initial.commit09911bf2008-07-26 23:55:2955 virtual void OnReceivedData(const char* data, int len) {
56 EXPECT_FALSE(complete_);
57 data_.append(data, len);
58 }
59
[email protected]c4891b32009-03-08 07:41:3160 virtual void OnCompletedRequest(const URLRequestStatus& status,
61 const std::string& security_info) {
initial.commit09911bf2008-07-26 23:55:2962 EXPECT_FALSE(complete_);
63 complete_ = true;
64 }
65
[email protected]9ee9a76a2009-10-28 21:02:5966 virtual GURL GetURLForDebugging() const {
67 return GURL();
initial.commit09911bf2008-07-26 23:55:2968 }
69
70 const std::string& data() const {
71 return data_;
72 }
[email protected]52120702010-03-09 21:44:4473 bool complete() const {
initial.commit09911bf2008-07-26 23:55:2974 return complete_;
75 }
76
77 private:
78 bool complete_;
79 std::string data_;
80};
81
82
83// Sets up the message sender override for the unit test
84class ResourceDispatcherTest : public testing::Test,
85 public IPC::Message::Sender {
86 public:
87 // Emulates IPC send operations (IPC::Message::Sender) by adding
88 // pending messages to the queue.
89 virtual bool Send(IPC::Message* msg) {
90 message_queue_.push_back(IPC::Message(*msg));
91 delete msg;
92 return true;
93 }
94
95 // Emulates the browser process and processes the pending IPC messages,
96 // returning the hardcoded file contents.
97 void ProcessMessages() {
98 while (!message_queue_.empty()) {
initial.commit09911bf2008-07-26 23:55:2999 int request_id;
initial.commit09911bf2008-07-26 23:55:29100 ViewHostMsg_Resource_Request request;
[email protected]eb9989092009-03-12 21:42:52101 ASSERT_TRUE(ViewHostMsg_RequestResource::Read(
102 &message_queue_[0], &request_id, &request));
initial.commit09911bf2008-07-26 23:55:29103
104 // check values
105 EXPECT_EQ(test_page_url, request.url.spec());
106
107 // received response message
[email protected]e09ba552009-02-05 03:26:29108 ResourceResponseHead response;
initial.commit09911bf2008-07-26 23:55:29109 std::string raw_headers(test_page_headers);
110 std::replace(raw_headers.begin(), raw_headers.end(), '\n', '\0');
111 response.headers = new net::HttpResponseHeaders(raw_headers);
112 response.mime_type = test_page_mime_type;
113 response.charset = test_page_charset;
initial.commit09911bf2008-07-26 23:55:29114 dispatcher_->OnReceivedResponse(request_id, response);
115
116 // received data message with the test contents
[email protected]176aa482008-11-14 03:25:15117 base::SharedMemory shared_mem;
initial.commit09911bf2008-07-26 23:55:29118 EXPECT_TRUE(shared_mem.Create(std::wstring(),
119 false, false, test_page_contents_len));
120 EXPECT_TRUE(shared_mem.Map(test_page_contents_len));
121 char* put_data_here = static_cast<char*>(shared_mem.memory());
122 memcpy(put_data_here, test_page_contents, test_page_contents_len);
[email protected]176aa482008-11-14 03:25:15123 base::SharedMemoryHandle dup_handle;
[email protected]4003d7142009-01-12 12:56:20124 EXPECT_TRUE(shared_mem.GiveToProcess(
125 base::Process::Current().handle(), &dup_handle));
[email protected]eb9989092009-03-12 21:42:52126 dispatcher_->OnReceivedData(
127 message_queue_[0], request_id, dup_handle, test_page_contents_len);
initial.commit09911bf2008-07-26 23:55:29128
129 message_queue_.erase(message_queue_.begin());
130
131 // read the ack message.
[email protected]c2fe31542009-05-20 18:24:14132 Tuple1<int> request_ack;
[email protected]eb9989092009-03-12 21:42:52133 ASSERT_TRUE(ViewHostMsg_DataReceived_ACK::Read(
134 &message_queue_[0], &request_ack));
initial.commit09911bf2008-07-26 23:55:29135
[email protected]c2fe31542009-05-20 18:24:14136 ASSERT_EQ(request_ack.a, request_id);
initial.commit09911bf2008-07-26 23:55:29137
138 message_queue_.erase(message_queue_.begin());
139 }
140 }
141
142 protected:
initial.commit09911bf2008-07-26 23:55:29143 // testing::Test
144 virtual void SetUp() {
[email protected]eb9989092009-03-12 21:42:52145 dispatcher_.reset(new ResourceDispatcher(this));
initial.commit09911bf2008-07-26 23:55:29146 }
147 virtual void TearDown() {
[email protected]eb9989092009-03-12 21:42:52148 dispatcher_.reset();
initial.commit09911bf2008-07-26 23:55:29149 }
150
[email protected]2602087e2009-08-24 23:12:16151 ResourceLoaderBridge* CreateBridge() {
[email protected]46b0d4a2009-12-19 00:46:33152 webkit_glue::ResourceLoaderBridge::RequestInfo request_info;
153 request_info.method = "GET";
154 request_info.url = GURL(test_page_url);
155 request_info.first_party_for_cookies = GURL(test_page_url);
156 request_info.referrer = GURL();
157 request_info.frame_origin = "null";
158 request_info.main_frame_origin = "null";
159 request_info.headers = std::string();
160 request_info.load_flags = 0;
161 request_info.requestor_pid = 0;
162 request_info.request_type = ResourceType::SUB_RESOURCE;
[email protected]52bbcd932010-01-06 18:56:12163 request_info.appcache_host_id = appcache::kNoHostId;
164 request_info.routing_id = 0;
[email protected]46b0d4a2009-12-19 00:46:33165
166 return dispatcher_->CreateBridge(request_info, -1, -1);
[email protected]2602087e2009-08-24 23:12:16167 }
168
initial.commit09911bf2008-07-26 23:55:29169 std::vector<IPC::Message> message_queue_;
[email protected]eb9989092009-03-12 21:42:52170 static scoped_ptr<ResourceDispatcher> dispatcher_;
initial.commit09911bf2008-07-26 23:55:29171};
172
173/*static*/
[email protected]eb9989092009-03-12 21:42:52174scoped_ptr<ResourceDispatcher> ResourceDispatcherTest::dispatcher_;
initial.commit09911bf2008-07-26 23:55:29175
176// Does a simple request and tests that the correct data is received.
177TEST_F(ResourceDispatcherTest, RoundTrip) {
178 TestRequestCallback callback;
[email protected]2602087e2009-08-24 23:12:16179 ResourceLoaderBridge* bridge = CreateBridge();
initial.commit09911bf2008-07-26 23:55:29180
181 bridge->Start(&callback);
182
183 ProcessMessages();
184
185 // FIXME(brettw) when the request complete messages are actually handledo
186 // and dispatched, uncomment this.
187 //EXPECT_TRUE(callback.complete());
188 //EXPECT_STREQ(test_page_contents, callback.data().c_str());
189
190 delete bridge;
191}
192
193// Tests that the request IDs are straight when there are multiple requests.
194TEST_F(ResourceDispatcherTest, MultipleRequests) {
195 // FIXME
196}
197
198// Tests that the cancel method prevents other messages from being received
199TEST_F(ResourceDispatcherTest, Cancel) {
200 // FIXME
201}
202
203TEST_F(ResourceDispatcherTest, Cookies) {
204 // FIXME
205}
206
207TEST_F(ResourceDispatcherTest, SerializedPostData) {
208 // FIXME
209}
[email protected]2602087e2009-08-24 23:12:16210
211// This class provides functionality to validate whether the ResourceDispatcher
212// object honors the deferred loading contract correctly, i.e. if deferred
213// loading is enabled it should queue up any responses received. If deferred
214// loading is enabled/disabled in the context of a dispatched message, other
215// queued messages should not be dispatched until deferred load is turned off.
216class DeferredResourceLoadingTest : public ResourceDispatcherTest,
217 public ResourceLoaderBridge::Peer {
218 public:
219 DeferredResourceLoadingTest()
220 : defer_loading_(false) {
221 }
222
223 virtual bool Send(IPC::Message* msg) {
224 delete msg;
225 return true;
226 }
227
228 void InitMessages() {
229 set_defer_loading(true);
230
231 ResourceResponseHead response_head;
232 response_head.status.set_status(URLRequestStatus::SUCCESS);
233
234 IPC::Message* response_message =
235 new ViewMsg_Resource_ReceivedResponse(0, 0, response_head);
236
237 dispatcher_->OnMessageReceived(*response_message);
238
239 delete response_message;
240
[email protected]a68114f72009-11-30 23:32:49241 // Duplicate the shared memory handle so both the test and the callee can
242 // close their copy.
243 base::SharedMemoryHandle duplicated_handle;
244 EXPECT_TRUE(shared_handle_.ShareToProcess(base::GetCurrentProcessHandle(),
245 &duplicated_handle));
246
[email protected]2602087e2009-08-24 23:12:16247 response_message =
[email protected]a68114f72009-11-30 23:32:49248 new ViewMsg_Resource_DataReceived(0, 0, duplicated_handle, 100);
[email protected]2602087e2009-08-24 23:12:16249
250 dispatcher_->OnMessageReceived(*response_message);
251
252 delete response_message;
253
254 set_defer_loading(false);
255 }
256
257 // ResourceLoaderBridge::Peer methods.
[email protected]bb551622010-07-22 20:52:49258 virtual void OnUploadProgress(uint64 position, uint64 size) {
[email protected]2602087e2009-08-24 23:12:16259 }
260
261 virtual bool OnReceivedRedirect(
262 const GURL& new_url,
[email protected]2581e572009-11-13 21:54:55263 const ResourceLoaderBridge::ResponseInfo& info,
[email protected]041b0bbb2009-11-18 02:27:34264 bool* has_new_first_party_for_cookies,
[email protected]2581e572009-11-13 21:54:55265 GURL* new_first_party_for_cookies) {
[email protected]041b0bbb2009-11-18 02:27:34266 *has_new_first_party_for_cookies = false;
[email protected]2602087e2009-08-24 23:12:16267 return true;
268 }
269
[email protected]bb551622010-07-22 20:52:49270 virtual void OnReceivedResponse(
271 const ResourceLoaderBridge::ResponseInfo& info,
272 bool content_filtered) {
273 EXPECT_EQ(defer_loading_, false);
274 set_defer_loading(true);
275 }
276
277 virtual void OnDownloadedData(int len) {
278 }
279
[email protected]2602087e2009-08-24 23:12:16280 virtual void OnReceivedData(const char* data, int len) {
281 EXPECT_EQ(defer_loading_, false);
282 set_defer_loading(false);
283 }
284
[email protected]2602087e2009-08-24 23:12:16285 virtual void OnCompletedRequest(const URLRequestStatus& status,
286 const std::string& security_info) {
287 }
288
[email protected]9ee9a76a2009-10-28 21:02:59289 virtual GURL GetURLForDebugging() const {
290 return GURL();
[email protected]2602087e2009-08-24 23:12:16291 }
292
293 protected:
294 virtual void SetUp() {
295 EXPECT_EQ(true, shared_handle_.Create(L"DeferredResourceLoaderTest", false,
296 false, 100));
297 ResourceDispatcherTest::SetUp();
298 }
299
300 virtual void TearDown() {
301 shared_handle_.Close();
302 ResourceDispatcherTest::TearDown();
303 }
304
305 private:
306 void set_defer_loading(bool defer) {
307 defer_loading_ = defer;
308 dispatcher_->SetDefersLoading(0, defer);
309 }
310
311 bool defer_loading() const {
312 return defer_loading_;
313 }
314
315 bool defer_loading_;
316 base::SharedMemory shared_handle_;
317};
318
319TEST_F(DeferredResourceLoadingTest, DeferredLoadTest) {
320 MessageLoop message_loop(MessageLoop::TYPE_IO);
321
322 ResourceLoaderBridge* bridge = CreateBridge();
323
324 bridge->Start(this);
325 InitMessages();
326
327 // Dispatch deferred messages.
328 message_loop.RunAllPending();
329 delete bridge;
330}
331