suppress unaddr error at WebResourceService::StartFetch
[chromium-blink-merge.git] / android_webview / browser / net / android_stream_reader_url_request_job_unittest.cc
blobf09b5c534327eca620272731a82e4543d4b272e7
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/message_loop/message_loop.h"
11 #include "base/run_loop.h"
12 #include "base/strings/stringprintf.h"
13 #include "net/base/request_priority.h"
14 #include "net/http/http_byte_range.h"
15 #include "net/url_request/url_request_job_factory_impl.h"
16 #include "net/url_request/url_request_test_util.h"
18 #include "testing/gmock/include/gmock/gmock.h"
19 #include "testing/gtest/include/gtest/gtest.h"
21 using android_webview::InputStream;
22 using android_webview::InputStreamReader;
23 using net::TestDelegate;
24 using net::TestJobInterceptor;
25 using net::TestNetworkDelegate;
26 using net::TestURLRequestContext;
27 using net::TestURLRequest;
28 using testing::DoAll;
29 using testing::Ge;
30 using testing::Gt;
31 using testing::InSequence;
32 using testing::Invoke;
33 using testing::InvokeWithoutArgs;
34 using testing::NotNull;
35 using testing::Return;
36 using testing::SaveArg;
37 using testing::SetArgPointee;
38 using testing::StrictMock;
39 using testing::Test;
40 using testing::WithArg;
41 using testing::WithArgs;
42 using testing::_;
44 // Some of the classes will DCHECK on a null InputStream (which is desirable).
45 // The workaround is to use this class. None of the methods need to be
46 // implemented as the mock InputStreamReader should never forward calls to the
47 // InputStream.
48 class NotImplInputStream : public InputStream {
49 public:
50 NotImplInputStream() {}
51 virtual ~NotImplInputStream() {}
52 virtual bool BytesAvailable(int* bytes_available) const OVERRIDE {
53 NOTIMPLEMENTED();
54 return false;
56 virtual bool Skip(int64_t n, int64_t* bytes_skipped) OVERRIDE {
57 NOTIMPLEMENTED();
58 return false;
60 virtual bool Read(net::IOBuffer* dest, int length, int* bytes_read) OVERRIDE {
61 NOTIMPLEMENTED();
62 return false;
66 // Required in order to create an instance of AndroidStreamReaderURLRequestJob.
67 class StreamReaderDelegate :
68 public AndroidStreamReaderURLRequestJob::Delegate {
69 public:
70 StreamReaderDelegate() {}
72 virtual scoped_ptr<InputStream> OpenInputStream(
73 JNIEnv* env,
74 const GURL& url) OVERRIDE {
75 return make_scoped_ptr<InputStream>(new NotImplInputStream());
78 virtual void OnInputStreamOpenFailed(net::URLRequest* request,
79 bool* restart) OVERRIDE {
80 *restart = false;
83 virtual bool GetMimeType(JNIEnv* env,
84 net::URLRequest* request,
85 android_webview::InputStream* stream,
86 std::string* mime_type) OVERRIDE {
87 return false;
90 virtual bool GetCharset(JNIEnv* env,
91 net::URLRequest* request,
92 android_webview::InputStream* stream,
93 std::string* charset) OVERRIDE {
94 return false;
98 class NullStreamReaderDelegate : public StreamReaderDelegate {
99 public:
100 NullStreamReaderDelegate() {}
102 virtual scoped_ptr<InputStream> OpenInputStream(
103 JNIEnv* env,
104 const GURL& url) OVERRIDE {
105 return make_scoped_ptr<InputStream>(NULL);
109 class MockInputStreamReader : public InputStreamReader {
110 public:
111 MockInputStreamReader() : InputStreamReader(new NotImplInputStream()) {}
112 ~MockInputStreamReader() {}
114 MOCK_METHOD1(Seek, int(const net::HttpByteRange& byte_range));
115 MOCK_METHOD2(ReadRawData, int(net::IOBuffer* buffer, int buffer_size));
119 class TestStreamReaderJob : public AndroidStreamReaderURLRequestJob {
120 public:
121 TestStreamReaderJob(
122 net::URLRequest* request,
123 net::NetworkDelegate* network_delegate,
124 scoped_ptr<Delegate> delegate,
125 scoped_ptr<InputStreamReader> stream_reader)
126 : AndroidStreamReaderURLRequestJob(request,
127 network_delegate,
128 delegate.Pass()),
129 stream_reader_(stream_reader.Pass()) {
130 message_loop_proxy_ = base::MessageLoopProxy::current();
133 virtual scoped_ptr<InputStreamReader> CreateStreamReader(
134 InputStream* stream) OVERRIDE {
135 return stream_reader_.Pass();
137 protected:
138 virtual ~TestStreamReaderJob() {}
140 virtual base::TaskRunner* GetWorkerThreadRunner() OVERRIDE {
141 return message_loop_proxy_.get();
144 scoped_ptr<InputStreamReader> stream_reader_;
145 scoped_refptr<base::MessageLoopProxy> message_loop_proxy_;
148 class AndroidStreamReaderURLRequestJobTest : public Test {
149 public:
150 AndroidStreamReaderURLRequestJobTest() {}
152 protected:
153 virtual void SetUp() {
154 context_.set_job_factory(&factory_);
155 context_.set_network_delegate(&network_delegate_);
156 req_.reset(new TestURLRequest(GURL("content://foo"),
157 net::DEFAULT_PRIORITY,
158 &url_request_delegate_,
159 &context_));
160 req_->set_method("GET");
163 void SetRange(net::URLRequest* req, int first_byte, int last_byte) {
164 net::HttpRequestHeaders headers;
165 headers.SetHeader(net::HttpRequestHeaders::kRange,
166 net::HttpByteRange::Bounded(
167 first_byte, last_byte).GetHeaderValue());
168 req->SetExtraRequestHeaders(headers);
171 void SetUpTestJob(scoped_ptr<InputStreamReader> stream_reader) {
172 SetUpTestJob(stream_reader.Pass(),
173 make_scoped_ptr(new StreamReaderDelegate())
174 .PassAs<AndroidStreamReaderURLRequestJob::Delegate>());
177 void SetUpTestJob(scoped_ptr<InputStreamReader> stream_reader,
178 scoped_ptr<AndroidStreamReaderURLRequestJob::Delegate>
179 stream_reader_delegate) {
180 TestStreamReaderJob* test_stream_reader_job =
181 new TestStreamReaderJob(
182 req_.get(),
183 &network_delegate_,
184 stream_reader_delegate.Pass(),
185 stream_reader.Pass());
186 // The Interceptor is owned by the |factory_|.
187 TestJobInterceptor* protocol_handler = new TestJobInterceptor;
188 protocol_handler->set_main_intercept_job(test_stream_reader_job);
189 bool set_protocol = factory_.SetProtocolHandler("http", protocol_handler);
190 DCHECK(set_protocol);
192 protocol_handler = new TestJobInterceptor;
193 protocol_handler->set_main_intercept_job(test_stream_reader_job);
194 set_protocol = factory_.SetProtocolHandler("content", protocol_handler);
195 DCHECK(set_protocol);
198 base::MessageLoopForIO loop_;
199 TestURLRequestContext context_;
200 android_webview::AwURLRequestJobFactory factory_;
201 TestDelegate url_request_delegate_;
202 TestNetworkDelegate network_delegate_;
203 scoped_ptr<TestURLRequest> req_;
206 TEST_F(AndroidStreamReaderURLRequestJobTest, ReadEmptyStream) {
207 scoped_ptr<StrictMock<MockInputStreamReader> > stream_reader(
208 new StrictMock<MockInputStreamReader>());
210 InSequence s;
211 EXPECT_CALL(*stream_reader, Seek(_))
212 .WillOnce(Return(0));
213 EXPECT_CALL(*stream_reader, ReadRawData(NotNull(), Gt(0)))
214 .WillOnce(Return(0));
217 SetUpTestJob(stream_reader.PassAs<InputStreamReader>());
219 req_->Start();
221 // The TestDelegate will quit the message loop on request completion.
222 base::MessageLoop::current()->Run();
224 EXPECT_FALSE(url_request_delegate_.request_failed());
225 EXPECT_EQ(1, network_delegate_.completed_requests());
226 EXPECT_EQ(0, network_delegate_.error_count());
227 EXPECT_EQ(200, req_->GetResponseCode());
230 TEST_F(AndroidStreamReaderURLRequestJobTest, ReadWithNullStream) {
231 SetUpTestJob(scoped_ptr<InputStreamReader>(),
232 make_scoped_ptr(new NullStreamReaderDelegate())
233 .PassAs<AndroidStreamReaderURLRequestJob::Delegate>());
234 req_->Start();
236 // The TestDelegate will quit the message loop on request completion.
237 base::MessageLoop::current()->Run();
239 // The request_failed() method is named confusingly but all it checks is
240 // whether the request got as far as calling NotifyHeadersComplete.
241 EXPECT_FALSE(url_request_delegate_.request_failed());
242 EXPECT_EQ(1, network_delegate_.completed_requests());
243 // A null input stream shouldn't result in an error. See crbug.com/180950.
244 EXPECT_EQ(0, network_delegate_.error_count());
245 EXPECT_EQ(404, req_->GetResponseCode());
248 TEST_F(AndroidStreamReaderURLRequestJobTest, ReadPartOfStream) {
249 const int bytes_available = 128;
250 const int offset = 32;
251 const int bytes_to_read = bytes_available - offset;
252 scoped_ptr<StrictMock<MockInputStreamReader> > stream_reader(
253 new StrictMock<MockInputStreamReader>());
255 InSequence s;
256 EXPECT_CALL(*stream_reader, Seek(_))
257 .WillOnce(Return(bytes_available));
258 EXPECT_CALL(*stream_reader, ReadRawData(NotNull(), Ge(bytes_to_read)))
259 .WillOnce(Return(bytes_to_read/2));
260 EXPECT_CALL(*stream_reader, ReadRawData(NotNull(), Ge(bytes_to_read)))
261 .WillOnce(Return(bytes_to_read/2));
262 EXPECT_CALL(*stream_reader, ReadRawData(NotNull(), Ge(bytes_to_read)))
263 .WillOnce(Return(0));
266 SetUpTestJob(stream_reader.PassAs<InputStreamReader>());
268 SetRange(req_.get(), offset, bytes_available);
269 req_->Start();
271 base::MessageLoop::current()->Run();
273 EXPECT_FALSE(url_request_delegate_.request_failed());
274 EXPECT_EQ(bytes_to_read, url_request_delegate_.bytes_received());
275 EXPECT_EQ(1, network_delegate_.completed_requests());
276 EXPECT_EQ(0, network_delegate_.error_count());
279 TEST_F(AndroidStreamReaderURLRequestJobTest,
280 ReadStreamWithMoreAvailableThanActual) {
281 const int bytes_available_reported = 190;
282 const int bytes_available = 128;
283 const int offset = 0;
284 const int bytes_to_read = bytes_available - offset;
285 scoped_ptr<StrictMock<MockInputStreamReader> > stream_reader(
286 new StrictMock<MockInputStreamReader>());
288 InSequence s;
289 EXPECT_CALL(*stream_reader, Seek(_))
290 .WillOnce(Return(bytes_available_reported));
291 EXPECT_CALL(*stream_reader, ReadRawData(NotNull(), Ge(bytes_to_read)))
292 .WillOnce(Return(bytes_available));
293 EXPECT_CALL(*stream_reader, ReadRawData(NotNull(), Ge(bytes_to_read)))
294 .WillOnce(Return(0));
297 SetUpTestJob(stream_reader.PassAs<InputStreamReader>());
299 SetRange(req_.get(), offset, bytes_available_reported);
300 req_->Start();
302 base::MessageLoop::current()->Run();
304 EXPECT_FALSE(url_request_delegate_.request_failed());
305 EXPECT_EQ(bytes_to_read, url_request_delegate_.bytes_received());
306 EXPECT_EQ(1, network_delegate_.completed_requests());
307 EXPECT_EQ(0, network_delegate_.error_count());
310 TEST_F(AndroidStreamReaderURLRequestJobTest, DeleteJobMidWaySeek) {
311 const int offset = 20;
312 const int bytes_available = 128;
313 base::RunLoop loop;
314 scoped_ptr<StrictMock<MockInputStreamReader> > stream_reader(
315 new StrictMock<MockInputStreamReader>());
316 EXPECT_CALL(*stream_reader, Seek(_))
317 .WillOnce(DoAll(InvokeWithoutArgs(&loop, &base::RunLoop::Quit),
318 Return(bytes_available)));
319 ON_CALL(*stream_reader, ReadRawData(_, _))
320 .WillByDefault(Return(0));
322 SetUpTestJob(stream_reader.PassAs<InputStreamReader>());
324 SetRange(req_.get(), offset, bytes_available);
325 req_->Start();
327 loop.Run();
329 EXPECT_EQ(0, network_delegate_.completed_requests());
330 req_->Cancel();
331 EXPECT_EQ(1, network_delegate_.completed_requests());
334 TEST_F(AndroidStreamReaderURLRequestJobTest, DeleteJobMidWayRead) {
335 const int offset = 20;
336 const int bytes_available = 128;
337 base::RunLoop loop;
338 scoped_ptr<StrictMock<MockInputStreamReader> > stream_reader(
339 new StrictMock<MockInputStreamReader>());
340 net::CompletionCallback read_completion_callback;
341 EXPECT_CALL(*stream_reader, Seek(_))
342 .WillOnce(Return(bytes_available));
343 EXPECT_CALL(*stream_reader, ReadRawData(_, _))
344 .WillOnce(DoAll(InvokeWithoutArgs(&loop, &base::RunLoop::Quit),
345 Return(bytes_available)));
347 SetUpTestJob(stream_reader.PassAs<InputStreamReader>());
349 SetRange(req_.get(), offset, bytes_available);
350 req_->Start();
352 loop.Run();
354 EXPECT_EQ(0, network_delegate_.completed_requests());
355 req_->Cancel();
356 EXPECT_EQ(1, network_delegate_.completed_requests());