Home | History | Annotate | Download | only in drive
      1 // Copyright 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/chromeos/drive/drive_file_stream_reader.h"
      6 
      7 #include <string>
      8 
      9 #include "base/bind.h"
     10 #include "base/files/file_path.h"
     11 #include "base/files/scoped_temp_dir.h"
     12 #include "base/run_loop.h"
     13 #include "base/threading/thread.h"
     14 #include "chrome/browser/chromeos/drive/fake_file_system.h"
     15 #include "chrome/browser/chromeos/drive/file_system_util.h"
     16 #include "chrome/browser/chromeos/drive/local_file_reader.h"
     17 #include "chrome/browser/chromeos/drive/test_util.h"
     18 #include "chrome/browser/drive/fake_drive_service.h"
     19 #include "chrome/browser/drive/test_util.h"
     20 #include "content/public/test/test_browser_thread_bundle.h"
     21 #include "content/public/test/test_utils.h"
     22 #include "google_apis/drive/drive_api_parser.h"
     23 #include "google_apis/drive/test_util.h"
     24 #include "net/base/io_buffer.h"
     25 #include "net/base/net_errors.h"
     26 #include "net/base/test_completion_callback.h"
     27 #include "net/http/http_byte_range.h"
     28 #include "testing/gtest/include/gtest/gtest.h"
     29 
     30 namespace drive {
     31 namespace internal {
     32 namespace {
     33 
     34 // Increments the |num_called|, when this method is invoked.
     35 void IncrementCallback(int* num_called) {
     36   DCHECK(num_called);
     37   ++*num_called;
     38 }
     39 
     40 }  // namespace
     41 
     42 class LocalReaderProxyTest : public ::testing::Test {
     43  protected:
     44   LocalReaderProxyTest()
     45       : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP) {
     46   }
     47 
     48   virtual void SetUp() OVERRIDE {
     49     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
     50     ASSERT_TRUE(google_apis::test_util::CreateFileOfSpecifiedSize(
     51         temp_dir_.path(), 1024, &file_path_, &file_content_));
     52 
     53     worker_thread_.reset(new base::Thread("ReaderProxyTest"));
     54     ASSERT_TRUE(worker_thread_->Start());
     55   }
     56 
     57   content::TestBrowserThreadBundle thread_bundle_;
     58 
     59   base::ScopedTempDir temp_dir_;
     60   base::FilePath file_path_;
     61   std::string file_content_;
     62 
     63   scoped_ptr<base::Thread> worker_thread_;
     64 };
     65 
     66 TEST_F(LocalReaderProxyTest, Read) {
     67   // Open the file first.
     68   scoped_ptr<util::LocalFileReader> file_reader(
     69       new util::LocalFileReader(worker_thread_->message_loop_proxy().get()));
     70   net::TestCompletionCallback callback;
     71   file_reader->Open(file_path_, 0, callback.callback());
     72   ASSERT_EQ(net::OK, callback.WaitForResult());
     73 
     74   // Test instance.
     75   LocalReaderProxy proxy(file_reader.Pass(), file_content_.size());
     76 
     77   // Make sure the read content is as same as the file.
     78   std::string content;
     79   ASSERT_EQ(net::OK, test_util::ReadAllData(&proxy, &content));
     80   EXPECT_EQ(file_content_, content);
     81 }
     82 
     83 TEST_F(LocalReaderProxyTest, ReadWithLimit) {
     84   // This test case, we only read first half of the file.
     85   const std::string expected_content =
     86       file_content_.substr(0, file_content_.size() / 2);
     87 
     88   // Open the file first.
     89   scoped_ptr<util::LocalFileReader> file_reader(
     90       new util::LocalFileReader(worker_thread_->message_loop_proxy().get()));
     91   net::TestCompletionCallback callback;
     92   file_reader->Open(file_path_, 0, callback.callback());
     93   ASSERT_EQ(net::OK, callback.WaitForResult());
     94 
     95   // Test instance.
     96   LocalReaderProxy proxy(file_reader.Pass(), expected_content.size());
     97 
     98   // Make sure the read content is as same as the file.
     99   std::string content;
    100   ASSERT_EQ(net::OK, test_util::ReadAllData(&proxy, &content));
    101   EXPECT_EQ(expected_content, content);
    102 }
    103 
    104 class NetworkReaderProxyTest : public ::testing::Test {
    105  protected:
    106   NetworkReaderProxyTest()
    107       : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP) {
    108   }
    109 
    110   content::TestBrowserThreadBundle thread_bundle_;
    111 };
    112 
    113 TEST_F(NetworkReaderProxyTest, EmptyFile) {
    114   NetworkReaderProxy proxy(0, 0, 0, base::Bind(&base::DoNothing));
    115 
    116   net::TestCompletionCallback callback;
    117   const int kBufferSize = 10;
    118   scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kBufferSize));
    119   int result = proxy.Read(buffer.get(), kBufferSize, callback.callback());
    120 
    121   // For empty file, Read() should return 0 immediately.
    122   EXPECT_EQ(0, result);
    123 }
    124 
    125 TEST_F(NetworkReaderProxyTest, Read) {
    126   int cancel_called = 0;
    127   {
    128     NetworkReaderProxy proxy(0, 10, 10,
    129                              base::Bind(&IncrementCallback, &cancel_called));
    130 
    131     net::TestCompletionCallback callback;
    132     const int kBufferSize = 3;
    133     scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kBufferSize));
    134 
    135     // If no data is available yet, ERR_IO_PENDING should be returned.
    136     int result = proxy.Read(buffer.get(), kBufferSize, callback.callback());
    137     EXPECT_EQ(net::ERR_IO_PENDING, result);
    138 
    139     // And when the data is supplied, the callback will be called.
    140     scoped_ptr<std::string> data(new std::string("abcde"));
    141     proxy.OnGetContent(data.Pass());
    142 
    143     // The returned data should be fit to the buffer size.
    144     result = callback.GetResult(result);
    145     EXPECT_EQ(3, result);
    146     EXPECT_EQ("abc", std::string(buffer->data(), result));
    147 
    148     // The next Read should return immediately because there is pending data
    149     result = proxy.Read(buffer.get(), kBufferSize, callback.callback());
    150     EXPECT_EQ(2, result);
    151     EXPECT_EQ("de", std::string(buffer->data(), result));
    152 
    153     // Supply the data before calling Read operation.
    154     data.reset(new std::string("fg"));
    155     proxy.OnGetContent(data.Pass());
    156     data.reset(new std::string("hij"));
    157     proxy.OnGetContent(data.Pass());  // Now 10 bytes are supplied.
    158 
    159     // The data should be concatenated if possible.
    160     result = proxy.Read(buffer.get(), kBufferSize, callback.callback());
    161     EXPECT_EQ(3, result);
    162     EXPECT_EQ("fgh", std::string(buffer->data(), result));
    163 
    164     result = proxy.Read(buffer.get(), kBufferSize, callback.callback());
    165     EXPECT_EQ(2, result);
    166     EXPECT_EQ("ij", std::string(buffer->data(), result));
    167 
    168     // The whole data is read, so Read() should return 0 immediately by then.
    169     result = proxy.Read(buffer.get(), kBufferSize, callback.callback());
    170     EXPECT_EQ(0, result);
    171   }
    172 
    173   // Proxy is deleted without any called to OnCompleted(). Even in the case,
    174   // cancel callback should not be invoked.
    175   EXPECT_EQ(0, cancel_called);
    176 }
    177 
    178 TEST_F(NetworkReaderProxyTest, ReadWithLimit) {
    179   NetworkReaderProxy proxy(10, 10, 10, base::Bind(&base::DoNothing));
    180 
    181   net::TestCompletionCallback callback;
    182   const int kBufferSize = 3;
    183   scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kBufferSize));
    184 
    185   // If no data is available yet, ERR_IO_PENDING should be returned.
    186   int result = proxy.Read(buffer.get(), kBufferSize, callback.callback());
    187   EXPECT_EQ(net::ERR_IO_PENDING, result);
    188 
    189   // And when the data is supplied, the callback will be called.
    190   scoped_ptr<std::string> data(new std::string("abcde"));
    191   proxy.OnGetContent(data.Pass());
    192   data.reset(new std::string("fgh"));
    193   proxy.OnGetContent(data.Pass());
    194   data.reset(new std::string("ijklmno"));
    195   proxy.OnGetContent(data.Pass());
    196 
    197   // The returned data should be fit to the buffer size.
    198   result = callback.GetResult(result);
    199   EXPECT_EQ(3, result);
    200   EXPECT_EQ("klm", std::string(buffer->data(), result));
    201 
    202   // The next Read should return immediately because there is pending data
    203   result = proxy.Read(buffer.get(), kBufferSize, callback.callback());
    204   EXPECT_EQ(2, result);
    205   EXPECT_EQ("no", std::string(buffer->data(), result));
    206 
    207   // Supply the data before calling Read operation.
    208   data.reset(new std::string("pqrs"));
    209   proxy.OnGetContent(data.Pass());
    210   data.reset(new std::string("tuvwxyz"));
    211   proxy.OnGetContent(data.Pass());  // 't' is the 20-th byte.
    212 
    213   // The data should be concatenated if possible.
    214   result = proxy.Read(buffer.get(), kBufferSize, callback.callback());
    215   EXPECT_EQ(3, result);
    216   EXPECT_EQ("pqr", std::string(buffer->data(), result));
    217 
    218   result = proxy.Read(buffer.get(), kBufferSize, callback.callback());
    219   EXPECT_EQ(2, result);
    220   EXPECT_EQ("st", std::string(buffer->data(), result));
    221 
    222   // The whole data is read, so Read() should return 0 immediately by then.
    223   result = proxy.Read(buffer.get(), kBufferSize, callback.callback());
    224   EXPECT_EQ(0, result);
    225 }
    226 
    227 TEST_F(NetworkReaderProxyTest, ErrorWithPendingCallback) {
    228   NetworkReaderProxy proxy(0, 10, 10, base::Bind(&base::DoNothing));
    229 
    230   net::TestCompletionCallback callback;
    231   const int kBufferSize = 3;
    232   scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kBufferSize));
    233 
    234   // Set pending callback.
    235   int result = proxy.Read(buffer.get(), kBufferSize, callback.callback());
    236   EXPECT_EQ(net::ERR_IO_PENDING, result);
    237 
    238   // Emulate that an error is found. The callback should be called internally.
    239   proxy.OnCompleted(FILE_ERROR_FAILED);
    240   result = callback.GetResult(result);
    241   EXPECT_EQ(net::ERR_FAILED, result);
    242 
    243   // The next Read call should also return the same error code.
    244   EXPECT_EQ(net::ERR_FAILED,
    245             proxy.Read(buffer.get(), kBufferSize, callback.callback()));
    246 }
    247 
    248 TEST_F(NetworkReaderProxyTest, ErrorWithPendingData) {
    249   NetworkReaderProxy proxy(0, 10, 10, base::Bind(&base::DoNothing));
    250 
    251   net::TestCompletionCallback callback;
    252   const int kBufferSize = 3;
    253   scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kBufferSize));
    254 
    255   // Supply the data before an error.
    256   scoped_ptr<std::string> data(new std::string("abcde"));
    257   proxy.OnGetContent(data.Pass());
    258 
    259   // Emulate that an error is found.
    260   proxy.OnCompleted(FILE_ERROR_FAILED);
    261 
    262   // The next Read call should return the error code, even if there is
    263   // pending data (the pending data should be released in OnCompleted.
    264   EXPECT_EQ(net::ERR_FAILED,
    265             proxy.Read(buffer.get(), kBufferSize, callback.callback()));
    266 }
    267 
    268 TEST_F(NetworkReaderProxyTest, CancelJob) {
    269   int num_called = 0;
    270   {
    271     NetworkReaderProxy proxy(
    272         0, 0, 0, base::Bind(&IncrementCallback, &num_called));
    273     proxy.OnCompleted(FILE_ERROR_OK);
    274     // Destroy the instance after the network operation is completed.
    275     // The cancelling callback shouldn't be called.
    276   }
    277   EXPECT_EQ(0, num_called);
    278 
    279   num_called = 0;
    280   {
    281     NetworkReaderProxy proxy(
    282         0, 0, 0, base::Bind(&IncrementCallback, &num_called));
    283     // Destroy the instance before the network operation is completed.
    284     // The cancelling callback should be called.
    285   }
    286   EXPECT_EQ(1, num_called);
    287 }
    288 
    289 }  // namespace internal
    290 
    291 class DriveFileStreamReaderTest : public ::testing::Test {
    292  protected:
    293   DriveFileStreamReaderTest()
    294       : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP) {
    295   }
    296 
    297   virtual void SetUp() OVERRIDE {
    298     worker_thread_.reset(new base::Thread("DriveFileStreamReaderTest"));
    299     ASSERT_TRUE(worker_thread_->Start());
    300 
    301     // Initialize FakeDriveService.
    302     fake_drive_service_.reset(new FakeDriveService);
    303     ASSERT_TRUE(test_util::SetUpTestEntries(fake_drive_service_.get()));
    304 
    305     // Create a testee instance.
    306     fake_file_system_.reset(
    307         new test_util::FakeFileSystem(fake_drive_service_.get()));
    308   }
    309 
    310   FileSystemInterface* GetFileSystem() {
    311     return fake_file_system_.get();
    312   }
    313 
    314   DriveFileStreamReader::FileSystemGetter GetFileSystemGetter() {
    315     return base::Bind(&DriveFileStreamReaderTest::GetFileSystem,
    316                       base::Unretained(this));
    317   }
    318 
    319   content::TestBrowserThreadBundle thread_bundle_;
    320 
    321   scoped_ptr<base::Thread> worker_thread_;
    322 
    323   scoped_ptr<FakeDriveService> fake_drive_service_;
    324   scoped_ptr<test_util::FakeFileSystem> fake_file_system_;
    325 };
    326 
    327 TEST_F(DriveFileStreamReaderTest, Read) {
    328   const base::FilePath kDriveFile =
    329       util::GetDriveMyDriveRootPath().AppendASCII("File 1.txt");
    330   // Create the reader, and initialize it.
    331   // In this case, the file is not yet locally cached.
    332   scoped_ptr<DriveFileStreamReader> reader(new DriveFileStreamReader(
    333       GetFileSystemGetter(), worker_thread_->message_loop_proxy().get()));
    334   EXPECT_FALSE(reader->IsInitialized());
    335 
    336   int error = net::ERR_FAILED;
    337   scoped_ptr<ResourceEntry> entry;
    338   {
    339     base::RunLoop run_loop;
    340     reader->Initialize(
    341         kDriveFile,
    342         net::HttpByteRange(),
    343         google_apis::test_util::CreateQuitCallback(
    344             &run_loop,
    345             google_apis::test_util::CreateCopyResultCallback(&error, &entry)));
    346     run_loop.Run();
    347   }
    348   EXPECT_EQ(net::OK, error);
    349   ASSERT_TRUE(entry);
    350   EXPECT_TRUE(reader->IsInitialized());
    351   size_t content_size = entry->file_info().size();
    352 
    353   // Read data from the reader.
    354   std::string first_content;
    355   ASSERT_EQ(net::OK, test_util::ReadAllData(reader.get(), &first_content));
    356   EXPECT_EQ(content_size, first_content.size());
    357 
    358   // Create second instance and initialize it.
    359   // In this case, the file should be cached one.
    360   reader.reset(new DriveFileStreamReader(
    361       GetFileSystemGetter(), worker_thread_->message_loop_proxy().get()));
    362   EXPECT_FALSE(reader->IsInitialized());
    363 
    364   error = net::ERR_FAILED;
    365   entry.reset();
    366   {
    367     base::RunLoop run_loop;
    368     reader->Initialize(
    369         kDriveFile,
    370         net::HttpByteRange(),
    371         google_apis::test_util::CreateQuitCallback(
    372             &run_loop,
    373             google_apis::test_util::CreateCopyResultCallback(&error, &entry)));
    374     run_loop.Run();
    375   }
    376   EXPECT_EQ(net::OK, error);
    377   ASSERT_TRUE(entry);
    378   EXPECT_TRUE(reader->IsInitialized());
    379 
    380   // The size should be same.
    381   EXPECT_EQ(content_size, static_cast<size_t>(entry->file_info().size()));
    382 
    383   // Read data from the reader, again.
    384   std::string second_content;
    385   ASSERT_EQ(net::OK, test_util::ReadAllData(reader.get(), &second_content));
    386 
    387   // The same content is expected.
    388   EXPECT_EQ(first_content, second_content);
    389 }
    390 
    391 TEST_F(DriveFileStreamReaderTest, ReadRange) {
    392   // In this test case, we just confirm that the part of file is read.
    393   const int64 kRangeOffset = 3;
    394   const int64 kRangeLength = 4;
    395 
    396   const base::FilePath kDriveFile =
    397       util::GetDriveMyDriveRootPath().AppendASCII("File 1.txt");
    398   // Create the reader, and initialize it.
    399   // In this case, the file is not yet locally cached.
    400   scoped_ptr<DriveFileStreamReader> reader(new DriveFileStreamReader(
    401       GetFileSystemGetter(), worker_thread_->message_loop_proxy().get()));
    402   EXPECT_FALSE(reader->IsInitialized());
    403 
    404   int error = net::ERR_FAILED;
    405   scoped_ptr<ResourceEntry> entry;
    406   net::HttpByteRange byte_range;
    407   byte_range.set_first_byte_position(kRangeOffset);
    408   // Last byte position is inclusive.
    409   byte_range.set_last_byte_position(kRangeOffset + kRangeLength - 1);
    410   {
    411     base::RunLoop run_loop;
    412     reader->Initialize(
    413         kDriveFile,
    414         byte_range,
    415         google_apis::test_util::CreateQuitCallback(
    416             &run_loop,
    417             google_apis::test_util::CreateCopyResultCallback(&error, &entry)));
    418     run_loop.Run();
    419   }
    420   EXPECT_EQ(net::OK, error);
    421   ASSERT_TRUE(entry);
    422   EXPECT_TRUE(reader->IsInitialized());
    423 
    424   // Read data from the reader.
    425   std::string first_content;
    426   ASSERT_EQ(net::OK, test_util::ReadAllData(reader.get(), &first_content));
    427 
    428   // The length should be equal to range length.
    429   EXPECT_EQ(kRangeLength, static_cast<int64>(first_content.size()));
    430 
    431   // Create second instance and initialize it.
    432   // In this case, the file should be cached one.
    433   reader.reset(new DriveFileStreamReader(
    434       GetFileSystemGetter(), worker_thread_->message_loop_proxy().get()));
    435   EXPECT_FALSE(reader->IsInitialized());
    436 
    437   error = net::ERR_FAILED;
    438   entry.reset();
    439   {
    440     base::RunLoop run_loop;
    441     reader->Initialize(
    442         kDriveFile,
    443         byte_range,
    444         google_apis::test_util::CreateQuitCallback(
    445             &run_loop,
    446             google_apis::test_util::CreateCopyResultCallback(&error, &entry)));
    447     run_loop.Run();
    448   }
    449   EXPECT_EQ(net::OK, error);
    450   ASSERT_TRUE(entry);
    451   EXPECT_TRUE(reader->IsInitialized());
    452 
    453   // Read data from the reader, again.
    454   std::string second_content;
    455   ASSERT_EQ(net::OK, test_util::ReadAllData(reader.get(), &second_content));
    456 
    457   // The same content is expected.
    458   EXPECT_EQ(first_content, second_content);
    459 }
    460 
    461 TEST_F(DriveFileStreamReaderTest, OutOfRangeError) {
    462   const int64 kRangeOffset = 1000000;  // Out of range.
    463   const int64 kRangeLength = 4;
    464 
    465   const base::FilePath kDriveFile =
    466       util::GetDriveMyDriveRootPath().AppendASCII("File 1.txt");
    467   // Create the reader, and initialize it.
    468   // In this case, the file is not yet locally cached.
    469   scoped_ptr<DriveFileStreamReader> reader(new DriveFileStreamReader(
    470       GetFileSystemGetter(), worker_thread_->message_loop_proxy().get()));
    471   EXPECT_FALSE(reader->IsInitialized());
    472 
    473   int error = net::ERR_FAILED;
    474   scoped_ptr<ResourceEntry> entry;
    475   net::HttpByteRange byte_range;
    476   byte_range.set_first_byte_position(kRangeOffset);
    477   // Last byte position is inclusive.
    478   byte_range.set_last_byte_position(kRangeOffset + kRangeLength - 1);
    479   {
    480     base::RunLoop run_loop;
    481     reader->Initialize(
    482         kDriveFile,
    483         byte_range,
    484         google_apis::test_util::CreateQuitCallback(
    485             &run_loop,
    486             google_apis::test_util::CreateCopyResultCallback(&error, &entry)));
    487     run_loop.Run();
    488   }
    489   EXPECT_EQ(net::ERR_REQUEST_RANGE_NOT_SATISFIABLE, error);
    490   EXPECT_FALSE(entry);
    491 }
    492 
    493 TEST_F(DriveFileStreamReaderTest, ZeroByteFileRead) {
    494   // Prepare an empty file
    495   {
    496     google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
    497     scoped_ptr<google_apis::FileResource> entry;
    498     fake_drive_service_->AddNewFile(
    499         "text/plain",
    500         "",  // empty
    501         fake_drive_service_->GetRootResourceId(),
    502         "EmptyFile.txt",
    503         false,  // shared_with_me
    504         google_apis::test_util::CreateCopyResultCallback(&error, &entry));
    505     content::RunAllBlockingPoolTasksUntilIdle();
    506     ASSERT_EQ(google_apis::HTTP_CREATED, error);
    507     ASSERT_TRUE(entry);
    508     ASSERT_EQ(0, entry->file_size());
    509   }
    510 
    511   const base::FilePath kDriveFile =
    512       util::GetDriveMyDriveRootPath().AppendASCII("EmptyFile.txt");
    513   // Create the reader, and initialize it.
    514   // In this case, the file is not yet locally cached.
    515   scoped_ptr<DriveFileStreamReader> reader(new DriveFileStreamReader(
    516       GetFileSystemGetter(), worker_thread_->message_loop_proxy().get()));
    517   EXPECT_FALSE(reader->IsInitialized());
    518 
    519   int error = net::ERR_FAILED;
    520   scoped_ptr<ResourceEntry> entry;
    521   {
    522     base::RunLoop run_loop;
    523     reader->Initialize(
    524         kDriveFile,
    525         net::HttpByteRange(),
    526         google_apis::test_util::CreateQuitCallback(
    527             &run_loop,
    528             google_apis::test_util::CreateCopyResultCallback(&error, &entry)));
    529     run_loop.Run();
    530   }
    531   EXPECT_EQ(net::OK, error);
    532   ASSERT_TRUE(entry);
    533   ASSERT_EQ(0u, entry->file_info().size());  // It's a zero-byte file.
    534   EXPECT_TRUE(reader->IsInitialized());
    535 
    536   // Read data from the reader. Check that it successfuly reads empty data.
    537   std::string first_content;
    538   ASSERT_EQ(net::OK, test_util::ReadAllData(reader.get(), &first_content));
    539   EXPECT_EQ(0u, first_content.size());
    540 
    541   // Create second instance and initialize it.
    542   // In this case, the file should be cached one.
    543   reader.reset(new DriveFileStreamReader(
    544       GetFileSystemGetter(), worker_thread_->message_loop_proxy().get()));
    545   EXPECT_FALSE(reader->IsInitialized());
    546 
    547   error = net::ERR_FAILED;
    548   entry.reset();
    549   {
    550     base::RunLoop run_loop;
    551     reader->Initialize(
    552         kDriveFile,
    553         net::HttpByteRange(),
    554         google_apis::test_util::CreateQuitCallback(
    555             &run_loop,
    556             google_apis::test_util::CreateCopyResultCallback(&error, &entry)));
    557     run_loop.Run();
    558   }
    559   EXPECT_EQ(net::OK, error);
    560   ASSERT_TRUE(entry);
    561   EXPECT_TRUE(reader->IsInitialized());
    562 
    563   // Read data from the reader, again.
    564   std::string second_content;
    565   ASSERT_EQ(net::OK, test_util::ReadAllData(reader.get(), &second_content));
    566   EXPECT_EQ(0u, second_content.size());
    567 }
    568 
    569 }  // namespace drive
    570