Revert of Disable spdy tests for constant failures on Volantis bot (patchset #2 id...
[chromium-blink-merge.git] / android_webview / browser / net / android_stream_reader_url_request_job_unittest.cc
blob4b80c41f8adcc185115e7df1b1a0a3f557f981e6
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 "android_webview/browser/input_stream.h"
6 #include "android_webview/browser/net/android_stream_reader_url_request_job.h"
7 #include "android_webview/browser/net/aw_url_request_job_factory.h"
8 #include "android_webview/browser/net/input_stream_reader.h"
9 #include "base/format_macros.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/message_loop/message_loop.h"
12 #include "base/run_loop.h"
13 #include "base/strings/stringprintf.h"
14 #include "net/base/request_priority.h"
15 #include "net/http/http_byte_range.h"
16 #include "net/http/http_response_headers.h"
17 #include "net/url_request/url_request.h"
18 #include "net/url_request/url_request_job_factory_impl.h"
19 #include "net/url_request/url_request_test_util.h"
21 #include "testing/gmock/include/gmock/gmock.h"
22 #include "testing/gtest/include/gtest/gtest.h"
24 using android_webview::InputStream;
25 using android_webview::InputStreamReader;
26 using net::TestDelegate;
27 using net::TestJobInterceptor;
28 using net::TestNetworkDelegate;
29 using net::TestURLRequestContext;
30 using net::URLRequest;
31 using testing::DoAll;
32 using testing::Ge;
33 using testing::Gt;
34 using testing::InSequence;
35 using testing::Invoke;
36 using testing::InvokeWithoutArgs;
37 using testing::NotNull;
38 using testing::Return;
39 using testing::SaveArg;
40 using testing::SetArgPointee;
41 using testing::StrictMock;
42 using testing::Test;
43 using testing::WithArg;
44 using testing::WithArgs;
45 using testing::_;
47 // Some of the classes will DCHECK on a null InputStream (which is desirable).
48 // The workaround is to use this class. None of the methods need to be
49 // implemented as the mock InputStreamReader should never forward calls to the
50 // InputStream.
51 class NotImplInputStream : public InputStream {
52 public:
53 NotImplInputStream() {}
54 virtual ~NotImplInputStream() {}
55 virtual bool BytesAvailable(int* bytes_available) const override {
56 NOTIMPLEMENTED();
57 return false;
59 virtual bool Skip(int64_t n, int64_t* bytes_skipped) override {
60 NOTIMPLEMENTED();
61 return false;
63 virtual bool Read(net::IOBuffer* dest, int length, int* bytes_read) override {
64 NOTIMPLEMENTED();
65 return false;
69 // Required in order to create an instance of AndroidStreamReaderURLRequestJob.
70 class StreamReaderDelegate :
71 public AndroidStreamReaderURLRequestJob::Delegate {
72 public:
73 StreamReaderDelegate() {}
75 virtual scoped_ptr<InputStream> OpenInputStream(
76 JNIEnv* env,
77 const GURL& url) override {
78 return make_scoped_ptr<InputStream>(new NotImplInputStream());
81 virtual void OnInputStreamOpenFailed(net::URLRequest* request,
82 bool* restart) override {
83 *restart = false;
86 virtual bool GetMimeType(JNIEnv* env,
87 net::URLRequest* request,
88 android_webview::InputStream* stream,
89 std::string* mime_type) override {
90 return false;
93 virtual bool GetCharset(JNIEnv* env,
94 net::URLRequest* request,
95 android_webview::InputStream* stream,
96 std::string* charset) override {
97 return false;
100 virtual void AppendResponseHeaders(
101 JNIEnv* env,
102 net::HttpResponseHeaders* headers) override {
103 // no-op
107 class NullStreamReaderDelegate : public StreamReaderDelegate {
108 public:
109 NullStreamReaderDelegate() {}
111 virtual scoped_ptr<InputStream> OpenInputStream(
112 JNIEnv* env,
113 const GURL& url) override {
114 return make_scoped_ptr<InputStream>(NULL);
118 class HeaderAlteringStreamReaderDelegate : public NullStreamReaderDelegate {
119 public:
120 HeaderAlteringStreamReaderDelegate() {}
122 virtual void AppendResponseHeaders(
123 JNIEnv* env,
124 net::HttpResponseHeaders* headers) override {
125 headers->ReplaceStatusLine(kStatusLine);
126 std::string headerLine(kCustomHeaderName);
127 headerLine.append(": ");
128 headerLine.append(kCustomHeaderValue);
129 headers->AddHeader(headerLine);
132 static const int kResponseCode;
133 static const char* kStatusLine;
134 static const char* kCustomHeaderName;
135 static const char* kCustomHeaderValue;
138 const int HeaderAlteringStreamReaderDelegate::kResponseCode = 401;
139 const char* HeaderAlteringStreamReaderDelegate::kStatusLine =
140 "HTTP/1.1 401 Gone";
141 const char* HeaderAlteringStreamReaderDelegate::kCustomHeaderName =
142 "X-Test-Header";
143 const char* HeaderAlteringStreamReaderDelegate::kCustomHeaderValue =
144 "TestHeaderValue";
146 class MockInputStreamReader : public InputStreamReader {
147 public:
148 MockInputStreamReader() : InputStreamReader(new NotImplInputStream()) {}
149 ~MockInputStreamReader() {}
151 MOCK_METHOD1(Seek, int(const net::HttpByteRange& byte_range));
152 MOCK_METHOD2(ReadRawData, int(net::IOBuffer* buffer, int buffer_size));
156 class TestStreamReaderJob : public AndroidStreamReaderURLRequestJob {
157 public:
158 TestStreamReaderJob(
159 net::URLRequest* request,
160 net::NetworkDelegate* network_delegate,
161 scoped_ptr<Delegate> delegate,
162 scoped_ptr<InputStreamReader> stream_reader)
163 : AndroidStreamReaderURLRequestJob(request,
164 network_delegate,
165 delegate.Pass()),
166 stream_reader_(stream_reader.Pass()) {
167 message_loop_proxy_ = base::MessageLoopProxy::current();
170 virtual scoped_ptr<InputStreamReader> CreateStreamReader(
171 InputStream* stream) override {
172 return stream_reader_.Pass();
174 protected:
175 virtual ~TestStreamReaderJob() {}
177 virtual base::TaskRunner* GetWorkerThreadRunner() override {
178 return message_loop_proxy_.get();
181 scoped_ptr<InputStreamReader> stream_reader_;
182 scoped_refptr<base::MessageLoopProxy> message_loop_proxy_;
185 class AndroidStreamReaderURLRequestJobTest : public Test {
186 public:
187 AndroidStreamReaderURLRequestJobTest() {}
189 protected:
190 virtual void SetUp() {
191 context_.set_job_factory(&factory_);
192 context_.set_network_delegate(&network_delegate_);
193 req_ = context_.CreateRequest(GURL("content://foo"),
194 net::DEFAULT_PRIORITY,
195 &url_request_delegate_,
196 NULL);
197 req_->set_method("GET");
200 void SetRange(net::URLRequest* req, int first_byte, int last_byte) {
201 net::HttpRequestHeaders headers;
202 headers.SetHeader(net::HttpRequestHeaders::kRange,
203 net::HttpByteRange::Bounded(
204 first_byte, last_byte).GetHeaderValue());
205 req->SetExtraRequestHeaders(headers);
208 void SetUpTestJob(scoped_ptr<InputStreamReader> stream_reader) {
209 SetUpTestJob(stream_reader.Pass(),
210 make_scoped_ptr(new StreamReaderDelegate()));
213 void SetUpTestJob(scoped_ptr<InputStreamReader> stream_reader,
214 scoped_ptr<AndroidStreamReaderURLRequestJob::Delegate>
215 stream_reader_delegate) {
216 TestStreamReaderJob* test_stream_reader_job =
217 new TestStreamReaderJob(
218 req_.get(),
219 &network_delegate_,
220 stream_reader_delegate.Pass(),
221 stream_reader.Pass());
222 // The Interceptor is owned by the |factory_|.
223 TestJobInterceptor* protocol_handler = new TestJobInterceptor;
224 protocol_handler->set_main_intercept_job(test_stream_reader_job);
225 bool set_protocol = factory_.SetProtocolHandler("http", protocol_handler);
226 DCHECK(set_protocol);
228 protocol_handler = new TestJobInterceptor;
229 protocol_handler->set_main_intercept_job(test_stream_reader_job);
230 set_protocol = factory_.SetProtocolHandler("content", protocol_handler);
231 DCHECK(set_protocol);
234 base::MessageLoopForIO loop_;
235 TestURLRequestContext context_;
236 android_webview::AwURLRequestJobFactory factory_;
237 TestDelegate url_request_delegate_;
238 TestNetworkDelegate network_delegate_;
239 scoped_ptr<URLRequest> req_;
242 TEST_F(AndroidStreamReaderURLRequestJobTest, ReadEmptyStream) {
243 scoped_ptr<StrictMock<MockInputStreamReader> > stream_reader(
244 new StrictMock<MockInputStreamReader>());
246 InSequence s;
247 EXPECT_CALL(*stream_reader, Seek(_))
248 .WillOnce(Return(0));
249 EXPECT_CALL(*stream_reader, ReadRawData(NotNull(), Gt(0)))
250 .WillOnce(Return(0));
253 SetUpTestJob(stream_reader.Pass());
255 req_->Start();
257 // The TestDelegate will quit the message loop on request completion.
258 base::MessageLoop::current()->Run();
260 EXPECT_FALSE(url_request_delegate_.request_failed());
261 EXPECT_EQ(1, network_delegate_.completed_requests());
262 EXPECT_EQ(0, network_delegate_.error_count());
263 EXPECT_EQ(200, req_->GetResponseCode());
266 TEST_F(AndroidStreamReaderURLRequestJobTest, ReadWithNullStream) {
267 SetUpTestJob(nullptr, make_scoped_ptr(new NullStreamReaderDelegate()));
268 req_->Start();
270 // The TestDelegate will quit the message loop on request completion.
271 base::MessageLoop::current()->Run();
273 // The request_failed() method is named confusingly but all it checks is
274 // whether the request got as far as calling NotifyHeadersComplete.
275 EXPECT_FALSE(url_request_delegate_.request_failed());
276 EXPECT_EQ(1, network_delegate_.completed_requests());
277 // A null input stream shouldn't result in an error. See crbug.com/180950.
278 EXPECT_EQ(0, network_delegate_.error_count());
279 EXPECT_EQ(404, req_->GetResponseCode());
282 TEST_F(AndroidStreamReaderURLRequestJobTest, ModifyHeadersAndStatus) {
283 SetUpTestJob(nullptr,
284 make_scoped_ptr(new HeaderAlteringStreamReaderDelegate()));
285 req_->Start();
287 // The TestDelegate will quit the message loop on request completion.
288 base::MessageLoop::current()->Run();
290 // The request_failed() method is named confusingly but all it checks is
291 // whether the request got as far as calling NotifyHeadersComplete.
292 EXPECT_FALSE(url_request_delegate_.request_failed());
293 EXPECT_EQ(1, network_delegate_.completed_requests());
294 // A null input stream shouldn't result in an error. See crbug.com/180950.
295 EXPECT_EQ(0, network_delegate_.error_count());
296 EXPECT_EQ(HeaderAlteringStreamReaderDelegate::kResponseCode,
297 req_->GetResponseCode());
298 EXPECT_EQ(HeaderAlteringStreamReaderDelegate::kStatusLine,
299 req_->response_headers()->GetStatusLine());
300 EXPECT_TRUE(req_->response_headers()->HasHeader(
301 HeaderAlteringStreamReaderDelegate::kCustomHeaderName));
302 std::string header_value;
303 EXPECT_TRUE(req_->response_headers()->EnumerateHeader(
304 NULL, HeaderAlteringStreamReaderDelegate::kCustomHeaderName,
305 &header_value));
306 EXPECT_EQ(HeaderAlteringStreamReaderDelegate::kCustomHeaderValue,
307 header_value);
310 TEST_F(AndroidStreamReaderURLRequestJobTest, ReadPartOfStream) {
311 const int bytes_available = 128;
312 const int offset = 32;
313 const int bytes_to_read = bytes_available - offset;
314 scoped_ptr<StrictMock<MockInputStreamReader> > stream_reader(
315 new StrictMock<MockInputStreamReader>());
317 InSequence s;
318 EXPECT_CALL(*stream_reader, Seek(_))
319 .WillOnce(Return(bytes_available));
320 EXPECT_CALL(*stream_reader, ReadRawData(NotNull(), Ge(bytes_to_read)))
321 .WillOnce(Return(bytes_to_read/2));
322 EXPECT_CALL(*stream_reader, ReadRawData(NotNull(), Ge(bytes_to_read)))
323 .WillOnce(Return(bytes_to_read/2));
324 EXPECT_CALL(*stream_reader, ReadRawData(NotNull(), Ge(bytes_to_read)))
325 .WillOnce(Return(0));
328 SetUpTestJob(stream_reader.Pass());
330 SetRange(req_.get(), offset, bytes_available);
331 req_->Start();
333 base::MessageLoop::current()->Run();
335 EXPECT_FALSE(url_request_delegate_.request_failed());
336 EXPECT_EQ(bytes_to_read, url_request_delegate_.bytes_received());
337 EXPECT_EQ(1, network_delegate_.completed_requests());
338 EXPECT_EQ(0, network_delegate_.error_count());
341 TEST_F(AndroidStreamReaderURLRequestJobTest,
342 ReadStreamWithMoreAvailableThanActual) {
343 const int bytes_available_reported = 190;
344 const int bytes_available = 128;
345 const int offset = 0;
346 const int bytes_to_read = bytes_available - offset;
347 scoped_ptr<StrictMock<MockInputStreamReader> > stream_reader(
348 new StrictMock<MockInputStreamReader>());
350 InSequence s;
351 EXPECT_CALL(*stream_reader, Seek(_))
352 .WillOnce(Return(bytes_available_reported));
353 EXPECT_CALL(*stream_reader, ReadRawData(NotNull(), Ge(bytes_to_read)))
354 .WillOnce(Return(bytes_available));
355 EXPECT_CALL(*stream_reader, ReadRawData(NotNull(), Ge(bytes_to_read)))
356 .WillOnce(Return(0));
359 SetUpTestJob(stream_reader.Pass());
361 SetRange(req_.get(), offset, bytes_available_reported);
362 req_->Start();
364 base::MessageLoop::current()->Run();
366 EXPECT_FALSE(url_request_delegate_.request_failed());
367 EXPECT_EQ(bytes_to_read, url_request_delegate_.bytes_received());
368 EXPECT_EQ(1, network_delegate_.completed_requests());
369 EXPECT_EQ(0, network_delegate_.error_count());
372 TEST_F(AndroidStreamReaderURLRequestJobTest, DeleteJobMidWaySeek) {
373 const int offset = 20;
374 const int bytes_available = 128;
375 base::RunLoop loop;
376 scoped_ptr<StrictMock<MockInputStreamReader> > stream_reader(
377 new StrictMock<MockInputStreamReader>());
378 EXPECT_CALL(*stream_reader, Seek(_))
379 .WillOnce(DoAll(InvokeWithoutArgs(&loop, &base::RunLoop::Quit),
380 Return(bytes_available)));
381 ON_CALL(*stream_reader, ReadRawData(_, _))
382 .WillByDefault(Return(0));
384 SetUpTestJob(stream_reader.Pass());
386 SetRange(req_.get(), offset, bytes_available);
387 req_->Start();
389 loop.Run();
391 EXPECT_EQ(0, network_delegate_.completed_requests());
392 req_->Cancel();
393 EXPECT_EQ(1, network_delegate_.completed_requests());
396 TEST_F(AndroidStreamReaderURLRequestJobTest, DeleteJobMidWayRead) {
397 const int offset = 20;
398 const int bytes_available = 128;
399 base::RunLoop loop;
400 scoped_ptr<StrictMock<MockInputStreamReader> > stream_reader(
401 new StrictMock<MockInputStreamReader>());
402 net::CompletionCallback read_completion_callback;
403 EXPECT_CALL(*stream_reader, Seek(_))
404 .WillOnce(Return(bytes_available));
405 EXPECT_CALL(*stream_reader, ReadRawData(_, _))
406 .WillOnce(DoAll(InvokeWithoutArgs(&loop, &base::RunLoop::Quit),
407 Return(bytes_available)));
409 SetUpTestJob(stream_reader.Pass());
411 SetRange(req_.get(), offset, bytes_available);
412 req_->Start();
414 loop.Run();
416 EXPECT_EQ(0, network_delegate_.completed_requests());
417 req_->Cancel();
418 EXPECT_EQ(1, network_delegate_.completed_requests());