Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / content / child / resource_dispatcher_unittest.cc
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.
4
5 #include <string>
6 #include <vector>
7
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/http/http_response_headers.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19 #include "webkit/common/appcache/appcache_interfaces.h"
20
21 using webkit_glue::ResourceLoaderBridge;
22 using webkit_glue::ResourceResponseInfo;
23
24 namespace content {
25
26 static const char test_page_url[] = "http://www.google.com/";
27 static const char test_page_headers[] =
28   "HTTP/1.1 200 OK\nContent-Type:text/html\n\n";
29 static const char test_page_mime_type[] = "text/html";
30 static const char test_page_charset[] = "";
31 static const char test_page_contents[] =
32   "<html><head><title>Google</title></head><body><h1>Google</h1></body></html>";
33 static const uint32 test_page_contents_len = arraysize(test_page_contents) - 1;
34
35 static const char kShmemSegmentName[] = "DeferredResourceLoaderTest";
36
37 // Listens for request response data and stores it so that it can be compared
38 // to the reference data.
39 class TestRequestCallback : public ResourceLoaderBridge::Peer {
40  public:
41   TestRequestCallback() : complete_(false) {
42   }
43
44   virtual void OnUploadProgress(uint64 position, uint64 size) OVERRIDE {
45   }
46
47   virtual bool OnReceivedRedirect(
48       const GURL& new_url,
49       const ResourceResponseInfo& info,
50       bool* has_new_first_party_for_cookies,
51       GURL* new_first_party_for_cookies) OVERRIDE {
52     *has_new_first_party_for_cookies = false;
53     return true;
54   }
55
56   virtual void OnReceivedResponse(const ResourceResponseInfo& info) OVERRIDE {
57   }
58
59   virtual void OnDownloadedData(int len, int encoded_data_length) OVERRIDE {
60   }
61
62   virtual void OnReceivedData(const char* data,
63                               int data_length,
64                               int encoded_data_length) OVERRIDE {
65     EXPECT_FALSE(complete_);
66     data_.append(data, data_length);
67     total_encoded_data_length_ += encoded_data_length;
68   }
69
70   virtual void OnCompletedRequest(
71       int error_code,
72       bool was_ignored_by_handler,
73       bool stale_copy_in_cache,
74       const std::string& security_info,
75       const base::TimeTicks& completion_time,
76       int64 total_transfer_size) OVERRIDE {
77     EXPECT_FALSE(complete_);
78     complete_ = true;
79   }
80
81   bool complete() const {
82     return complete_;
83   }
84   const std::string& data() const {
85     return data_;
86   }
87   int total_encoded_data_length() const {
88     return total_encoded_data_length_;
89   }
90
91  private:
92   bool complete_;
93   std::string data_;
94   int total_encoded_data_length_;
95 };
96
97
98 // Sets up the message sender override for the unit test
99 class ResourceDispatcherTest : public testing::Test, public IPC::Sender {
100  public:
101   // Emulates IPC send operations (IPC::Sender) by adding
102   // pending messages to the queue.
103   virtual bool Send(IPC::Message* msg) OVERRIDE {
104     message_queue_.push_back(IPC::Message(*msg));
105     delete msg;
106     return true;
107   }
108
109   // Emulates the browser process and processes the pending IPC messages,
110   // returning the hardcoded file contents.
111   void ProcessMessages() {
112     while (!message_queue_.empty()) {
113       int request_id;
114       ResourceHostMsg_Request request;
115       ASSERT_TRUE(ResourceHostMsg_RequestResource::Read(
116           &message_queue_[0], &request_id, &request));
117
118       // check values
119       EXPECT_EQ(test_page_url, request.url.spec());
120
121       // received response message
122       ResourceResponseHead response;
123       std::string raw_headers(test_page_headers);
124       std::replace(raw_headers.begin(), raw_headers.end(), '\n', '\0');
125       response.headers = new net::HttpResponseHeaders(raw_headers);
126       response.mime_type = test_page_mime_type;
127       response.charset = test_page_charset;
128       dispatcher_->OnReceivedResponse(request_id, response);
129
130       // received data message with the test contents
131       base::SharedMemory shared_mem;
132       EXPECT_TRUE(shared_mem.CreateAndMapAnonymous(test_page_contents_len));
133       char* put_data_here = static_cast<char*>(shared_mem.memory());
134       memcpy(put_data_here, test_page_contents, test_page_contents_len);
135       base::SharedMemoryHandle dup_handle;
136       EXPECT_TRUE(shared_mem.GiveToProcess(
137           base::Process::Current().handle(), &dup_handle));
138       dispatcher_->OnSetDataBuffer(request_id, dup_handle,
139                                    test_page_contents_len, 0);
140       dispatcher_->OnReceivedData(request_id, 0, test_page_contents_len,
141                                   test_page_contents_len);
142
143       message_queue_.erase(message_queue_.begin());
144
145       // read the ack message.
146       Tuple1<int> request_ack;
147       ASSERT_TRUE(ResourceHostMsg_DataReceived_ACK::Read(
148           &message_queue_[0], &request_ack));
149
150       ASSERT_EQ(request_ack.a, request_id);
151
152       message_queue_.erase(message_queue_.begin());
153     }
154   }
155
156  protected:
157   // testing::Test
158   virtual void SetUp() OVERRIDE {
159     dispatcher_.reset(new ResourceDispatcher(this));
160   }
161   virtual void TearDown() OVERRIDE {
162     dispatcher_.reset();
163   }
164
165   ResourceLoaderBridge* CreateBridge() {
166     webkit_glue::ResourceLoaderBridge::RequestInfo request_info;
167     request_info.method = "GET";
168     request_info.url = GURL(test_page_url);
169     request_info.first_party_for_cookies = GURL(test_page_url);
170     request_info.referrer = GURL();
171     request_info.headers = std::string();
172     request_info.load_flags = 0;
173     request_info.requestor_pid = 0;
174     request_info.request_type = ResourceType::SUB_RESOURCE;
175     request_info.appcache_host_id = appcache::kNoHostId;
176     request_info.routing_id = 0;
177     RequestExtraData extra_data(blink::WebPageVisibilityStateVisible,
178                                 blink::WebString(),
179                                 false, MSG_ROUTING_NONE, true, 0, GURL(),
180                                 false, -1, true,
181                                 PAGE_TRANSITION_LINK, false, -1, -1);
182     request_info.extra_data = &extra_data;
183
184     return dispatcher_->CreateBridge(request_info);
185   }
186
187   std::vector<IPC::Message> message_queue_;
188   static scoped_ptr<ResourceDispatcher> dispatcher_;
189 };
190
191 /*static*/
192 scoped_ptr<ResourceDispatcher> ResourceDispatcherTest::dispatcher_;
193
194 // Does a simple request and tests that the correct data is received.
195 TEST_F(ResourceDispatcherTest, RoundTrip) {
196   TestRequestCallback callback;
197   ResourceLoaderBridge* bridge = CreateBridge();
198
199   bridge->Start(&callback);
200
201   ProcessMessages();
202
203   // FIXME(brettw) when the request complete messages are actually handledo
204   // and dispatched, uncomment this.
205   //EXPECT_TRUE(callback.complete());
206   //EXPECT_STREQ(test_page_contents, callback.data().c_str());
207   //EXPECT_EQ(test_page_contents_len, callback.total_encoded_data_length());
208
209   delete bridge;
210 }
211
212 // Tests that the request IDs are straight when there are multiple requests.
213 TEST_F(ResourceDispatcherTest, MultipleRequests) {
214   // FIXME
215 }
216
217 // Tests that the cancel method prevents other messages from being received
218 TEST_F(ResourceDispatcherTest, Cancel) {
219   // FIXME
220 }
221
222 TEST_F(ResourceDispatcherTest, Cookies) {
223   // FIXME
224 }
225
226 TEST_F(ResourceDispatcherTest, SerializedPostData) {
227   // FIXME
228 }
229
230 // This class provides functionality to validate whether the ResourceDispatcher
231 // object honors the deferred loading contract correctly, i.e. if deferred
232 // loading is enabled it should queue up any responses received. If deferred
233 // loading is enabled/disabled in the context of a dispatched message, other
234 // queued messages should not be dispatched until deferred load is turned off.
235 class DeferredResourceLoadingTest : public ResourceDispatcherTest,
236                                     public ResourceLoaderBridge::Peer {
237  public:
238   DeferredResourceLoadingTest()
239       : defer_loading_(false) {
240   }
241
242   virtual bool Send(IPC::Message* msg) OVERRIDE {
243     delete msg;
244     return true;
245   }
246
247   void InitMessages() {
248     set_defer_loading(true);
249
250     ResourceResponseHead response_head;
251     response_head.error_code = net::OK;
252
253     dispatcher_->OnMessageReceived(
254         ResourceMsg_ReceivedResponse(0, response_head));
255
256     // Duplicate the shared memory handle so both the test and the callee can
257     // close their copy.
258     base::SharedMemoryHandle duplicated_handle;
259     EXPECT_TRUE(shared_handle_.ShareToProcess(base::GetCurrentProcessHandle(),
260                                               &duplicated_handle));
261
262     dispatcher_->OnMessageReceived(
263         ResourceMsg_SetDataBuffer(0, duplicated_handle, 100, 0));
264     dispatcher_->OnMessageReceived(ResourceMsg_DataReceived(0, 0, 100, 100));
265
266     set_defer_loading(false);
267   }
268
269   // ResourceLoaderBridge::Peer methods.
270   virtual void OnUploadProgress(uint64 position, uint64 size) OVERRIDE {
271   }
272
273   virtual bool OnReceivedRedirect(
274       const GURL& new_url,
275       const ResourceResponseInfo& info,
276       bool* has_new_first_party_for_cookies,
277       GURL* new_first_party_for_cookies) OVERRIDE {
278     *has_new_first_party_for_cookies = false;
279     return true;
280   }
281
282   virtual void OnReceivedResponse(const ResourceResponseInfo& info) OVERRIDE {
283     EXPECT_EQ(defer_loading_, false);
284     set_defer_loading(true);
285   }
286
287   virtual void OnDownloadedData(int len, int encoded_data_length) OVERRIDE {
288   }
289
290   virtual void OnReceivedData(const char* data,
291                               int data_length,
292                               int encoded_data_length) OVERRIDE {
293     EXPECT_EQ(defer_loading_, false);
294     set_defer_loading(false);
295   }
296
297   virtual void OnCompletedRequest(
298       int error_code,
299       bool was_ignored_by_handler,
300       bool stale_copy_in_cache,
301       const std::string& security_info,
302       const base::TimeTicks& completion_time,
303       int64 total_transfer_size) OVERRIDE {
304   }
305
306  protected:
307   virtual void SetUp() OVERRIDE {
308     ResourceDispatcherTest::SetUp();
309     shared_handle_.Delete(kShmemSegmentName);
310     EXPECT_TRUE(shared_handle_.CreateNamed(kShmemSegmentName, false, 100));
311   }
312
313   virtual void TearDown() OVERRIDE {
314     shared_handle_.Close();
315     EXPECT_TRUE(shared_handle_.Delete(kShmemSegmentName));
316     ResourceDispatcherTest::TearDown();
317   }
318
319  private:
320   void set_defer_loading(bool defer) {
321     defer_loading_ = defer;
322     dispatcher_->SetDefersLoading(0, defer);
323   }
324
325   bool defer_loading() const {
326     return defer_loading_;
327   }
328
329   bool defer_loading_;
330   base::SharedMemory shared_handle_;
331 };
332
333 TEST_F(DeferredResourceLoadingTest, DeferredLoadTest) {
334   base::MessageLoopForIO message_loop;
335
336   ResourceLoaderBridge* bridge = CreateBridge();
337
338   bridge->Start(this);
339   InitMessages();
340
341   // Dispatch deferred messages.
342   message_loop.RunUntilIdle();
343   delete bridge;
344 }
345
346 class TimeConversionTest : public ResourceDispatcherTest,
347                            public ResourceLoaderBridge::Peer {
348  public:
349   virtual bool Send(IPC::Message* msg) OVERRIDE {
350     delete msg;
351     return true;
352   }
353
354   void PerformTest(const ResourceResponseHead& response_head) {
355     scoped_ptr<ResourceLoaderBridge> bridge(CreateBridge());
356     bridge->Start(this);
357
358     dispatcher_->OnMessageReceived(
359         ResourceMsg_ReceivedResponse(0, response_head));
360   }
361
362   // ResourceLoaderBridge::Peer methods.
363   virtual void OnUploadProgress(uint64 position, uint64 size) OVERRIDE {
364   }
365
366   virtual bool OnReceivedRedirect(
367       const GURL& new_url,
368       const ResourceResponseInfo& info,
369       bool* has_new_first_party_for_cookies,
370       GURL* new_first_party_for_cookies) OVERRIDE {
371     return true;
372   }
373
374   virtual void OnReceivedResponse(const ResourceResponseInfo& info) OVERRIDE {
375     response_info_ = info;
376   }
377
378   virtual void OnDownloadedData(int len, int encoded_data_length) OVERRIDE {
379   }
380
381   virtual void OnReceivedData(const char* data,
382                               int data_length,
383                               int encoded_data_length) OVERRIDE {
384   }
385
386   virtual void OnCompletedRequest(
387       int error_code,
388       bool was_ignored_by_handler,
389       bool stale_copy_in_cache,
390       const std::string& security_info,
391       const base::TimeTicks& completion_time,
392       int64 total_transfer_size) OVERRIDE {
393   }
394
395   const ResourceResponseInfo& response_info() const { return response_info_; }
396
397  private:
398   ResourceResponseInfo response_info_;
399 };
400
401 // TODO(simonjam): Enable this when 10829031 lands.
402 TEST_F(TimeConversionTest, DISABLED_ProperlyInitialized) {
403   ResourceResponseHead response_head;
404   response_head.error_code = net::OK;
405   response_head.request_start = base::TimeTicks::FromInternalValue(5);
406   response_head.response_start = base::TimeTicks::FromInternalValue(15);
407   response_head.load_timing.request_start_time = base::Time::Now();
408   response_head.load_timing.request_start =
409       base::TimeTicks::FromInternalValue(10);
410   response_head.load_timing.connect_timing.connect_start =
411       base::TimeTicks::FromInternalValue(13);
412
413   PerformTest(response_head);
414
415   EXPECT_LT(base::TimeTicks(), response_info().load_timing.request_start);
416   EXPECT_EQ(base::TimeTicks(),
417             response_info().load_timing.connect_timing.dns_start);
418   EXPECT_LE(response_head.load_timing.request_start,
419             response_info().load_timing.connect_timing.connect_start);
420 }
421
422 TEST_F(TimeConversionTest, PartiallyInitialized) {
423   ResourceResponseHead response_head;
424   response_head.error_code = net::OK;
425   response_head.request_start = base::TimeTicks::FromInternalValue(5);
426   response_head.response_start = base::TimeTicks::FromInternalValue(15);
427
428   PerformTest(response_head);
429
430   EXPECT_EQ(base::TimeTicks(), response_info().load_timing.request_start);
431   EXPECT_EQ(base::TimeTicks(),
432             response_info().load_timing.connect_timing.dns_start);
433 }
434
435 TEST_F(TimeConversionTest, NotInitialized) {
436   ResourceResponseHead response_head;
437   response_head.error_code = net::OK;
438
439   PerformTest(response_head);
440
441   EXPECT_EQ(base::TimeTicks(), response_info().load_timing.request_start);
442   EXPECT_EQ(base::TimeTicks(),
443             response_info().load_timing.connect_timing.dns_start);
444 }
445
446 }  // namespace content