12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "android_webview/browser/input_stream.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "android_webview/browser/net/android_stream_reader_url_request_job.h" 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "android_webview/browser/net/aw_url_request_job_factory.h" 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "android_webview/browser/net/input_stream_reader.h" 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/format_macros.h" 101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/memory/scoped_ptr.h" 117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/message_loop/message_loop.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/run_loop.h" 13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h" 140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "net/base/request_priority.h" 15f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "net/http/http_byte_range.h" 166d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "net/http/http_response_headers.h" 171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "net/url_request/url_request.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/url_request/url_request_job_factory_impl.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/url_request/url_request_test_util.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h" 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using android_webview::InputStream; 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using android_webview::InputStreamReader; 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using net::TestDelegate; 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using net::TestJobInterceptor; 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using net::TestNetworkDelegate; 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using net::TestURLRequestContext; 301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing net::URLRequest; 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::DoAll; 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::Ge; 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::Gt; 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::InSequence; 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::Invoke; 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::InvokeWithoutArgs; 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::NotNull; 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::Return; 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::SaveArg; 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::SetArgPointee; 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::StrictMock; 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::Test; 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::WithArg; 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::WithArgs; 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::_; 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Some of the classes will DCHECK on a null InputStream (which is desirable). 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The workaround is to use this class. None of the methods need to be 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// implemented as the mock InputStreamReader should never forward calls to the 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// InputStream. 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class NotImplInputStream : public InputStream { 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NotImplInputStream() {} 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~NotImplInputStream() {} 55a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) virtual bool BytesAvailable(int* bytes_available) const OVERRIDE { 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOTIMPLEMENTED(); 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 59a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) virtual bool Skip(int64_t n, int64_t* bytes_skipped) OVERRIDE { 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOTIMPLEMENTED(); 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 63a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) virtual bool Read(net::IOBuffer* dest, int length, int* bytes_read) OVERRIDE { 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOTIMPLEMENTED(); 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Required in order to create an instance of AndroidStreamReaderURLRequestJob. 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class StreamReaderDelegate : 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public AndroidStreamReaderURLRequestJob::Delegate { 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StreamReaderDelegate() {} 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual scoped_ptr<InputStream> OpenInputStream( 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) JNIEnv* env, 77a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) const GURL& url) OVERRIDE { 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return make_scoped_ptr<InputStream>(new NotImplInputStream()); 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnInputStreamOpenFailed(net::URLRequest* request, 82a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) bool* restart) OVERRIDE { 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *restart = false; 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 86a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) virtual bool GetMimeType(JNIEnv* env, 87a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) net::URLRequest* request, 88a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) android_webview::InputStream* stream, 89a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) std::string* mime_type) OVERRIDE { 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 93a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) virtual bool GetCharset(JNIEnv* env, 94a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) net::URLRequest* request, 95a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) android_webview::InputStream* stream, 96a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) std::string* charset) OVERRIDE { 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 996d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 1006d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) virtual void AppendResponseHeaders( 1016d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) JNIEnv* env, 1026d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) net::HttpResponseHeaders* headers) OVERRIDE { 1036d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // no-op 1046d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) } 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class NullStreamReaderDelegate : public StreamReaderDelegate { 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NullStreamReaderDelegate() {} 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual scoped_ptr<InputStream> OpenInputStream( 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) JNIEnv* env, 113a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) const GURL& url) OVERRIDE { 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return make_scoped_ptr<InputStream>(NULL); 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1186d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)class HeaderAlteringStreamReaderDelegate : public NullStreamReaderDelegate { 1196d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) public: 1206d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) HeaderAlteringStreamReaderDelegate() {} 1216d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 1226d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) virtual void AppendResponseHeaders( 1236d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) JNIEnv* env, 1246d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) net::HttpResponseHeaders* headers) OVERRIDE { 1256d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) headers->ReplaceStatusLine(kStatusLine); 1266d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) std::string headerLine(kCustomHeaderName); 1276d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) headerLine.append(": "); 1286d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) headerLine.append(kCustomHeaderValue); 1296d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) headers->AddHeader(headerLine); 1306d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) } 1316d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 1326d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) static const int kResponseCode; 1336d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) static const char* kStatusLine; 1346d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) static const char* kCustomHeaderName; 1356d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) static const char* kCustomHeaderValue; 1366d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)}; 1376d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 1386d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)const int HeaderAlteringStreamReaderDelegate::kResponseCode = 401; 1396d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)const char* HeaderAlteringStreamReaderDelegate::kStatusLine = 1406d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) "HTTP/1.1 401 Gone"; 1416d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)const char* HeaderAlteringStreamReaderDelegate::kCustomHeaderName = 1426d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) "X-Test-Header"; 1436d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)const char* HeaderAlteringStreamReaderDelegate::kCustomHeaderValue = 1446d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) "TestHeaderValue"; 1456d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class MockInputStreamReader : public InputStreamReader { 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockInputStreamReader() : InputStreamReader(new NotImplInputStream()) {} 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ~MockInputStreamReader() {} 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MOCK_METHOD1(Seek, int(const net::HttpByteRange& byte_range)); 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MOCK_METHOD2(ReadRawData, int(net::IOBuffer* buffer, int buffer_size)); 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class TestStreamReaderJob : public AndroidStreamReaderURLRequestJob { 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestStreamReaderJob( 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net::URLRequest* request, 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net::NetworkDelegate* network_delegate, 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<Delegate> delegate, 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<InputStreamReader> stream_reader) 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : AndroidStreamReaderURLRequestJob(request, 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) network_delegate, 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delegate.Pass()), 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) stream_reader_(stream_reader.Pass()) { 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) message_loop_proxy_ = base::MessageLoopProxy::current(); 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual scoped_ptr<InputStreamReader> CreateStreamReader( 171a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) InputStream* stream) OVERRIDE { 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return stream_reader_.Pass(); 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected: 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~TestStreamReaderJob() {} 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 177a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) virtual base::TaskRunner* GetWorkerThreadRunner() OVERRIDE { 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return message_loop_proxy_.get(); 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<InputStreamReader> stream_reader_; 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<base::MessageLoopProxy> message_loop_proxy_; 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class AndroidStreamReaderURLRequestJobTest : public Test { 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AndroidStreamReaderURLRequestJobTest() {} 188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected: 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void SetUp() { 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) context_.set_job_factory(&factory_); 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) context_.set_network_delegate(&network_delegate_); 1931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci req_ = context_.CreateRequest(GURL("content://foo"), 1940f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) net::DEFAULT_PRIORITY, 1950f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) &url_request_delegate_, 1961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NULL); 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) req_->set_method("GET"); 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void SetRange(net::URLRequest* req, int first_byte, int last_byte) { 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net::HttpRequestHeaders headers; 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) headers.SetHeader(net::HttpRequestHeaders::kRange, 203f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) net::HttpByteRange::Bounded( 204f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) first_byte, last_byte).GetHeaderValue()); 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) req->SetExtraRequestHeaders(headers); 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void SetUpTestJob(scoped_ptr<InputStreamReader> stream_reader) { 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetUpTestJob(stream_reader.Pass(), 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) make_scoped_ptr(new StreamReaderDelegate()) 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .PassAs<AndroidStreamReaderURLRequestJob::Delegate>()); 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void SetUpTestJob(scoped_ptr<InputStreamReader> stream_reader, 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<AndroidStreamReaderURLRequestJob::Delegate> 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) stream_reader_delegate) { 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestStreamReaderJob* test_stream_reader_job = 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new TestStreamReaderJob( 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) req_.get(), 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &network_delegate_, 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) stream_reader_delegate.Pass(), 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) stream_reader.Pass()); 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The Interceptor is owned by the |factory_|. 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestJobInterceptor* protocol_handler = new TestJobInterceptor; 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protocol_handler->set_main_intercept_job(test_stream_reader_job); 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool set_protocol = factory_.SetProtocolHandler("http", protocol_handler); 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(set_protocol); 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protocol_handler = new TestJobInterceptor; 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protocol_handler->set_main_intercept_job(test_stream_reader_job); 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) set_protocol = factory_.SetProtocolHandler("content", protocol_handler); 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(set_protocol); 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::MessageLoopForIO loop_; 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestURLRequestContext context_; 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) android_webview::AwURLRequestJobFactory factory_; 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestDelegate url_request_delegate_; 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestNetworkDelegate network_delegate_; 2401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<URLRequest> req_; 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(AndroidStreamReaderURLRequestJobTest, ReadEmptyStream) { 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<StrictMock<MockInputStreamReader> > stream_reader( 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new StrictMock<MockInputStreamReader>()); 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) InSequence s; 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_CALL(*stream_reader, Seek(_)) 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .WillOnce(Return(0)); 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_CALL(*stream_reader, ReadRawData(NotNull(), Gt(0))) 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .WillOnce(Return(0)); 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetUpTestJob(stream_reader.PassAs<InputStreamReader>()); 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) req_->Start(); 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The TestDelegate will quit the message loop on request completion. 259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoop::current()->Run(); 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(url_request_delegate_.request_failed()); 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(1, network_delegate_.completed_requests()); 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0, network_delegate_.error_count()); 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(200, req_->GetResponseCode()); 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(AndroidStreamReaderURLRequestJobTest, ReadWithNullStream) { 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetUpTestJob(scoped_ptr<InputStreamReader>(), 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) make_scoped_ptr(new NullStreamReaderDelegate()) 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .PassAs<AndroidStreamReaderURLRequestJob::Delegate>()); 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) req_->Start(); 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The TestDelegate will quit the message loop on request completion. 274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoop::current()->Run(); 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The request_failed() method is named confusingly but all it checks is 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // whether the request got as far as calling NotifyHeadersComplete. 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(url_request_delegate_.request_failed()); 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(1, network_delegate_.completed_requests()); 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // A null input stream shouldn't result in an error. See crbug.com/180950. 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0, network_delegate_.error_count()); 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(404, req_->GetResponseCode()); 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2856d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_F(AndroidStreamReaderURLRequestJobTest, ModifyHeadersAndStatus) { 2866d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) SetUpTestJob(scoped_ptr<InputStreamReader>(), 2876d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) make_scoped_ptr(new HeaderAlteringStreamReaderDelegate()) 2886d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) .PassAs<AndroidStreamReaderURLRequestJob::Delegate>()); 2896d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) req_->Start(); 2906d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 2916d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // The TestDelegate will quit the message loop on request completion. 2926d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) base::MessageLoop::current()->Run(); 2936d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 2946d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // The request_failed() method is named confusingly but all it checks is 2956d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // whether the request got as far as calling NotifyHeadersComplete. 2966d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) EXPECT_FALSE(url_request_delegate_.request_failed()); 2976d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) EXPECT_EQ(1, network_delegate_.completed_requests()); 2986d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // A null input stream shouldn't result in an error. See crbug.com/180950. 2996d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) EXPECT_EQ(0, network_delegate_.error_count()); 3006d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) EXPECT_EQ(HeaderAlteringStreamReaderDelegate::kResponseCode, 3016d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) req_->GetResponseCode()); 3026d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) EXPECT_EQ(HeaderAlteringStreamReaderDelegate::kStatusLine, 3036d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) req_->response_headers()->GetStatusLine()); 3046d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) EXPECT_TRUE(req_->response_headers()->HasHeader( 3056d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) HeaderAlteringStreamReaderDelegate::kCustomHeaderName)); 3066d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) std::string header_value; 3076d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) EXPECT_TRUE(req_->response_headers()->EnumerateHeader( 3086d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) NULL, HeaderAlteringStreamReaderDelegate::kCustomHeaderName, 3096d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) &header_value)); 3106d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) EXPECT_EQ(HeaderAlteringStreamReaderDelegate::kCustomHeaderValue, 3116d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) header_value); 3126d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)} 3136d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(AndroidStreamReaderURLRequestJobTest, ReadPartOfStream) { 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int bytes_available = 128; 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int offset = 32; 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int bytes_to_read = bytes_available - offset; 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<StrictMock<MockInputStreamReader> > stream_reader( 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new StrictMock<MockInputStreamReader>()); 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) InSequence s; 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_CALL(*stream_reader, Seek(_)) 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .WillOnce(Return(bytes_available)); 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_CALL(*stream_reader, ReadRawData(NotNull(), Ge(bytes_to_read))) 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .WillOnce(Return(bytes_to_read/2)); 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_CALL(*stream_reader, ReadRawData(NotNull(), Ge(bytes_to_read))) 3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .WillOnce(Return(bytes_to_read/2)); 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_CALL(*stream_reader, ReadRawData(NotNull(), Ge(bytes_to_read))) 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .WillOnce(Return(0)); 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetUpTestJob(stream_reader.PassAs<InputStreamReader>()); 3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetRange(req_.get(), offset, bytes_available); 3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) req_->Start(); 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoop::current()->Run(); 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(url_request_delegate_.request_failed()); 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(bytes_to_read, url_request_delegate_.bytes_received()); 3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(1, network_delegate_.completed_requests()); 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0, network_delegate_.error_count()); 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(AndroidStreamReaderURLRequestJobTest, 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ReadStreamWithMoreAvailableThanActual) { 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int bytes_available_reported = 190; 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int bytes_available = 128; 3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int offset = 0; 3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int bytes_to_read = bytes_available - offset; 3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<StrictMock<MockInputStreamReader> > stream_reader( 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new StrictMock<MockInputStreamReader>()); 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) InSequence s; 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_CALL(*stream_reader, Seek(_)) 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .WillOnce(Return(bytes_available_reported)); 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_CALL(*stream_reader, ReadRawData(NotNull(), Ge(bytes_to_read))) 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .WillOnce(Return(bytes_available)); 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_CALL(*stream_reader, ReadRawData(NotNull(), Ge(bytes_to_read))) 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .WillOnce(Return(0)); 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetUpTestJob(stream_reader.PassAs<InputStreamReader>()); 3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetRange(req_.get(), offset, bytes_available_reported); 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) req_->Start(); 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoop::current()->Run(); 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(url_request_delegate_.request_failed()); 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(bytes_to_read, url_request_delegate_.bytes_received()); 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(1, network_delegate_.completed_requests()); 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0, network_delegate_.error_count()); 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(AndroidStreamReaderURLRequestJobTest, DeleteJobMidWaySeek) { 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int offset = 20; 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int bytes_available = 128; 3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::RunLoop loop; 3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<StrictMock<MockInputStreamReader> > stream_reader( 3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new StrictMock<MockInputStreamReader>()); 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_CALL(*stream_reader, Seek(_)) 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .WillOnce(DoAll(InvokeWithoutArgs(&loop, &base::RunLoop::Quit), 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Return(bytes_available))); 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ON_CALL(*stream_reader, ReadRawData(_, _)) 3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .WillByDefault(Return(0)); 3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetUpTestJob(stream_reader.PassAs<InputStreamReader>()); 3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetRange(req_.get(), offset, bytes_available); 3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) req_->Start(); 3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) loop.Run(); 3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0, network_delegate_.completed_requests()); 3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) req_->Cancel(); 3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(1, network_delegate_.completed_requests()); 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(AndroidStreamReaderURLRequestJobTest, DeleteJobMidWayRead) { 4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int offset = 20; 4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int bytes_available = 128; 4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::RunLoop loop; 4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<StrictMock<MockInputStreamReader> > stream_reader( 4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new StrictMock<MockInputStreamReader>()); 4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net::CompletionCallback read_completion_callback; 4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_CALL(*stream_reader, Seek(_)) 4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .WillOnce(Return(bytes_available)); 4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_CALL(*stream_reader, ReadRawData(_, _)) 4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .WillOnce(DoAll(InvokeWithoutArgs(&loop, &base::RunLoop::Quit), 4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Return(bytes_available))); 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetUpTestJob(stream_reader.PassAs<InputStreamReader>()); 4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetRange(req_.get(), offset, bytes_available); 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) req_->Start(); 4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) loop.Run(); 4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0, network_delegate_.completed_requests()); 4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) req_->Cancel(); 4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(1, network_delegate_.completed_requests()); 4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 424