provider_async_file_util_unittest.cc revision 010d83a9304c5a91596085d917d248abff47903a
1// Copyright 2014 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 <string>
6#include <vector>
7
8#include "base/files/file.h"
9#include "base/files/file_path.h"
10#include "base/files/scoped_temp_dir.h"
11#include "base/memory/scoped_ptr.h"
12#include "base/memory/weak_ptr.h"
13#include "base/platform_file.h"
14#include "base/run_loop.h"
15#include "chrome/browser/chromeos/file_system_provider/fake_provided_file_system.h"
16#include "chrome/browser/chromeos/file_system_provider/fileapi/provider_async_file_util.h"
17#include "chrome/browser/chromeos/file_system_provider/service.h"
18#include "chrome/browser/chromeos/file_system_provider/service_factory.h"
19#include "chrome/test/base/testing_browser_process.h"
20#include "chrome/test/base/testing_profile.h"
21#include "chrome/test/base/testing_profile_manager.h"
22#include "content/public/test/test_browser_thread_bundle.h"
23#include "content/public/test/test_file_system_context.h"
24#include "extensions/browser/extension_registry.h"
25#include "testing/gtest/include/gtest/gtest.h"
26#include "webkit/browser/fileapi/async_file_util.h"
27#include "webkit/browser/fileapi/external_mount_points.h"
28#include "webkit/browser/fileapi/file_system_context.h"
29#include "webkit/browser/fileapi/file_system_url.h"
30#include "webkit/common/blob/shareable_file_reference.h"
31
32namespace chromeos {
33namespace file_system_provider {
34namespace {
35
36const char kExtensionId[] = "mbflcebpggnecokmikipoihdbecnjfoj";
37
38// Logs callbacks invocations on the tested operations.
39// TODO(mtomasz): Store and verify more arguments, once the operations return
40// anything else than just an error.
41class EventLogger {
42 public:
43  EventLogger() : weak_ptr_factory_(this) {}
44  virtual ~EventLogger() {}
45
46  void OnStatus(base::File::Error error) {
47    error_.reset(new base::File::Error(error));
48  }
49
50  void OnCreateOrOpen(base::File::Error error,
51                      base::PassPlatformFile platform_file,
52                      const base::Closure& on_close_callback) {
53    error_.reset(new base::File::Error(error));
54  }
55
56  void OnEnsureFileExists(base::File::Error error, bool created) {
57    error_.reset(new base::File::Error(error));
58  }
59
60  void OnGetFileInfo(base::File::Error error,
61                     const base::File::Info& file_info) {
62    error_.reset(new base::File::Error(error));
63  }
64
65  void OnReadDirectory(base::File::Error error,
66                       const fileapi::AsyncFileUtil::EntryList& file_list,
67                       bool has_more) {
68    error_.reset(new base::File::Error(error));
69  }
70
71  void OnCreateSnapshotFile(
72      base::File::Error error,
73      const base::File::Info& file_info,
74      const base::FilePath& platform_path,
75      const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref) {
76    error_.reset(new base::File::Error(error));
77  }
78
79  void OnCopyFileProgress(int64 size) {}
80
81  base::WeakPtr<EventLogger> GetWeakPtr() {
82    return weak_ptr_factory_.GetWeakPtr();
83  }
84
85  base::File::Error* error() { return error_.get(); }
86
87 private:
88  scoped_ptr<base::File::Error> error_;
89  base::WeakPtrFactory<EventLogger> weak_ptr_factory_;
90
91  DISALLOW_COPY_AND_ASSIGN(EventLogger);
92};
93
94// Creates a cracked FileSystemURL for tests.
95fileapi::FileSystemURL CreateFileSystemURL(const std::string& mount_point_name,
96                                           const base::FilePath& file_path) {
97  const std::string origin = std::string("chrome-extension://") + kExtensionId;
98  const fileapi::ExternalMountPoints* const mount_points =
99      fileapi::ExternalMountPoints::GetSystemInstance();
100  return mount_points->CreateCrackedFileSystemURL(
101      GURL(origin),
102      fileapi::kFileSystemTypeExternal,
103      base::FilePath::FromUTF8Unsafe(mount_point_name).Append(file_path));
104}
105
106// Creates a Service instance. Used to be able to destroy the service in
107// TearDown().
108KeyedService* CreateService(content::BrowserContext* context) {
109  return new Service(Profile::FromBrowserContext(context),
110                     extensions::ExtensionRegistry::Get(context));
111}
112
113}  // namespace
114
115// Tests in this file are very lightweight and just test integration between
116// AsyncFileUtil and ProvideFileSystemInterface. Currently it tests if not
117// implemented operations return a correct error code. For not allowed
118// operations it is FILE_ERROR_SECURITY, and for not implemented the error is
119// FILE_ERROR_NOT_FOUND.
120class FileSystemProviderProviderAsyncFileUtilTest : public testing::Test {
121 protected:
122  FileSystemProviderProviderAsyncFileUtilTest() {}
123  virtual ~FileSystemProviderProviderAsyncFileUtilTest() {}
124
125  virtual void SetUp() OVERRIDE {
126    ASSERT_TRUE(data_dir_.CreateUniqueTempDir());
127    profile_manager_.reset(
128        new TestingProfileManager(TestingBrowserProcess::GetGlobal()));
129    ASSERT_TRUE(profile_manager_->SetUp());
130    profile_ = profile_manager_->CreateTestingProfile("testing-profile");
131    async_file_util_.reset(new internal::ProviderAsyncFileUtil);
132
133    file_system_context_ =
134        content::CreateFileSystemContextForTesting(NULL, data_dir_.path());
135
136    ServiceFactory::GetInstance()->SetTestingFactory(profile_, &CreateService);
137    Service* service = Service::Get(profile_);  // Owned by its factory.
138    service->SetFileSystemFactoryForTests(
139        base::Bind(&FakeProvidedFileSystem::Create));
140
141    const int file_system_id =
142        service->MountFileSystem(kExtensionId, "testing-file-system");
143    ASSERT_LT(0, file_system_id);
144    const ProvidedFileSystemInfo& file_system_info =
145        service->GetProvidedFileSystem(kExtensionId, file_system_id)
146            ->GetFileSystemInfo();
147    const std::string mount_point_name =
148        file_system_info.mount_path().BaseName().AsUTF8Unsafe();
149
150    file_url_ = CreateFileSystemURL(
151        mount_point_name, base::FilePath::FromUTF8Unsafe("hello/world.txt"));
152    ASSERT_TRUE(file_url_.is_valid());
153    directory_url_ = CreateFileSystemURL(
154        mount_point_name, base::FilePath::FromUTF8Unsafe("hello"));
155    ASSERT_TRUE(directory_url_.is_valid());
156    root_url_ = CreateFileSystemURL(mount_point_name, base::FilePath());
157    ASSERT_TRUE(root_url_.is_valid());
158  }
159
160  virtual void TearDown() OVERRIDE {
161    // Setting the testing factory to NULL will destroy the created service
162    // associated with the testing profile.
163    ServiceFactory::GetInstance()->SetTestingFactory(profile_, NULL);
164  }
165
166  scoped_ptr<fileapi::FileSystemOperationContext> CreateOperationContext() {
167    return make_scoped_ptr(
168        new fileapi::FileSystemOperationContext(file_system_context_.get()));
169  }
170
171  content::TestBrowserThreadBundle thread_bundle_;
172  base::ScopedTempDir data_dir_;
173  scoped_ptr<TestingProfileManager> profile_manager_;
174  TestingProfile* profile_;  // Owned by TestingProfileManager.
175  scoped_ptr<fileapi::AsyncFileUtil> async_file_util_;
176  scoped_refptr<fileapi::FileSystemContext> file_system_context_;
177  fileapi::FileSystemURL file_url_;
178  fileapi::FileSystemURL directory_url_;
179  fileapi::FileSystemURL root_url_;
180};
181
182TEST_F(FileSystemProviderProviderAsyncFileUtilTest, CreateOrOpen_Create) {
183  EventLogger logger;
184
185  async_file_util_->CreateOrOpen(
186      CreateOperationContext(),
187      file_url_,
188      base::PLATFORM_FILE_CREATE,
189      base::Bind(&EventLogger::OnCreateOrOpen, logger.GetWeakPtr()));
190
191  ASSERT_TRUE(logger.error());
192  EXPECT_EQ(base::File::FILE_ERROR_SECURITY, *logger.error());
193}
194
195TEST_F(FileSystemProviderProviderAsyncFileUtilTest, CreateOrOpen_CreateAlways) {
196  EventLogger logger;
197
198  async_file_util_->CreateOrOpen(
199      CreateOperationContext(),
200      file_url_,
201      base::PLATFORM_FILE_CREATE_ALWAYS,
202      base::Bind(&EventLogger::OnCreateOrOpen, logger.GetWeakPtr()));
203
204  ASSERT_TRUE(logger.error());
205  EXPECT_EQ(base::File::FILE_ERROR_SECURITY, *logger.error());
206}
207
208TEST_F(FileSystemProviderProviderAsyncFileUtilTest, CreateOrOpen_OpenAlways) {
209  EventLogger logger;
210
211  async_file_util_->CreateOrOpen(
212      CreateOperationContext(),
213      file_url_,
214      base::PLATFORM_FILE_OPEN_ALWAYS,
215      base::Bind(&EventLogger::OnCreateOrOpen, logger.GetWeakPtr()));
216
217  ASSERT_TRUE(logger.error());
218  EXPECT_EQ(base::File::FILE_ERROR_SECURITY, *logger.error());
219}
220
221TEST_F(FileSystemProviderProviderAsyncFileUtilTest,
222       CreateOrOpen_OpenTruncated) {
223  EventLogger logger;
224
225  async_file_util_->CreateOrOpen(
226      CreateOperationContext(),
227      file_url_,
228      base::PLATFORM_FILE_OPEN_TRUNCATED,
229      base::Bind(&EventLogger::OnCreateOrOpen, logger.GetWeakPtr()));
230
231  ASSERT_TRUE(logger.error());
232  EXPECT_EQ(base::File::FILE_ERROR_SECURITY, *logger.error());
233}
234
235TEST_F(FileSystemProviderProviderAsyncFileUtilTest, CreateOrOpen_Open) {
236  EventLogger logger;
237
238  async_file_util_->CreateOrOpen(
239      CreateOperationContext(),
240      file_url_,
241      base::PLATFORM_FILE_OPEN,
242      base::Bind(&EventLogger::OnCreateOrOpen, logger.GetWeakPtr()));
243
244  ASSERT_TRUE(logger.error());
245  EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND, *logger.error());
246}
247
248TEST_F(FileSystemProviderProviderAsyncFileUtilTest, EnsureFileExists) {
249  EventLogger logger;
250
251  async_file_util_->EnsureFileExists(
252      CreateOperationContext(),
253      file_url_,
254      base::Bind(&EventLogger::OnEnsureFileExists, logger.GetWeakPtr()));
255
256  ASSERT_TRUE(logger.error());
257  EXPECT_EQ(base::File::FILE_ERROR_SECURITY, *logger.error());
258}
259
260TEST_F(FileSystemProviderProviderAsyncFileUtilTest, CreateDirectory) {
261  EventLogger logger;
262
263  async_file_util_->CreateDirectory(
264      CreateOperationContext(),
265      directory_url_,
266      false,  // exclusive
267      false,  // recursive
268      base::Bind(&EventLogger::OnStatus, logger.GetWeakPtr()));
269
270  ASSERT_TRUE(logger.error());
271  EXPECT_EQ(base::File::FILE_ERROR_SECURITY, *logger.error());
272}
273
274TEST_F(FileSystemProviderProviderAsyncFileUtilTest, GetFileInfo) {
275  EventLogger logger;
276
277  async_file_util_->GetFileInfo(
278      CreateOperationContext(),
279      root_url_,
280      base::Bind(&EventLogger::OnGetFileInfo, logger.GetWeakPtr()));
281  base::RunLoop().RunUntilIdle();
282
283  ASSERT_TRUE(logger.error());
284  EXPECT_EQ(base::File::FILE_OK, *logger.error());
285}
286
287TEST_F(FileSystemProviderProviderAsyncFileUtilTest, ReadDirectory) {
288  EventLogger logger;
289
290  async_file_util_->ReadDirectory(
291      CreateOperationContext(),
292      root_url_,
293      base::Bind(&EventLogger::OnReadDirectory, logger.GetWeakPtr()));
294  base::RunLoop().RunUntilIdle();
295
296  ASSERT_TRUE(logger.error());
297  EXPECT_EQ(base::File::FILE_OK, *logger.error());
298}
299
300TEST_F(FileSystemProviderProviderAsyncFileUtilTest, Touch) {
301  EventLogger logger;
302
303  async_file_util_->CreateDirectory(
304      CreateOperationContext(),
305      file_url_,
306      false,  // exclusive
307      false,  // recursive
308      base::Bind(&EventLogger::OnStatus, logger.GetWeakPtr()));
309
310  ASSERT_TRUE(logger.error());
311  EXPECT_EQ(base::File::FILE_ERROR_SECURITY, *logger.error());
312}
313
314TEST_F(FileSystemProviderProviderAsyncFileUtilTest, Truncate) {
315  EventLogger logger;
316
317  async_file_util_->Truncate(
318      CreateOperationContext(),
319      file_url_,
320      0,  // length
321      base::Bind(&EventLogger::OnStatus, logger.GetWeakPtr()));
322
323  ASSERT_TRUE(logger.error());
324  EXPECT_EQ(base::File::FILE_ERROR_SECURITY, *logger.error());
325}
326
327TEST_F(FileSystemProviderProviderAsyncFileUtilTest, CopyFileLocal) {
328  EventLogger logger;
329
330  async_file_util_->CopyFileLocal(
331      CreateOperationContext(),
332      file_url_,  // src_url
333      file_url_,  // dst_url
334      fileapi::FileSystemOperation::OPTION_NONE,
335      base::Bind(&EventLogger::OnCopyFileProgress, logger.GetWeakPtr()),
336      base::Bind(&EventLogger::OnStatus, logger.GetWeakPtr()));
337
338  ASSERT_TRUE(logger.error());
339  EXPECT_EQ(base::File::FILE_ERROR_SECURITY, *logger.error());
340}
341
342TEST_F(FileSystemProviderProviderAsyncFileUtilTest, MoveFileLocal) {
343  EventLogger logger;
344
345  async_file_util_->MoveFileLocal(
346      CreateOperationContext(),
347      file_url_,  // src_url
348      file_url_,  // dst_url
349      fileapi::FileSystemOperation::OPTION_NONE,
350      base::Bind(&EventLogger::OnStatus, logger.GetWeakPtr()));
351
352  ASSERT_TRUE(logger.error());
353  EXPECT_EQ(base::File::FILE_ERROR_SECURITY, *logger.error());
354}
355
356TEST_F(FileSystemProviderProviderAsyncFileUtilTest, CopyInForeignFile) {
357  EventLogger logger;
358
359  async_file_util_->CopyInForeignFile(
360      CreateOperationContext(),
361      base::FilePath(),  // src_file_path
362      file_url_,         // dst_url
363      base::Bind(&EventLogger::OnStatus, logger.GetWeakPtr()));
364
365  ASSERT_TRUE(logger.error());
366  EXPECT_EQ(base::File::FILE_ERROR_SECURITY, *logger.error());
367}
368
369TEST_F(FileSystemProviderProviderAsyncFileUtilTest, DeleteFile) {
370  EventLogger logger;
371
372  async_file_util_->DeleteFile(
373      CreateOperationContext(),
374      file_url_,
375      base::Bind(&EventLogger::OnStatus, logger.GetWeakPtr()));
376
377  ASSERT_TRUE(logger.error());
378  EXPECT_EQ(base::File::FILE_ERROR_SECURITY, *logger.error());
379}
380
381TEST_F(FileSystemProviderProviderAsyncFileUtilTest, DeleteDirectory) {
382  EventLogger logger;
383
384  async_file_util_->DeleteDirectory(
385      CreateOperationContext(),
386      directory_url_,
387      base::Bind(&EventLogger::OnStatus, logger.GetWeakPtr()));
388
389  ASSERT_TRUE(logger.error());
390  EXPECT_EQ(base::File::FILE_ERROR_SECURITY, *logger.error());
391}
392
393TEST_F(FileSystemProviderProviderAsyncFileUtilTest, DeleteRecursively) {
394  EventLogger logger;
395
396  async_file_util_->DeleteRecursively(
397      CreateOperationContext(),
398      directory_url_,
399      base::Bind(&EventLogger::OnStatus, logger.GetWeakPtr()));
400
401  ASSERT_TRUE(logger.error());
402  EXPECT_EQ(base::File::FILE_ERROR_SECURITY, *logger.error());
403}
404
405TEST_F(FileSystemProviderProviderAsyncFileUtilTest, CreateSnapshotFile) {
406  EventLogger logger;
407
408  async_file_util_->CreateSnapshotFile(
409      CreateOperationContext(),
410      file_url_,
411      base::Bind(&EventLogger::OnCreateSnapshotFile, logger.GetWeakPtr()));
412
413  ASSERT_TRUE(logger.error());
414  EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND, *logger.error());
415}
416
417}  // namespace file_system_provider
418}  // namespace chromeos
419