Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / net / url_request / url_request_http_job_unittest.cc
1 // Copyright (c) 2013 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 "net/url_request/url_request_http_job.h"
6
7 #include <cstddef>
8
9 #include "base/compiler_specific.h"
10 #include "base/memory/ref_counted.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/run_loop.h"
13 #include "net/base/auth.h"
14 #include "net/base/request_priority.h"
15 #include "net/http/http_transaction_factory.h"
16 #include "net/http/http_transaction_test_util.h"
17 #include "net/socket/socket_test_util.h"
18 #include "net/url_request/url_request.h"
19 #include "net/url_request/url_request_status.h"
20 #include "net/url_request/url_request_test_util.h"
21 #include "net/websockets/websocket_handshake_stream_base.h"
22 #include "testing/gmock/include/gmock/gmock.h"
23 #include "testing/gtest/include/gtest/gtest.h"
24 #include "url/gurl.h"
25
26 namespace net {
27
28 namespace {
29
30 using ::testing::Return;
31
32 // Inherit from URLRequestHttpJob to expose the priority and some
33 // other hidden functions.
34 class TestURLRequestHttpJob : public URLRequestHttpJob {
35  public:
36   explicit TestURLRequestHttpJob(URLRequest* request)
37       : URLRequestHttpJob(request, request->context()->network_delegate(),
38                           request->context()->http_user_agent_settings()) {}
39
40   using URLRequestHttpJob::SetPriority;
41   using URLRequestHttpJob::Start;
42   using URLRequestHttpJob::Kill;
43   using URLRequestHttpJob::priority;
44
45  protected:
46   virtual ~TestURLRequestHttpJob() {}
47 };
48
49 class URLRequestHttpJobTest : public ::testing::Test {
50  protected:
51   URLRequestHttpJobTest()
52       : req_(context_.CreateRequest(GURL("http://www.example.com"),
53                                     DEFAULT_PRIORITY,
54                                     &delegate_,
55                                     NULL)) {
56     context_.set_http_transaction_factory(&network_layer_);
57   }
58
59   bool TransactionAcceptsSdchEncoding() {
60     base::WeakPtr<MockNetworkTransaction> transaction(
61         network_layer_.last_transaction());
62     EXPECT_TRUE(transaction);
63     if (!transaction) return false;
64
65     const HttpRequestInfo* request_info = transaction->request();
66     EXPECT_TRUE(request_info);
67     if (!request_info) return false;
68
69     std::string encoding_headers;
70     bool get_success = request_info->extra_headers.GetHeader(
71         "Accept-Encoding", &encoding_headers);
72     EXPECT_TRUE(get_success);
73     if (!get_success) return false;
74
75     // This check isn't wrapped with EXPECT* macros because different
76     // results from this function may be expected in different tests.
77     std::vector<std::string> tokens;
78     size_t num_tokens = Tokenize(encoding_headers, ", ", &tokens);
79     for (size_t i = 0; i < num_tokens; i++) {
80       if (!base::strncasecmp(tokens[i].data(), "sdch", tokens[i].length()))
81         return true;
82     }
83     return false;
84   }
85
86   void EnableSdch() {
87     context_.SetSdchManager(scoped_ptr<SdchManager>(new SdchManager).Pass());
88   }
89
90   MockNetworkLayer network_layer_;
91   TestURLRequestContext context_;
92   TestDelegate delegate_;
93   scoped_ptr<URLRequest> req_;
94 };
95
96 // Make sure that SetPriority actually sets the URLRequestHttpJob's
97 // priority, both before and after start.
98 TEST_F(URLRequestHttpJobTest, SetPriorityBasic) {
99   scoped_refptr<TestURLRequestHttpJob> job(
100       new TestURLRequestHttpJob(req_.get()));
101   EXPECT_EQ(DEFAULT_PRIORITY, job->priority());
102
103   job->SetPriority(LOWEST);
104   EXPECT_EQ(LOWEST, job->priority());
105
106   job->SetPriority(LOW);
107   EXPECT_EQ(LOW, job->priority());
108
109   job->Start();
110   EXPECT_EQ(LOW, job->priority());
111
112   job->SetPriority(MEDIUM);
113   EXPECT_EQ(MEDIUM, job->priority());
114 }
115
116 // Make sure that URLRequestHttpJob passes on its priority to its
117 // transaction on start.
118 TEST_F(URLRequestHttpJobTest, SetTransactionPriorityOnStart) {
119   scoped_refptr<TestURLRequestHttpJob> job(
120       new TestURLRequestHttpJob(req_.get()));
121   job->SetPriority(LOW);
122
123   EXPECT_FALSE(network_layer_.last_transaction());
124
125   job->Start();
126
127   ASSERT_TRUE(network_layer_.last_transaction());
128   EXPECT_EQ(LOW, network_layer_.last_transaction()->priority());
129 }
130
131 // Make sure that URLRequestHttpJob passes on its priority updates to
132 // its transaction.
133 TEST_F(URLRequestHttpJobTest, SetTransactionPriority) {
134   scoped_refptr<TestURLRequestHttpJob> job(
135       new TestURLRequestHttpJob(req_.get()));
136   job->SetPriority(LOW);
137   job->Start();
138   ASSERT_TRUE(network_layer_.last_transaction());
139   EXPECT_EQ(LOW, network_layer_.last_transaction()->priority());
140
141   job->SetPriority(HIGHEST);
142   EXPECT_EQ(HIGHEST, network_layer_.last_transaction()->priority());
143 }
144
145 // Make sure that URLRequestHttpJob passes on its priority updates to
146 // newly-created transactions after the first one.
147 TEST_F(URLRequestHttpJobTest, SetSubsequentTransactionPriority) {
148   scoped_refptr<TestURLRequestHttpJob> job(
149       new TestURLRequestHttpJob(req_.get()));
150   job->Start();
151
152   job->SetPriority(LOW);
153   ASSERT_TRUE(network_layer_.last_transaction());
154   EXPECT_EQ(LOW, network_layer_.last_transaction()->priority());
155
156   job->Kill();
157   network_layer_.ClearLastTransaction();
158
159   // Creates a second transaction.
160   job->Start();
161   ASSERT_TRUE(network_layer_.last_transaction());
162   EXPECT_EQ(LOW, network_layer_.last_transaction()->priority());
163 }
164
165 // Confirm we do advertise SDCH encoding in the case of a GET.
166 TEST_F(URLRequestHttpJobTest, SdchAdvertisementGet) {
167   EnableSdch();
168   req_->set_method("GET");  // Redundant with default.
169   scoped_refptr<TestURLRequestHttpJob> job(
170       new TestURLRequestHttpJob(req_.get()));
171   job->Start();
172   EXPECT_TRUE(TransactionAcceptsSdchEncoding());
173 }
174
175 // Confirm we don't advertise SDCH encoding in the case of a POST.
176 TEST_F(URLRequestHttpJobTest, SdchAdvertisementPost) {
177   EnableSdch();
178   req_->set_method("POST");
179   scoped_refptr<TestURLRequestHttpJob> job(
180       new TestURLRequestHttpJob(req_.get()));
181   job->Start();
182   EXPECT_FALSE(TransactionAcceptsSdchEncoding());
183 }
184
185 // This base class just serves to set up some things before the TestURLRequest
186 // constructor is called.
187 class URLRequestHttpJobWebSocketTestBase : public ::testing::Test {
188  protected:
189   URLRequestHttpJobWebSocketTestBase() : socket_data_(NULL, 0, NULL, 0),
190                                          context_(true) {
191     // A Network Delegate is required for the WebSocketHandshakeStreamBase
192     // object to be passed on to the HttpNetworkTransaction.
193     context_.set_network_delegate(&network_delegate_);
194
195     // Attempting to create real ClientSocketHandles is not going to work out so
196     // well. Set up a fake socket factory.
197     socket_factory_.AddSocketDataProvider(&socket_data_);
198     context_.set_client_socket_factory(&socket_factory_);
199     context_.Init();
200   }
201
202   StaticSocketDataProvider socket_data_;
203   TestNetworkDelegate network_delegate_;
204   MockClientSocketFactory socket_factory_;
205   TestURLRequestContext context_;
206 };
207
208 class URLRequestHttpJobWebSocketTest
209     : public URLRequestHttpJobWebSocketTestBase {
210  protected:
211   URLRequestHttpJobWebSocketTest()
212       : req_(context_.CreateRequest(GURL("ws://www.example.com"),
213                                     DEFAULT_PRIORITY,
214                                     &delegate_,
215                                     NULL)) {
216     // The TestNetworkDelegate expects a call to NotifyBeforeURLRequest before
217     // anything else happens.
218     GURL url("ws://localhost/");
219     TestCompletionCallback dummy;
220     network_delegate_.NotifyBeforeURLRequest(
221         req_.get(), dummy.callback(), &url);
222   }
223
224   TestDelegate delegate_;
225   scoped_ptr<URLRequest> req_;
226 };
227
228 class MockCreateHelper : public WebSocketHandshakeStreamBase::CreateHelper {
229  public:
230   // GoogleMock does not appear to play nicely with move-only types like
231   // scoped_ptr, so this forwarding method acts as a workaround.
232   virtual WebSocketHandshakeStreamBase* CreateBasicStream(
233       scoped_ptr<ClientSocketHandle> connection,
234       bool using_proxy) OVERRIDE {
235     // Discard the arguments since we don't need them anyway.
236     return CreateBasicStreamMock();
237   }
238
239   MOCK_METHOD0(CreateBasicStreamMock,
240                WebSocketHandshakeStreamBase*());
241
242   MOCK_METHOD2(CreateSpdyStream,
243                WebSocketHandshakeStreamBase*(const base::WeakPtr<SpdySession>&,
244                                              bool));
245 };
246
247 class FakeWebSocketHandshakeStream : public WebSocketHandshakeStreamBase {
248  public:
249   FakeWebSocketHandshakeStream() : initialize_stream_was_called_(false) {}
250
251   bool initialize_stream_was_called() const {
252     return initialize_stream_was_called_;
253   }
254
255   // Fake implementation of HttpStreamBase methods.
256   virtual int InitializeStream(const HttpRequestInfo* request_info,
257                                RequestPriority priority,
258                                const BoundNetLog& net_log,
259                                const CompletionCallback& callback) OVERRIDE {
260     initialize_stream_was_called_ = true;
261     return ERR_IO_PENDING;
262   }
263
264   virtual int SendRequest(const HttpRequestHeaders& request_headers,
265                           HttpResponseInfo* response,
266                           const CompletionCallback& callback) OVERRIDE {
267     return ERR_IO_PENDING;
268   }
269
270   virtual int ReadResponseHeaders(const CompletionCallback& callback) OVERRIDE {
271     return ERR_IO_PENDING;
272   }
273
274   virtual int ReadResponseBody(IOBuffer* buf,
275                                int buf_len,
276                                const CompletionCallback& callback) OVERRIDE {
277     return ERR_IO_PENDING;
278   }
279
280   virtual void Close(bool not_reusable) OVERRIDE {}
281
282   virtual bool IsResponseBodyComplete() const OVERRIDE { return false; }
283
284   virtual bool CanFindEndOfResponse() const OVERRIDE { return false; }
285
286   virtual bool IsConnectionReused() const OVERRIDE { return false; }
287   virtual void SetConnectionReused() OVERRIDE {}
288
289   virtual bool IsConnectionReusable() const OVERRIDE { return false; }
290
291   virtual int64 GetTotalReceivedBytes() const OVERRIDE { return 0; }
292
293   virtual bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const
294       OVERRIDE {
295     return false;
296   }
297
298   virtual void GetSSLInfo(SSLInfo* ssl_info) OVERRIDE {}
299
300   virtual void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info)
301       OVERRIDE {}
302
303   virtual bool IsSpdyHttpStream() const OVERRIDE { return false; }
304
305   virtual void Drain(HttpNetworkSession* session) OVERRIDE {}
306
307   virtual void SetPriority(RequestPriority priority) OVERRIDE {}
308
309   // Fake implementation of WebSocketHandshakeStreamBase method(s)
310   virtual scoped_ptr<WebSocketStream> Upgrade() OVERRIDE {
311     return scoped_ptr<WebSocketStream>();
312   }
313
314  private:
315   bool initialize_stream_was_called_;
316 };
317
318 TEST_F(URLRequestHttpJobWebSocketTest, RejectedWithoutCreateHelper) {
319   scoped_refptr<TestURLRequestHttpJob> job(
320       new TestURLRequestHttpJob(req_.get()));
321   job->Start();
322   base::RunLoop().RunUntilIdle();
323   EXPECT_EQ(URLRequestStatus::FAILED, req_->status().status());
324   EXPECT_EQ(ERR_DISALLOWED_URL_SCHEME, req_->status().error());
325 }
326
327 TEST_F(URLRequestHttpJobWebSocketTest, CreateHelperPassedThrough) {
328   scoped_refptr<TestURLRequestHttpJob> job(
329       new TestURLRequestHttpJob(req_.get()));
330   scoped_ptr<MockCreateHelper> create_helper(
331       new ::testing::StrictMock<MockCreateHelper>());
332   FakeWebSocketHandshakeStream* fake_handshake_stream(
333       new FakeWebSocketHandshakeStream);
334   // Ownership of fake_handshake_stream is transferred when CreateBasicStream()
335   // is called.
336   EXPECT_CALL(*create_helper, CreateBasicStreamMock())
337       .WillOnce(Return(fake_handshake_stream));
338   req_->SetUserData(WebSocketHandshakeStreamBase::CreateHelper::DataKey(),
339                     create_helper.release());
340   req_->SetLoadFlags(LOAD_DISABLE_CACHE);
341   job->Start();
342   base::RunLoop().RunUntilIdle();
343   EXPECT_EQ(URLRequestStatus::IO_PENDING, req_->status().status());
344   EXPECT_TRUE(fake_handshake_stream->initialize_stream_was_called());
345 }
346
347 }  // namespace
348
349 }  // namespace net