Don't call into driver for unsupported extensions.
[chromium-blink-merge.git] / content / child / resource_dispatcher_unittest.cc
blobb072ecf55b1cb95eb659eab70f79795a4af8a891
1 // Copyright (c) 2012 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.
5 #include <string>
6 #include <vector>
8 #include "base/memory/scoped_ptr.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/process/process.h"
11 #include "base/process/process_handle.h"
12 #include "content/child/request_extra_data.h"
13 #include "content/child/resource_dispatcher.h"
14 #include "content/common/resource_messages.h"
15 #include "content/public/common/resource_response.h"
16 #include "net/base/net_errors.h"
17 #include "net/base/upload_data.h"
18 #include "net/http/http_response_headers.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20 #include "webkit/common/appcache/appcache_interfaces.h"
22 using webkit_glue::ResourceLoaderBridge;
23 using webkit_glue::ResourceResponseInfo;
25 namespace content {
27 static const char test_page_url[] = "http://www.google.com/";
28 static const char test_page_headers[] =
29 "HTTP/1.1 200 OK\nContent-Type:text/html\n\n";
30 static const char test_page_mime_type[] = "text/html";
31 static const char test_page_charset[] = "";
32 static const char test_page_contents[] =
33 "<html><head><title>Google</title></head><body><h1>Google</h1></body></html>";
34 static const uint32 test_page_contents_len = arraysize(test_page_contents) - 1;
36 static const char kShmemSegmentName[] = "DeferredResourceLoaderTest";
38 // Listens for request response data and stores it so that it can be compared
39 // to the reference data.
40 class TestRequestCallback : public ResourceLoaderBridge::Peer {
41 public:
42 TestRequestCallback() : complete_(false) {
45 virtual void OnUploadProgress(uint64 position, uint64 size) OVERRIDE {
48 virtual bool OnReceivedRedirect(
49 const GURL& new_url,
50 const ResourceResponseInfo& info,
51 bool* has_new_first_party_for_cookies,
52 GURL* new_first_party_for_cookies) OVERRIDE {
53 *has_new_first_party_for_cookies = false;
54 return true;
57 virtual void OnReceivedResponse(const ResourceResponseInfo& info) OVERRIDE {
60 virtual void OnDownloadedData(int len, int encoded_data_length) OVERRIDE {
63 virtual void OnReceivedData(const char* data,
64 int data_length,
65 int encoded_data_length) OVERRIDE {
66 EXPECT_FALSE(complete_);
67 data_.append(data, data_length);
68 total_encoded_data_length_ += encoded_data_length;
71 virtual void OnCompletedRequest(
72 int error_code,
73 bool was_ignored_by_handler,
74 const std::string& security_info,
75 const base::TimeTicks& completion_time) OVERRIDE {
76 EXPECT_FALSE(complete_);
77 complete_ = true;
80 bool complete() const {
81 return complete_;
83 const std::string& data() const {
84 return data_;
86 int total_encoded_data_length() const {
87 return total_encoded_data_length_;
90 private:
91 bool complete_;
92 std::string data_;
93 int total_encoded_data_length_;
97 // Sets up the message sender override for the unit test
98 class ResourceDispatcherTest : public testing::Test, public IPC::Sender {
99 public:
100 // Emulates IPC send operations (IPC::Sender) by adding
101 // pending messages to the queue.
102 virtual bool Send(IPC::Message* msg) OVERRIDE {
103 message_queue_.push_back(IPC::Message(*msg));
104 delete msg;
105 return true;
108 // Emulates the browser process and processes the pending IPC messages,
109 // returning the hardcoded file contents.
110 void ProcessMessages() {
111 while (!message_queue_.empty()) {
112 int request_id;
113 ResourceHostMsg_Request request;
114 ASSERT_TRUE(ResourceHostMsg_RequestResource::Read(
115 &message_queue_[0], &request_id, &request));
117 // check values
118 EXPECT_EQ(test_page_url, request.url.spec());
120 // received response message
121 ResourceResponseHead response;
122 std::string raw_headers(test_page_headers);
123 std::replace(raw_headers.begin(), raw_headers.end(), '\n', '\0');
124 response.headers = new net::HttpResponseHeaders(raw_headers);
125 response.mime_type = test_page_mime_type;
126 response.charset = test_page_charset;
127 dispatcher_->OnReceivedResponse(request_id, response);
129 // received data message with the test contents
130 base::SharedMemory shared_mem;
131 EXPECT_TRUE(shared_mem.CreateAndMapAnonymous(test_page_contents_len));
132 char* put_data_here = static_cast<char*>(shared_mem.memory());
133 memcpy(put_data_here, test_page_contents, test_page_contents_len);
134 base::SharedMemoryHandle dup_handle;
135 EXPECT_TRUE(shared_mem.GiveToProcess(
136 base::Process::Current().handle(), &dup_handle));
137 dispatcher_->OnSetDataBuffer(request_id, dup_handle,
138 test_page_contents_len, 0);
139 dispatcher_->OnReceivedData(request_id, 0, test_page_contents_len,
140 test_page_contents_len);
142 message_queue_.erase(message_queue_.begin());
144 // read the ack message.
145 Tuple1<int> request_ack;
146 ASSERT_TRUE(ResourceHostMsg_DataReceived_ACK::Read(
147 &message_queue_[0], &request_ack));
149 ASSERT_EQ(request_ack.a, request_id);
151 message_queue_.erase(message_queue_.begin());
155 protected:
156 // testing::Test
157 virtual void SetUp() OVERRIDE {
158 dispatcher_.reset(new ResourceDispatcher(this));
160 virtual void TearDown() OVERRIDE {
161 dispatcher_.reset();
164 ResourceLoaderBridge* CreateBridge() {
165 webkit_glue::ResourceLoaderBridge::RequestInfo request_info;
166 request_info.method = "GET";
167 request_info.url = GURL(test_page_url);
168 request_info.first_party_for_cookies = GURL(test_page_url);
169 request_info.referrer = GURL();
170 request_info.headers = std::string();
171 request_info.load_flags = 0;
172 request_info.requestor_pid = 0;
173 request_info.request_type = ResourceType::SUB_RESOURCE;
174 request_info.appcache_host_id = appcache::kNoHostId;
175 request_info.routing_id = 0;
176 RequestExtraData extra_data(WebKit::WebReferrerPolicyDefault,
177 WebKit::WebString(),
178 false, true, 0, GURL(),
179 false, -1, true,
180 PAGE_TRANSITION_LINK, -1, -1);
181 request_info.extra_data = &extra_data;
183 return dispatcher_->CreateBridge(request_info);
186 std::vector<IPC::Message> message_queue_;
187 static scoped_ptr<ResourceDispatcher> dispatcher_;
190 /*static*/
191 scoped_ptr<ResourceDispatcher> ResourceDispatcherTest::dispatcher_;
193 // Does a simple request and tests that the correct data is received.
194 TEST_F(ResourceDispatcherTest, RoundTrip) {
195 TestRequestCallback callback;
196 ResourceLoaderBridge* bridge = CreateBridge();
198 bridge->Start(&callback);
200 ProcessMessages();
202 // FIXME(brettw) when the request complete messages are actually handledo
203 // and dispatched, uncomment this.
204 //EXPECT_TRUE(callback.complete());
205 //EXPECT_STREQ(test_page_contents, callback.data().c_str());
206 //EXPECT_EQ(test_page_contents_len, callback.total_encoded_data_length());
208 delete bridge;
211 // Tests that the request IDs are straight when there are multiple requests.
212 TEST_F(ResourceDispatcherTest, MultipleRequests) {
213 // FIXME
216 // Tests that the cancel method prevents other messages from being received
217 TEST_F(ResourceDispatcherTest, Cancel) {
218 // FIXME
221 TEST_F(ResourceDispatcherTest, Cookies) {
222 // FIXME
225 TEST_F(ResourceDispatcherTest, SerializedPostData) {
226 // FIXME
229 // This class provides functionality to validate whether the ResourceDispatcher
230 // object honors the deferred loading contract correctly, i.e. if deferred
231 // loading is enabled it should queue up any responses received. If deferred
232 // loading is enabled/disabled in the context of a dispatched message, other
233 // queued messages should not be dispatched until deferred load is turned off.
234 class DeferredResourceLoadingTest : public ResourceDispatcherTest,
235 public ResourceLoaderBridge::Peer {
236 public:
237 DeferredResourceLoadingTest()
238 : defer_loading_(false) {
241 virtual bool Send(IPC::Message* msg) OVERRIDE {
242 delete msg;
243 return true;
246 void InitMessages() {
247 set_defer_loading(true);
249 ResourceResponseHead response_head;
250 response_head.error_code = net::OK;
252 dispatcher_->OnMessageReceived(
253 ResourceMsg_ReceivedResponse(0, response_head));
255 // 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));
261 dispatcher_->OnMessageReceived(
262 ResourceMsg_SetDataBuffer(0, duplicated_handle, 100, 0));
263 dispatcher_->OnMessageReceived(ResourceMsg_DataReceived(0, 0, 100, 100));
265 set_defer_loading(false);
268 // ResourceLoaderBridge::Peer methods.
269 virtual void OnUploadProgress(uint64 position, uint64 size) OVERRIDE {
272 virtual bool OnReceivedRedirect(
273 const GURL& new_url,
274 const ResourceResponseInfo& info,
275 bool* has_new_first_party_for_cookies,
276 GURL* new_first_party_for_cookies) OVERRIDE {
277 *has_new_first_party_for_cookies = false;
278 return true;
281 virtual void OnReceivedResponse(const ResourceResponseInfo& info) OVERRIDE {
282 EXPECT_EQ(defer_loading_, false);
283 set_defer_loading(true);
286 virtual void OnDownloadedData(int len, int encoded_data_length) OVERRIDE {
289 virtual void OnReceivedData(const char* data,
290 int data_length,
291 int encoded_data_length) OVERRIDE {
292 EXPECT_EQ(defer_loading_, false);
293 set_defer_loading(false);
296 virtual void OnCompletedRequest(
297 int error_code,
298 bool was_ignored_by_handler,
299 const std::string& security_info,
300 const base::TimeTicks& completion_time) OVERRIDE {
303 protected:
304 virtual void SetUp() OVERRIDE {
305 ResourceDispatcherTest::SetUp();
306 shared_handle_.Delete(kShmemSegmentName);
307 EXPECT_TRUE(shared_handle_.CreateNamed(kShmemSegmentName, false, 100));
310 virtual void TearDown() OVERRIDE {
311 shared_handle_.Close();
312 EXPECT_TRUE(shared_handle_.Delete(kShmemSegmentName));
313 ResourceDispatcherTest::TearDown();
316 private:
317 void set_defer_loading(bool defer) {
318 defer_loading_ = defer;
319 dispatcher_->SetDefersLoading(0, defer);
322 bool defer_loading() const {
323 return defer_loading_;
326 bool defer_loading_;
327 base::SharedMemory shared_handle_;
330 TEST_F(DeferredResourceLoadingTest, DeferredLoadTest) {
331 base::MessageLoop message_loop(base::MessageLoop::TYPE_IO);
333 ResourceLoaderBridge* bridge = CreateBridge();
335 bridge->Start(this);
336 InitMessages();
338 // Dispatch deferred messages.
339 message_loop.RunUntilIdle();
340 delete bridge;
343 class TimeConversionTest : public ResourceDispatcherTest,
344 public ResourceLoaderBridge::Peer {
345 public:
346 virtual bool Send(IPC::Message* msg) OVERRIDE {
347 delete msg;
348 return true;
351 void PerformTest(const ResourceResponseHead& response_head) {
352 scoped_ptr<ResourceLoaderBridge> bridge(CreateBridge());
353 bridge->Start(this);
355 dispatcher_->OnMessageReceived(
356 ResourceMsg_ReceivedResponse(0, response_head));
359 // ResourceLoaderBridge::Peer methods.
360 virtual void OnUploadProgress(uint64 position, uint64 size) OVERRIDE {
363 virtual bool OnReceivedRedirect(
364 const GURL& new_url,
365 const ResourceResponseInfo& info,
366 bool* has_new_first_party_for_cookies,
367 GURL* new_first_party_for_cookies) OVERRIDE {
368 return true;
371 virtual void OnReceivedResponse(const ResourceResponseInfo& info) OVERRIDE {
372 response_info_ = info;
375 virtual void OnDownloadedData(int len, int encoded_data_length) OVERRIDE {
378 virtual void OnReceivedData(const char* data,
379 int data_length,
380 int encoded_data_length) OVERRIDE {
383 virtual void OnCompletedRequest(
384 int error_code,
385 bool was_ignored_by_handler,
386 const std::string& security_info,
387 const base::TimeTicks& completion_time) OVERRIDE {
390 const ResourceResponseInfo& response_info() const { return response_info_; }
392 private:
393 ResourceResponseInfo response_info_;
396 // TODO(simonjam): Enable this when 10829031 lands.
397 TEST_F(TimeConversionTest, DISABLED_ProperlyInitialized) {
398 ResourceResponseHead response_head;
399 response_head.error_code = net::OK;
400 response_head.request_start = base::TimeTicks::FromInternalValue(5);
401 response_head.response_start = base::TimeTicks::FromInternalValue(15);
402 response_head.load_timing.request_start_time = base::Time::Now();
403 response_head.load_timing.request_start =
404 base::TimeTicks::FromInternalValue(10);
405 response_head.load_timing.connect_timing.connect_start =
406 base::TimeTicks::FromInternalValue(13);
408 PerformTest(response_head);
410 EXPECT_LT(base::TimeTicks(), response_info().load_timing.request_start);
411 EXPECT_EQ(base::TimeTicks(),
412 response_info().load_timing.connect_timing.dns_start);
413 EXPECT_LE(response_head.load_timing.request_start,
414 response_info().load_timing.connect_timing.connect_start);
417 TEST_F(TimeConversionTest, PartiallyInitialized) {
418 ResourceResponseHead response_head;
419 response_head.error_code = net::OK;
420 response_head.request_start = base::TimeTicks::FromInternalValue(5);
421 response_head.response_start = base::TimeTicks::FromInternalValue(15);
423 PerformTest(response_head);
425 EXPECT_EQ(base::TimeTicks(), response_info().load_timing.request_start);
426 EXPECT_EQ(base::TimeTicks(),
427 response_info().load_timing.connect_timing.dns_start);
430 TEST_F(TimeConversionTest, NotInitialized) {
431 ResourceResponseHead response_head;
432 response_head.error_code = net::OK;
434 PerformTest(response_head);
436 EXPECT_EQ(base::TimeTicks(), response_info().load_timing.request_start);
437 EXPECT_EQ(base::TimeTicks(),
438 response_info().load_timing.connect_timing.dns_start);
441 } // namespace content