1cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// found in the LICENSE file.
4cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
5116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/chromeos/file_system_provider/fileapi/file_stream_reader.h"
6116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
7cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include <string>
8cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include <vector>
9cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
10cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/files/file.h"
11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/files/file_path.h"
12cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/files/scoped_temp_dir.h"
13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/memory/weak_ptr.h"
15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/run_loop.h"
16cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/chromeos/file_system_provider/fake_provided_file_system.h"
17cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/chromeos/file_system_provider/service.h"
18cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/chromeos/file_system_provider/service_factory.h"
19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/test/base/testing_browser_process.h"
20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/test/base/testing_profile.h"
21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/test/base/testing_profile_manager.h"
22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/public/test/test_browser_thread_bundle.h"
23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/public/test/test_file_system_context.h"
24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "extensions/browser/extension_registry.h"
25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "net/base/io_buffer.h"
26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "net/base/net_errors.h"
271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/async_file_util.h"
281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/external_mount_points.h"
291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_url.h"
30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace chromeos {
33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace file_system_provider {
34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace {
35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const char kExtensionId[] = "mbflcebpggnecokmikipoihdbecnjfoj";
37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const char kFileSystemId[] = "testing-file-system";
38cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
39cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Logs callbacks invocations on the file stream reader.
40cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class EventLogger {
41cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public:
42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EventLogger() : weak_ptr_factory_(this) {}
43cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual ~EventLogger() {}
44cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
45cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void OnRead(int result) { results_.push_back(result); }
46cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void OnGetLength(int64 result) { results_.push_back(result); }
47cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
48cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::WeakPtr<EventLogger> GetWeakPtr() {
49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return weak_ptr_factory_.GetWeakPtr();
50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const std::vector<int64>& results() const { return results_; }
53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) private:
55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::vector<int64> results_;
56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::WeakPtrFactory<EventLogger> weak_ptr_factory_;
57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(EventLogger);
59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Creates a cracked FileSystemURL for tests.
6203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)storage::FileSystemURL CreateFileSystemURL(const std::string& mount_point_name,
63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                           const base::FilePath& file_path) {
64cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const std::string origin = std::string("chrome-extension://") + kExtensionId;
6503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  const storage::ExternalMountPoints* const mount_points =
6603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::ExternalMountPoints::GetSystemInstance();
67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return mount_points->CreateCrackedFileSystemURL(
68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      GURL(origin),
6903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::kFileSystemTypeExternal,
70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::FilePath::FromUTF8Unsafe(mount_point_name).Append(file_path));
71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Creates a Service instance. Used to be able to destroy the service in
74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// TearDown().
75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)KeyedService* CreateService(content::BrowserContext* context) {
76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return new Service(Profile::FromBrowserContext(context),
77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                     extensions::ExtensionRegistry::Get(context));
78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
80cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}  // namespace
81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
82cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class FileSystemProviderFileStreamReader : public testing::Test {
83cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) protected:
841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  FileSystemProviderFileStreamReader() : profile_(NULL), fake_file_(NULL) {}
85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual ~FileSystemProviderFileStreamReader() {}
86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual void SetUp() OVERRIDE {
88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ASSERT_TRUE(data_dir_.CreateUniqueTempDir());
89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    profile_manager_.reset(
90cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        new TestingProfileManager(TestingBrowserProcess::GetGlobal()));
91cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ASSERT_TRUE(profile_manager_->SetUp());
92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    profile_ = profile_manager_->CreateTestingProfile("testing-profile");
93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
94cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ServiceFactory::GetInstance()->SetTestingFactory(profile_, &CreateService);
95cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    Service* service = Service::Get(profile_);  // Owned by its factory.
96f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    service->SetFileSystemFactoryForTesting(
97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        base::Bind(&FakeProvidedFileSystem::Create));
98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
99116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const bool result = service->MountFileSystem(kExtensionId,
100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                                 kFileSystemId,
101116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                                 "Testing File System",
102116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                                 false /* writable */);
103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ASSERT_TRUE(result);
104116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    FakeProvidedFileSystem* provided_file_system =
105116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        static_cast<FakeProvidedFileSystem*>(
106116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            service->GetProvidedFileSystem(kExtensionId, kFileSystemId));
1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ASSERT_TRUE(provided_file_system);
1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    fake_file_ = provided_file_system->GetEntry(
1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        base::FilePath::FromUTF8Unsafe(kFakeFilePath));
1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ASSERT_TRUE(fake_file_);
111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const ProvidedFileSystemInfo& file_system_info =
112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        service->GetProvidedFileSystem(kExtensionId, kFileSystemId)
113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            ->GetFileSystemInfo();
114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const std::string mount_point_name =
115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        file_system_info.mount_path().BaseName().AsUTF8Unsafe();
116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    file_url_ = CreateFileSystemURL(
118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        mount_point_name, base::FilePath::FromUTF8Unsafe(kFakeFilePath + 1));
119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ASSERT_TRUE(file_url_.is_valid());
120cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    wrong_file_url_ = CreateFileSystemURL(
121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        mount_point_name, base::FilePath::FromUTF8Unsafe("im-not-here.txt"));
122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ASSERT_TRUE(wrong_file_url_.is_valid());
123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual void TearDown() OVERRIDE {
126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Setting the testing factory to NULL will destroy the created service
127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // associated with the testing profile.
128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ServiceFactory::GetInstance()->SetTestingFactory(profile_, NULL);
129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  content::TestBrowserThreadBundle thread_bundle_;
132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::ScopedTempDir data_dir_;
133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<TestingProfileManager> profile_manager_;
1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TestingProfile* profile_;     // Owned by TestingProfileManager.
1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const FakeEntry* fake_file_;  // Owned by FakePRovidedFileSystem.
13603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  storage::FileSystemURL file_url_;
13703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  storage::FileSystemURL wrong_file_url_;
138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST_F(FileSystemProviderFileStreamReader, Read_AllAtOnce) {
141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EventLogger logger;
142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const int64 initial_offset = 0;
144116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  FileStreamReader reader(
1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      NULL, file_url_, initial_offset, fake_file_->metadata->modification_time);
146116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_refptr<net::IOBuffer> io_buffer(
1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new net::IOBuffer(fake_file_->metadata->size));
148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const int result =
150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      reader.Read(io_buffer.get(),
1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                  fake_file_->metadata->size,
152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                  base::Bind(&EventLogger::OnRead, logger.GetWeakPtr()));
153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(net::ERR_IO_PENDING, result);
154cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::RunLoop().RunUntilIdle();
155cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ASSERT_EQ(1u, logger.results().size());
157cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_LT(0, logger.results()[0]);
1581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(fake_file_->metadata->size, logger.results()[0]);
159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::string buffer_as_string(io_buffer->data(), fake_file_->metadata->size);
1611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(fake_file_->contents, buffer_as_string);
162cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
163cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
164cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST_F(FileSystemProviderFileStreamReader, Read_WrongFile) {
165cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EventLogger logger;
166cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
167cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const int64 initial_offset = 0;
168cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FileStreamReader reader(NULL,
169cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                          wrong_file_url_,
170cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                          initial_offset,
1711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                          fake_file_->metadata->modification_time);
172116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_refptr<net::IOBuffer> io_buffer(
1731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new net::IOBuffer(fake_file_->metadata->size));
174cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
175cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const int result =
176cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      reader.Read(io_buffer.get(),
1771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                  fake_file_->metadata->size,
178cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                  base::Bind(&EventLogger::OnRead, logger.GetWeakPtr()));
179cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(net::ERR_IO_PENDING, result);
180cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::RunLoop().RunUntilIdle();
181cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
182cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ASSERT_EQ(1u, logger.results().size());
183cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(net::ERR_FILE_NOT_FOUND, logger.results()[0]);
184cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
185cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
186cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST_F(FileSystemProviderFileStreamReader, Read_InChunks) {
187cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EventLogger logger;
188cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
189cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const int64 initial_offset = 0;
190116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  FileStreamReader reader(
1911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      NULL, file_url_, initial_offset, fake_file_->metadata->modification_time);
192cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (int64 offset = 0; offset < fake_file_->metadata->size; ++offset) {
194cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    scoped_refptr<net::IOBuffer> io_buffer(new net::IOBuffer(1));
195cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const int result =
196cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        reader.Read(io_buffer.get(),
197cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                    1,
198cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                    base::Bind(&EventLogger::OnRead, logger.GetWeakPtr()));
199cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_EQ(net::ERR_IO_PENDING, result);
200cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    base::RunLoop().RunUntilIdle();
201116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ASSERT_EQ(offset + 1, static_cast<int64>(logger.results().size()));
202cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_EQ(1, logger.results()[offset]);
2031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(fake_file_->contents[offset], io_buffer->data()[0]);
204cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
205cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
206cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
207cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST_F(FileSystemProviderFileStreamReader, Read_Slice) {
208cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EventLogger logger;
209cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
210cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Trim first 3 and last 3 characters.
211cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const int64 initial_offset = 3;
2121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const int length = fake_file_->metadata->size - initial_offset - 3;
2131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_GT(fake_file_->metadata->size, initial_offset);
214cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ASSERT_LT(0, length);
215cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
216116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  FileStreamReader reader(
2171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      NULL, file_url_, initial_offset, fake_file_->metadata->modification_time);
218cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_refptr<net::IOBuffer> io_buffer(new net::IOBuffer(length));
219cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
220cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const int result =
221cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      reader.Read(io_buffer.get(),
222cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                  length,
223cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                  base::Bind(&EventLogger::OnRead, logger.GetWeakPtr()));
224cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(net::ERR_IO_PENDING, result);
225cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::RunLoop().RunUntilIdle();
226cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
227cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ASSERT_EQ(1u, logger.results().size());
228cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(length, logger.results()[0]);
229cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
230cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::string buffer_as_string(io_buffer->data(), length);
2311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::string expected_buffer(fake_file_->contents.data() + initial_offset,
232116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                              length);
233cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(expected_buffer, buffer_as_string);
234cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
235cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
236cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST_F(FileSystemProviderFileStreamReader, Read_Beyond) {
237cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EventLogger logger;
238cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
239cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Request reading 1KB more than available.
240cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const int64 initial_offset = 0;
2411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const int length = fake_file_->metadata->size + 1024;
242cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
243116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  FileStreamReader reader(
2441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      NULL, file_url_, initial_offset, fake_file_->metadata->modification_time);
245cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_refptr<net::IOBuffer> io_buffer(new net::IOBuffer(length));
246cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
247cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const int result =
248cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      reader.Read(io_buffer.get(),
249cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                  length,
250cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                  base::Bind(&EventLogger::OnRead, logger.GetWeakPtr()));
251cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(net::ERR_IO_PENDING, result);
252cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::RunLoop().RunUntilIdle();
253cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
254cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ASSERT_EQ(1u, logger.results().size());
255cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_LT(0, logger.results()[0]);
2561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(fake_file_->metadata->size, logger.results()[0]);
257116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
2581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::string buffer_as_string(io_buffer->data(), fake_file_->metadata->size);
2591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(fake_file_->contents, buffer_as_string);
260116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
261116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
262116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_F(FileSystemProviderFileStreamReader, Read_ModifiedFile) {
263116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EventLogger logger;
264116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
265116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const int64 initial_offset = 0;
266116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  FileStreamReader reader(NULL, file_url_, initial_offset, base::Time::Max());
267cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
268116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_refptr<net::IOBuffer> io_buffer(
2691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new net::IOBuffer(fake_file_->metadata->size));
270116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const int result =
271116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      reader.Read(io_buffer.get(),
2721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                  fake_file_->metadata->size,
273116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                  base::Bind(&EventLogger::OnRead, logger.GetWeakPtr()));
274116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
275116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(net::ERR_IO_PENDING, result);
276116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  base::RunLoop().RunUntilIdle();
277116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
278116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ASSERT_EQ(1u, logger.results().size());
279116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(net::ERR_UPLOAD_FILE_CHANGED, logger.results()[0]);
280116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
281116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
282116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_F(FileSystemProviderFileStreamReader, Read_ExpectedModificationTimeNull) {
283116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EventLogger logger;
284116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
285116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const int64 initial_offset = 0;
286116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  FileStreamReader reader(NULL, file_url_, initial_offset, base::Time());
287116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
288116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_refptr<net::IOBuffer> io_buffer(
2891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new net::IOBuffer(fake_file_->metadata->size));
290116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const int result =
291116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      reader.Read(io_buffer.get(),
2921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                  fake_file_->metadata->size,
293116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                  base::Bind(&EventLogger::OnRead, logger.GetWeakPtr()));
294116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
295116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(net::ERR_IO_PENDING, result);
296116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  base::RunLoop().RunUntilIdle();
297116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
298116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ASSERT_EQ(1u, logger.results().size());
2991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(fake_file_->metadata->size, logger.results()[0]);
300116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
3011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::string buffer_as_string(io_buffer->data(), fake_file_->metadata->size);
3021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(fake_file_->contents, buffer_as_string);
303cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
304cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
305cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST_F(FileSystemProviderFileStreamReader, GetLength) {
306cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EventLogger logger;
307cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
308cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const int64 initial_offset = 0;
309116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  FileStreamReader reader(
3101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      NULL, file_url_, initial_offset, fake_file_->metadata->modification_time);
311cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
312cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const int result = reader.GetLength(
313cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::Bind(&EventLogger::OnGetLength, logger.GetWeakPtr()));
314cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(net::ERR_IO_PENDING, result);
315cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::RunLoop().RunUntilIdle();
316cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
317cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ASSERT_EQ(1u, logger.results().size());
318cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_LT(0, logger.results()[0]);
3191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(fake_file_->metadata->size, logger.results()[0]);
320cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
321cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
322cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST_F(FileSystemProviderFileStreamReader, GetLength_WrongFile) {
323cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EventLogger logger;
324cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
325cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const int64 initial_offset = 0;
326cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FileStreamReader reader(NULL,
327cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                          wrong_file_url_,
328cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                          initial_offset,
3291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                          fake_file_->metadata->modification_time);
330cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
331cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const int result = reader.GetLength(
332cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::Bind(&EventLogger::OnGetLength, logger.GetWeakPtr()));
333cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(net::ERR_IO_PENDING, result);
334cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::RunLoop().RunUntilIdle();
335cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
336cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ASSERT_EQ(1u, logger.results().size());
337cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(net::ERR_FILE_NOT_FOUND, logger.results()[0]);
338cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
339cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
340116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_F(FileSystemProviderFileStreamReader, GetLength_ModifiedFile) {
341116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EventLogger logger;
342116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
343116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const int64 initial_offset = 0;
344116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  FileStreamReader reader(NULL, file_url_, initial_offset, base::Time::Max());
345116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
346116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const int result = reader.GetLength(
347116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::Bind(&EventLogger::OnGetLength, logger.GetWeakPtr()));
348116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(net::ERR_IO_PENDING, result);
349116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  base::RunLoop().RunUntilIdle();
350116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
351116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ASSERT_EQ(1u, logger.results().size());
352116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(net::ERR_UPLOAD_FILE_CHANGED, logger.results()[0]);
353116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
354116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
355116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_F(FileSystemProviderFileStreamReader,
356116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch       GetLength_ExpectedModificationTimeNull) {
357116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EventLogger logger;
358116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
359116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const int64 initial_offset = 0;
360116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  FileStreamReader reader(NULL, file_url_, initial_offset, base::Time());
361116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
362116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const int result = reader.GetLength(
363116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::Bind(&EventLogger::OnGetLength, logger.GetWeakPtr()));
364116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(net::ERR_IO_PENDING, result);
365116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  base::RunLoop().RunUntilIdle();
366116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
367116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ASSERT_EQ(1u, logger.results().size());
368116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_LT(0, logger.results()[0]);
3691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(fake_file_->metadata->size, logger.results()[0]);
370116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
371116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
372cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}  // namespace file_system_provider
373cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}  // namespace chromeos
374