This source file includes following definitions.
- BytesAvailable
 
- Skip
 
- Read
 
- OpenInputStream
 
- OnInputStreamOpenFailed
 
- GetMimeType
 
- GetCharset
 
- OpenInputStream
 
- stream_reader_
 
- CreateStreamReader
 
- GetWorkerThreadRunner
 
- SetUp
 
- SetRange
 
- SetUpTestJob
 
- SetUpTestJob
 
- TEST_F
 
- TEST_F
 
- TEST_F
 
- TEST_F
 
- TEST_F
 
- TEST_F
 
#include "android_webview/browser/input_stream.h"
#include "android_webview/browser/net/android_stream_reader_url_request_job.h"
#include "android_webview/browser/net/aw_url_request_job_factory.h"
#include "android_webview/browser/net/input_stream_reader.h"
#include "base/format_macros.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "net/base/request_priority.h"
#include "net/http/http_byte_range.h"
#include "net/url_request/url_request_job_factory_impl.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
using android_webview::InputStream;
using android_webview::InputStreamReader;
using net::TestDelegate;
using net::TestJobInterceptor;
using net::TestNetworkDelegate;
using net::TestURLRequestContext;
using net::TestURLRequest;
using testing::DoAll;
using testing::Ge;
using testing::Gt;
using testing::InSequence;
using testing::Invoke;
using testing::InvokeWithoutArgs;
using testing::NotNull;
using testing::Return;
using testing::SaveArg;
using testing::SetArgPointee;
using testing::StrictMock;
using testing::Test;
using testing::WithArg;
using testing::WithArgs;
using testing::_;
class NotImplInputStream : public InputStream {
 public:
  NotImplInputStream() {}
  virtual ~NotImplInputStream() {}
  virtual bool BytesAvailable(int* bytes_available) const OVERRIDE {
    NOTIMPLEMENTED();
    return false;
  }
  virtual bool Skip(int64_t n, int64_t* bytes_skipped) OVERRIDE {
    NOTIMPLEMENTED();
    return false;
  }
  virtual bool Read(net::IOBuffer* dest, int length, int* bytes_read) OVERRIDE {
    NOTIMPLEMENTED();
    return false;
  }
};
class StreamReaderDelegate :
    public AndroidStreamReaderURLRequestJob::Delegate {
 public:
  StreamReaderDelegate() {}
  virtual scoped_ptr<InputStream> OpenInputStream(
      JNIEnv* env,
      const GURL& url) OVERRIDE {
    return make_scoped_ptr<InputStream>(new NotImplInputStream());
  }
  virtual void OnInputStreamOpenFailed(net::URLRequest* request,
                                       bool* restart) OVERRIDE {
    *restart = false;
  }
  virtual bool GetMimeType(JNIEnv* env,
                           net::URLRequest* request,
                           android_webview::InputStream* stream,
                           std::string* mime_type) OVERRIDE {
    return false;
  }
  virtual bool GetCharset(JNIEnv* env,
                          net::URLRequest* request,
                          android_webview::InputStream* stream,
                          std::string* charset) OVERRIDE {
    return false;
  }
};
class NullStreamReaderDelegate : public StreamReaderDelegate {
 public:
  NullStreamReaderDelegate() {}
  virtual scoped_ptr<InputStream> OpenInputStream(
      JNIEnv* env,
      const GURL& url) OVERRIDE {
    return make_scoped_ptr<InputStream>(NULL);
  }
};
class MockInputStreamReader : public InputStreamReader {
 public:
  MockInputStreamReader() : InputStreamReader(new NotImplInputStream()) {}
  ~MockInputStreamReader() {}
  MOCK_METHOD1(Seek, int(const net::HttpByteRange& byte_range));
  MOCK_METHOD2(ReadRawData, int(net::IOBuffer* buffer, int buffer_size));
};
class TestStreamReaderJob : public AndroidStreamReaderURLRequestJob {
 public:
  TestStreamReaderJob(
      net::URLRequest* request,
      net::NetworkDelegate* network_delegate,
      scoped_ptr<Delegate> delegate,
      scoped_ptr<InputStreamReader> stream_reader)
      : AndroidStreamReaderURLRequestJob(request,
                                         network_delegate,
                                         delegate.Pass()),
        stream_reader_(stream_reader.Pass()) {
    message_loop_proxy_ = base::MessageLoopProxy::current();
  }
  virtual scoped_ptr<InputStreamReader> CreateStreamReader(
      InputStream* stream) OVERRIDE {
    return stream_reader_.Pass();
  }
 protected:
  virtual ~TestStreamReaderJob() {}
  virtual base::TaskRunner* GetWorkerThreadRunner() OVERRIDE {
    return message_loop_proxy_.get();
  }
  scoped_ptr<InputStreamReader> stream_reader_;
  scoped_refptr<base::MessageLoopProxy> message_loop_proxy_;
};
class AndroidStreamReaderURLRequestJobTest : public Test {
 public:
  AndroidStreamReaderURLRequestJobTest() {}
 protected:
  virtual void SetUp() {
    context_.set_job_factory(&factory_);
    context_.set_network_delegate(&network_delegate_);
    req_.reset(new TestURLRequest(GURL("content://foo"),
                                  net::DEFAULT_PRIORITY,
                                  &url_request_delegate_,
                                  &context_));
    req_->set_method("GET");
  }
  void SetRange(net::URLRequest* req, int first_byte, int last_byte) {
    net::HttpRequestHeaders headers;
    headers.SetHeader(net::HttpRequestHeaders::kRange,
                      net::HttpByteRange::Bounded(
                          first_byte, last_byte).GetHeaderValue());
    req->SetExtraRequestHeaders(headers);
  }
  void SetUpTestJob(scoped_ptr<InputStreamReader> stream_reader) {
    SetUpTestJob(stream_reader.Pass(),
                 make_scoped_ptr(new StreamReaderDelegate())
                     .PassAs<AndroidStreamReaderURLRequestJob::Delegate>());
  }
  void SetUpTestJob(scoped_ptr<InputStreamReader> stream_reader,
                    scoped_ptr<AndroidStreamReaderURLRequestJob::Delegate>
                        stream_reader_delegate) {
    TestStreamReaderJob* test_stream_reader_job =
        new TestStreamReaderJob(
            req_.get(),
            &network_delegate_,
            stream_reader_delegate.Pass(),
            stream_reader.Pass());
    
    TestJobInterceptor* protocol_handler = new TestJobInterceptor;
    protocol_handler->set_main_intercept_job(test_stream_reader_job);
    bool set_protocol = factory_.SetProtocolHandler("http", protocol_handler);
    DCHECK(set_protocol);
    protocol_handler = new TestJobInterceptor;
    protocol_handler->set_main_intercept_job(test_stream_reader_job);
    set_protocol = factory_.SetProtocolHandler("content", protocol_handler);
    DCHECK(set_protocol);
  }
  base::MessageLoopForIO loop_;
  TestURLRequestContext context_;
  android_webview::AwURLRequestJobFactory factory_;
  TestDelegate url_request_delegate_;
  TestNetworkDelegate network_delegate_;
  scoped_ptr<TestURLRequest> req_;
};
TEST_F(AndroidStreamReaderURLRequestJobTest, ReadEmptyStream) {
  scoped_ptr<StrictMock<MockInputStreamReader> > stream_reader(
      new StrictMock<MockInputStreamReader>());
  {
    InSequence s;
    EXPECT_CALL(*stream_reader, Seek(_))
        .WillOnce(Return(0));
    EXPECT_CALL(*stream_reader, ReadRawData(NotNull(), Gt(0)))
        .WillOnce(Return(0));
  }
  SetUpTestJob(stream_reader.PassAs<InputStreamReader>());
  req_->Start();
  
  base::MessageLoop::current()->Run();
  EXPECT_FALSE(url_request_delegate_.request_failed());
  EXPECT_EQ(1, network_delegate_.completed_requests());
  EXPECT_EQ(0, network_delegate_.error_count());
  EXPECT_EQ(200, req_->GetResponseCode());
}
TEST_F(AndroidStreamReaderURLRequestJobTest, ReadWithNullStream) {
  SetUpTestJob(scoped_ptr<InputStreamReader>(),
               make_scoped_ptr(new NullStreamReaderDelegate())
                   .PassAs<AndroidStreamReaderURLRequestJob::Delegate>());
  req_->Start();
  
  base::MessageLoop::current()->Run();
  
  
  EXPECT_FALSE(url_request_delegate_.request_failed());
  EXPECT_EQ(1, network_delegate_.completed_requests());
  
  EXPECT_EQ(0, network_delegate_.error_count());
  EXPECT_EQ(404, req_->GetResponseCode());
}
TEST_F(AndroidStreamReaderURLRequestJobTest, ReadPartOfStream) {
  const int bytes_available = 128;
  const int offset = 32;
  const int bytes_to_read = bytes_available - offset;
  scoped_ptr<StrictMock<MockInputStreamReader> > stream_reader(
      new StrictMock<MockInputStreamReader>());
  {
    InSequence s;
    EXPECT_CALL(*stream_reader, Seek(_))
        .WillOnce(Return(bytes_available));
    EXPECT_CALL(*stream_reader, ReadRawData(NotNull(), Ge(bytes_to_read)))
        .WillOnce(Return(bytes_to_read/2));
    EXPECT_CALL(*stream_reader, ReadRawData(NotNull(), Ge(bytes_to_read)))
        .WillOnce(Return(bytes_to_read/2));
    EXPECT_CALL(*stream_reader, ReadRawData(NotNull(), Ge(bytes_to_read)))
        .WillOnce(Return(0));
  }
  SetUpTestJob(stream_reader.PassAs<InputStreamReader>());
  SetRange(req_.get(), offset, bytes_available);
  req_->Start();
  base::MessageLoop::current()->Run();
  EXPECT_FALSE(url_request_delegate_.request_failed());
  EXPECT_EQ(bytes_to_read, url_request_delegate_.bytes_received());
  EXPECT_EQ(1, network_delegate_.completed_requests());
  EXPECT_EQ(0, network_delegate_.error_count());
}
TEST_F(AndroidStreamReaderURLRequestJobTest,
       ReadStreamWithMoreAvailableThanActual) {
  const int bytes_available_reported = 190;
  const int bytes_available = 128;
  const int offset = 0;
  const int bytes_to_read = bytes_available - offset;
  scoped_ptr<StrictMock<MockInputStreamReader> > stream_reader(
      new StrictMock<MockInputStreamReader>());
  {
    InSequence s;
    EXPECT_CALL(*stream_reader, Seek(_))
        .WillOnce(Return(bytes_available_reported));
    EXPECT_CALL(*stream_reader, ReadRawData(NotNull(), Ge(bytes_to_read)))
        .WillOnce(Return(bytes_available));
    EXPECT_CALL(*stream_reader, ReadRawData(NotNull(), Ge(bytes_to_read)))
        .WillOnce(Return(0));
  }
  SetUpTestJob(stream_reader.PassAs<InputStreamReader>());
  SetRange(req_.get(), offset, bytes_available_reported);
  req_->Start();
  base::MessageLoop::current()->Run();
  EXPECT_FALSE(url_request_delegate_.request_failed());
  EXPECT_EQ(bytes_to_read, url_request_delegate_.bytes_received());
  EXPECT_EQ(1, network_delegate_.completed_requests());
  EXPECT_EQ(0, network_delegate_.error_count());
}
TEST_F(AndroidStreamReaderURLRequestJobTest, DeleteJobMidWaySeek) {
  const int offset = 20;
  const int bytes_available = 128;
  base::RunLoop loop;
  scoped_ptr<StrictMock<MockInputStreamReader> > stream_reader(
      new StrictMock<MockInputStreamReader>());
  EXPECT_CALL(*stream_reader, Seek(_))
      .WillOnce(DoAll(InvokeWithoutArgs(&loop, &base::RunLoop::Quit),
                      Return(bytes_available)));
  ON_CALL(*stream_reader, ReadRawData(_, _))
      .WillByDefault(Return(0));
  SetUpTestJob(stream_reader.PassAs<InputStreamReader>());
  SetRange(req_.get(), offset, bytes_available);
  req_->Start();
  loop.Run();
  EXPECT_EQ(0, network_delegate_.completed_requests());
  req_->Cancel();
  EXPECT_EQ(1, network_delegate_.completed_requests());
}
TEST_F(AndroidStreamReaderURLRequestJobTest, DeleteJobMidWayRead) {
  const int offset = 20;
  const int bytes_available = 128;
  base::RunLoop loop;
  scoped_ptr<StrictMock<MockInputStreamReader> > stream_reader(
      new StrictMock<MockInputStreamReader>());
  net::CompletionCallback read_completion_callback;
  EXPECT_CALL(*stream_reader, Seek(_))
      .WillOnce(Return(bytes_available));
  EXPECT_CALL(*stream_reader, ReadRawData(_, _))
      .WillOnce(DoAll(InvokeWithoutArgs(&loop, &base::RunLoop::Quit),
                      Return(bytes_available)));
  SetUpTestJob(stream_reader.PassAs<InputStreamReader>());
  SetRange(req_.get(), offset, bytes_available);
  req_->Start();
  loop.Run();
  EXPECT_EQ(0, network_delegate_.completed_requests());
  req_->Cancel();
  EXPECT_EQ(1, network_delegate_.completed_requests());
}