[email protected] | 8a58f9a | 2010-05-18 18:38:09 | [diff] [blame] | 1 | // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
license.bot | bf09a50 | 2008-08-24 00:55:55 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 4 | |
| 5 | #include <string> |
| 6 | #include <vector> |
| 7 | |
[email protected] | 2602087e | 2009-08-24 23:12:16 | [diff] [blame] | 8 | #include "base/message_loop.h" |
[email protected] | 4003d714 | 2009-01-12 12:56:20 | [diff] [blame] | 9 | #include "base/process.h" |
[email protected] | a68114f7 | 2009-11-30 23:32:49 | [diff] [blame] | 10 | #include "base/process_util.h" |
[email protected] | 1fec840 | 2009-03-13 19:11:59 | [diff] [blame] | 11 | #include "base/scoped_ptr.h" |
[email protected] | e09ba55 | 2009-02-05 03:26:29 | [diff] [blame] | 12 | #include "chrome/common/render_messages.h" |
[email protected] | 939856a | 2010-08-24 20:29:02 | [diff] [blame^] | 13 | #include "chrome/common/render_messages_params.h" |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 14 | #include "chrome/common/resource_dispatcher.h" |
[email protected] | 939856a | 2010-08-24 20:29:02 | [diff] [blame^] | 15 | #include "net/base/upload_data.h" |
[email protected] | 7a4de7a6 | 2010-08-17 18:38:24 | [diff] [blame] | 16 | #include "net/http/http_response_headers.h" |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 17 | #include "testing/gtest/include/gtest/gtest.h" |
[email protected] | f430b571 | 2009-08-21 21:46:31 | [diff] [blame] | 18 | #include "webkit/appcache/appcache_interfaces.h" |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 19 | |
| 20 | using webkit_glue::ResourceLoaderBridge; |
| 21 | |
| 22 | static const char test_page_url[] = "http://www.google.com/"; |
| 23 | static const char test_page_headers[] = |
| 24 | "HTTP/1.1 200 OK\nContent-Type:text/html\n\n"; |
| 25 | static const char test_page_mime_type[] = "text/html"; |
| 26 | static const char test_page_charset[] = ""; |
| 27 | static const char test_page_contents[] = |
| 28 | "<html><head><title>Google</title></head><body><h1>Google</h1></body></html>"; |
[email protected] | b5ab398 | 2010-02-16 23:58:27 | [diff] [blame] | 29 | static const uint32 test_page_contents_len = arraysize(test_page_contents) - 1; |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 30 | |
| 31 | // Listens for request response data and stores it so that it can be compared |
| 32 | // to the reference data. |
| 33 | class TestRequestCallback : public ResourceLoaderBridge::Peer { |
| 34 | public: |
| 35 | TestRequestCallback() : complete_(false) { |
| 36 | } |
| 37 | |
[email protected] | bb55162 | 2010-07-22 20:52:49 | [diff] [blame] | 38 | virtual void OnUploadProgress(uint64 position, uint64 size) { |
| 39 | } |
| 40 | |
[email protected] | 6568a9e3 | 2009-07-30 18:01:39 | [diff] [blame] | 41 | virtual bool OnReceivedRedirect( |
| 42 | const GURL& new_url, |
[email protected] | 2581e57 | 2009-11-13 21:54:55 | [diff] [blame] | 43 | const ResourceLoaderBridge::ResponseInfo& info, |
[email protected] | 041b0bbb | 2009-11-18 02:27:34 | [diff] [blame] | 44 | bool* has_new_first_party_for_cookies, |
[email protected] | 2581e57 | 2009-11-13 21:54:55 | [diff] [blame] | 45 | GURL* new_first_party_for_cookies) { |
[email protected] | 041b0bbb | 2009-11-18 02:27:34 | [diff] [blame] | 46 | *has_new_first_party_for_cookies = false; |
[email protected] | 6568a9e3 | 2009-07-30 18:01:39 | [diff] [blame] | 47 | return true; |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 48 | } |
| 49 | |
| 50 | virtual void OnReceivedResponse( |
[email protected] | 8a3422c9 | 2008-09-24 17:42:42 | [diff] [blame] | 51 | const ResourceLoaderBridge::ResponseInfo& info, |
| 52 | bool content_filtered) { |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 53 | } |
| 54 | |
[email protected] | bb55162 | 2010-07-22 20:52:49 | [diff] [blame] | 55 | virtual void OnDownloadedData(int len) { |
| 56 | } |
| 57 | |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 58 | virtual void OnReceivedData(const char* data, int len) { |
| 59 | EXPECT_FALSE(complete_); |
| 60 | data_.append(data, len); |
| 61 | } |
| 62 | |
[email protected] | c4891b3 | 2009-03-08 07:41:31 | [diff] [blame] | 63 | virtual void OnCompletedRequest(const URLRequestStatus& status, |
| 64 | const std::string& security_info) { |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 65 | EXPECT_FALSE(complete_); |
| 66 | complete_ = true; |
| 67 | } |
| 68 | |
[email protected] | 9ee9a76a | 2009-10-28 21:02:59 | [diff] [blame] | 69 | virtual GURL GetURLForDebugging() const { |
| 70 | return GURL(); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 71 | } |
| 72 | |
| 73 | const std::string& data() const { |
| 74 | return data_; |
| 75 | } |
[email protected] | 5212070 | 2010-03-09 21:44:44 | [diff] [blame] | 76 | bool complete() const { |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 77 | 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 |
| 87 | class 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.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 102 | int request_id; |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 103 | ViewHostMsg_Resource_Request request; |
[email protected] | eb998909 | 2009-03-12 21:42:52 | [diff] [blame] | 104 | ASSERT_TRUE(ViewHostMsg_RequestResource::Read( |
| 105 | &message_queue_[0], &request_id, &request)); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 106 | |
| 107 | // check values |
| 108 | EXPECT_EQ(test_page_url, request.url.spec()); |
| 109 | |
| 110 | // received response message |
[email protected] | e09ba55 | 2009-02-05 03:26:29 | [diff] [blame] | 111 | ResourceResponseHead response; |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 112 | 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.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 117 | dispatcher_->OnReceivedResponse(request_id, response); |
| 118 | |
| 119 | // received data message with the test contents |
[email protected] | 176aa48 | 2008-11-14 03:25:15 | [diff] [blame] | 120 | base::SharedMemory shared_mem; |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 121 | 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] | 176aa48 | 2008-11-14 03:25:15 | [diff] [blame] | 126 | base::SharedMemoryHandle dup_handle; |
[email protected] | 4003d714 | 2009-01-12 12:56:20 | [diff] [blame] | 127 | EXPECT_TRUE(shared_mem.GiveToProcess( |
| 128 | base::Process::Current().handle(), &dup_handle)); |
[email protected] | eb998909 | 2009-03-12 21:42:52 | [diff] [blame] | 129 | dispatcher_->OnReceivedData( |
| 130 | message_queue_[0], request_id, dup_handle, test_page_contents_len); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 131 | |
| 132 | message_queue_.erase(message_queue_.begin()); |
| 133 | |
| 134 | // read the ack message. |
[email protected] | c2fe3154 | 2009-05-20 18:24:14 | [diff] [blame] | 135 | Tuple1<int> request_ack; |
[email protected] | eb998909 | 2009-03-12 21:42:52 | [diff] [blame] | 136 | ASSERT_TRUE(ViewHostMsg_DataReceived_ACK::Read( |
| 137 | &message_queue_[0], &request_ack)); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 138 | |
[email protected] | c2fe3154 | 2009-05-20 18:24:14 | [diff] [blame] | 139 | ASSERT_EQ(request_ack.a, request_id); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 140 | |
| 141 | message_queue_.erase(message_queue_.begin()); |
| 142 | } |
| 143 | } |
| 144 | |
| 145 | protected: |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 146 | // testing::Test |
| 147 | virtual void SetUp() { |
[email protected] | eb998909 | 2009-03-12 21:42:52 | [diff] [blame] | 148 | dispatcher_.reset(new ResourceDispatcher(this)); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 149 | } |
| 150 | virtual void TearDown() { |
[email protected] | eb998909 | 2009-03-12 21:42:52 | [diff] [blame] | 151 | dispatcher_.reset(); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 152 | } |
| 153 | |
[email protected] | 2602087e | 2009-08-24 23:12:16 | [diff] [blame] | 154 | ResourceLoaderBridge* CreateBridge() { |
[email protected] | 46b0d4a | 2009-12-19 00:46:33 | [diff] [blame] | 155 | 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] | 52bbcd93 | 2010-01-06 18:56:12 | [diff] [blame] | 166 | request_info.appcache_host_id = appcache::kNoHostId; |
| 167 | request_info.routing_id = 0; |
[email protected] | 46b0d4a | 2009-12-19 00:46:33 | [diff] [blame] | 168 | |
| 169 | return dispatcher_->CreateBridge(request_info, -1, -1); |
[email protected] | 2602087e | 2009-08-24 23:12:16 | [diff] [blame] | 170 | } |
| 171 | |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 172 | std::vector<IPC::Message> message_queue_; |
[email protected] | eb998909 | 2009-03-12 21:42:52 | [diff] [blame] | 173 | static scoped_ptr<ResourceDispatcher> dispatcher_; |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 174 | }; |
| 175 | |
| 176 | /*static*/ |
[email protected] | eb998909 | 2009-03-12 21:42:52 | [diff] [blame] | 177 | scoped_ptr<ResourceDispatcher> ResourceDispatcherTest::dispatcher_; |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 178 | |
| 179 | // Does a simple request and tests that the correct data is received. |
| 180 | TEST_F(ResourceDispatcherTest, RoundTrip) { |
| 181 | TestRequestCallback callback; |
[email protected] | 2602087e | 2009-08-24 23:12:16 | [diff] [blame] | 182 | ResourceLoaderBridge* bridge = CreateBridge(); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 183 | |
| 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. |
| 197 | TEST_F(ResourceDispatcherTest, MultipleRequests) { |
| 198 | // FIXME |
| 199 | } |
| 200 | |
| 201 | // Tests that the cancel method prevents other messages from being received |
| 202 | TEST_F(ResourceDispatcherTest, Cancel) { |
| 203 | // FIXME |
| 204 | } |
| 205 | |
| 206 | TEST_F(ResourceDispatcherTest, Cookies) { |
| 207 | // FIXME |
| 208 | } |
| 209 | |
| 210 | TEST_F(ResourceDispatcherTest, SerializedPostData) { |
| 211 | // FIXME |
| 212 | } |
[email protected] | 2602087e | 2009-08-24 23:12:16 | [diff] [blame] | 213 | |
| 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. |
| 219 | class 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] | a68114f7 | 2009-11-30 23:32:49 | [diff] [blame] | 244 | // 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] | 2602087e | 2009-08-24 23:12:16 | [diff] [blame] | 250 | response_message = |
[email protected] | a68114f7 | 2009-11-30 23:32:49 | [diff] [blame] | 251 | new ViewMsg_Resource_DataReceived(0, 0, duplicated_handle, 100); |
[email protected] | 2602087e | 2009-08-24 23:12:16 | [diff] [blame] | 252 | |
| 253 | dispatcher_->OnMessageReceived(*response_message); |
| 254 | |
| 255 | delete response_message; |
| 256 | |
| 257 | set_defer_loading(false); |
| 258 | } |
| 259 | |
| 260 | // ResourceLoaderBridge::Peer methods. |
[email protected] | bb55162 | 2010-07-22 20:52:49 | [diff] [blame] | 261 | virtual void OnUploadProgress(uint64 position, uint64 size) { |
[email protected] | 2602087e | 2009-08-24 23:12:16 | [diff] [blame] | 262 | } |
| 263 | |
| 264 | virtual bool OnReceivedRedirect( |
| 265 | const GURL& new_url, |
[email protected] | 2581e57 | 2009-11-13 21:54:55 | [diff] [blame] | 266 | const ResourceLoaderBridge::ResponseInfo& info, |
[email protected] | 041b0bbb | 2009-11-18 02:27:34 | [diff] [blame] | 267 | bool* has_new_first_party_for_cookies, |
[email protected] | 2581e57 | 2009-11-13 21:54:55 | [diff] [blame] | 268 | GURL* new_first_party_for_cookies) { |
[email protected] | 041b0bbb | 2009-11-18 02:27:34 | [diff] [blame] | 269 | *has_new_first_party_for_cookies = false; |
[email protected] | 2602087e | 2009-08-24 23:12:16 | [diff] [blame] | 270 | return true; |
| 271 | } |
| 272 | |
[email protected] | bb55162 | 2010-07-22 20:52:49 | [diff] [blame] | 273 | 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] | 2602087e | 2009-08-24 23:12:16 | [diff] [blame] | 283 | virtual void OnReceivedData(const char* data, int len) { |
| 284 | EXPECT_EQ(defer_loading_, false); |
| 285 | set_defer_loading(false); |
| 286 | } |
| 287 | |
[email protected] | 2602087e | 2009-08-24 23:12:16 | [diff] [blame] | 288 | virtual void OnCompletedRequest(const URLRequestStatus& status, |
| 289 | const std::string& security_info) { |
| 290 | } |
| 291 | |
[email protected] | 9ee9a76a | 2009-10-28 21:02:59 | [diff] [blame] | 292 | virtual GURL GetURLForDebugging() const { |
| 293 | return GURL(); |
[email protected] | 2602087e | 2009-08-24 23:12:16 | [diff] [blame] | 294 | } |
| 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 | |
| 322 | TEST_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 | |