blob: 3e846f98ad979ff2e64e076f8a9b08c56876a63d [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]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]b4b3a912010-10-08 19:05:3715#include "chrome/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
54 virtual void OnReceivedResponse(
[email protected]b4b3a912010-10-08 19:05:3755 const ResourceResponseInfo& info,
[email protected]8a3422c92008-09-24 17:42:4256 bool content_filtered) {
initial.commit09911bf2008-07-26 23:55:2957 }
58
[email protected]bb551622010-07-22 20:52:4959 virtual void OnDownloadedData(int len) {
60 }
61
initial.commit09911bf2008-07-26 23:55:2962 virtual void OnReceivedData(const char* data, int len) {
63 EXPECT_FALSE(complete_);
64 data_.append(data, len);
65 }
66
[email protected]f90bf0d92011-01-13 02:12:4467 virtual void OnCompletedRequest(const net::URLRequestStatus& status,
[email protected]e0f458c2010-09-16 04:50:4168 const std::string& security_info,
69 const base::Time& completion_time) {
initial.commit09911bf2008-07-26 23:55:2970 EXPECT_FALSE(complete_);
71 complete_ = true;
72 }
73
initial.commit09911bf2008-07-26 23:55:2974 const std::string& data() const {
75 return data_;
76 }
[email protected]52120702010-03-09 21:44:4477 bool complete() const {
initial.commit09911bf2008-07-26 23:55:2978 return complete_;
79 }
80
81 private:
82 bool complete_;
83 std::string data_;
84};
85
86
87// Sets up the message sender override for the unit test
88class ResourceDispatcherTest : public testing::Test,
89 public IPC::Message::Sender {
90 public:
91 // Emulates IPC send operations (IPC::Message::Sender) by adding
92 // pending messages to the queue.
93 virtual bool Send(IPC::Message* msg) {
94 message_queue_.push_back(IPC::Message(*msg));
95 delete msg;
96 return true;
97 }
98
99 // Emulates the browser process and processes the pending IPC messages,
100 // returning the hardcoded file contents.
101 void ProcessMessages() {
102 while (!message_queue_.empty()) {
initial.commit09911bf2008-07-26 23:55:29103 int request_id;
initial.commit09911bf2008-07-26 23:55:29104 ViewHostMsg_Resource_Request request;
[email protected]eb9989092009-03-12 21:42:52105 ASSERT_TRUE(ViewHostMsg_RequestResource::Read(
106 &message_queue_[0], &request_id, &request));
initial.commit09911bf2008-07-26 23:55:29107
108 // check values
109 EXPECT_EQ(test_page_url, request.url.spec());
110
111 // received response message
[email protected]e09ba552009-02-05 03:26:29112 ResourceResponseHead response;
initial.commit09911bf2008-07-26 23:55:29113 std::string raw_headers(test_page_headers);
114 std::replace(raw_headers.begin(), raw_headers.end(), '\n', '\0');
115 response.headers = new net::HttpResponseHeaders(raw_headers);
116 response.mime_type = test_page_mime_type;
117 response.charset = test_page_charset;
initial.commit09911bf2008-07-26 23:55:29118 dispatcher_->OnReceivedResponse(request_id, response);
119
120 // received data message with the test contents
[email protected]176aa482008-11-14 03:25:15121 base::SharedMemory shared_mem;
[email protected]54e3dfa22010-10-27 18:16:06122 EXPECT_TRUE(shared_mem.CreateAndMapAnonymous(test_page_contents_len));
initial.commit09911bf2008-07-26 23:55:29123 char* put_data_here = static_cast<char*>(shared_mem.memory());
124 memcpy(put_data_here, test_page_contents, test_page_contents_len);
[email protected]176aa482008-11-14 03:25:15125 base::SharedMemoryHandle dup_handle;
[email protected]4003d7142009-01-12 12:56:20126 EXPECT_TRUE(shared_mem.GiveToProcess(
127 base::Process::Current().handle(), &dup_handle));
[email protected]eb9989092009-03-12 21:42:52128 dispatcher_->OnReceivedData(
129 message_queue_[0], request_id, dup_handle, test_page_contents_len);
initial.commit09911bf2008-07-26 23:55:29130
131 message_queue_.erase(message_queue_.begin());
132
133 // read the ack message.
[email protected]c2fe31542009-05-20 18:24:14134 Tuple1<int> request_ack;
[email protected]eb9989092009-03-12 21:42:52135 ASSERT_TRUE(ViewHostMsg_DataReceived_ACK::Read(
136 &message_queue_[0], &request_ack));
initial.commit09911bf2008-07-26 23:55:29137
[email protected]c2fe31542009-05-20 18:24:14138 ASSERT_EQ(request_ack.a, request_id);
initial.commit09911bf2008-07-26 23:55:29139
140 message_queue_.erase(message_queue_.begin());
141 }
142 }
143
144 protected:
initial.commit09911bf2008-07-26 23:55:29145 // testing::Test
146 virtual void SetUp() {
[email protected]eb9989092009-03-12 21:42:52147 dispatcher_.reset(new ResourceDispatcher(this));
initial.commit09911bf2008-07-26 23:55:29148 }
149 virtual void TearDown() {
[email protected]eb9989092009-03-12 21:42:52150 dispatcher_.reset();
initial.commit09911bf2008-07-26 23:55:29151 }
152
[email protected]2602087e2009-08-24 23:12:16153 ResourceLoaderBridge* CreateBridge() {
[email protected]46b0d4a2009-12-19 00:46:33154 webkit_glue::ResourceLoaderBridge::RequestInfo request_info;
155 request_info.method = "GET";
156 request_info.url = GURL(test_page_url);
157 request_info.first_party_for_cookies = GURL(test_page_url);
158 request_info.referrer = GURL();
159 request_info.frame_origin = "null";
160 request_info.main_frame_origin = "null";
161 request_info.headers = std::string();
162 request_info.load_flags = 0;
163 request_info.requestor_pid = 0;
164 request_info.request_type = ResourceType::SUB_RESOURCE;
[email protected]52bbcd932010-01-06 18:56:12165 request_info.appcache_host_id = appcache::kNoHostId;
166 request_info.routing_id = 0;
[email protected]46b0d4a2009-12-19 00:46:33167
168 return dispatcher_->CreateBridge(request_info, -1, -1);
[email protected]2602087e2009-08-24 23:12:16169 }
170
initial.commit09911bf2008-07-26 23:55:29171 std::vector<IPC::Message> message_queue_;
[email protected]eb9989092009-03-12 21:42:52172 static scoped_ptr<ResourceDispatcher> dispatcher_;
initial.commit09911bf2008-07-26 23:55:29173};
174
175/*static*/
[email protected]eb9989092009-03-12 21:42:52176scoped_ptr<ResourceDispatcher> ResourceDispatcherTest::dispatcher_;
initial.commit09911bf2008-07-26 23:55:29177
178// Does a simple request and tests that the correct data is received.
179TEST_F(ResourceDispatcherTest, RoundTrip) {
180 TestRequestCallback callback;
[email protected]2602087e2009-08-24 23:12:16181 ResourceLoaderBridge* bridge = CreateBridge();
initial.commit09911bf2008-07-26 23:55:29182
183 bridge->Start(&callback);
184
185 ProcessMessages();
186
187 // FIXME(brettw) when the request complete messages are actually handledo
188 // and dispatched, uncomment this.
189 //EXPECT_TRUE(callback.complete());
190 //EXPECT_STREQ(test_page_contents, callback.data().c_str());
191
192 delete bridge;
193}
194
195// Tests that the request IDs are straight when there are multiple requests.
196TEST_F(ResourceDispatcherTest, MultipleRequests) {
197 // FIXME
198}
199
200// Tests that the cancel method prevents other messages from being received
201TEST_F(ResourceDispatcherTest, Cancel) {
202 // FIXME
203}
204
205TEST_F(ResourceDispatcherTest, Cookies) {
206 // FIXME
207}
208
209TEST_F(ResourceDispatcherTest, SerializedPostData) {
210 // FIXME
211}
[email protected]2602087e2009-08-24 23:12:16212
213// This class provides functionality to validate whether the ResourceDispatcher
214// object honors the deferred loading contract correctly, i.e. if deferred
215// loading is enabled it should queue up any responses received. If deferred
216// loading is enabled/disabled in the context of a dispatched message, other
217// queued messages should not be dispatched until deferred load is turned off.
218class DeferredResourceLoadingTest : public ResourceDispatcherTest,
219 public ResourceLoaderBridge::Peer {
220 public:
221 DeferredResourceLoadingTest()
222 : defer_loading_(false) {
223 }
224
225 virtual bool Send(IPC::Message* msg) {
226 delete msg;
227 return true;
228 }
229
230 void InitMessages() {
231 set_defer_loading(true);
232
233 ResourceResponseHead response_head;
[email protected]f90bf0d92011-01-13 02:12:44234 response_head.status.set_status(net::URLRequestStatus::SUCCESS);
[email protected]2602087e2009-08-24 23:12:16235
236 IPC::Message* response_message =
237 new ViewMsg_Resource_ReceivedResponse(0, 0, response_head);
238
239 dispatcher_->OnMessageReceived(*response_message);
240
241 delete response_message;
242
[email protected]a68114f72009-11-30 23:32:49243 // Duplicate the shared memory handle so both the test and the callee can
244 // close their copy.
245 base::SharedMemoryHandle duplicated_handle;
246 EXPECT_TRUE(shared_handle_.ShareToProcess(base::GetCurrentProcessHandle(),
247 &duplicated_handle));
248
[email protected]2602087e2009-08-24 23:12:16249 response_message =
[email protected]a68114f72009-11-30 23:32:49250 new ViewMsg_Resource_DataReceived(0, 0, duplicated_handle, 100);
[email protected]2602087e2009-08-24 23:12:16251
252 dispatcher_->OnMessageReceived(*response_message);
253
254 delete response_message;
255
256 set_defer_loading(false);
257 }
258
259 // ResourceLoaderBridge::Peer methods.
[email protected]bb551622010-07-22 20:52:49260 virtual void OnUploadProgress(uint64 position, uint64 size) {
[email protected]2602087e2009-08-24 23:12:16261 }
262
263 virtual bool OnReceivedRedirect(
264 const GURL& new_url,
[email protected]b4b3a912010-10-08 19:05:37265 const ResourceResponseInfo& info,
[email protected]041b0bbb2009-11-18 02:27:34266 bool* has_new_first_party_for_cookies,
[email protected]2581e572009-11-13 21:54:55267 GURL* new_first_party_for_cookies) {
[email protected]041b0bbb2009-11-18 02:27:34268 *has_new_first_party_for_cookies = false;
[email protected]2602087e2009-08-24 23:12:16269 return true;
270 }
271
[email protected]bb551622010-07-22 20:52:49272 virtual void OnReceivedResponse(
[email protected]b4b3a912010-10-08 19:05:37273 const ResourceResponseInfo& info,
[email protected]bb551622010-07-22 20:52:49274 bool content_filtered) {
275 EXPECT_EQ(defer_loading_, false);
276 set_defer_loading(true);
277 }
278
279 virtual void OnDownloadedData(int len) {
280 }
281
[email protected]2602087e2009-08-24 23:12:16282 virtual void OnReceivedData(const char* data, int len) {
283 EXPECT_EQ(defer_loading_, false);
284 set_defer_loading(false);
285 }
286
[email protected]f90bf0d92011-01-13 02:12:44287 virtual void OnCompletedRequest(const net::URLRequestStatus& status,
[email protected]e0f458c2010-09-16 04:50:41288 const std::string& security_info,
289 const base::Time& completion_time) {
[email protected]2602087e2009-08-24 23:12:16290 }
291
[email protected]2602087e2009-08-24 23:12:16292 protected:
293 virtual void SetUp() {
[email protected]2602087e2009-08-24 23:12:16294 ResourceDispatcherTest::SetUp();
[email protected]b8901082010-11-12 01:14:28295 shared_handle_.Delete(kShmemSegmentName);
[email protected]515f2492011-01-14 10:36:28296 EXPECT_TRUE(shared_handle_.CreateNamed(kShmemSegmentName, false, 100));
[email protected]2602087e2009-08-24 23:12:16297 }
298
299 virtual void TearDown() {
300 shared_handle_.Close();
[email protected]b8901082010-11-12 01:14:28301 EXPECT_TRUE(shared_handle_.Delete(kShmemSegmentName));
[email protected]2602087e2009-08-24 23:12:16302 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}