1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file.
4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/drive/drive_file_stream_reader.h"
6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <string>
8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/bind.h"
10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/files/file_path.h"
11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/files/scoped_temp_dir.h"
12eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/run_loop.h"
13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/threading/thread.h"
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/drive/fake_file_system.h"
15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/drive/file_system_util.h"
16b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "chrome/browser/chromeos/drive/local_file_reader.h"
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/drive/test_util.h"
187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chrome/browser/drive/fake_drive_service.h"
195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "chrome/browser/drive/test_util.h"
20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/public/test/test_browser_thread_bundle.h"
21116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/public/test/test_utils.h"
2246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "google_apis/drive/drive_api_parser.h"
23a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "google_apis/drive/test_util.h"
24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/base/io_buffer.h"
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/base/net_errors.h"
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/base/test_completion_callback.h"
27a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "net/http/http_byte_range.h"
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace drive {
31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace internal {
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace {
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Increments the |num_called|, when this method is invoked.
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IncrementCallback(int* num_called) {
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(num_called);
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ++*num_called;
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class LocalReaderProxyTest : public ::testing::Test {
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) protected:
44868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  LocalReaderProxyTest()
45868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP) {
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void SetUp() OVERRIDE {
49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_TRUE(google_apis::test_util::CreateFileOfSpecifiedSize(
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        temp_dir_.path(), 1024, &file_path_, &file_content_));
52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    worker_thread_.reset(new base::Thread("ReaderProxyTest"));
54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_TRUE(worker_thread_->Start());
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
57868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  content::TestBrowserThreadBundle thread_bundle_;
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::ScopedTempDir temp_dir_;
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::FilePath file_path_;
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string file_content_;
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<base::Thread> worker_thread_;
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(LocalReaderProxyTest, Read) {
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Open the file first.
68b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  scoped_ptr<util::LocalFileReader> file_reader(
697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      new util::LocalFileReader(worker_thread_->message_loop_proxy().get()));
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  net::TestCompletionCallback callback;
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  file_reader->Open(file_path_, 0, callback.callback());
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(net::OK, callback.WaitForResult());
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Test instance.
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  LocalReaderProxy proxy(file_reader.Pass(), file_content_.size());
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
77eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Make sure the read content is as same as the file.
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string content;
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(net::OK, test_util::ReadAllData(&proxy, &content));
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(file_content_, content);
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(LocalReaderProxyTest, ReadWithLimit) {
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // This test case, we only read first half of the file.
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const std::string expected_content =
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      file_content_.substr(0, file_content_.size() / 2);
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Open the file first.
89b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  scoped_ptr<util::LocalFileReader> file_reader(
907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      new util::LocalFileReader(worker_thread_->message_loop_proxy().get()));
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  net::TestCompletionCallback callback;
92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  file_reader->Open(file_path_, 0, callback.callback());
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(net::OK, callback.WaitForResult());
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Test instance.
96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  LocalReaderProxy proxy(file_reader.Pass(), expected_content.size());
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
98eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Make sure the read content is as same as the file.
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string content;
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(net::OK, test_util::ReadAllData(&proxy, &content));
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(expected_content, content);
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class NetworkReaderProxyTest : public ::testing::Test {
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) protected:
106868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NetworkReaderProxyTest()
107868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP) {
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
110868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  content::TestBrowserThreadBundle thread_bundle_;
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(NetworkReaderProxyTest, EmptyFile) {
114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  NetworkReaderProxy proxy(0, 0, 0, base::Bind(&base::DoNothing));
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  net::TestCompletionCallback callback;
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const int kBufferSize = 10;
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kBufferSize));
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int result = proxy.Read(buffer.get(), kBufferSize, callback.callback());
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // For empty file, Read() should return 0 immediately.
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, result);
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(NetworkReaderProxyTest, Read) {
126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int cancel_called = 0;
127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  {
128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    NetworkReaderProxy proxy(0, 10, 10,
129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                             base::Bind(&IncrementCallback, &cancel_called));
130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    net::TestCompletionCallback callback;
132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const int kBufferSize = 3;
133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kBufferSize));
134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // If no data is available yet, ERR_IO_PENDING should be returned.
136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    int result = proxy.Read(buffer.get(), kBufferSize, callback.callback());
137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_EQ(net::ERR_IO_PENDING, result);
138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // And when the data is supplied, the callback will be called.
140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    scoped_ptr<std::string> data(new std::string("abcde"));
141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    proxy.OnGetContent(data.Pass());
142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // The returned data should be fit to the buffer size.
144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    result = callback.GetResult(result);
145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_EQ(3, result);
146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_EQ("abc", std::string(buffer->data(), result));
147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // The next Read should return immediately because there is pending data
149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    result = proxy.Read(buffer.get(), kBufferSize, callback.callback());
150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_EQ(2, result);
151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_EQ("de", std::string(buffer->data(), result));
152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Supply the data before calling Read operation.
154cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    data.reset(new std::string("fg"));
155cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    proxy.OnGetContent(data.Pass());
156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    data.reset(new std::string("hij"));
157cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    proxy.OnGetContent(data.Pass());  // Now 10 bytes are supplied.
158cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // The data should be concatenated if possible.
160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    result = proxy.Read(buffer.get(), kBufferSize, callback.callback());
161cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_EQ(3, result);
162cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_EQ("fgh", std::string(buffer->data(), result));
163cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
164cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    result = proxy.Read(buffer.get(), kBufferSize, callback.callback());
165cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_EQ(2, result);
166cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_EQ("ij", std::string(buffer->data(), result));
167cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
168cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // The whole data is read, so Read() should return 0 immediately by then.
169cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    result = proxy.Read(buffer.get(), kBufferSize, callback.callback());
170cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_EQ(0, result);
171cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Proxy is deleted without any called to OnCompleted(). Even in the case,
174cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // cancel callback should not be invoked.
175cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(0, cancel_called);
176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(NetworkReaderProxyTest, ReadWithLimit) {
179cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  NetworkReaderProxy proxy(10, 10, 10, base::Bind(&base::DoNothing));
180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  net::TestCompletionCallback callback;
182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const int kBufferSize = 3;
183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kBufferSize));
184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // If no data is available yet, ERR_IO_PENDING should be returned.
186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int result = proxy.Read(buffer.get(), kBufferSize, callback.callback());
187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(net::ERR_IO_PENDING, result);
188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // And when the data is supplied, the callback will be called.
190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<std::string> data(new std::string("abcde"));
191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  proxy.OnGetContent(data.Pass());
192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  data.reset(new std::string("fgh"));
193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  proxy.OnGetContent(data.Pass());
194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  data.reset(new std::string("ijklmno"));
195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  proxy.OnGetContent(data.Pass());
196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The returned data should be fit to the buffer size.
198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  result = callback.GetResult(result);
199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(3, result);
200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ("klm", std::string(buffer->data(), result));
201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The next Read should return immediately because there is pending data
203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  result = proxy.Read(buffer.get(), kBufferSize, callback.callback());
204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(2, result);
205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ("no", std::string(buffer->data(), result));
206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Supply the data before calling Read operation.
208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  data.reset(new std::string("pqrs"));
209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  proxy.OnGetContent(data.Pass());
210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  data.reset(new std::string("tuvwxyz"));
211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  proxy.OnGetContent(data.Pass());  // 't' is the 20-th byte.
212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The data should be concatenated if possible.
214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  result = proxy.Read(buffer.get(), kBufferSize, callback.callback());
215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(3, result);
216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ("pqr", std::string(buffer->data(), result));
217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  result = proxy.Read(buffer.get(), kBufferSize, callback.callback());
219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(2, result);
220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ("st", std::string(buffer->data(), result));
221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The whole data is read, so Read() should return 0 immediately by then.
223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  result = proxy.Read(buffer.get(), kBufferSize, callback.callback());
224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, result);
225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(NetworkReaderProxyTest, ErrorWithPendingCallback) {
228cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  NetworkReaderProxy proxy(0, 10, 10, base::Bind(&base::DoNothing));
229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  net::TestCompletionCallback callback;
231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const int kBufferSize = 3;
232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kBufferSize));
233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Set pending callback.
235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int result = proxy.Read(buffer.get(), kBufferSize, callback.callback());
236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(net::ERR_IO_PENDING, result);
237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Emulate that an error is found. The callback should be called internally.
239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  proxy.OnCompleted(FILE_ERROR_FAILED);
240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  result = callback.GetResult(result);
241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(net::ERR_FAILED, result);
242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The next Read call should also return the same error code.
244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(net::ERR_FAILED,
245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            proxy.Read(buffer.get(), kBufferSize, callback.callback()));
246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(NetworkReaderProxyTest, ErrorWithPendingData) {
249cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  NetworkReaderProxy proxy(0, 10, 10, base::Bind(&base::DoNothing));
250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  net::TestCompletionCallback callback;
252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const int kBufferSize = 3;
253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kBufferSize));
254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Supply the data before an error.
256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<std::string> data(new std::string("abcde"));
257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  proxy.OnGetContent(data.Pass());
258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Emulate that an error is found.
260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  proxy.OnCompleted(FILE_ERROR_FAILED);
261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The next Read call should return the error code, even if there is
263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // pending data (the pending data should be released in OnCompleted.
264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(net::ERR_FAILED,
265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            proxy.Read(buffer.get(), kBufferSize, callback.callback()));
266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(NetworkReaderProxyTest, CancelJob) {
269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int num_called = 0;
270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  {
271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    NetworkReaderProxy proxy(
272cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        0, 0, 0, base::Bind(&IncrementCallback, &num_called));
273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    proxy.OnCompleted(FILE_ERROR_OK);
274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Destroy the instance after the network operation is completed.
275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // The cancelling callback shouldn't be called.
276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, num_called);
278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  num_called = 0;
280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  {
281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    NetworkReaderProxy proxy(
282cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        0, 0, 0, base::Bind(&IncrementCallback, &num_called));
283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Destroy the instance before the network operation is completed.
284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // The cancelling callback should be called.
285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, num_called);
287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace internal
290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class DriveFileStreamReaderTest : public ::testing::Test {
292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) protected:
293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DriveFileStreamReaderTest()
294868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP) {
295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void SetUp() OVERRIDE {
298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    worker_thread_.reset(new base::Thread("DriveFileStreamReaderTest"));
299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_TRUE(worker_thread_->Start());
300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Initialize FakeDriveService.
302eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    fake_drive_service_.reset(new FakeDriveService);
3035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    ASSERT_TRUE(test_util::SetUpTestEntries(fake_drive_service_.get()));
304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Create a testee instance.
306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    fake_file_system_.reset(
307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        new test_util::FakeFileSystem(fake_drive_service_.get()));
308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  FileSystemInterface* GetFileSystem() {
311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return fake_file_system_.get();
312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DriveFileStreamReader::FileSystemGetter GetFileSystemGetter() {
315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return base::Bind(&DriveFileStreamReaderTest::GetFileSystem,
316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                      base::Unretained(this));
317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
319868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  content::TestBrowserThreadBundle thread_bundle_;
320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<base::Thread> worker_thread_;
322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
323eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<FakeDriveService> fake_drive_service_;
324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<test_util::FakeFileSystem> fake_file_system_;
325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(DriveFileStreamReaderTest, Read) {
328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const base::FilePath kDriveFile =
329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      util::GetDriveMyDriveRootPath().AppendASCII("File 1.txt");
330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Create the reader, and initialize it.
331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // In this case, the file is not yet locally cached.
332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<DriveFileStreamReader> reader(new DriveFileStreamReader(
3337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      GetFileSystemGetter(), worker_thread_->message_loop_proxy().get()));
334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(reader->IsInitialized());
335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int error = net::ERR_FAILED;
337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<ResourceEntry> entry;
338eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  {
339eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    base::RunLoop run_loop;
340eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    reader->Initialize(
341eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        kDriveFile,
342eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        net::HttpByteRange(),
343eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        google_apis::test_util::CreateQuitCallback(
344eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch            &run_loop,
345eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch            google_apis::test_util::CreateCopyResultCallback(&error, &entry)));
346eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    run_loop.Run();
347eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(net::OK, error);
349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(entry);
350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(reader->IsInitialized());
351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  size_t content_size = entry->file_info().size();
352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Read data from the reader.
354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string first_content;
355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(net::OK, test_util::ReadAllData(reader.get(), &first_content));
356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(content_size, first_content.size());
357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Create second instance and initialize it.
359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // In this case, the file should be cached one.
3607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  reader.reset(new DriveFileStreamReader(
3617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      GetFileSystemGetter(), worker_thread_->message_loop_proxy().get()));
362c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(reader->IsInitialized());
363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  error = net::ERR_FAILED;
365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  entry.reset();
366eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  {
367eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    base::RunLoop run_loop;
368eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    reader->Initialize(
369eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        kDriveFile,
370eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        net::HttpByteRange(),
371eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        google_apis::test_util::CreateQuitCallback(
372eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch            &run_loop,
373eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch            google_apis::test_util::CreateCopyResultCallback(&error, &entry)));
374eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    run_loop.Run();
375eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(net::OK, error);
377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(entry);
378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(reader->IsInitialized());
379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The size should be same.
381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(content_size, static_cast<size_t>(entry->file_info().size()));
382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Read data from the reader, again.
384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string second_content;
385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(net::OK, test_util::ReadAllData(reader.get(), &second_content));
386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The same content is expected.
388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(first_content, second_content);
389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(DriveFileStreamReaderTest, ReadRange) {
392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // In this test case, we just confirm that the part of file is read.
393a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  const int64 kRangeOffset = 3;
394a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  const int64 kRangeLength = 4;
395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const base::FilePath kDriveFile =
397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      util::GetDriveMyDriveRootPath().AppendASCII("File 1.txt");
398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Create the reader, and initialize it.
399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // In this case, the file is not yet locally cached.
400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<DriveFileStreamReader> reader(new DriveFileStreamReader(
4017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      GetFileSystemGetter(), worker_thread_->message_loop_proxy().get()));
402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(reader->IsInitialized());
403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int error = net::ERR_FAILED;
405c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<ResourceEntry> entry;
406a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  net::HttpByteRange byte_range;
407a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  byte_range.set_first_byte_position(kRangeOffset);
408a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // Last byte position is inclusive.
409a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  byte_range.set_last_byte_position(kRangeOffset + kRangeLength - 1);
410eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  {
411eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    base::RunLoop run_loop;
412eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    reader->Initialize(
413eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        kDriveFile,
414eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        byte_range,
415eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        google_apis::test_util::CreateQuitCallback(
416eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch            &run_loop,
417eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch            google_apis::test_util::CreateCopyResultCallback(&error, &entry)));
418eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    run_loop.Run();
419eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(net::OK, error);
421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(entry);
422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(reader->IsInitialized());
423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Read data from the reader.
425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string first_content;
426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(net::OK, test_util::ReadAllData(reader.get(), &first_content));
427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
428c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The length should be equal to range length.
429a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ(kRangeLength, static_cast<int64>(first_content.size()));
430c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
431c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Create second instance and initialize it.
432c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // In this case, the file should be cached one.
4337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  reader.reset(new DriveFileStreamReader(
4347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      GetFileSystemGetter(), worker_thread_->message_loop_proxy().get()));
435c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(reader->IsInitialized());
436c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
437c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  error = net::ERR_FAILED;
438c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  entry.reset();
439eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  {
440eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    base::RunLoop run_loop;
441eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    reader->Initialize(
442eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        kDriveFile,
443eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        byte_range,
444eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        google_apis::test_util::CreateQuitCallback(
445eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch            &run_loop,
446eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch            google_apis::test_util::CreateCopyResultCallback(&error, &entry)));
447eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    run_loop.Run();
448eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(net::OK, error);
450c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(entry);
451c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(reader->IsInitialized());
452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
453c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Read data from the reader, again.
454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string second_content;
455c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(net::OK, test_util::ReadAllData(reader.get(), &second_content));
456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The same content is expected.
458c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(first_content, second_content);
459c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
460c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
461a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)TEST_F(DriveFileStreamReaderTest, OutOfRangeError) {
462a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  const int64 kRangeOffset = 1000000;  // Out of range.
463a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  const int64 kRangeLength = 4;
464a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
465a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  const base::FilePath kDriveFile =
466a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      util::GetDriveMyDriveRootPath().AppendASCII("File 1.txt");
467a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // Create the reader, and initialize it.
468a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // In this case, the file is not yet locally cached.
469a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  scoped_ptr<DriveFileStreamReader> reader(new DriveFileStreamReader(
4707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      GetFileSystemGetter(), worker_thread_->message_loop_proxy().get()));
471a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_FALSE(reader->IsInitialized());
472a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
473a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  int error = net::ERR_FAILED;
474a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  scoped_ptr<ResourceEntry> entry;
475a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  net::HttpByteRange byte_range;
476a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  byte_range.set_first_byte_position(kRangeOffset);
477a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // Last byte position is inclusive.
478a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  byte_range.set_last_byte_position(kRangeOffset + kRangeLength - 1);
479eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  {
480eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    base::RunLoop run_loop;
481eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    reader->Initialize(
482eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        kDriveFile,
483eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        byte_range,
484eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        google_apis::test_util::CreateQuitCallback(
485eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch            &run_loop,
486eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch            google_apis::test_util::CreateCopyResultCallback(&error, &entry)));
487eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    run_loop.Run();
488eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
489a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ(net::ERR_REQUEST_RANGE_NOT_SATISFIABLE, error);
490a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_FALSE(entry);
491a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
492a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
4935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(DriveFileStreamReaderTest, ZeroByteFileRead) {
4945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Prepare an empty file
4955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  {
4965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
49746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    scoped_ptr<google_apis::FileResource> entry;
4985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    fake_drive_service_->AddNewFile(
4995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        "text/plain",
5005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        "",  // empty
5015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        fake_drive_service_->GetRootResourceId(),
5025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        "EmptyFile.txt",
5035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        false,  // shared_with_me
5045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        google_apis::test_util::CreateCopyResultCallback(&error, &entry));
505116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    content::RunAllBlockingPoolTasksUntilIdle();
5065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_EQ(google_apis::HTTP_CREATED, error);
5075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_TRUE(entry);
5085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_EQ(0, entry->file_size());
5095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
5105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::FilePath kDriveFile =
5125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      util::GetDriveMyDriveRootPath().AppendASCII("EmptyFile.txt");
5135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Create the reader, and initialize it.
5145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // In this case, the file is not yet locally cached.
5155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<DriveFileStreamReader> reader(new DriveFileStreamReader(
5165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      GetFileSystemGetter(), worker_thread_->message_loop_proxy().get()));
5175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(reader->IsInitialized());
5185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int error = net::ERR_FAILED;
5205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<ResourceEntry> entry;
5215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  {
5225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::RunLoop run_loop;
5235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    reader->Initialize(
5245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        kDriveFile,
5255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        net::HttpByteRange(),
5265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        google_apis::test_util::CreateQuitCallback(
5275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            &run_loop,
5285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            google_apis::test_util::CreateCopyResultCallback(&error, &entry)));
5295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    run_loop.Run();
5305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
5315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(net::OK, error);
5325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(entry);
5335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(0u, entry->file_info().size());  // It's a zero-byte file.
5345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(reader->IsInitialized());
5355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Read data from the reader. Check that it successfuly reads empty data.
5375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string first_content;
5385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(net::OK, test_util::ReadAllData(reader.get(), &first_content));
5395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(0u, first_content.size());
5405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Create second instance and initialize it.
5425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // In this case, the file should be cached one.
5435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  reader.reset(new DriveFileStreamReader(
5445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      GetFileSystemGetter(), worker_thread_->message_loop_proxy().get()));
5455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(reader->IsInitialized());
5465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  error = net::ERR_FAILED;
5485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  entry.reset();
5495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  {
5505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::RunLoop run_loop;
5515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    reader->Initialize(
5525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        kDriveFile,
5535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        net::HttpByteRange(),
5545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        google_apis::test_util::CreateQuitCallback(
5555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            &run_loop,
5565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            google_apis::test_util::CreateCopyResultCallback(&error, &entry)));
5575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    run_loop.Run();
5585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
5595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(net::OK, error);
5605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(entry);
5615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(reader->IsInitialized());
5625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Read data from the reader, again.
5645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string second_content;
5655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(net::OK, test_util::ReadAllData(reader.get(), &second_content));
5665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(0u, second_content.size());
5675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
5685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
569c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace drive
570