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