blob: 67b935114e1fb8d315b6084d0835f841ab2c3408 [file] [log] [blame]
license.botbf09a502008-08-24 00:55:551// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2// 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"
initial.commit09911bf2008-07-26 23:55:2912#include "chrome/common/filter_policy.h"
[email protected]e09ba552009-02-05 03:26:2913#include "chrome/common/render_messages.h"
initial.commit09911bf2008-07-26 23:55:2914#include "chrome/common/resource_dispatcher.h"
initial.commit09911bf2008-07-26 23:55:2915#include "testing/gtest/include/gtest/gtest.h"
[email protected]f430b5712009-08-21 21:46:3116#include "webkit/appcache/appcache_interfaces.h"
initial.commit09911bf2008-07-26 23:55:2917
18using webkit_glue::ResourceLoaderBridge;
19
20static const char test_page_url[] = "http://www.google.com/";
21static const char test_page_headers[] =
22 "HTTP/1.1 200 OK\nContent-Type:text/html\n\n";
23static const char test_page_mime_type[] = "text/html";
24static const char test_page_charset[] = "";
25static const char test_page_contents[] =
26 "<html><head><title>Google</title></head><body><h1>Google</h1></body></html>";
27static const int test_page_contents_len = arraysize(test_page_contents) - 1;
28
29// Listens for request response data and stores it so that it can be compared
30// to the reference data.
31class TestRequestCallback : public ResourceLoaderBridge::Peer {
32 public:
33 TestRequestCallback() : complete_(false) {
34 }
35
[email protected]6568a9e32009-07-30 18:01:3936 virtual bool OnReceivedRedirect(
37 const GURL& new_url,
[email protected]2581e572009-11-13 21:54:5538 const ResourceLoaderBridge::ResponseInfo& info,
[email protected]041b0bbb2009-11-18 02:27:3439 bool* has_new_first_party_for_cookies,
[email protected]2581e572009-11-13 21:54:5540 GURL* new_first_party_for_cookies) {
[email protected]041b0bbb2009-11-18 02:27:3441 *has_new_first_party_for_cookies = false;
[email protected]6568a9e32009-07-30 18:01:3942 return true;
initial.commit09911bf2008-07-26 23:55:2943 }
44
45 virtual void OnReceivedResponse(
[email protected]8a3422c92008-09-24 17:42:4246 const ResourceLoaderBridge::ResponseInfo& info,
47 bool content_filtered) {
initial.commit09911bf2008-07-26 23:55:2948 }
49
50 virtual void OnReceivedData(const char* data, int len) {
51 EXPECT_FALSE(complete_);
52 data_.append(data, len);
53 }
54
[email protected]89c7ed002009-03-12 19:54:5755 virtual void OnUploadProgress(uint64 position, uint64 size) {
56 }
57
[email protected]c4891b32009-03-08 07:41:3158 virtual void OnCompletedRequest(const URLRequestStatus& status,
59 const std::string& security_info) {
initial.commit09911bf2008-07-26 23:55:2960 EXPECT_FALSE(complete_);
61 complete_ = true;
62 }
63
[email protected]9ee9a76a2009-10-28 21:02:5964 virtual GURL GetURLForDebugging() const {
65 return GURL();
initial.commit09911bf2008-07-26 23:55:2966 }
67
68 const std::string& data() const {
69 return data_;
70 }
71 const bool complete() const {
72 return complete_;
73 }
74
75 private:
76 bool complete_;
77 std::string data_;
78};
79
80
81// Sets up the message sender override for the unit test
82class ResourceDispatcherTest : public testing::Test,
83 public IPC::Message::Sender {
84 public:
85 // Emulates IPC send operations (IPC::Message::Sender) by adding
86 // pending messages to the queue.
87 virtual bool Send(IPC::Message* msg) {
88 message_queue_.push_back(IPC::Message(*msg));
89 delete msg;
90 return true;
91 }
92
93 // Emulates the browser process and processes the pending IPC messages,
94 // returning the hardcoded file contents.
95 void ProcessMessages() {
96 while (!message_queue_.empty()) {
initial.commit09911bf2008-07-26 23:55:2997 int request_id;
initial.commit09911bf2008-07-26 23:55:2998 ViewHostMsg_Resource_Request request;
[email protected]eb9989092009-03-12 21:42:5299 ASSERT_TRUE(ViewHostMsg_RequestResource::Read(
100 &message_queue_[0], &request_id, &request));
initial.commit09911bf2008-07-26 23:55:29101
102 // check values
103 EXPECT_EQ(test_page_url, request.url.spec());
104
105 // received response message
[email protected]e09ba552009-02-05 03:26:29106 ResourceResponseHead response;
initial.commit09911bf2008-07-26 23:55:29107 std::string raw_headers(test_page_headers);
108 std::replace(raw_headers.begin(), raw_headers.end(), '\n', '\0');
109 response.headers = new net::HttpResponseHeaders(raw_headers);
110 response.mime_type = test_page_mime_type;
111 response.charset = test_page_charset;
112 response.filter_policy = FilterPolicy::DONT_FILTER;
113 dispatcher_->OnReceivedResponse(request_id, response);
114
115 // received data message with the test contents
[email protected]176aa482008-11-14 03:25:15116 base::SharedMemory shared_mem;
initial.commit09911bf2008-07-26 23:55:29117 EXPECT_TRUE(shared_mem.Create(std::wstring(),
118 false, false, test_page_contents_len));
119 EXPECT_TRUE(shared_mem.Map(test_page_contents_len));
120 char* put_data_here = static_cast<char*>(shared_mem.memory());
121 memcpy(put_data_here, test_page_contents, test_page_contents_len);
[email protected]176aa482008-11-14 03:25:15122 base::SharedMemoryHandle dup_handle;
[email protected]4003d7142009-01-12 12:56:20123 EXPECT_TRUE(shared_mem.GiveToProcess(
124 base::Process::Current().handle(), &dup_handle));
[email protected]eb9989092009-03-12 21:42:52125 dispatcher_->OnReceivedData(
126 message_queue_[0], request_id, dup_handle, test_page_contents_len);
initial.commit09911bf2008-07-26 23:55:29127
128 message_queue_.erase(message_queue_.begin());
129
130 // read the ack message.
[email protected]c2fe31542009-05-20 18:24:14131 Tuple1<int> request_ack;
[email protected]eb9989092009-03-12 21:42:52132 ASSERT_TRUE(ViewHostMsg_DataReceived_ACK::Read(
133 &message_queue_[0], &request_ack));
initial.commit09911bf2008-07-26 23:55:29134
[email protected]c2fe31542009-05-20 18:24:14135 ASSERT_EQ(request_ack.a, request_id);
initial.commit09911bf2008-07-26 23:55:29136
137 message_queue_.erase(message_queue_.begin());
138 }
139 }
140
141 protected:
initial.commit09911bf2008-07-26 23:55:29142 // testing::Test
143 virtual void SetUp() {
[email protected]eb9989092009-03-12 21:42:52144 dispatcher_.reset(new ResourceDispatcher(this));
initial.commit09911bf2008-07-26 23:55:29145 }
146 virtual void TearDown() {
[email protected]eb9989092009-03-12 21:42:52147 dispatcher_.reset();
initial.commit09911bf2008-07-26 23:55:29148 }
149
[email protected]2602087e2009-08-24 23:12:16150 ResourceLoaderBridge* CreateBridge() {
151 ResourceLoaderBridge* bridge = dispatcher_->CreateBridge(
152 "GET", GURL(test_page_url), GURL(test_page_url), GURL(), "null",
153 "null", std::string(), 0, 0, ResourceType::SUB_RESOURCE, 0,
[email protected]2799c02a2009-11-07 15:39:55154 appcache::kNoHostId, MSG_ROUTING_CONTROL, -1, -1);
[email protected]2602087e2009-08-24 23:12:16155 return bridge;
156 }
157
initial.commit09911bf2008-07-26 23:55:29158 std::vector<IPC::Message> message_queue_;
[email protected]eb9989092009-03-12 21:42:52159 static scoped_ptr<ResourceDispatcher> dispatcher_;
initial.commit09911bf2008-07-26 23:55:29160};
161
162/*static*/
[email protected]eb9989092009-03-12 21:42:52163scoped_ptr<ResourceDispatcher> ResourceDispatcherTest::dispatcher_;
initial.commit09911bf2008-07-26 23:55:29164
165// Does a simple request and tests that the correct data is received.
166TEST_F(ResourceDispatcherTest, RoundTrip) {
167 TestRequestCallback callback;
[email protected]2602087e2009-08-24 23:12:16168 ResourceLoaderBridge* bridge = CreateBridge();
initial.commit09911bf2008-07-26 23:55:29169
170 bridge->Start(&callback);
171
172 ProcessMessages();
173
174 // FIXME(brettw) when the request complete messages are actually handledo
175 // and dispatched, uncomment this.
176 //EXPECT_TRUE(callback.complete());
177 //EXPECT_STREQ(test_page_contents, callback.data().c_str());
178
179 delete bridge;
180}
181
182// Tests that the request IDs are straight when there are multiple requests.
183TEST_F(ResourceDispatcherTest, MultipleRequests) {
184 // FIXME
185}
186
187// Tests that the cancel method prevents other messages from being received
188TEST_F(ResourceDispatcherTest, Cancel) {
189 // FIXME
190}
191
192TEST_F(ResourceDispatcherTest, Cookies) {
193 // FIXME
194}
195
196TEST_F(ResourceDispatcherTest, SerializedPostData) {
197 // FIXME
198}
[email protected]2602087e2009-08-24 23:12:16199
200// This class provides functionality to validate whether the ResourceDispatcher
201// object honors the deferred loading contract correctly, i.e. if deferred
202// loading is enabled it should queue up any responses received. If deferred
203// loading is enabled/disabled in the context of a dispatched message, other
204// queued messages should not be dispatched until deferred load is turned off.
205class DeferredResourceLoadingTest : public ResourceDispatcherTest,
206 public ResourceLoaderBridge::Peer {
207 public:
208 DeferredResourceLoadingTest()
209 : defer_loading_(false) {
210 }
211
212 virtual bool Send(IPC::Message* msg) {
213 delete msg;
214 return true;
215 }
216
217 void InitMessages() {
218 set_defer_loading(true);
219
220 ResourceResponseHead response_head;
221 response_head.status.set_status(URLRequestStatus::SUCCESS);
222
223 IPC::Message* response_message =
224 new ViewMsg_Resource_ReceivedResponse(0, 0, response_head);
225
226 dispatcher_->OnMessageReceived(*response_message);
227
228 delete response_message;
229
[email protected]a68114f72009-11-30 23:32:49230 // Duplicate the shared memory handle so both the test and the callee can
231 // close their copy.
232 base::SharedMemoryHandle duplicated_handle;
233 EXPECT_TRUE(shared_handle_.ShareToProcess(base::GetCurrentProcessHandle(),
234 &duplicated_handle));
235
[email protected]2602087e2009-08-24 23:12:16236 response_message =
[email protected]a68114f72009-11-30 23:32:49237 new ViewMsg_Resource_DataReceived(0, 0, duplicated_handle, 100);
[email protected]2602087e2009-08-24 23:12:16238
239 dispatcher_->OnMessageReceived(*response_message);
240
241 delete response_message;
242
243 set_defer_loading(false);
244 }
245
246 // ResourceLoaderBridge::Peer methods.
247 virtual void OnReceivedResponse(
248 const ResourceLoaderBridge::ResponseInfo& info,
249 bool content_filtered) {
250 EXPECT_EQ(defer_loading_, false);
251 set_defer_loading(true);
252 }
253
254 virtual bool OnReceivedRedirect(
255 const GURL& new_url,
[email protected]2581e572009-11-13 21:54:55256 const ResourceLoaderBridge::ResponseInfo& info,
[email protected]041b0bbb2009-11-18 02:27:34257 bool* has_new_first_party_for_cookies,
[email protected]2581e572009-11-13 21:54:55258 GURL* new_first_party_for_cookies) {
[email protected]041b0bbb2009-11-18 02:27:34259 *has_new_first_party_for_cookies = false;
[email protected]2602087e2009-08-24 23:12:16260 return true;
261 }
262
263 virtual void OnReceivedData(const char* data, int len) {
264 EXPECT_EQ(defer_loading_, false);
265 set_defer_loading(false);
266 }
267
268 virtual void OnUploadProgress(uint64 position, uint64 size) {
269 }
270
271 virtual void OnCompletedRequest(const URLRequestStatus& status,
272 const std::string& security_info) {
273 }
274
[email protected]9ee9a76a2009-10-28 21:02:59275 virtual GURL GetURLForDebugging() const {
276 return GURL();
[email protected]2602087e2009-08-24 23:12:16277 }
278
279 protected:
280 virtual void SetUp() {
281 EXPECT_EQ(true, shared_handle_.Create(L"DeferredResourceLoaderTest", false,
282 false, 100));
283 ResourceDispatcherTest::SetUp();
284 }
285
286 virtual void TearDown() {
287 shared_handle_.Close();
288 ResourceDispatcherTest::TearDown();
289 }
290
291 private:
292 void set_defer_loading(bool defer) {
293 defer_loading_ = defer;
294 dispatcher_->SetDefersLoading(0, defer);
295 }
296
297 bool defer_loading() const {
298 return defer_loading_;
299 }
300
301 bool defer_loading_;
302 base::SharedMemory shared_handle_;
303};
304
305TEST_F(DeferredResourceLoadingTest, DeferredLoadTest) {
306 MessageLoop message_loop(MessageLoop::TYPE_IO);
307
308 ResourceLoaderBridge* bridge = CreateBridge();
309
310 bridge->Start(this);
311 InitMessages();
312
313 // Dispatch deferred messages.
314 message_loop.RunAllPending();
315 delete bridge;
316}
317