blob: e5c8a08578ce22e7e60f9e3d0f20e0d06f3a19ee [file] [log] [blame]
[email protected]f90bf0d92011-01-13 02:12:441// Copyright (c) 2011 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]3b63f8f42011-03-28 01:54:158#include "base/memory/scoped_ptr.h"
[email protected]2602087e2009-08-24 23:12:169#include "base/message_loop.h"
[email protected]4003d7142009-01-12 12:56:2010#include "base/process.h"
[email protected]a68114f72009-11-30 23:32:4911#include "base/process_util.h"
[email protected]940895b2011-08-20 00:50:0512#include "content/common/request_extra_data.h"
[email protected]620161e2011-03-07 18:05:2613#include "content/common/resource_dispatcher.h"
[email protected]94dc971d2011-03-05 19:08:3214#include "content/common/resource_messages.h"
[email protected]2336ffe2011-11-24 01:23:3415#include "content/public/common/resource_response.h"
[email protected]939856a2010-08-24 20:29:0216#include "net/base/upload_data.h"
[email protected]7a4de7a62010-08-17 18:38:2417#include "net/http/http_response_headers.h"
initial.commit09911bf2008-07-26 23:55:2918#include "testing/gtest/include/gtest/gtest.h"
[email protected]f430b5712009-08-21 21:46:3119#include "webkit/appcache/appcache_interfaces.h"
initial.commit09911bf2008-07-26 23:55:2920
21using webkit_glue::ResourceLoaderBridge;
[email protected]b4b3a912010-10-08 19:05:3722using webkit_glue::ResourceResponseInfo;
initial.commit09911bf2008-07-26 23:55:2923
24static const char test_page_url[] = "http://www.google.com/";
25static const char test_page_headers[] =
26 "HTTP/1.1 200 OK\nContent-Type:text/html\n\n";
27static const char test_page_mime_type[] = "text/html";
28static const char test_page_charset[] = "";
29static const char test_page_contents[] =
30 "<html><head><title>Google</title></head><body><h1>Google</h1></body></html>";
[email protected]b5ab3982010-02-16 23:58:2731static const uint32 test_page_contents_len = arraysize(test_page_contents) - 1;
initial.commit09911bf2008-07-26 23:55:2932
[email protected]b8901082010-11-12 01:14:2833static const char kShmemSegmentName[] = "DeferredResourceLoaderTest";
34
initial.commit09911bf2008-07-26 23:55:2935// Listens for request response data and stores it so that it can be compared
36// to the reference data.
37class TestRequestCallback : public ResourceLoaderBridge::Peer {
38 public:
39 TestRequestCallback() : complete_(false) {
40 }
41
[email protected]bb551622010-07-22 20:52:4942 virtual void OnUploadProgress(uint64 position, uint64 size) {
43 }
44
[email protected]6568a9e32009-07-30 18:01:3945 virtual bool OnReceivedRedirect(
46 const GURL& new_url,
[email protected]b4b3a912010-10-08 19:05:3747 const ResourceResponseInfo& info,
[email protected]041b0bbb2009-11-18 02:27:3448 bool* has_new_first_party_for_cookies,
[email protected]2581e572009-11-13 21:54:5549 GURL* new_first_party_for_cookies) {
[email protected]041b0bbb2009-11-18 02:27:3450 *has_new_first_party_for_cookies = false;
[email protected]6568a9e32009-07-30 18:01:3951 return true;
initial.commit09911bf2008-07-26 23:55:2952 }
53
[email protected]b9e8ea62011-03-04 06:29:0954 virtual void OnReceivedResponse(const ResourceResponseInfo& info) {
initial.commit09911bf2008-07-26 23:55:2955 }
56
[email protected]bb551622010-07-22 20:52:4957 virtual void OnDownloadedData(int len) {
58 }
59
[email protected]8bd0de72011-04-08 18:52:1060 virtual void OnReceivedData(const char* data,
61 int data_length,
[email protected]dfd682172011-04-13 19:57:2562 int encoded_data_length) {
initial.commit09911bf2008-07-26 23:55:2963 EXPECT_FALSE(complete_);
[email protected]8bd0de72011-04-08 18:52:1064 data_.append(data, data_length);
[email protected]dfd682172011-04-13 19:57:2565 total_encoded_data_length_ += encoded_data_length;
initial.commit09911bf2008-07-26 23:55:2966 }
67
[email protected]f90bf0d92011-01-13 02:12:4468 virtual void OnCompletedRequest(const net::URLRequestStatus& status,
[email protected]e0f458c2010-09-16 04:50:4169 const std::string& security_info,
70 const base::Time& completion_time) {
initial.commit09911bf2008-07-26 23:55:2971 EXPECT_FALSE(complete_);
72 complete_ = true;
73 }
74
[email protected]8bd0de72011-04-08 18:52:1075 bool complete() const {
76 return complete_;
77 }
initial.commit09911bf2008-07-26 23:55:2978 const std::string& data() const {
79 return data_;
80 }
[email protected]dfd682172011-04-13 19:57:2581 int total_encoded_data_length() const {
82 return total_encoded_data_length_;
initial.commit09911bf2008-07-26 23:55:2983 }
84
85 private:
86 bool complete_;
87 std::string data_;
[email protected]dfd682172011-04-13 19:57:2588 int total_encoded_data_length_;
initial.commit09911bf2008-07-26 23:55:2989};
90
91
92// Sets up the message sender override for the unit test
93class ResourceDispatcherTest : public testing::Test,
94 public IPC::Message::Sender {
95 public:
96 // Emulates IPC send operations (IPC::Message::Sender) by adding
97 // pending messages to the queue.
98 virtual bool Send(IPC::Message* msg) {
99 message_queue_.push_back(IPC::Message(*msg));
100 delete msg;
101 return true;
102 }
103
104 // Emulates the browser process and processes the pending IPC messages,
105 // returning the hardcoded file contents.
106 void ProcessMessages() {
107 while (!message_queue_.empty()) {
initial.commit09911bf2008-07-26 23:55:29108 int request_id;
[email protected]94dc971d2011-03-05 19:08:32109 ResourceHostMsg_Request request;
110 ASSERT_TRUE(ResourceHostMsg_RequestResource::Read(
[email protected]eb9989092009-03-12 21:42:52111 &message_queue_[0], &request_id, &request));
initial.commit09911bf2008-07-26 23:55:29112
113 // check values
114 EXPECT_EQ(test_page_url, request.url.spec());
115
116 // received response message
[email protected]2336ffe2011-11-24 01:23:34117 content::ResourceResponseHead response;
initial.commit09911bf2008-07-26 23:55:29118 std::string raw_headers(test_page_headers);
119 std::replace(raw_headers.begin(), raw_headers.end(), '\n', '\0');
120 response.headers = new net::HttpResponseHeaders(raw_headers);
121 response.mime_type = test_page_mime_type;
122 response.charset = test_page_charset;
initial.commit09911bf2008-07-26 23:55:29123 dispatcher_->OnReceivedResponse(request_id, response);
124
125 // received data message with the test contents
[email protected]176aa482008-11-14 03:25:15126 base::SharedMemory shared_mem;
[email protected]54e3dfa22010-10-27 18:16:06127 EXPECT_TRUE(shared_mem.CreateAndMapAnonymous(test_page_contents_len));
initial.commit09911bf2008-07-26 23:55:29128 char* put_data_here = static_cast<char*>(shared_mem.memory());
129 memcpy(put_data_here, test_page_contents, test_page_contents_len);
[email protected]176aa482008-11-14 03:25:15130 base::SharedMemoryHandle dup_handle;
[email protected]4003d7142009-01-12 12:56:20131 EXPECT_TRUE(shared_mem.GiveToProcess(
132 base::Process::Current().handle(), &dup_handle));
[email protected]eb9989092009-03-12 21:42:52133 dispatcher_->OnReceivedData(
[email protected]8bd0de72011-04-08 18:52:10134 message_queue_[0],
135 request_id,
136 dup_handle,
137 test_page_contents_len,
138 test_page_contents_len);
initial.commit09911bf2008-07-26 23:55:29139
140 message_queue_.erase(message_queue_.begin());
141
142 // read the ack message.
[email protected]c2fe31542009-05-20 18:24:14143 Tuple1<int> request_ack;
[email protected]94dc971d2011-03-05 19:08:32144 ASSERT_TRUE(ResourceHostMsg_DataReceived_ACK::Read(
[email protected]eb9989092009-03-12 21:42:52145 &message_queue_[0], &request_ack));
initial.commit09911bf2008-07-26 23:55:29146
[email protected]c2fe31542009-05-20 18:24:14147 ASSERT_EQ(request_ack.a, request_id);
initial.commit09911bf2008-07-26 23:55:29148
149 message_queue_.erase(message_queue_.begin());
150 }
151 }
152
153 protected:
initial.commit09911bf2008-07-26 23:55:29154 // testing::Test
155 virtual void SetUp() {
[email protected]eb9989092009-03-12 21:42:52156 dispatcher_.reset(new ResourceDispatcher(this));
initial.commit09911bf2008-07-26 23:55:29157 }
158 virtual void TearDown() {
[email protected]eb9989092009-03-12 21:42:52159 dispatcher_.reset();
initial.commit09911bf2008-07-26 23:55:29160 }
161
[email protected]2602087e2009-08-24 23:12:16162 ResourceLoaderBridge* CreateBridge() {
[email protected]46b0d4a2009-12-19 00:46:33163 webkit_glue::ResourceLoaderBridge::RequestInfo request_info;
164 request_info.method = "GET";
165 request_info.url = GURL(test_page_url);
166 request_info.first_party_for_cookies = GURL(test_page_url);
167 request_info.referrer = GURL();
[email protected]46b0d4a2009-12-19 00:46:33168 request_info.headers = std::string();
169 request_info.load_flags = 0;
170 request_info.requestor_pid = 0;
171 request_info.request_type = ResourceType::SUB_RESOURCE;
[email protected]52bbcd932010-01-06 18:56:12172 request_info.appcache_host_id = appcache::kNoHostId;
173 request_info.routing_id = 0;
[email protected]537fbe02011-11-24 00:58:06174 RequestExtraData extra_data(WebKit::WebReferrerPolicyDefault,
175 true, 0, false, -1,
[email protected]91043a8232011-11-04 16:41:19176 content::PAGE_TRANSITION_LINK);
[email protected]940895b2011-08-20 00:50:05177 request_info.extra_data = &extra_data;
[email protected]46b0d4a2009-12-19 00:46:33178
[email protected]50285ff2011-03-11 23:10:56179 return dispatcher_->CreateBridge(request_info);
[email protected]2602087e2009-08-24 23:12:16180 }
181
initial.commit09911bf2008-07-26 23:55:29182 std::vector<IPC::Message> message_queue_;
[email protected]eb9989092009-03-12 21:42:52183 static scoped_ptr<ResourceDispatcher> dispatcher_;
initial.commit09911bf2008-07-26 23:55:29184};
185
186/*static*/
[email protected]eb9989092009-03-12 21:42:52187scoped_ptr<ResourceDispatcher> ResourceDispatcherTest::dispatcher_;
initial.commit09911bf2008-07-26 23:55:29188
189// Does a simple request and tests that the correct data is received.
190TEST_F(ResourceDispatcherTest, RoundTrip) {
191 TestRequestCallback callback;
[email protected]2602087e2009-08-24 23:12:16192 ResourceLoaderBridge* bridge = CreateBridge();
initial.commit09911bf2008-07-26 23:55:29193
194 bridge->Start(&callback);
195
196 ProcessMessages();
197
198 // FIXME(brettw) when the request complete messages are actually handledo
199 // and dispatched, uncomment this.
200 //EXPECT_TRUE(callback.complete());
201 //EXPECT_STREQ(test_page_contents, callback.data().c_str());
[email protected]dfd682172011-04-13 19:57:25202 //EXPECT_EQ(test_page_contents_len, callback.total_encoded_data_length());
initial.commit09911bf2008-07-26 23:55:29203
204 delete bridge;
205}
206
207// Tests that the request IDs are straight when there are multiple requests.
208TEST_F(ResourceDispatcherTest, MultipleRequests) {
209 // FIXME
210}
211
212// Tests that the cancel method prevents other messages from being received
213TEST_F(ResourceDispatcherTest, Cancel) {
214 // FIXME
215}
216
217TEST_F(ResourceDispatcherTest, Cookies) {
218 // FIXME
219}
220
221TEST_F(ResourceDispatcherTest, SerializedPostData) {
222 // FIXME
223}
[email protected]2602087e2009-08-24 23:12:16224
225// This class provides functionality to validate whether the ResourceDispatcher
226// object honors the deferred loading contract correctly, i.e. if deferred
227// loading is enabled it should queue up any responses received. If deferred
228// loading is enabled/disabled in the context of a dispatched message, other
229// queued messages should not be dispatched until deferred load is turned off.
230class DeferredResourceLoadingTest : public ResourceDispatcherTest,
231 public ResourceLoaderBridge::Peer {
232 public:
233 DeferredResourceLoadingTest()
234 : defer_loading_(false) {
235 }
236
237 virtual bool Send(IPC::Message* msg) {
238 delete msg;
239 return true;
240 }
241
242 void InitMessages() {
243 set_defer_loading(true);
244
[email protected]2336ffe2011-11-24 01:23:34245 content::ResourceResponseHead response_head;
[email protected]f90bf0d92011-01-13 02:12:44246 response_head.status.set_status(net::URLRequestStatus::SUCCESS);
[email protected]2602087e2009-08-24 23:12:16247
248 IPC::Message* response_message =
[email protected]94dc971d2011-03-05 19:08:32249 new ResourceMsg_ReceivedResponse(0, 0, response_head);
[email protected]2602087e2009-08-24 23:12:16250
251 dispatcher_->OnMessageReceived(*response_message);
252
253 delete response_message;
254
[email protected]a68114f72009-11-30 23:32:49255 // Duplicate the shared memory handle so both the test and the callee can
256 // close their copy.
257 base::SharedMemoryHandle duplicated_handle;
258 EXPECT_TRUE(shared_handle_.ShareToProcess(base::GetCurrentProcessHandle(),
259 &duplicated_handle));
260
[email protected]2602087e2009-08-24 23:12:16261 response_message =
[email protected]8bd0de72011-04-08 18:52:10262 new ResourceMsg_DataReceived(0, 0, duplicated_handle, 100, 100);
[email protected]2602087e2009-08-24 23:12:16263
264 dispatcher_->OnMessageReceived(*response_message);
265
266 delete response_message;
267
268 set_defer_loading(false);
269 }
270
271 // ResourceLoaderBridge::Peer methods.
[email protected]bb551622010-07-22 20:52:49272 virtual void OnUploadProgress(uint64 position, uint64 size) {
[email protected]2602087e2009-08-24 23:12:16273 }
274
275 virtual bool OnReceivedRedirect(
276 const GURL& new_url,
[email protected]b4b3a912010-10-08 19:05:37277 const ResourceResponseInfo& info,
[email protected]041b0bbb2009-11-18 02:27:34278 bool* has_new_first_party_for_cookies,
[email protected]2581e572009-11-13 21:54:55279 GURL* new_first_party_for_cookies) {
[email protected]041b0bbb2009-11-18 02:27:34280 *has_new_first_party_for_cookies = false;
[email protected]2602087e2009-08-24 23:12:16281 return true;
282 }
283
[email protected]b9e8ea62011-03-04 06:29:09284 virtual void OnReceivedResponse(const ResourceResponseInfo& info) {
[email protected]bb551622010-07-22 20:52:49285 EXPECT_EQ(defer_loading_, false);
286 set_defer_loading(true);
287 }
288
289 virtual void OnDownloadedData(int len) {
290 }
291
[email protected]8bd0de72011-04-08 18:52:10292 virtual void OnReceivedData(const char* data,
293 int data_length,
[email protected]dfd682172011-04-13 19:57:25294 int encoded_data_length) {
[email protected]2602087e2009-08-24 23:12:16295 EXPECT_EQ(defer_loading_, false);
296 set_defer_loading(false);
297 }
298
[email protected]f90bf0d92011-01-13 02:12:44299 virtual void OnCompletedRequest(const net::URLRequestStatus& status,
[email protected]e0f458c2010-09-16 04:50:41300 const std::string& security_info,
301 const base::Time& completion_time) {
[email protected]2602087e2009-08-24 23:12:16302 }
303
[email protected]2602087e2009-08-24 23:12:16304 protected:
305 virtual void SetUp() {
[email protected]2602087e2009-08-24 23:12:16306 ResourceDispatcherTest::SetUp();
[email protected]b8901082010-11-12 01:14:28307 shared_handle_.Delete(kShmemSegmentName);
[email protected]515f2492011-01-14 10:36:28308 EXPECT_TRUE(shared_handle_.CreateNamed(kShmemSegmentName, false, 100));
[email protected]2602087e2009-08-24 23:12:16309 }
310
311 virtual void TearDown() {
312 shared_handle_.Close();
[email protected]b8901082010-11-12 01:14:28313 EXPECT_TRUE(shared_handle_.Delete(kShmemSegmentName));
[email protected]2602087e2009-08-24 23:12:16314 ResourceDispatcherTest::TearDown();
315 }
316
317 private:
318 void set_defer_loading(bool defer) {
319 defer_loading_ = defer;
320 dispatcher_->SetDefersLoading(0, defer);
321 }
322
323 bool defer_loading() const {
324 return defer_loading_;
325 }
326
327 bool defer_loading_;
328 base::SharedMemory shared_handle_;
329};
330
331TEST_F(DeferredResourceLoadingTest, DeferredLoadTest) {
332 MessageLoop message_loop(MessageLoop::TYPE_IO);
333
334 ResourceLoaderBridge* bridge = CreateBridge();
335
336 bridge->Start(this);
337 InitMessages();
338
339 // Dispatch deferred messages.
340 message_loop.RunAllPending();
341 delete bridge;
342}