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.
10 #include "base/files/file.h"
11 #include "base/files/file_path.h"
12 #include "base/files/file_util.h"
13 #include "base/files/scoped_temp_dir.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/run_loop.h"
16 #include "content/browser/fileapi/mock_file_change_observer.h"
17 #include "content/public/test/async_file_test_helper.h"
18 #include "content/public/test/mock_special_storage_policy.h"
19 #include "content/public/test/sandbox_file_system_test_helper.h"
20 #include "content/public/test/test_file_system_context.h"
21 #include "content/test/fileapi_test_file_set.h"
22 #include "storage/browser/fileapi/external_mount_points.h"
23 #include "storage/browser/fileapi/file_system_backend.h"
24 #include "storage/browser/fileapi/file_system_context.h"
25 #include "storage/browser/fileapi/file_system_operation_context.h"
26 #include "storage/browser/fileapi/file_system_usage_cache.h"
27 #include "storage/browser/fileapi/obfuscated_file_util.h"
28 #include "storage/browser/fileapi/sandbox_directory_database.h"
29 #include "storage/browser/fileapi/sandbox_file_system_backend_delegate.h"
30 #include "storage/browser/fileapi/sandbox_isolated_origin_database.h"
31 #include "storage/browser/fileapi/sandbox_origin_database.h"
32 #include "storage/browser/quota/quota_manager.h"
33 #include "storage/common/database/database_identifier.h"
34 #include "storage/common/quota/quota_types.h"
35 #include "testing/gtest/include/gtest/gtest.h"
37 using content::AsyncFileTestHelper
;
38 using storage::FileSystemContext
;
39 using storage::FileSystemOperation
;
40 using storage::FileSystemOperationContext
;
41 using storage::FileSystemURL
;
42 using storage::ObfuscatedFileUtil
;
43 using storage::SandboxDirectoryDatabase
;
44 using storage::SandboxIsolatedOriginDatabase
;
45 using storage::kFileSystemTypeTemporary
;
46 using storage::kFileSystemTypePersistent
;
52 bool FileExists(const base::FilePath
& path
) {
53 return base::PathExists(path
) && !base::DirectoryExists(path
);
56 int64
GetSize(const base::FilePath
& path
) {
58 EXPECT_TRUE(base::GetFileSize(path
, &size
));
62 // After a move, the dest exists and the source doesn't.
63 // After a copy, both source and dest exist.
64 struct CopyMoveTestCaseRecord
{
65 bool is_copy_not_move
;
66 const char source_path
[64];
67 const char dest_path
[64];
71 const CopyMoveTestCaseRecord kCopyMoveTestCases
[] = {
72 // This is the combinatoric set of:
73 // rename vs. same-name
74 // different directory vs. same directory
75 // overwrite vs. no-overwrite
77 // We can never be called with source and destination paths identical, so
78 // those cases are omitted.
79 {true, "dir0/file0", "dir0/file1", false},
80 {false, "dir0/file0", "dir0/file1", false},
81 {true, "dir0/file0", "dir0/file1", true},
82 {false, "dir0/file0", "dir0/file1", true},
84 {true, "dir0/file0", "dir1/file0", false},
85 {false, "dir0/file0", "dir1/file0", false},
86 {true, "dir0/file0", "dir1/file0", true},
87 {false, "dir0/file0", "dir1/file0", true},
88 {true, "dir0/file0", "dir1/file1", false},
89 {false, "dir0/file0", "dir1/file1", false},
90 {true, "dir0/file0", "dir1/file1", true},
91 {false, "dir0/file0", "dir1/file1", true},
94 struct OriginEnumerationTestRecord
{
95 std::string origin_url
;
100 const OriginEnumerationTestRecord kOriginEnumerationTestRecords
[] = {
101 {"http://example.com", false, true},
102 {"http://example1.com", true, false},
103 {"https://example1.com", true, true},
104 {"file://", false, true},
105 {"http://example.com:8000", false, true},
108 FileSystemURL
FileSystemURLAppend(
109 const FileSystemURL
& url
, const base::FilePath::StringType
& child
) {
110 return FileSystemURL::CreateForTest(
111 url
.origin(), url
.mount_type(), url
.virtual_path().Append(child
));
114 FileSystemURL
FileSystemURLAppendUTF8(
115 const FileSystemURL
& url
, const std::string
& child
) {
116 return FileSystemURL::CreateForTest(
119 url
.virtual_path().Append(base::FilePath::FromUTF8Unsafe(child
)));
122 FileSystemURL
FileSystemURLDirName(const FileSystemURL
& url
) {
123 return FileSystemURL::CreateForTest(
126 storage::VirtualPath::DirName(url
.virtual_path()));
129 std::string
GetTypeString(storage::FileSystemType type
) {
130 return storage::SandboxFileSystemBackendDelegate::GetTypeString(type
);
133 bool HasFileSystemType(ObfuscatedFileUtil::AbstractOriginEnumerator
* enumerator
,
134 storage::FileSystemType type
) {
135 return enumerator
->HasTypeDirectory(GetTypeString(type
));
140 // TODO(ericu): The vast majority of this and the other FSFU subclass tests
141 // could theoretically be shared. It would basically be a FSFU interface
142 // compliance test, and only the subclass-specific bits that look into the
143 // implementation would need to be written per-subclass.
144 class ObfuscatedFileUtilTest
: public testing::Test
{
146 ObfuscatedFileUtilTest()
147 : origin_(GURL("http://www.example.com")),
148 type_(storage::kFileSystemTypeTemporary
),
149 sandbox_file_system_(origin_
, type_
),
150 quota_status_(storage::kQuotaStatusUnknown
),
152 weak_factory_(this) {}
154 void SetUp() override
{
155 ASSERT_TRUE(data_dir_
.CreateUniqueTempDir());
157 storage_policy_
= new MockSpecialStoragePolicy();
160 new storage::QuotaManager(false /* is_incognito */,
162 base::MessageLoopProxy::current().get(),
163 base::MessageLoopProxy::current().get(),
164 storage_policy_
.get());
166 // Every time we create a new sandbox_file_system helper,
167 // it creates another context, which creates another path manager,
168 // another sandbox_backend, and another OFU.
169 // We need to pass in the context to skip all that.
170 file_system_context_
= CreateFileSystemContextForTesting(
171 quota_manager_
->proxy(),
174 sandbox_file_system_
.SetUp(file_system_context_
.get());
177 storage::MockFileChangeObserver::CreateList(&change_observer_
);
180 void TearDown() override
{
181 quota_manager_
= NULL
;
182 sandbox_file_system_
.TearDown();
185 scoped_ptr
<FileSystemOperationContext
> LimitedContext(
186 int64 allowed_bytes_growth
) {
187 scoped_ptr
<FileSystemOperationContext
> context(
188 sandbox_file_system_
.NewOperationContext());
189 context
->set_allowed_bytes_growth(allowed_bytes_growth
);
190 return context
.Pass();
193 scoped_ptr
<FileSystemOperationContext
> UnlimitedContext() {
194 return LimitedContext(kint64max
);
197 FileSystemOperationContext
* NewContext(
198 SandboxFileSystemTestHelper
* file_system
) {
199 change_observer()->ResetCount();
200 FileSystemOperationContext
* context
;
202 context
= file_system
->NewOperationContext();
204 context
= sandbox_file_system_
.NewOperationContext();
205 // Setting allowed_bytes_growth big enough for all tests.
206 context
->set_allowed_bytes_growth(1024 * 1024);
207 context
->set_change_observers(change_observers());
211 const storage::ChangeObserverList
& change_observers() const {
212 return change_observers_
;
215 storage::MockFileChangeObserver
* change_observer() {
216 return &change_observer_
;
219 // This can only be used after SetUp has run and created file_system_context_
220 // and obfuscated_file_util_.
221 // Use this for tests which need to run in multiple origins; we need a test
222 // helper per origin.
223 SandboxFileSystemTestHelper
* NewFileSystem(const GURL
& origin
,
224 storage::FileSystemType type
) {
225 SandboxFileSystemTestHelper
* file_system
=
226 new SandboxFileSystemTestHelper(origin
, type
);
228 file_system
->SetUp(file_system_context_
.get());
232 scoped_ptr
<ObfuscatedFileUtil
> CreateObfuscatedFileUtil(
233 storage::SpecialStoragePolicy
* storage_policy
) {
234 return scoped_ptr
<ObfuscatedFileUtil
>(
235 ObfuscatedFileUtil::CreateForTesting(
236 storage_policy
, data_dir_path(), NULL
,
237 base::MessageLoopProxy::current().get()));
240 ObfuscatedFileUtil
* ofu() {
241 return static_cast<ObfuscatedFileUtil
*>(sandbox_file_system_
.file_util());
244 const base::FilePath
& test_directory() const {
245 return data_dir_
.path();
248 const GURL
& origin() const {
252 storage::FileSystemType
type() const { return type_
; }
254 std::string
type_string() const {
255 return GetTypeString(type_
);
258 int64
ComputeTotalFileSize() {
259 return sandbox_file_system_
.ComputeCurrentOriginUsage() -
260 sandbox_file_system_
.ComputeCurrentDirectoryDatabaseUsage();
263 void GetUsageFromQuotaManager() {
266 AsyncFileTestHelper::GetUsageAndQuota(quota_manager_
.get(),
268 sandbox_file_system_
.type(),
271 EXPECT_EQ(storage::kQuotaStatusOk
, quota_status_
);
274 void RevokeUsageCache() {
275 quota_manager_
->ResetUsageTracker(sandbox_file_system_
.storage_type());
276 usage_cache()->Delete(sandbox_file_system_
.GetUsageCachePath());
279 int64
SizeByQuotaUtil() {
280 return sandbox_file_system_
.GetCachedOriginUsage();
283 int64
SizeInUsageFile() {
284 base::RunLoop().RunUntilIdle();
286 return usage_cache()->GetUsage(
287 sandbox_file_system_
.GetUsageCachePath(), &usage
) ? usage
: -1;
290 bool PathExists(const FileSystemURL
& url
) {
291 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
292 base::File::Info file_info
;
293 base::FilePath platform_path
;
294 base::File::Error error
= ofu()->GetFileInfo(
295 context
.get(), url
, &file_info
, &platform_path
);
296 return error
== base::File::FILE_OK
;
299 bool DirectoryExists(const FileSystemURL
& url
) {
300 return AsyncFileTestHelper::DirectoryExists(file_system_context(), url
);
303 int64
usage() const { return usage_
; }
304 storage::FileSystemUsageCache
* usage_cache() {
305 return sandbox_file_system_
.usage_cache();
308 FileSystemURL
CreateURLFromUTF8(const std::string
& path
) {
309 return sandbox_file_system_
.CreateURLFromUTF8(path
);
312 int64
PathCost(const FileSystemURL
& url
) {
313 return ObfuscatedFileUtil::ComputeFilePathCost(url
.path());
316 FileSystemURL
CreateURL(const base::FilePath
& path
) {
317 return sandbox_file_system_
.CreateURL(path
);
320 void CheckFileAndCloseHandle(const FileSystemURL
& url
, base::File file
) {
321 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
322 base::FilePath local_path
;
323 EXPECT_EQ(base::File::FILE_OK
,
324 ofu()->GetLocalFilePath(context
.get(), url
, &local_path
));
326 base::File::Info file_info0
;
327 base::FilePath data_path
;
328 EXPECT_EQ(base::File::FILE_OK
,
329 ofu()->GetFileInfo(context
.get(), url
, &file_info0
, &data_path
));
330 EXPECT_EQ(data_path
, local_path
);
331 EXPECT_TRUE(FileExists(data_path
));
332 EXPECT_EQ(0, GetSize(data_path
));
334 const char data
[] = "test data";
335 const int length
= arraysize(data
) - 1;
337 if (!file
.IsValid()) {
338 file
.Initialize(data_path
,
339 base::File::FLAG_OPEN
| base::File::FLAG_WRITE
);
340 ASSERT_TRUE(file
.IsValid());
341 EXPECT_FALSE(file
.created());
343 ASSERT_EQ(length
, file
.Write(0, data
, length
));
346 base::File::Info file_info1
;
347 EXPECT_EQ(length
, GetSize(data_path
));
348 context
.reset(NewContext(NULL
));
349 EXPECT_EQ(base::File::FILE_OK
,
350 ofu()->GetFileInfo(context
.get(), url
, &file_info1
, &data_path
));
351 EXPECT_EQ(data_path
, local_path
);
353 EXPECT_FALSE(file_info0
.is_directory
);
354 EXPECT_FALSE(file_info1
.is_directory
);
355 EXPECT_FALSE(file_info0
.is_symbolic_link
);
356 EXPECT_FALSE(file_info1
.is_symbolic_link
);
357 EXPECT_EQ(0, file_info0
.size
);
358 EXPECT_EQ(length
, file_info1
.size
);
359 EXPECT_LE(file_info0
.last_modified
, file_info1
.last_modified
);
361 context
.reset(NewContext(NULL
));
362 EXPECT_EQ(base::File::FILE_OK
,
363 ofu()->Truncate(context
.get(), url
, length
* 2));
364 EXPECT_EQ(length
* 2, GetSize(data_path
));
366 context
.reset(NewContext(NULL
));
367 EXPECT_EQ(base::File::FILE_OK
,
368 ofu()->Truncate(context
.get(), url
, 0));
369 EXPECT_EQ(0, GetSize(data_path
));
372 void ValidateTestDirectory(
373 const FileSystemURL
& root_url
,
374 const std::set
<base::FilePath::StringType
>& files
,
375 const std::set
<base::FilePath::StringType
>& directories
) {
376 scoped_ptr
<FileSystemOperationContext
> context
;
377 std::set
<base::FilePath::StringType
>::const_iterator iter
;
378 for (iter
= files
.begin(); iter
!= files
.end(); ++iter
) {
380 context
.reset(NewContext(NULL
));
381 ASSERT_EQ(base::File::FILE_OK
,
382 ofu()->EnsureFileExists(context
.get(),
383 FileSystemURLAppend(root_url
, *iter
),
385 ASSERT_FALSE(created
);
387 for (iter
= directories
.begin(); iter
!= directories
.end(); ++iter
) {
388 context
.reset(NewContext(NULL
));
389 EXPECT_TRUE(DirectoryExists(
390 FileSystemURLAppend(root_url
, *iter
)));
394 class UsageVerifyHelper
{
396 UsageVerifyHelper(scoped_ptr
<FileSystemOperationContext
> context
,
397 SandboxFileSystemTestHelper
* file_system
,
398 int64 expected_usage
)
399 : context_(context
.Pass()),
400 sandbox_file_system_(file_system
),
401 expected_usage_(expected_usage
) {}
403 ~UsageVerifyHelper() {
404 base::RunLoop().RunUntilIdle();
408 FileSystemOperationContext
* context() {
409 return context_
.get();
414 ASSERT_EQ(expected_usage_
,
415 sandbox_file_system_
->GetCachedOriginUsage());
418 scoped_ptr
<FileSystemOperationContext
> context_
;
419 SandboxFileSystemTestHelper
* sandbox_file_system_
;
420 int64 expected_usage_
;
423 scoped_ptr
<UsageVerifyHelper
> AllowUsageIncrease(int64 requested_growth
) {
424 int64 usage
= sandbox_file_system_
.GetCachedOriginUsage();
425 return scoped_ptr
<UsageVerifyHelper
>(new UsageVerifyHelper(
426 LimitedContext(requested_growth
),
427 &sandbox_file_system_
, usage
+ requested_growth
));
430 scoped_ptr
<UsageVerifyHelper
> DisallowUsageIncrease(int64 requested_growth
) {
431 int64 usage
= sandbox_file_system_
.GetCachedOriginUsage();
432 return scoped_ptr
<UsageVerifyHelper
>(new UsageVerifyHelper(
433 LimitedContext(requested_growth
- 1), &sandbox_file_system_
, usage
));
436 void FillTestDirectory(
437 const FileSystemURL
& root_url
,
438 std::set
<base::FilePath::StringType
>* files
,
439 std::set
<base::FilePath::StringType
>* directories
) {
440 scoped_ptr
<FileSystemOperationContext
> context
;
441 std::vector
<storage::DirectoryEntry
> entries
;
442 EXPECT_EQ(base::File::FILE_OK
,
443 AsyncFileTestHelper::ReadDirectory(file_system_context(),
444 root_url
, &entries
));
445 EXPECT_EQ(0UL, entries
.size());
448 files
->insert(FILE_PATH_LITERAL("first"));
449 files
->insert(FILE_PATH_LITERAL("second"));
450 files
->insert(FILE_PATH_LITERAL("third"));
451 directories
->clear();
452 directories
->insert(FILE_PATH_LITERAL("fourth"));
453 directories
->insert(FILE_PATH_LITERAL("fifth"));
454 directories
->insert(FILE_PATH_LITERAL("sixth"));
455 std::set
<base::FilePath::StringType
>::iterator iter
;
456 for (iter
= files
->begin(); iter
!= files
->end(); ++iter
) {
457 bool created
= false;
458 context
.reset(NewContext(NULL
));
459 ASSERT_EQ(base::File::FILE_OK
,
460 ofu()->EnsureFileExists(context
.get(),
461 FileSystemURLAppend(root_url
, *iter
),
463 ASSERT_TRUE(created
);
465 for (iter
= directories
->begin(); iter
!= directories
->end(); ++iter
) {
466 bool exclusive
= true;
467 bool recursive
= false;
468 context
.reset(NewContext(NULL
));
469 EXPECT_EQ(base::File::FILE_OK
,
470 ofu()->CreateDirectory(context
.get(),
471 FileSystemURLAppend(root_url
, *iter
),
472 exclusive
, recursive
));
474 ValidateTestDirectory(root_url
, *files
, *directories
);
477 void TestReadDirectoryHelper(const FileSystemURL
& root_url
) {
478 std::set
<base::FilePath::StringType
> files
;
479 std::set
<base::FilePath::StringType
> directories
;
480 FillTestDirectory(root_url
, &files
, &directories
);
482 scoped_ptr
<FileSystemOperationContext
> context
;
483 std::vector
<storage::DirectoryEntry
> entries
;
484 context
.reset(NewContext(NULL
));
485 EXPECT_EQ(base::File::FILE_OK
,
486 AsyncFileTestHelper::ReadDirectory(
487 file_system_context(), root_url
, &entries
));
488 std::vector
<storage::DirectoryEntry
>::iterator entry_iter
;
489 EXPECT_EQ(files
.size() + directories
.size(), entries
.size());
490 EXPECT_TRUE(change_observer()->HasNoChange());
491 for (entry_iter
= entries
.begin(); entry_iter
!= entries
.end();
493 const storage::DirectoryEntry
& entry
= *entry_iter
;
494 std::set
<base::FilePath::StringType
>::iterator iter
=
495 files
.find(entry
.name
);
496 if (iter
!= files
.end()) {
497 EXPECT_FALSE(entry
.is_directory
);
501 iter
= directories
.find(entry
.name
);
502 EXPECT_FALSE(directories
.end() == iter
);
503 EXPECT_TRUE(entry
.is_directory
);
504 directories
.erase(iter
);
508 void TestTouchHelper(const FileSystemURL
& url
, bool is_file
) {
509 base::Time last_access_time
= base::Time::Now();
510 base::Time last_modified_time
= base::Time::Now();
512 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
513 EXPECT_EQ(base::File::FILE_OK
,
514 ofu()->Touch(context
.get(), url
, last_access_time
,
515 last_modified_time
));
516 // Currently we fire no change notifications for Touch.
517 EXPECT_TRUE(change_observer()->HasNoChange());
518 base::FilePath local_path
;
519 base::File::Info file_info
;
520 context
.reset(NewContext(NULL
));
521 EXPECT_EQ(base::File::FILE_OK
, ofu()->GetFileInfo(
522 context
.get(), url
, &file_info
, &local_path
));
523 // We compare as time_t here to lower our resolution, to avoid false
524 // negatives caused by conversion to the local filesystem's native
525 // representation and back.
526 EXPECT_EQ(file_info
.last_modified
.ToTimeT(), last_modified_time
.ToTimeT());
528 context
.reset(NewContext(NULL
));
529 last_modified_time
+= base::TimeDelta::FromHours(1);
530 last_access_time
+= base::TimeDelta::FromHours(14);
531 EXPECT_EQ(base::File::FILE_OK
,
532 ofu()->Touch(context
.get(), url
, last_access_time
,
533 last_modified_time
));
534 EXPECT_TRUE(change_observer()->HasNoChange());
535 context
.reset(NewContext(NULL
));
536 EXPECT_EQ(base::File::FILE_OK
,
537 ofu()->GetFileInfo(context
.get(), url
, &file_info
, &local_path
));
538 EXPECT_EQ(file_info
.last_modified
.ToTimeT(), last_modified_time
.ToTimeT());
539 if (is_file
) // Directories in OFU don't support atime.
540 EXPECT_EQ(file_info
.last_accessed
.ToTimeT(), last_access_time
.ToTimeT());
543 void TestCopyInForeignFileHelper(bool overwrite
) {
544 base::ScopedTempDir source_dir
;
545 ASSERT_TRUE(source_dir
.CreateUniqueTempDir());
546 base::FilePath root_file_path
= source_dir
.path();
547 base::FilePath src_file_path
= root_file_path
.AppendASCII("file_name");
548 FileSystemURL dest_url
= CreateURLFromUTF8("new file");
549 int64 src_file_length
= 87;
551 base::File
file(src_file_path
,
552 base::File::FLAG_CREATE
| base::File::FLAG_WRITE
);
553 ASSERT_TRUE(file
.IsValid());
554 EXPECT_TRUE(file
.created());
555 ASSERT_TRUE(file
.SetLength(src_file_length
));
558 scoped_ptr
<FileSystemOperationContext
> context
;
561 context
.reset(NewContext(NULL
));
562 bool created
= false;
563 EXPECT_EQ(base::File::FILE_OK
,
564 ofu()->EnsureFileExists(context
.get(), dest_url
, &created
));
565 EXPECT_TRUE(created
);
567 // We must have observed one (and only one) create_file_count.
568 EXPECT_EQ(1, change_observer()->get_and_reset_create_file_count());
569 EXPECT_TRUE(change_observer()->HasNoChange());
572 const int64 path_cost
=
573 ObfuscatedFileUtil::ComputeFilePathCost(dest_url
.path());
575 // Verify that file creation requires sufficient quota for the path.
576 context
.reset(NewContext(NULL
));
577 context
->set_allowed_bytes_growth(path_cost
+ src_file_length
- 1);
578 EXPECT_EQ(base::File::FILE_ERROR_NO_SPACE
,
579 ofu()->CopyInForeignFile(context
.get(),
580 src_file_path
, dest_url
));
583 context
.reset(NewContext(NULL
));
584 context
->set_allowed_bytes_growth(path_cost
+ src_file_length
);
585 EXPECT_EQ(base::File::FILE_OK
,
586 ofu()->CopyInForeignFile(context
.get(),
587 src_file_path
, dest_url
));
589 EXPECT_TRUE(PathExists(dest_url
));
590 EXPECT_FALSE(DirectoryExists(dest_url
));
592 context
.reset(NewContext(NULL
));
593 base::File::Info file_info
;
594 base::FilePath data_path
;
595 EXPECT_EQ(base::File::FILE_OK
,
596 ofu()->GetFileInfo(context
.get(), dest_url
, &file_info
,
598 EXPECT_NE(data_path
, src_file_path
);
599 EXPECT_TRUE(FileExists(data_path
));
600 EXPECT_EQ(src_file_length
, GetSize(data_path
));
602 EXPECT_EQ(base::File::FILE_OK
,
603 ofu()->DeleteFile(context
.get(), dest_url
));
606 void ClearTimestamp(const FileSystemURL
& url
) {
607 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
608 EXPECT_EQ(base::File::FILE_OK
,
609 ofu()->Touch(context
.get(), url
, base::Time(), base::Time()));
610 EXPECT_EQ(base::Time(), GetModifiedTime(url
));
613 base::Time
GetModifiedTime(const FileSystemURL
& url
) {
614 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
615 base::FilePath data_path
;
616 base::File::Info file_info
;
617 context
.reset(NewContext(NULL
));
618 EXPECT_EQ(base::File::FILE_OK
,
619 ofu()->GetFileInfo(context
.get(), url
, &file_info
, &data_path
));
620 EXPECT_TRUE(change_observer()->HasNoChange());
621 return file_info
.last_modified
;
624 void TestDirectoryTimestampHelper(const FileSystemURL
& base_dir
,
627 scoped_ptr
<FileSystemOperationContext
> context
;
628 const FileSystemURL
src_dir_url(
629 FileSystemURLAppendUTF8(base_dir
, "foo_dir"));
630 const FileSystemURL
dest_dir_url(
631 FileSystemURLAppendUTF8(base_dir
, "bar_dir"));
633 const FileSystemURL
src_file_url(
634 FileSystemURLAppendUTF8(src_dir_url
, "hoge"));
635 const FileSystemURL
dest_file_url(
636 FileSystemURLAppendUTF8(dest_dir_url
, "fuga"));
638 context
.reset(NewContext(NULL
));
639 EXPECT_EQ(base::File::FILE_OK
,
640 ofu()->CreateDirectory(context
.get(), src_dir_url
, true, true));
641 context
.reset(NewContext(NULL
));
642 EXPECT_EQ(base::File::FILE_OK
,
643 ofu()->CreateDirectory(context
.get(), dest_dir_url
, true, true));
645 bool created
= false;
646 context
.reset(NewContext(NULL
));
647 EXPECT_EQ(base::File::FILE_OK
,
648 ofu()->EnsureFileExists(context
.get(), src_file_url
, &created
));
650 context
.reset(NewContext(NULL
));
651 EXPECT_EQ(base::File::FILE_OK
,
652 ofu()->EnsureFileExists(context
.get(),
653 dest_file_url
, &created
));
656 ClearTimestamp(src_dir_url
);
657 ClearTimestamp(dest_dir_url
);
658 context
.reset(NewContext(NULL
));
659 EXPECT_EQ(base::File::FILE_OK
,
660 ofu()->CopyOrMoveFile(context
.get(),
661 src_file_url
, dest_file_url
,
662 FileSystemOperation::OPTION_NONE
,
665 EXPECT_EQ(base::Time(), GetModifiedTime(src_dir_url
));
667 EXPECT_NE(base::Time(), GetModifiedTime(src_dir_url
));
668 EXPECT_NE(base::Time(), GetModifiedTime(dest_dir_url
));
671 void MaybeDropDatabasesAliveCaseTestBody() {
672 scoped_ptr
<ObfuscatedFileUtil
> file_util
= CreateObfuscatedFileUtil(NULL
);
673 file_util
->InitOriginDatabase(GURL(), true /*create*/);
674 ASSERT_TRUE(file_util
->origin_database_
!= NULL
);
676 // Callback to Drop DB is called while ObfuscatedFileUtilTest is
678 file_util
->db_flush_delay_seconds_
= 0;
679 file_util
->MarkUsed();
680 base::RunLoop().RunUntilIdle();
682 ASSERT_TRUE(file_util
->origin_database_
== NULL
);
685 void MaybeDropDatabasesAlreadyDeletedCaseTestBody() {
686 // Run message loop after OFU is already deleted to make sure callback
687 // doesn't cause a crash for use after free.
689 scoped_ptr
<ObfuscatedFileUtil
> file_util
= CreateObfuscatedFileUtil(NULL
);
690 file_util
->InitOriginDatabase(GURL(), true /*create*/);
691 file_util
->db_flush_delay_seconds_
= 0;
692 file_util
->MarkUsed();
695 // At this point the callback is still in the message queue but OFU is gone.
696 base::RunLoop().RunUntilIdle();
699 void DestroyDirectoryDatabase_IsolatedTestBody() {
700 storage_policy_
->AddIsolated(origin_
);
701 scoped_ptr
<ObfuscatedFileUtil
> file_util
= CreateObfuscatedFileUtil(
702 storage_policy_
.get());
703 const FileSystemURL url
= FileSystemURL::CreateForTest(
704 origin_
, kFileSystemTypePersistent
, base::FilePath());
706 // Create DirectoryDatabase for isolated origin.
707 SandboxDirectoryDatabase
* db
=
708 file_util
->GetDirectoryDatabase(url
, true /* create */);
709 ASSERT_TRUE(db
!= NULL
);
712 file_util
->DestroyDirectoryDatabase(
713 url
.origin(), GetTypeString(url
.type()));
714 ASSERT_TRUE(file_util
->directories_
.empty());
717 void GetDirectoryDatabase_IsolatedTestBody() {
718 storage_policy_
->AddIsolated(origin_
);
719 scoped_ptr
<ObfuscatedFileUtil
> file_util
= CreateObfuscatedFileUtil(
720 storage_policy_
.get());
721 const FileSystemURL url
= FileSystemURL::CreateForTest(
722 origin_
, kFileSystemTypePersistent
, base::FilePath());
724 // Create DirectoryDatabase for isolated origin.
725 SandboxDirectoryDatabase
* db
=
726 file_util
->GetDirectoryDatabase(url
, true /* create */);
727 ASSERT_TRUE(db
!= NULL
);
728 ASSERT_EQ(1U, file_util
->directories_
.size());
731 storage_policy_
->RemoveIsolated(url
.origin());
733 // This should still get the same database.
734 SandboxDirectoryDatabase
* db2
=
735 file_util
->GetDirectoryDatabase(url
, false /* create */);
739 void MigrationBackFromIsolatedTestBody() {
740 std::string
kFakeDirectoryData("0123456789");
741 base::FilePath old_directory_db_path
;
743 // Initialize the directory with one origin using
744 // SandboxIsolatedOriginDatabase.
746 std::string origin_string
= storage::GetIdentifierFromOrigin(origin_
);
747 SandboxIsolatedOriginDatabase
database_old(
748 origin_string
, data_dir_path(),
750 SandboxIsolatedOriginDatabase::kObsoleteOriginDirectory
));
752 EXPECT_TRUE(database_old
.GetPathForOrigin(origin_string
, &path
));
753 EXPECT_FALSE(path
.empty());
755 // Populate the origin directory with some fake data.
756 old_directory_db_path
= data_dir_path().Append(path
);
757 ASSERT_TRUE(base::CreateDirectory(old_directory_db_path
));
758 EXPECT_EQ(static_cast<int>(kFakeDirectoryData
.size()),
759 base::WriteFile(old_directory_db_path
.AppendASCII("dummy"),
760 kFakeDirectoryData
.data(),
761 kFakeDirectoryData
.size()));
764 storage_policy_
->AddIsolated(origin_
);
765 scoped_ptr
<ObfuscatedFileUtil
> file_util
= CreateObfuscatedFileUtil(
766 storage_policy_
.get());
767 base::File::Error error
= base::File::FILE_ERROR_FAILED
;
768 base::FilePath origin_directory
= file_util
->GetDirectoryForOrigin(
769 origin_
, true /* create */, &error
);
770 EXPECT_EQ(base::File::FILE_OK
, error
);
772 // The database is migrated from the old one.
773 EXPECT_TRUE(base::DirectoryExists(origin_directory
));
774 EXPECT_FALSE(base::DirectoryExists(old_directory_db_path
));
776 // Check we see the same contents in the new origin directory.
777 std::string origin_db_data
;
778 EXPECT_TRUE(base::PathExists(origin_directory
.AppendASCII("dummy")));
779 EXPECT_TRUE(base::ReadFileToString(
780 origin_directory
.AppendASCII("dummy"), &origin_db_data
));
781 EXPECT_EQ(kFakeDirectoryData
, origin_db_data
);
784 int64
ComputeCurrentUsage() {
785 return sandbox_file_system_
.ComputeCurrentOriginUsage() -
786 sandbox_file_system_
.ComputeCurrentDirectoryDatabaseUsage();
789 FileSystemContext
* file_system_context() {
790 return sandbox_file_system_
.file_system_context();
793 const base::FilePath
& data_dir_path() const {
794 return data_dir_
.path();
798 base::ScopedTempDir data_dir_
;
799 base::MessageLoopForIO message_loop_
;
800 scoped_refptr
<MockSpecialStoragePolicy
> storage_policy_
;
801 scoped_refptr
<storage::QuotaManager
> quota_manager_
;
802 scoped_refptr
<FileSystemContext
> file_system_context_
;
804 storage::FileSystemType type_
;
805 SandboxFileSystemTestHelper sandbox_file_system_
;
806 storage::QuotaStatusCode quota_status_
;
808 storage::MockFileChangeObserver change_observer_
;
809 storage::ChangeObserverList change_observers_
;
810 base::WeakPtrFactory
<ObfuscatedFileUtilTest
> weak_factory_
;
813 DISALLOW_COPY_AND_ASSIGN(ObfuscatedFileUtilTest
);
816 TEST_F(ObfuscatedFileUtilTest
, TestCreateAndDeleteFile
) {
817 FileSystemURL url
= CreateURLFromUTF8("fake/file");
818 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
819 int file_flags
= base::File::FLAG_CREATE
| base::File::FLAG_WRITE
;
821 base::File file
= ofu()->CreateOrOpen(context
.get(), url
, file_flags
);
822 EXPECT_FALSE(file
.IsValid());
823 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
, file
.error_details());
825 context
.reset(NewContext(NULL
));
826 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
,
827 ofu()->DeleteFile(context
.get(), url
));
829 url
= CreateURLFromUTF8("test file");
831 EXPECT_TRUE(change_observer()->HasNoChange());
833 // Verify that file creation requires sufficient quota for the path.
834 context
.reset(NewContext(NULL
));
835 context
->set_allowed_bytes_growth(
836 ObfuscatedFileUtil::ComputeFilePathCost(url
.path()) - 1);
837 file
= ofu()->CreateOrOpen(context
.get(), url
, file_flags
);
838 EXPECT_FALSE(file
.IsValid());
839 ASSERT_EQ(base::File::FILE_ERROR_NO_SPACE
, file
.error_details());
841 context
.reset(NewContext(NULL
));
842 context
->set_allowed_bytes_growth(
843 ObfuscatedFileUtil::ComputeFilePathCost(url
.path()));
844 file
= ofu()->CreateOrOpen(context
.get(), url
, file_flags
);
845 EXPECT_TRUE(file
.IsValid());
846 ASSERT_TRUE(file
.created());
847 EXPECT_EQ(1, change_observer()->get_and_reset_create_file_count());
849 CheckFileAndCloseHandle(url
, file
.Pass());
851 context
.reset(NewContext(NULL
));
852 base::FilePath local_path
;
853 EXPECT_EQ(base::File::FILE_OK
,
854 ofu()->GetLocalFilePath(context
.get(), url
, &local_path
));
855 EXPECT_TRUE(base::PathExists(local_path
));
857 // Verify that deleting a file isn't stopped by zero quota, and that it frees
858 // up quote from its path.
859 context
.reset(NewContext(NULL
));
860 context
->set_allowed_bytes_growth(0);
861 EXPECT_EQ(base::File::FILE_OK
, ofu()->DeleteFile(context
.get(), url
));
862 EXPECT_EQ(1, change_observer()->get_and_reset_remove_file_count());
863 EXPECT_FALSE(base::PathExists(local_path
));
864 EXPECT_EQ(ObfuscatedFileUtil::ComputeFilePathCost(url
.path()),
865 context
->allowed_bytes_growth());
867 context
.reset(NewContext(NULL
));
868 bool exclusive
= true;
869 bool recursive
= true;
870 FileSystemURL directory_url
= CreateURLFromUTF8(
871 "series/of/directories");
872 url
= FileSystemURLAppendUTF8(directory_url
, "file name");
873 EXPECT_EQ(base::File::FILE_OK
,
874 ofu()->CreateDirectory(context
.get(), directory_url
, exclusive
,
876 // The oepration created 3 directories recursively.
877 EXPECT_EQ(3, change_observer()->get_and_reset_create_directory_count());
879 context
.reset(NewContext(NULL
));
880 file
= ofu()->CreateOrOpen(context
.get(), url
, file_flags
);
881 ASSERT_TRUE(file
.IsValid());
882 ASSERT_TRUE(file
.created());
883 EXPECT_EQ(1, change_observer()->get_and_reset_create_file_count());
885 CheckFileAndCloseHandle(url
, file
.Pass());
887 context
.reset(NewContext(NULL
));
888 EXPECT_EQ(base::File::FILE_OK
,
889 ofu()->GetLocalFilePath(context
.get(), url
, &local_path
));
890 EXPECT_TRUE(base::PathExists(local_path
));
892 context
.reset(NewContext(NULL
));
893 EXPECT_EQ(base::File::FILE_OK
, ofu()->DeleteFile(context
.get(), url
));
894 EXPECT_EQ(1, change_observer()->get_and_reset_remove_file_count());
895 EXPECT_FALSE(base::PathExists(local_path
));
897 // Make sure we have no unexpected changes.
898 EXPECT_TRUE(change_observer()->HasNoChange());
901 TEST_F(ObfuscatedFileUtilTest
, TestTruncate
) {
902 bool created
= false;
903 FileSystemURL url
= CreateURLFromUTF8("file");
904 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
906 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
,
907 ofu()->Truncate(context
.get(), url
, 4));
909 context
.reset(NewContext(NULL
));
910 ASSERT_EQ(base::File::FILE_OK
,
911 ofu()->EnsureFileExists(context
.get(), url
, &created
));
912 ASSERT_TRUE(created
);
913 EXPECT_EQ(1, change_observer()->get_and_reset_create_file_count());
915 context
.reset(NewContext(NULL
));
916 base::FilePath local_path
;
917 EXPECT_EQ(base::File::FILE_OK
,
918 ofu()->GetLocalFilePath(context
.get(), url
, &local_path
));
919 EXPECT_EQ(0, GetSize(local_path
));
921 context
.reset(NewContext(NULL
));
922 EXPECT_EQ(base::File::FILE_OK
, ofu()->Truncate(context
.get(), url
, 10));
923 EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count());
924 EXPECT_EQ(10, GetSize(local_path
));
926 context
.reset(NewContext(NULL
));
927 EXPECT_EQ(base::File::FILE_OK
, ofu()->Truncate(context
.get(), url
, 1));
928 EXPECT_EQ(1, GetSize(local_path
));
929 EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count());
931 EXPECT_FALSE(DirectoryExists(url
));
932 EXPECT_TRUE(PathExists(url
));
934 // Make sure we have no unexpected changes.
935 EXPECT_TRUE(change_observer()->HasNoChange());
938 TEST_F(ObfuscatedFileUtilTest
, TestQuotaOnTruncation
) {
939 bool created
= false;
940 FileSystemURL url
= CreateURLFromUTF8("file");
942 ASSERT_EQ(base::File::FILE_OK
,
943 ofu()->EnsureFileExists(
944 AllowUsageIncrease(PathCost(url
))->context(),
946 ASSERT_TRUE(created
);
947 ASSERT_EQ(0, ComputeTotalFileSize());
949 ASSERT_EQ(base::File::FILE_OK
,
950 ofu()->Truncate(AllowUsageIncrease(1020)->context(), url
, 1020));
951 ASSERT_EQ(1020, ComputeTotalFileSize());
953 ASSERT_EQ(base::File::FILE_OK
,
954 ofu()->Truncate(AllowUsageIncrease(-1020)->context(), url
, 0));
955 ASSERT_EQ(0, ComputeTotalFileSize());
957 EXPECT_EQ(base::File::FILE_ERROR_NO_SPACE
,
958 ofu()->Truncate(DisallowUsageIncrease(1021)->context(),
960 ASSERT_EQ(0, ComputeTotalFileSize());
962 EXPECT_EQ(base::File::FILE_OK
,
963 ofu()->Truncate(AllowUsageIncrease(1020)->context(), url
, 1020));
964 ASSERT_EQ(1020, ComputeTotalFileSize());
966 EXPECT_EQ(base::File::FILE_OK
,
967 ofu()->Truncate(AllowUsageIncrease(0)->context(), url
, 1020));
968 ASSERT_EQ(1020, ComputeTotalFileSize());
972 scoped_ptr
<UsageVerifyHelper
> helper
= AllowUsageIncrease(-1);
973 helper
->context()->set_allowed_bytes_growth(
974 helper
->context()->allowed_bytes_growth() - 1);
975 EXPECT_EQ(base::File::FILE_OK
,
976 ofu()->Truncate(helper
->context(), url
, 1019));
977 ASSERT_EQ(1019, ComputeTotalFileSize());
980 // Delete backing file to make following truncation fail.
981 base::FilePath local_path
;
982 ASSERT_EQ(base::File::FILE_OK
,
983 ofu()->GetLocalFilePath(UnlimitedContext().get(), url
,
985 ASSERT_FALSE(local_path
.empty());
986 ASSERT_TRUE(base::DeleteFile(local_path
, false));
988 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
,
989 ofu()->Truncate(LimitedContext(1234).get(), url
, 1234));
990 ASSERT_EQ(0, ComputeTotalFileSize());
993 TEST_F(ObfuscatedFileUtilTest
, TestEnsureFileExists
) {
994 FileSystemURL url
= CreateURLFromUTF8("fake/file");
995 bool created
= false;
996 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
997 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
,
998 ofu()->EnsureFileExists(context
.get(), url
, &created
));
999 EXPECT_TRUE(change_observer()->HasNoChange());
1001 // Verify that file creation requires sufficient quota for the path.
1002 context
.reset(NewContext(NULL
));
1003 url
= CreateURLFromUTF8("test file");
1005 context
->set_allowed_bytes_growth(
1006 ObfuscatedFileUtil::ComputeFilePathCost(url
.path()) - 1);
1007 ASSERT_EQ(base::File::FILE_ERROR_NO_SPACE
,
1008 ofu()->EnsureFileExists(context
.get(), url
, &created
));
1009 ASSERT_FALSE(created
);
1010 EXPECT_TRUE(change_observer()->HasNoChange());
1012 context
.reset(NewContext(NULL
));
1013 context
->set_allowed_bytes_growth(
1014 ObfuscatedFileUtil::ComputeFilePathCost(url
.path()));
1015 ASSERT_EQ(base::File::FILE_OK
,
1016 ofu()->EnsureFileExists(context
.get(), url
, &created
));
1017 ASSERT_TRUE(created
);
1018 EXPECT_EQ(1, change_observer()->get_and_reset_create_file_count());
1020 CheckFileAndCloseHandle(url
, base::File());
1022 context
.reset(NewContext(NULL
));
1023 ASSERT_EQ(base::File::FILE_OK
,
1024 ofu()->EnsureFileExists(context
.get(), url
, &created
));
1025 ASSERT_FALSE(created
);
1026 EXPECT_TRUE(change_observer()->HasNoChange());
1028 // Also test in a subdirectory.
1029 url
= CreateURLFromUTF8("path/to/file.txt");
1030 context
.reset(NewContext(NULL
));
1031 bool exclusive
= true;
1032 bool recursive
= true;
1033 EXPECT_EQ(base::File::FILE_OK
,
1034 ofu()->CreateDirectory(context
.get(), FileSystemURLDirName(url
),
1035 exclusive
, recursive
));
1036 // 2 directories: path/ and path/to.
1037 EXPECT_EQ(2, change_observer()->get_and_reset_create_directory_count());
1039 context
.reset(NewContext(NULL
));
1040 ASSERT_EQ(base::File::FILE_OK
,
1041 ofu()->EnsureFileExists(context
.get(), url
, &created
));
1042 ASSERT_TRUE(created
);
1043 EXPECT_FALSE(DirectoryExists(url
));
1044 EXPECT_TRUE(PathExists(url
));
1045 EXPECT_TRUE(change_observer()->HasNoChange());
1048 TEST_F(ObfuscatedFileUtilTest
, TestDirectoryOps
) {
1049 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
1051 bool exclusive
= false;
1052 bool recursive
= false;
1053 FileSystemURL url
= CreateURLFromUTF8("foo/bar");
1054 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
,
1055 ofu()->CreateDirectory(context
.get(), url
, exclusive
, recursive
));
1057 context
.reset(NewContext(NULL
));
1058 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
,
1059 ofu()->DeleteDirectory(context
.get(), url
));
1061 FileSystemURL root
= CreateURLFromUTF8(std::string());
1062 EXPECT_FALSE(DirectoryExists(url
));
1063 EXPECT_FALSE(PathExists(url
));
1064 context
.reset(NewContext(NULL
));
1065 EXPECT_TRUE(ofu()->IsDirectoryEmpty(context
.get(), root
));
1067 context
.reset(NewContext(NULL
));
1070 EXPECT_EQ(base::File::FILE_OK
,
1071 ofu()->CreateDirectory(context
.get(), url
, exclusive
, recursive
));
1072 EXPECT_EQ(2, change_observer()->get_and_reset_create_directory_count());
1074 EXPECT_TRUE(DirectoryExists(url
));
1075 EXPECT_TRUE(PathExists(url
));
1077 context
.reset(NewContext(NULL
));
1078 EXPECT_FALSE(ofu()->IsDirectoryEmpty(context
.get(), root
));
1079 EXPECT_TRUE(DirectoryExists(FileSystemURLDirName(url
)));
1081 context
.reset(NewContext(NULL
));
1082 EXPECT_FALSE(ofu()->IsDirectoryEmpty(context
.get(),
1083 FileSystemURLDirName(url
)));
1085 // Can't remove a non-empty directory.
1086 context
.reset(NewContext(NULL
));
1087 EXPECT_EQ(base::File::FILE_ERROR_NOT_EMPTY
,
1088 ofu()->DeleteDirectory(context
.get(),
1089 FileSystemURLDirName(url
)));
1090 EXPECT_TRUE(change_observer()->HasNoChange());
1092 base::File::Info file_info
;
1093 base::FilePath local_path
;
1094 EXPECT_EQ(base::File::FILE_OK
,
1095 ofu()->GetFileInfo(context
.get(), url
, &file_info
, &local_path
));
1096 EXPECT_TRUE(local_path
.empty());
1097 EXPECT_TRUE(file_info
.is_directory
);
1098 EXPECT_FALSE(file_info
.is_symbolic_link
);
1100 // Same create again should succeed, since exclusive is false.
1101 context
.reset(NewContext(NULL
));
1102 EXPECT_EQ(base::File::FILE_OK
,
1103 ofu()->CreateDirectory(context
.get(), url
, exclusive
, recursive
));
1104 EXPECT_TRUE(change_observer()->HasNoChange());
1108 context
.reset(NewContext(NULL
));
1109 EXPECT_EQ(base::File::FILE_ERROR_EXISTS
,
1110 ofu()->CreateDirectory(context
.get(), url
, exclusive
, recursive
));
1111 EXPECT_TRUE(change_observer()->HasNoChange());
1113 // Verify that deleting a directory isn't stopped by zero quota, and that it
1114 // frees up quota from its path.
1115 context
.reset(NewContext(NULL
));
1116 context
->set_allowed_bytes_growth(0);
1117 EXPECT_EQ(base::File::FILE_OK
, ofu()->DeleteDirectory(context
.get(), url
));
1118 EXPECT_EQ(1, change_observer()->get_and_reset_remove_directory_count());
1119 EXPECT_EQ(ObfuscatedFileUtil::ComputeFilePathCost(url
.path()),
1120 context
->allowed_bytes_growth());
1122 url
= CreateURLFromUTF8("foo/bop");
1124 EXPECT_FALSE(DirectoryExists(url
));
1125 EXPECT_FALSE(PathExists(url
));
1127 context
.reset(NewContext(NULL
));
1128 EXPECT_TRUE(ofu()->IsDirectoryEmpty(context
.get(), url
));
1129 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
,
1130 ofu()->GetFileInfo(context
.get(), url
, &file_info
, &local_path
));
1132 // Verify that file creation requires sufficient quota for the path.
1135 context
.reset(NewContext(NULL
));
1136 context
->set_allowed_bytes_growth(
1137 ObfuscatedFileUtil::ComputeFilePathCost(url
.path()) - 1);
1138 EXPECT_EQ(base::File::FILE_ERROR_NO_SPACE
,
1139 ofu()->CreateDirectory(context
.get(), url
, exclusive
, recursive
));
1140 EXPECT_TRUE(change_observer()->HasNoChange());
1142 context
.reset(NewContext(NULL
));
1143 context
->set_allowed_bytes_growth(
1144 ObfuscatedFileUtil::ComputeFilePathCost(url
.path()));
1145 EXPECT_EQ(base::File::FILE_OK
,
1146 ofu()->CreateDirectory(context
.get(), url
, exclusive
, recursive
));
1147 EXPECT_EQ(1, change_observer()->get_and_reset_create_directory_count());
1149 EXPECT_TRUE(DirectoryExists(url
));
1150 EXPECT_TRUE(PathExists(url
));
1154 context
.reset(NewContext(NULL
));
1155 EXPECT_EQ(base::File::FILE_ERROR_EXISTS
,
1156 ofu()->CreateDirectory(context
.get(), url
, exclusive
, recursive
));
1157 EXPECT_TRUE(change_observer()->HasNoChange());
1161 url
= CreateURLFromUTF8("foo");
1162 context
.reset(NewContext(NULL
));
1163 EXPECT_EQ(base::File::FILE_ERROR_EXISTS
,
1164 ofu()->CreateDirectory(context
.get(), url
, exclusive
, recursive
));
1165 EXPECT_TRUE(change_observer()->HasNoChange());
1167 url
= CreateURLFromUTF8("blah");
1169 EXPECT_FALSE(DirectoryExists(url
));
1170 EXPECT_FALSE(PathExists(url
));
1174 context
.reset(NewContext(NULL
));
1175 EXPECT_EQ(base::File::FILE_OK
,
1176 ofu()->CreateDirectory(context
.get(), url
, exclusive
, recursive
));
1177 EXPECT_EQ(1, change_observer()->get_and_reset_create_directory_count());
1179 EXPECT_TRUE(DirectoryExists(url
));
1180 EXPECT_TRUE(PathExists(url
));
1184 context
.reset(NewContext(NULL
));
1185 EXPECT_EQ(base::File::FILE_ERROR_EXISTS
,
1186 ofu()->CreateDirectory(context
.get(), url
, exclusive
, recursive
));
1187 EXPECT_TRUE(change_observer()->HasNoChange());
1190 TEST_F(ObfuscatedFileUtilTest
, TestReadDirectory
) {
1191 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
1192 bool exclusive
= true;
1193 bool recursive
= true;
1194 FileSystemURL url
= CreateURLFromUTF8("directory/to/use");
1195 EXPECT_EQ(base::File::FILE_OK
,
1196 ofu()->CreateDirectory(context
.get(), url
, exclusive
, recursive
));
1197 TestReadDirectoryHelper(url
);
1200 TEST_F(ObfuscatedFileUtilTest
, TestReadRootWithSlash
) {
1201 TestReadDirectoryHelper(CreateURLFromUTF8(std::string()));
1204 TEST_F(ObfuscatedFileUtilTest
, TestReadRootWithEmptyString
) {
1205 TestReadDirectoryHelper(CreateURLFromUTF8("/"));
1208 TEST_F(ObfuscatedFileUtilTest
, TestReadDirectoryOnFile
) {
1209 FileSystemURL url
= CreateURLFromUTF8("file");
1210 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
1212 bool created
= false;
1213 ASSERT_EQ(base::File::FILE_OK
,
1214 ofu()->EnsureFileExists(context
.get(), url
, &created
));
1215 ASSERT_TRUE(created
);
1217 std::vector
<storage::DirectoryEntry
> entries
;
1218 EXPECT_EQ(base::File::FILE_ERROR_NOT_A_DIRECTORY
,
1219 AsyncFileTestHelper::ReadDirectory(file_system_context(), url
,
1222 EXPECT_TRUE(ofu()->IsDirectoryEmpty(context
.get(), url
));
1225 TEST_F(ObfuscatedFileUtilTest
, TestTouch
) {
1226 FileSystemURL url
= CreateURLFromUTF8("file");
1227 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
1229 base::Time last_access_time
= base::Time::Now();
1230 base::Time last_modified_time
= base::Time::Now();
1232 // It's not there yet.
1233 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
,
1234 ofu()->Touch(context
.get(), url
, last_access_time
,
1235 last_modified_time
));
1237 // OK, now create it.
1238 context
.reset(NewContext(NULL
));
1239 bool created
= false;
1240 ASSERT_EQ(base::File::FILE_OK
,
1241 ofu()->EnsureFileExists(context
.get(), url
, &created
));
1242 ASSERT_TRUE(created
);
1243 TestTouchHelper(url
, true);
1245 // Now test a directory:
1246 context
.reset(NewContext(NULL
));
1247 bool exclusive
= true;
1248 bool recursive
= false;
1249 url
= CreateURLFromUTF8("dir");
1250 ASSERT_EQ(base::File::FILE_OK
,
1251 ofu()->CreateDirectory(context
.get(), url
, exclusive
, recursive
));
1252 TestTouchHelper(url
, false);
1255 TEST_F(ObfuscatedFileUtilTest
, TestPathQuotas
) {
1256 FileSystemURL url
= CreateURLFromUTF8("fake/file");
1257 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
1259 url
= CreateURLFromUTF8("file name");
1260 context
->set_allowed_bytes_growth(5);
1261 bool created
= false;
1262 EXPECT_EQ(base::File::FILE_ERROR_NO_SPACE
,
1263 ofu()->EnsureFileExists(context
.get(), url
, &created
));
1264 EXPECT_FALSE(created
);
1265 context
->set_allowed_bytes_growth(1024);
1266 EXPECT_EQ(base::File::FILE_OK
,
1267 ofu()->EnsureFileExists(context
.get(), url
, &created
));
1268 EXPECT_TRUE(created
);
1269 int64 path_cost
= ObfuscatedFileUtil::ComputeFilePathCost(url
.path());
1270 EXPECT_EQ(1024 - path_cost
, context
->allowed_bytes_growth());
1272 context
->set_allowed_bytes_growth(1024);
1273 bool exclusive
= true;
1274 bool recursive
= true;
1275 url
= CreateURLFromUTF8("directory/to/use");
1276 std::vector
<base::FilePath::StringType
> components
;
1277 url
.path().GetComponents(&components
);
1279 typedef std::vector
<base::FilePath::StringType
>::iterator iterator
;
1280 for (iterator iter
= components
.begin();
1281 iter
!= components
.end(); ++iter
) {
1282 path_cost
+= ObfuscatedFileUtil::ComputeFilePathCost(
1283 base::FilePath(*iter
));
1285 context
.reset(NewContext(NULL
));
1286 context
->set_allowed_bytes_growth(1024);
1287 EXPECT_EQ(base::File::FILE_OK
,
1288 ofu()->CreateDirectory(context
.get(), url
, exclusive
, recursive
));
1289 EXPECT_EQ(1024 - path_cost
, context
->allowed_bytes_growth());
1292 TEST_F(ObfuscatedFileUtilTest
, TestCopyOrMoveFileNotFound
) {
1293 FileSystemURL source_url
= CreateURLFromUTF8("path0.txt");
1294 FileSystemURL dest_url
= CreateURLFromUTF8("path1.txt");
1295 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
1297 bool is_copy_not_move
= false;
1298 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
,
1299 ofu()->CopyOrMoveFile(context
.get(), source_url
, dest_url
,
1300 FileSystemOperation::OPTION_NONE
,
1302 EXPECT_TRUE(change_observer()->HasNoChange());
1303 context
.reset(NewContext(NULL
));
1304 is_copy_not_move
= true;
1305 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
,
1306 ofu()->CopyOrMoveFile(context
.get(), source_url
, dest_url
,
1307 FileSystemOperation::OPTION_NONE
,
1309 EXPECT_TRUE(change_observer()->HasNoChange());
1310 source_url
= CreateURLFromUTF8("dir/dir/file");
1311 bool exclusive
= true;
1312 bool recursive
= true;
1313 context
.reset(NewContext(NULL
));
1314 ASSERT_EQ(base::File::FILE_OK
,
1315 ofu()->CreateDirectory(context
.get(),
1316 FileSystemURLDirName(source_url
),
1317 exclusive
, recursive
));
1318 EXPECT_EQ(2, change_observer()->get_and_reset_create_directory_count());
1319 is_copy_not_move
= false;
1320 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
,
1321 ofu()->CopyOrMoveFile(context
.get(), source_url
, dest_url
,
1322 FileSystemOperation::OPTION_NONE
,
1324 EXPECT_TRUE(change_observer()->HasNoChange());
1325 context
.reset(NewContext(NULL
));
1326 is_copy_not_move
= true;
1327 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
,
1328 ofu()->CopyOrMoveFile(context
.get(), source_url
, dest_url
,
1329 FileSystemOperation::OPTION_NONE
,
1331 EXPECT_TRUE(change_observer()->HasNoChange());
1334 TEST_F(ObfuscatedFileUtilTest
, TestCopyOrMoveFileSuccess
) {
1335 const int64 kSourceLength
= 5;
1336 const int64 kDestLength
= 50;
1338 for (size_t i
= 0; i
< arraysize(kCopyMoveTestCases
); ++i
) {
1339 SCOPED_TRACE(testing::Message() << "kCopyMoveTestCase " << i
);
1340 const CopyMoveTestCaseRecord
& test_case
= kCopyMoveTestCases
[i
];
1341 SCOPED_TRACE(testing::Message() << "\t is_copy_not_move " <<
1342 test_case
.is_copy_not_move
);
1343 SCOPED_TRACE(testing::Message() << "\t source_path " <<
1344 test_case
.source_path
);
1345 SCOPED_TRACE(testing::Message() << "\t dest_path " <<
1346 test_case
.dest_path
);
1347 SCOPED_TRACE(testing::Message() << "\t cause_overwrite " <<
1348 test_case
.cause_overwrite
);
1349 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
1351 bool exclusive
= false;
1352 bool recursive
= true;
1353 FileSystemURL source_url
= CreateURLFromUTF8(test_case
.source_path
);
1354 FileSystemURL dest_url
= CreateURLFromUTF8(test_case
.dest_path
);
1356 context
.reset(NewContext(NULL
));
1357 ASSERT_EQ(base::File::FILE_OK
,
1358 ofu()->CreateDirectory(context
.get(),
1359 FileSystemURLDirName(source_url
),
1360 exclusive
, recursive
));
1361 context
.reset(NewContext(NULL
));
1362 ASSERT_EQ(base::File::FILE_OK
,
1363 ofu()->CreateDirectory(context
.get(),
1364 FileSystemURLDirName(dest_url
),
1365 exclusive
, recursive
));
1367 bool created
= false;
1368 context
.reset(NewContext(NULL
));
1369 ASSERT_EQ(base::File::FILE_OK
,
1370 ofu()->EnsureFileExists(context
.get(), source_url
, &created
));
1371 ASSERT_TRUE(created
);
1372 context
.reset(NewContext(NULL
));
1373 ASSERT_EQ(base::File::FILE_OK
,
1374 ofu()->Truncate(context
.get(), source_url
, kSourceLength
));
1376 if (test_case
.cause_overwrite
) {
1377 context
.reset(NewContext(NULL
));
1379 ASSERT_EQ(base::File::FILE_OK
,
1380 ofu()->EnsureFileExists(context
.get(), dest_url
, &created
));
1381 ASSERT_TRUE(created
);
1382 context
.reset(NewContext(NULL
));
1383 ASSERT_EQ(base::File::FILE_OK
,
1384 ofu()->Truncate(context
.get(), dest_url
, kDestLength
));
1387 context
.reset(NewContext(NULL
));
1388 EXPECT_EQ(base::File::FILE_OK
,
1389 ofu()->CopyOrMoveFile(context
.get(), source_url
, dest_url
,
1390 FileSystemOperation::OPTION_NONE
,
1391 test_case
.is_copy_not_move
));
1393 if (test_case
.is_copy_not_move
) {
1394 base::File::Info file_info
;
1395 base::FilePath local_path
;
1396 context
.reset(NewContext(NULL
));
1397 EXPECT_EQ(base::File::FILE_OK
,
1398 ofu()->GetFileInfo(context
.get(), source_url
, &file_info
,
1400 EXPECT_EQ(kSourceLength
, file_info
.size
);
1401 EXPECT_EQ(base::File::FILE_OK
,
1402 ofu()->DeleteFile(context
.get(), source_url
));
1404 base::File::Info file_info
;
1405 base::FilePath local_path
;
1406 context
.reset(NewContext(NULL
));
1407 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
,
1408 ofu()->GetFileInfo(context
.get(), source_url
, &file_info
,
1411 base::File::Info file_info
;
1412 base::FilePath local_path
;
1413 EXPECT_EQ(base::File::FILE_OK
,
1414 ofu()->GetFileInfo(context
.get(), dest_url
, &file_info
,
1416 EXPECT_EQ(kSourceLength
, file_info
.size
);
1418 EXPECT_EQ(base::File::FILE_OK
,
1419 ofu()->DeleteFile(context
.get(), dest_url
));
1423 TEST_F(ObfuscatedFileUtilTest
, TestCopyPathQuotas
) {
1424 FileSystemURL src_url
= CreateURLFromUTF8("src path");
1425 FileSystemURL dest_url
= CreateURLFromUTF8("destination path");
1426 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
1427 bool created
= false;
1428 ASSERT_EQ(base::File::FILE_OK
,
1429 ofu()->EnsureFileExists(context
.get(), src_url
, &created
));
1431 bool is_copy
= true;
1432 // Copy, no overwrite.
1433 context
->set_allowed_bytes_growth(
1434 ObfuscatedFileUtil::ComputeFilePathCost(dest_url
.path()) - 1);
1435 EXPECT_EQ(base::File::FILE_ERROR_NO_SPACE
,
1436 ofu()->CopyOrMoveFile(context
.get(), src_url
, dest_url
,
1437 FileSystemOperation::OPTION_NONE
, is_copy
));
1438 context
.reset(NewContext(NULL
));
1439 context
->set_allowed_bytes_growth(
1440 ObfuscatedFileUtil::ComputeFilePathCost(dest_url
.path()));
1441 EXPECT_EQ(base::File::FILE_OK
,
1442 ofu()->CopyOrMoveFile(context
.get(), src_url
, dest_url
,
1443 FileSystemOperation::OPTION_NONE
, is_copy
));
1445 // Copy, with overwrite.
1446 context
.reset(NewContext(NULL
));
1447 context
->set_allowed_bytes_growth(0);
1448 EXPECT_EQ(base::File::FILE_OK
,
1449 ofu()->CopyOrMoveFile(context
.get(), src_url
, dest_url
,
1450 FileSystemOperation::OPTION_NONE
, is_copy
));
1453 TEST_F(ObfuscatedFileUtilTest
, TestMovePathQuotasWithRename
) {
1454 FileSystemURL src_url
= CreateURLFromUTF8("src path");
1455 FileSystemURL dest_url
= CreateURLFromUTF8("destination path");
1456 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
1457 bool created
= false;
1458 ASSERT_EQ(base::File::FILE_OK
,
1459 ofu()->EnsureFileExists(context
.get(), src_url
, &created
));
1461 bool is_copy
= false;
1462 // Move, rename, no overwrite.
1463 context
.reset(NewContext(NULL
));
1464 context
->set_allowed_bytes_growth(
1465 ObfuscatedFileUtil::ComputeFilePathCost(dest_url
.path()) -
1466 ObfuscatedFileUtil::ComputeFilePathCost(src_url
.path()) - 1);
1467 EXPECT_EQ(base::File::FILE_ERROR_NO_SPACE
,
1468 ofu()->CopyOrMoveFile(context
.get(), src_url
, dest_url
,
1469 FileSystemOperation::OPTION_NONE
, is_copy
));
1470 context
.reset(NewContext(NULL
));
1471 context
->set_allowed_bytes_growth(
1472 ObfuscatedFileUtil::ComputeFilePathCost(dest_url
.path()) -
1473 ObfuscatedFileUtil::ComputeFilePathCost(src_url
.path()));
1474 EXPECT_EQ(base::File::FILE_OK
,
1475 ofu()->CopyOrMoveFile(context
.get(), src_url
, dest_url
,
1476 FileSystemOperation::OPTION_NONE
, is_copy
));
1478 context
.reset(NewContext(NULL
));
1479 ASSERT_EQ(base::File::FILE_OK
,
1480 ofu()->EnsureFileExists(context
.get(), src_url
, &created
));
1482 // Move, rename, with overwrite.
1483 context
.reset(NewContext(NULL
));
1484 context
->set_allowed_bytes_growth(0);
1485 EXPECT_EQ(base::File::FILE_OK
,
1486 ofu()->CopyOrMoveFile(context
.get(), src_url
, dest_url
,
1487 FileSystemOperation::OPTION_NONE
, is_copy
));
1490 TEST_F(ObfuscatedFileUtilTest
, TestMovePathQuotasWithoutRename
) {
1491 FileSystemURL src_url
= CreateURLFromUTF8("src path");
1492 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
1493 bool created
= false;
1494 ASSERT_EQ(base::File::FILE_OK
,
1495 ofu()->EnsureFileExists(context
.get(), src_url
, &created
));
1497 bool exclusive
= true;
1498 bool recursive
= false;
1499 FileSystemURL dir_url
= CreateURLFromUTF8("directory path");
1500 context
.reset(NewContext(NULL
));
1501 ASSERT_EQ(base::File::FILE_OK
,
1502 ofu()->CreateDirectory(context
.get(), dir_url
, exclusive
,
1505 FileSystemURL dest_url
= FileSystemURLAppend(
1506 dir_url
, src_url
.path().value());
1508 bool is_copy
= false;
1509 int64 allowed_bytes_growth
= -1000; // Over quota, this should still work.
1510 // Move, no rename, no overwrite.
1511 context
.reset(NewContext(NULL
));
1512 context
->set_allowed_bytes_growth(allowed_bytes_growth
);
1513 EXPECT_EQ(base::File::FILE_OK
,
1514 ofu()->CopyOrMoveFile(context
.get(), src_url
, dest_url
,
1515 FileSystemOperation::OPTION_NONE
, is_copy
));
1516 EXPECT_EQ(allowed_bytes_growth
, context
->allowed_bytes_growth());
1518 // Move, no rename, with overwrite.
1519 context
.reset(NewContext(NULL
));
1520 ASSERT_EQ(base::File::FILE_OK
,
1521 ofu()->EnsureFileExists(context
.get(), src_url
, &created
));
1522 context
.reset(NewContext(NULL
));
1523 context
->set_allowed_bytes_growth(allowed_bytes_growth
);
1524 EXPECT_EQ(base::File::FILE_OK
,
1525 ofu()->CopyOrMoveFile(context
.get(), src_url
, dest_url
,
1526 FileSystemOperation::OPTION_NONE
, is_copy
));
1528 allowed_bytes_growth
+
1529 ObfuscatedFileUtil::ComputeFilePathCost(src_url
.path()),
1530 context
->allowed_bytes_growth());
1533 TEST_F(ObfuscatedFileUtilTest
, TestCopyInForeignFile
) {
1534 TestCopyInForeignFileHelper(false /* overwrite */);
1535 TestCopyInForeignFileHelper(true /* overwrite */);
1538 TEST_F(ObfuscatedFileUtilTest
, TestEnumerator
) {
1539 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
1540 FileSystemURL src_url
= CreateURLFromUTF8("source dir");
1541 bool exclusive
= true;
1542 bool recursive
= false;
1543 ASSERT_EQ(base::File::FILE_OK
,
1544 ofu()->CreateDirectory(context
.get(), src_url
, exclusive
,
1547 std::set
<base::FilePath::StringType
> files
;
1548 std::set
<base::FilePath::StringType
> directories
;
1549 FillTestDirectory(src_url
, &files
, &directories
);
1551 FileSystemURL dest_url
= CreateURLFromUTF8("destination dir");
1553 EXPECT_FALSE(DirectoryExists(dest_url
));
1554 ASSERT_EQ(base::File::FILE_OK
,
1555 AsyncFileTestHelper::Copy(
1556 file_system_context(), src_url
, dest_url
));
1558 ValidateTestDirectory(dest_url
, files
, directories
);
1559 EXPECT_TRUE(DirectoryExists(src_url
));
1560 EXPECT_TRUE(DirectoryExists(dest_url
));
1562 ASSERT_EQ(base::File::FILE_OK
,
1563 AsyncFileTestHelper::Remove(
1564 file_system_context(), dest_url
, recursive
));
1565 EXPECT_FALSE(DirectoryExists(dest_url
));
1568 TEST_F(ObfuscatedFileUtilTest
, TestOriginEnumerator
) {
1569 scoped_ptr
<ObfuscatedFileUtil::AbstractOriginEnumerator
>
1570 enumerator(ofu()->CreateOriginEnumerator());
1571 // The test helper starts out with a single filesystem.
1572 EXPECT_TRUE(enumerator
.get());
1573 EXPECT_EQ(origin(), enumerator
->Next());
1574 ASSERT_TRUE(type() == kFileSystemTypeTemporary
);
1575 EXPECT_TRUE(HasFileSystemType(enumerator
.get(), kFileSystemTypeTemporary
));
1576 EXPECT_FALSE(HasFileSystemType(enumerator
.get(), kFileSystemTypePersistent
));
1577 EXPECT_EQ(GURL(), enumerator
->Next());
1578 EXPECT_FALSE(HasFileSystemType(enumerator
.get(), kFileSystemTypeTemporary
));
1579 EXPECT_FALSE(HasFileSystemType(enumerator
.get(), kFileSystemTypePersistent
));
1581 std::set
<GURL
> origins_expected
;
1582 origins_expected
.insert(origin());
1584 for (size_t i
= 0; i
< arraysize(kOriginEnumerationTestRecords
); ++i
) {
1585 SCOPED_TRACE(testing::Message() <<
1586 "Validating kOriginEnumerationTestRecords " << i
);
1587 const OriginEnumerationTestRecord
& record
=
1588 kOriginEnumerationTestRecords
[i
];
1589 GURL
origin_url(record
.origin_url
);
1590 origins_expected
.insert(origin_url
);
1591 if (record
.has_temporary
) {
1592 scoped_ptr
<SandboxFileSystemTestHelper
> file_system(
1593 NewFileSystem(origin_url
, kFileSystemTypeTemporary
));
1594 scoped_ptr
<FileSystemOperationContext
> context(
1595 NewContext(file_system
.get()));
1596 bool created
= false;
1597 ASSERT_EQ(base::File::FILE_OK
,
1598 ofu()->EnsureFileExists(
1600 file_system
->CreateURLFromUTF8("file"),
1602 EXPECT_TRUE(created
);
1604 if (record
.has_persistent
) {
1605 scoped_ptr
<SandboxFileSystemTestHelper
> file_system(
1606 NewFileSystem(origin_url
, kFileSystemTypePersistent
));
1607 scoped_ptr
<FileSystemOperationContext
> context(
1608 NewContext(file_system
.get()));
1609 bool created
= false;
1610 ASSERT_EQ(base::File::FILE_OK
,
1611 ofu()->EnsureFileExists(
1613 file_system
->CreateURLFromUTF8("file"),
1615 EXPECT_TRUE(created
);
1618 enumerator
.reset(ofu()->CreateOriginEnumerator());
1619 EXPECT_TRUE(enumerator
.get());
1620 std::set
<GURL
> origins_found
;
1622 while (!(origin_url
= enumerator
->Next()).is_empty()) {
1623 origins_found
.insert(origin_url
);
1624 SCOPED_TRACE(testing::Message() << "Handling " << origin_url
.spec());
1626 for (size_t i
= 0; !found
&& i
< arraysize(kOriginEnumerationTestRecords
);
1628 const OriginEnumerationTestRecord
& record
=
1629 kOriginEnumerationTestRecords
[i
];
1630 if (GURL(record
.origin_url
) != origin_url
)
1633 EXPECT_EQ(record
.has_temporary
,
1634 HasFileSystemType(enumerator
.get(), kFileSystemTypeTemporary
));
1635 EXPECT_EQ(record
.has_persistent
,
1636 HasFileSystemType(enumerator
.get(), kFileSystemTypePersistent
));
1638 // Deal with the default filesystem created by the test helper.
1639 if (!found
&& origin_url
== origin()) {
1640 ASSERT_TRUE(type() == kFileSystemTypeTemporary
);
1641 EXPECT_TRUE(HasFileSystemType(enumerator
.get(),
1642 kFileSystemTypeTemporary
));
1643 EXPECT_FALSE(HasFileSystemType(enumerator
.get(),
1644 kFileSystemTypePersistent
));
1650 std::set
<GURL
> diff
;
1651 std::set_symmetric_difference(origins_expected
.begin(),
1652 origins_expected
.end(), origins_found
.begin(), origins_found
.end(),
1653 inserter(diff
, diff
.begin()));
1654 EXPECT_TRUE(diff
.empty());
1657 TEST_F(ObfuscatedFileUtilTest
, TestRevokeUsageCache
) {
1658 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
1660 int64 expected_quota
= 0;
1662 for (size_t i
= 0; i
< kRegularFileSystemTestCaseSize
; ++i
) {
1663 SCOPED_TRACE(testing::Message() << "Creating kRegularTestCase " << i
);
1664 const FileSystemTestCaseRecord
& test_case
=
1665 kRegularFileSystemTestCases
[i
];
1666 base::FilePath
file_path(test_case
.path
);
1667 expected_quota
+= ObfuscatedFileUtil::ComputeFilePathCost(file_path
);
1668 if (test_case
.is_directory
) {
1669 bool exclusive
= true;
1670 bool recursive
= false;
1671 ASSERT_EQ(base::File::FILE_OK
,
1672 ofu()->CreateDirectory(context
.get(), CreateURL(file_path
),
1673 exclusive
, recursive
));
1675 bool created
= false;
1676 ASSERT_EQ(base::File::FILE_OK
,
1677 ofu()->EnsureFileExists(context
.get(), CreateURL(file_path
),
1679 ASSERT_TRUE(created
);
1680 ASSERT_EQ(base::File::FILE_OK
,
1681 ofu()->Truncate(context
.get(), CreateURL(file_path
),
1682 test_case
.data_file_size
));
1683 expected_quota
+= test_case
.data_file_size
;
1687 // Usually raw size in usage cache and the usage returned by QuotaUtil
1689 EXPECT_EQ(expected_quota
, SizeInUsageFile());
1690 EXPECT_EQ(expected_quota
, SizeByQuotaUtil());
1693 EXPECT_EQ(-1, SizeInUsageFile());
1694 EXPECT_EQ(expected_quota
, SizeByQuotaUtil());
1696 // This should reconstruct the cache.
1697 GetUsageFromQuotaManager();
1698 EXPECT_EQ(expected_quota
, SizeInUsageFile());
1699 EXPECT_EQ(expected_quota
, SizeByQuotaUtil());
1700 EXPECT_EQ(expected_quota
, usage());
1703 TEST_F(ObfuscatedFileUtilTest
, TestInconsistency
) {
1704 const FileSystemURL kPath1
= CreateURLFromUTF8("hoge");
1705 const FileSystemURL kPath2
= CreateURLFromUTF8("fuga");
1707 scoped_ptr
<FileSystemOperationContext
> context
;
1708 base::File::Info file_info
;
1709 base::FilePath data_path
;
1710 bool created
= false;
1712 // Create a non-empty file.
1713 context
.reset(NewContext(NULL
));
1714 EXPECT_EQ(base::File::FILE_OK
,
1715 ofu()->EnsureFileExists(context
.get(), kPath1
, &created
));
1716 EXPECT_TRUE(created
);
1717 context
.reset(NewContext(NULL
));
1718 EXPECT_EQ(base::File::FILE_OK
,
1719 ofu()->Truncate(context
.get(), kPath1
, 10));
1720 context
.reset(NewContext(NULL
));
1721 EXPECT_EQ(base::File::FILE_OK
,
1723 context
.get(), kPath1
, &file_info
, &data_path
));
1724 EXPECT_EQ(10, file_info
.size
);
1726 // Destroy database to make inconsistency between database and filesystem.
1727 ofu()->DestroyDirectoryDatabase(origin(), type_string());
1729 // Try to get file info of broken file.
1730 EXPECT_FALSE(PathExists(kPath1
));
1731 context
.reset(NewContext(NULL
));
1732 EXPECT_EQ(base::File::FILE_OK
,
1733 ofu()->EnsureFileExists(context
.get(), kPath1
, &created
));
1734 EXPECT_TRUE(created
);
1735 context
.reset(NewContext(NULL
));
1736 EXPECT_EQ(base::File::FILE_OK
,
1738 context
.get(), kPath1
, &file_info
, &data_path
));
1739 EXPECT_EQ(0, file_info
.size
);
1741 // Make another broken file to |kPath2|.
1742 context
.reset(NewContext(NULL
));
1743 EXPECT_EQ(base::File::FILE_OK
,
1744 ofu()->EnsureFileExists(context
.get(), kPath2
, &created
));
1745 EXPECT_TRUE(created
);
1748 ofu()->DestroyDirectoryDatabase(origin(), type_string());
1750 // Repair broken |kPath1|.
1751 context
.reset(NewContext(NULL
));
1752 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
,
1753 ofu()->Touch(context
.get(), kPath1
, base::Time::Now(),
1754 base::Time::Now()));
1755 EXPECT_EQ(base::File::FILE_OK
,
1756 ofu()->EnsureFileExists(context
.get(), kPath1
, &created
));
1757 EXPECT_TRUE(created
);
1759 // Copy from sound |kPath1| to broken |kPath2|.
1760 context
.reset(NewContext(NULL
));
1761 EXPECT_EQ(base::File::FILE_OK
,
1762 ofu()->CopyOrMoveFile(context
.get(), kPath1
, kPath2
,
1763 FileSystemOperation::OPTION_NONE
,
1766 ofu()->DestroyDirectoryDatabase(origin(), type_string());
1767 context
.reset(NewContext(NULL
));
1769 ofu()->CreateOrOpen(context
.get(), kPath1
,
1770 base::File::FLAG_READ
| base::File::FLAG_CREATE
);
1771 EXPECT_TRUE(file
.IsValid());
1772 EXPECT_TRUE(file
.created());
1774 EXPECT_TRUE(file
.GetInfo(&file_info
));
1775 EXPECT_EQ(0, file_info
.size
);
1778 TEST_F(ObfuscatedFileUtilTest
, TestIncompleteDirectoryReading
) {
1779 const FileSystemURL kPath
[] = {
1780 CreateURLFromUTF8("foo"),
1781 CreateURLFromUTF8("bar"),
1782 CreateURLFromUTF8("baz")
1784 const FileSystemURL empty_path
= CreateURL(base::FilePath());
1785 scoped_ptr
<FileSystemOperationContext
> context
;
1787 for (size_t i
= 0; i
< arraysize(kPath
); ++i
) {
1788 bool created
= false;
1789 context
.reset(NewContext(NULL
));
1790 EXPECT_EQ(base::File::FILE_OK
,
1791 ofu()->EnsureFileExists(context
.get(), kPath
[i
], &created
));
1792 EXPECT_TRUE(created
);
1795 std::vector
<storage::DirectoryEntry
> entries
;
1796 EXPECT_EQ(base::File::FILE_OK
,
1797 AsyncFileTestHelper::ReadDirectory(
1798 file_system_context(), empty_path
, &entries
));
1799 EXPECT_EQ(3u, entries
.size());
1801 base::FilePath local_path
;
1802 EXPECT_EQ(base::File::FILE_OK
,
1803 ofu()->GetLocalFilePath(context
.get(), kPath
[0], &local_path
));
1804 EXPECT_TRUE(base::DeleteFile(local_path
, false));
1807 EXPECT_EQ(base::File::FILE_OK
,
1808 AsyncFileTestHelper::ReadDirectory(
1809 file_system_context(), empty_path
, &entries
));
1810 EXPECT_EQ(arraysize(kPath
) - 1, entries
.size());
1813 TEST_F(ObfuscatedFileUtilTest
, TestDirectoryTimestampForCreation
) {
1814 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
1815 const FileSystemURL dir_url
= CreateURLFromUTF8("foo_dir");
1817 // Create working directory.
1818 EXPECT_EQ(base::File::FILE_OK
,
1819 ofu()->CreateDirectory(context
.get(), dir_url
, false, false));
1821 // EnsureFileExists, create case.
1822 FileSystemURL
url(FileSystemURLAppendUTF8(dir_url
, "EnsureFileExists_file"));
1823 bool created
= false;
1824 ClearTimestamp(dir_url
);
1825 context
.reset(NewContext(NULL
));
1826 EXPECT_EQ(base::File::FILE_OK
,
1827 ofu()->EnsureFileExists(context
.get(), url
, &created
));
1828 EXPECT_TRUE(created
);
1829 EXPECT_NE(base::Time(), GetModifiedTime(dir_url
));
1833 ClearTimestamp(dir_url
);
1834 context
.reset(NewContext(NULL
));
1835 EXPECT_EQ(base::File::FILE_OK
,
1836 ofu()->EnsureFileExists(context
.get(), url
, &created
));
1837 EXPECT_FALSE(created
);
1838 EXPECT_EQ(base::Time(), GetModifiedTime(dir_url
));
1841 url
= FileSystemURLAppendUTF8(dir_url
, "EnsureFileExists_dir");
1842 context
.reset(NewContext(NULL
));
1843 EXPECT_EQ(base::File::FILE_OK
,
1844 ofu()->CreateDirectory(context
.get(), url
, false, false));
1846 ClearTimestamp(dir_url
);
1847 context
.reset(NewContext(NULL
));
1848 EXPECT_EQ(base::File::FILE_ERROR_NOT_A_FILE
,
1849 ofu()->EnsureFileExists(context
.get(), url
, &created
));
1850 EXPECT_EQ(base::Time(), GetModifiedTime(dir_url
));
1852 // CreateOrOpen, create case.
1853 url
= FileSystemURLAppendUTF8(dir_url
, "CreateOrOpen_file");
1854 ClearTimestamp(dir_url
);
1855 context
.reset(NewContext(NULL
));
1857 ofu()->CreateOrOpen(context
.get(), url
,
1858 base::File::FLAG_CREATE
| base::File::FLAG_WRITE
);
1860 EXPECT_TRUE(file
.IsValid());
1861 EXPECT_TRUE(file
.created());
1863 EXPECT_NE(base::Time(), GetModifiedTime(dir_url
));
1866 ClearTimestamp(dir_url
);
1867 context
.reset(NewContext(NULL
));
1868 file
= ofu()->CreateOrOpen(context
.get(), url
,
1869 base::File::FLAG_OPEN
| base::File::FLAG_WRITE
);
1870 EXPECT_TRUE(file
.IsValid());
1871 EXPECT_FALSE(file
.created());
1873 EXPECT_EQ(base::Time(), GetModifiedTime(dir_url
));
1876 ClearTimestamp(dir_url
);
1877 context
.reset(NewContext(NULL
));
1878 file
= ofu()->CreateOrOpen(context
.get(), url
,
1879 base::File::FLAG_CREATE
| base::File::FLAG_WRITE
);
1880 EXPECT_FALSE(file
.IsValid());
1881 EXPECT_EQ(base::File::FILE_ERROR_EXISTS
, file
.error_details());
1882 EXPECT_EQ(base::Time(), GetModifiedTime(dir_url
));
1884 // CreateDirectory, create case.
1885 // Creating CreateDirectory_dir and CreateDirectory_dir/subdir.
1886 url
= FileSystemURLAppendUTF8(dir_url
, "CreateDirectory_dir");
1887 FileSystemURL
subdir_url(FileSystemURLAppendUTF8(url
, "subdir"));
1888 ClearTimestamp(dir_url
);
1889 context
.reset(NewContext(NULL
));
1890 EXPECT_EQ(base::File::FILE_OK
,
1891 ofu()->CreateDirectory(context
.get(), subdir_url
,
1892 true /* exclusive */, true /* recursive */));
1893 EXPECT_NE(base::Time(), GetModifiedTime(dir_url
));
1895 // create subdir case.
1896 // Creating CreateDirectory_dir/subdir2.
1897 subdir_url
= FileSystemURLAppendUTF8(url
, "subdir2");
1898 ClearTimestamp(dir_url
);
1899 ClearTimestamp(url
);
1900 context
.reset(NewContext(NULL
));
1901 EXPECT_EQ(base::File::FILE_OK
,
1902 ofu()->CreateDirectory(context
.get(), subdir_url
,
1903 true /* exclusive */, true /* recursive */));
1904 EXPECT_EQ(base::Time(), GetModifiedTime(dir_url
));
1905 EXPECT_NE(base::Time(), GetModifiedTime(url
));
1908 url
= FileSystemURLAppendUTF8(dir_url
, "CreateDirectory_dir");
1909 ClearTimestamp(dir_url
);
1910 context
.reset(NewContext(NULL
));
1911 EXPECT_EQ(base::File::FILE_ERROR_EXISTS
,
1912 ofu()->CreateDirectory(context
.get(), url
,
1913 true /* exclusive */, true /* recursive */));
1914 EXPECT_EQ(base::Time(), GetModifiedTime(dir_url
));
1916 // CopyInForeignFile, create case.
1917 url
= FileSystemURLAppendUTF8(dir_url
, "CopyInForeignFile_file");
1918 FileSystemURL src_path
= FileSystemURLAppendUTF8(
1919 dir_url
, "CopyInForeignFile_src_file");
1920 context
.reset(NewContext(NULL
));
1921 EXPECT_EQ(base::File::FILE_OK
,
1922 ofu()->EnsureFileExists(context
.get(), src_path
, &created
));
1923 EXPECT_TRUE(created
);
1924 base::FilePath src_local_path
;
1925 context
.reset(NewContext(NULL
));
1926 EXPECT_EQ(base::File::FILE_OK
,
1927 ofu()->GetLocalFilePath(context
.get(), src_path
, &src_local_path
));
1929 ClearTimestamp(dir_url
);
1930 context
.reset(NewContext(NULL
));
1931 EXPECT_EQ(base::File::FILE_OK
,
1932 ofu()->CopyInForeignFile(context
.get(),
1935 EXPECT_NE(base::Time(), GetModifiedTime(dir_url
));
1938 TEST_F(ObfuscatedFileUtilTest
, TestDirectoryTimestampForDeletion
) {
1939 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
1940 const FileSystemURL dir_url
= CreateURLFromUTF8("foo_dir");
1942 // Create working directory.
1943 EXPECT_EQ(base::File::FILE_OK
,
1944 ofu()->CreateDirectory(context
.get(), dir_url
, false, false));
1946 // DeleteFile, delete case.
1947 FileSystemURL url
= FileSystemURLAppendUTF8(
1948 dir_url
, "DeleteFile_file");
1949 bool created
= false;
1950 context
.reset(NewContext(NULL
));
1951 EXPECT_EQ(base::File::FILE_OK
,
1952 ofu()->EnsureFileExists(context
.get(), url
, &created
));
1953 EXPECT_TRUE(created
);
1955 ClearTimestamp(dir_url
);
1956 context
.reset(NewContext(NULL
));
1957 EXPECT_EQ(base::File::FILE_OK
,
1958 ofu()->DeleteFile(context
.get(), url
));
1959 EXPECT_NE(base::Time(), GetModifiedTime(dir_url
));
1962 ClearTimestamp(dir_url
);
1963 context
.reset(NewContext(NULL
));
1964 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
,
1965 ofu()->DeleteFile(context
.get(), url
));
1966 EXPECT_EQ(base::Time(), GetModifiedTime(dir_url
));
1968 // DeleteDirectory, fail case.
1969 url
= FileSystemURLAppendUTF8(dir_url
, "DeleteDirectory_dir");
1970 FileSystemURL
file_path(FileSystemURLAppendUTF8(url
, "pakeratta"));
1971 context
.reset(NewContext(NULL
));
1972 EXPECT_EQ(base::File::FILE_OK
,
1973 ofu()->CreateDirectory(context
.get(), url
, true, true));
1975 context
.reset(NewContext(NULL
));
1976 EXPECT_EQ(base::File::FILE_OK
,
1977 ofu()->EnsureFileExists(context
.get(), file_path
, &created
));
1978 EXPECT_TRUE(created
);
1980 ClearTimestamp(dir_url
);
1981 context
.reset(NewContext(NULL
));
1982 EXPECT_EQ(base::File::FILE_ERROR_NOT_EMPTY
,
1983 ofu()->DeleteDirectory(context
.get(), url
));
1984 EXPECT_EQ(base::Time(), GetModifiedTime(dir_url
));
1987 context
.reset(NewContext(NULL
));
1988 EXPECT_EQ(base::File::FILE_OK
,
1989 ofu()->DeleteFile(context
.get(), file_path
));
1991 ClearTimestamp(dir_url
);
1992 context
.reset(NewContext(NULL
));
1993 EXPECT_EQ(base::File::FILE_OK
, ofu()->DeleteDirectory(context
.get(), url
));
1994 EXPECT_NE(base::Time(), GetModifiedTime(dir_url
));
1997 TEST_F(ObfuscatedFileUtilTest
, TestDirectoryTimestampForCopyAndMove
) {
1998 TestDirectoryTimestampHelper(
1999 CreateURLFromUTF8("copy overwrite"), true, true);
2000 TestDirectoryTimestampHelper(
2001 CreateURLFromUTF8("copy non-overwrite"), true, false);
2002 TestDirectoryTimestampHelper(
2003 CreateURLFromUTF8("move overwrite"), false, true);
2004 TestDirectoryTimestampHelper(
2005 CreateURLFromUTF8("move non-overwrite"), false, false);
2008 TEST_F(ObfuscatedFileUtilTest
, TestFileEnumeratorTimestamp
) {
2009 FileSystemURL dir
= CreateURLFromUTF8("foo");
2010 FileSystemURL url1
= FileSystemURLAppendUTF8(dir
, "bar");
2011 FileSystemURL url2
= FileSystemURLAppendUTF8(dir
, "baz");
2013 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
2014 EXPECT_EQ(base::File::FILE_OK
,
2015 ofu()->CreateDirectory(context
.get(), dir
, false, false));
2017 bool created
= false;
2018 context
.reset(NewContext(NULL
));
2019 EXPECT_EQ(base::File::FILE_OK
,
2020 ofu()->EnsureFileExists(context
.get(), url1
, &created
));
2021 EXPECT_TRUE(created
);
2023 context
.reset(NewContext(NULL
));
2024 EXPECT_EQ(base::File::FILE_OK
,
2025 ofu()->CreateDirectory(context
.get(), url2
, false, false));
2027 base::FilePath file_path
;
2028 context
.reset(NewContext(NULL
));
2029 EXPECT_EQ(base::File::FILE_OK
,
2030 ofu()->GetLocalFilePath(context
.get(), url1
, &file_path
));
2031 EXPECT_FALSE(file_path
.empty());
2033 context
.reset(NewContext(NULL
));
2034 EXPECT_EQ(base::File::FILE_OK
,
2035 ofu()->Touch(context
.get(), url1
,
2036 base::Time::Now() + base::TimeDelta::FromHours(1),
2039 context
.reset(NewContext(NULL
));
2040 scoped_ptr
<storage::FileSystemFileUtil::AbstractFileEnumerator
> file_enum(
2041 ofu()->CreateFileEnumerator(context
.get(), dir
, false));
2044 base::FilePath file_path_each
;
2045 while (!(file_path_each
= file_enum
->Next()).empty()) {
2046 context
.reset(NewContext(NULL
));
2047 base::File::Info file_info
;
2048 base::FilePath file_path
;
2049 EXPECT_EQ(base::File::FILE_OK
,
2050 ofu()->GetFileInfo(context
.get(),
2051 FileSystemURL::CreateForTest(
2055 &file_info
, &file_path
));
2056 EXPECT_EQ(file_info
.is_directory
, file_enum
->IsDirectory());
2057 EXPECT_EQ(file_info
.last_modified
, file_enum
->LastModifiedTime());
2058 EXPECT_EQ(file_info
.size
, file_enum
->Size());
2061 EXPECT_EQ(2, count
);
2065 #if defined(OS_WIN) || defined(OS_ANDROID)
2066 #define MAYBE_TestQuotaOnCopyFile DISABLED_TestQuotaOnCopyFile
2068 #define MAYBE_TestQuotaOnCopyFile TestQuotaOnCopyFile
2070 TEST_F(ObfuscatedFileUtilTest
, MAYBE_TestQuotaOnCopyFile
) {
2071 FileSystemURL
from_file(CreateURLFromUTF8("fromfile"));
2072 FileSystemURL
obstacle_file(CreateURLFromUTF8("obstaclefile"));
2073 FileSystemURL
to_file1(CreateURLFromUTF8("tofile1"));
2074 FileSystemURL
to_file2(CreateURLFromUTF8("tofile2"));
2077 int64 expected_total_file_size
= 0;
2078 ASSERT_EQ(base::File::FILE_OK
,
2079 ofu()->EnsureFileExists(
2080 AllowUsageIncrease(PathCost(from_file
))->context(),
2081 from_file
, &created
));
2082 ASSERT_TRUE(created
);
2083 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2085 ASSERT_EQ(base::File::FILE_OK
,
2086 ofu()->EnsureFileExists(
2087 AllowUsageIncrease(PathCost(obstacle_file
))->context(),
2088 obstacle_file
, &created
));
2089 ASSERT_TRUE(created
);
2090 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2092 int64 from_file_size
= 1020;
2093 expected_total_file_size
+= from_file_size
;
2094 ASSERT_EQ(base::File::FILE_OK
,
2096 AllowUsageIncrease(from_file_size
)->context(),
2097 from_file
, from_file_size
));
2098 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2100 int64 obstacle_file_size
= 1;
2101 expected_total_file_size
+= obstacle_file_size
;
2102 ASSERT_EQ(base::File::FILE_OK
,
2104 AllowUsageIncrease(obstacle_file_size
)->context(),
2105 obstacle_file
, obstacle_file_size
));
2106 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2108 int64 to_file1_size
= from_file_size
;
2109 expected_total_file_size
+= to_file1_size
;
2110 ASSERT_EQ(base::File::FILE_OK
,
2111 ofu()->CopyOrMoveFile(
2113 PathCost(to_file1
) + to_file1_size
)->context(),
2114 from_file
, to_file1
,
2115 FileSystemOperation::OPTION_NONE
,
2117 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2119 ASSERT_EQ(base::File::FILE_ERROR_NO_SPACE
,
2120 ofu()->CopyOrMoveFile(
2121 DisallowUsageIncrease(
2122 PathCost(to_file2
) + from_file_size
)->context(),
2123 from_file
, to_file2
, FileSystemOperation::OPTION_NONE
,
2125 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2127 int64 old_obstacle_file_size
= obstacle_file_size
;
2128 obstacle_file_size
= from_file_size
;
2129 expected_total_file_size
+= obstacle_file_size
- old_obstacle_file_size
;
2130 ASSERT_EQ(base::File::FILE_OK
,
2131 ofu()->CopyOrMoveFile(
2133 obstacle_file_size
- old_obstacle_file_size
)->context(),
2134 from_file
, obstacle_file
,
2135 FileSystemOperation::OPTION_NONE
,
2137 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2139 int64 old_from_file_size
= from_file_size
;
2140 from_file_size
= old_from_file_size
- 1;
2141 expected_total_file_size
+= from_file_size
- old_from_file_size
;
2142 ASSERT_EQ(base::File::FILE_OK
,
2145 from_file_size
- old_from_file_size
)->context(),
2146 from_file
, from_file_size
));
2147 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2151 old_obstacle_file_size
= obstacle_file_size
;
2152 obstacle_file_size
= from_file_size
;
2153 expected_total_file_size
+= obstacle_file_size
- old_obstacle_file_size
;
2154 scoped_ptr
<UsageVerifyHelper
> helper
= AllowUsageIncrease(
2155 obstacle_file_size
- old_obstacle_file_size
);
2156 helper
->context()->set_allowed_bytes_growth(
2157 helper
->context()->allowed_bytes_growth() - 1);
2158 ASSERT_EQ(base::File::FILE_OK
,
2159 ofu()->CopyOrMoveFile(
2161 from_file
, obstacle_file
,
2162 FileSystemOperation::OPTION_NONE
,
2164 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2168 TEST_F(ObfuscatedFileUtilTest
, TestQuotaOnMoveFile
) {
2169 FileSystemURL
from_file(CreateURLFromUTF8("fromfile"));
2170 FileSystemURL
obstacle_file(CreateURLFromUTF8("obstaclefile"));
2171 FileSystemURL
to_file(CreateURLFromUTF8("tofile"));
2174 int64 expected_total_file_size
= 0;
2175 ASSERT_EQ(base::File::FILE_OK
,
2176 ofu()->EnsureFileExists(
2177 AllowUsageIncrease(PathCost(from_file
))->context(),
2178 from_file
, &created
));
2179 ASSERT_TRUE(created
);
2180 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2182 int64 from_file_size
= 1020;
2183 expected_total_file_size
+= from_file_size
;
2184 ASSERT_EQ(base::File::FILE_OK
,
2186 AllowUsageIncrease(from_file_size
)->context(),
2187 from_file
, from_file_size
));
2188 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2191 ASSERT_EQ(base::File::FILE_OK
,
2192 ofu()->CopyOrMoveFile(
2193 AllowUsageIncrease(-PathCost(from_file
) +
2194 PathCost(to_file
))->context(),
2196 FileSystemOperation::OPTION_NONE
,
2198 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2200 ASSERT_EQ(base::File::FILE_OK
,
2201 ofu()->EnsureFileExists(
2202 AllowUsageIncrease(PathCost(from_file
))->context(),
2203 from_file
, &created
));
2204 ASSERT_TRUE(created
);
2205 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2207 ASSERT_EQ(base::File::FILE_OK
,
2208 ofu()->EnsureFileExists(
2209 AllowUsageIncrease(PathCost(obstacle_file
))->context(),
2210 obstacle_file
, &created
));
2211 ASSERT_TRUE(created
);
2212 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2214 from_file_size
= 1020;
2215 expected_total_file_size
+= from_file_size
;
2216 ASSERT_EQ(base::File::FILE_OK
,
2218 AllowUsageIncrease(from_file_size
)->context(),
2219 from_file
, from_file_size
));
2220 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2222 int64 obstacle_file_size
= 1;
2223 expected_total_file_size
+= obstacle_file_size
;
2224 ASSERT_EQ(base::File::FILE_OK
,
2226 AllowUsageIncrease(1)->context(),
2227 obstacle_file
, obstacle_file_size
));
2228 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2230 int64 old_obstacle_file_size
= obstacle_file_size
;
2231 obstacle_file_size
= from_file_size
;
2233 expected_total_file_size
-= old_obstacle_file_size
;
2234 ASSERT_EQ(base::File::FILE_OK
,
2235 ofu()->CopyOrMoveFile(
2237 -old_obstacle_file_size
- PathCost(from_file
))->context(),
2238 from_file
, obstacle_file
,
2239 FileSystemOperation::OPTION_NONE
,
2241 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2243 ASSERT_EQ(base::File::FILE_OK
,
2244 ofu()->EnsureFileExists(
2245 AllowUsageIncrease(PathCost(from_file
))->context(),
2246 from_file
, &created
));
2247 ASSERT_TRUE(created
);
2248 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2250 from_file_size
= 10;
2251 expected_total_file_size
+= from_file_size
;
2252 ASSERT_EQ(base::File::FILE_OK
,
2254 AllowUsageIncrease(from_file_size
)->context(),
2255 from_file
, from_file_size
));
2256 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2258 // quota exceeded even after operation
2259 old_obstacle_file_size
= obstacle_file_size
;
2260 obstacle_file_size
= from_file_size
;
2262 expected_total_file_size
-= old_obstacle_file_size
;
2263 scoped_ptr
<FileSystemOperationContext
> context
=
2264 LimitedContext(-old_obstacle_file_size
- PathCost(from_file
) - 1);
2265 ASSERT_EQ(base::File::FILE_OK
,
2266 ofu()->CopyOrMoveFile(
2267 context
.get(), from_file
, obstacle_file
,
2268 FileSystemOperation::OPTION_NONE
,
2270 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2274 TEST_F(ObfuscatedFileUtilTest
, TestQuotaOnRemove
) {
2275 FileSystemURL
dir(CreateURLFromUTF8("dir"));
2276 FileSystemURL
file(CreateURLFromUTF8("file"));
2277 FileSystemURL
dfile1(CreateURLFromUTF8("dir/dfile1"));
2278 FileSystemURL
dfile2(CreateURLFromUTF8("dir/dfile2"));
2281 ASSERT_EQ(base::File::FILE_OK
,
2282 ofu()->EnsureFileExists(
2283 AllowUsageIncrease(PathCost(file
))->context(),
2285 ASSERT_TRUE(created
);
2286 ASSERT_EQ(0, ComputeTotalFileSize());
2288 ASSERT_EQ(base::File::FILE_OK
,
2289 ofu()->CreateDirectory(
2290 AllowUsageIncrease(PathCost(dir
))->context(),
2291 dir
, false, false));
2292 ASSERT_EQ(0, ComputeTotalFileSize());
2294 ASSERT_EQ(base::File::FILE_OK
,
2295 ofu()->EnsureFileExists(
2296 AllowUsageIncrease(PathCost(dfile1
))->context(),
2298 ASSERT_TRUE(created
);
2299 ASSERT_EQ(0, ComputeTotalFileSize());
2301 ASSERT_EQ(base::File::FILE_OK
,
2302 ofu()->EnsureFileExists(
2303 AllowUsageIncrease(PathCost(dfile2
))->context(),
2305 ASSERT_TRUE(created
);
2306 ASSERT_EQ(0, ComputeTotalFileSize());
2308 ASSERT_EQ(base::File::FILE_OK
,
2310 AllowUsageIncrease(340)->context(),
2312 ASSERT_EQ(340, ComputeTotalFileSize());
2314 ASSERT_EQ(base::File::FILE_OK
,
2316 AllowUsageIncrease(1020)->context(),
2318 ASSERT_EQ(1360, ComputeTotalFileSize());
2320 ASSERT_EQ(base::File::FILE_OK
,
2322 AllowUsageIncrease(120)->context(),
2324 ASSERT_EQ(1480, ComputeTotalFileSize());
2326 ASSERT_EQ(base::File::FILE_OK
,
2328 AllowUsageIncrease(-PathCost(file
) - 340)->context(),
2330 ASSERT_EQ(1140, ComputeTotalFileSize());
2332 ASSERT_EQ(base::File::FILE_OK
,
2333 AsyncFileTestHelper::Remove(
2334 file_system_context(), dir
, true /* recursive */));
2335 ASSERT_EQ(0, ComputeTotalFileSize());
2338 TEST_F(ObfuscatedFileUtilTest
, TestQuotaOnOpen
) {
2339 FileSystemURL
url(CreateURLFromUTF8("file"));
2343 ASSERT_EQ(base::File::FILE_OK
,
2344 ofu()->EnsureFileExists(
2345 AllowUsageIncrease(PathCost(url
))->context(),
2347 ASSERT_TRUE(created
);
2348 ASSERT_EQ(0, ComputeTotalFileSize());
2350 // Opening it, which shouldn't change the usage.
2352 ofu()->CreateOrOpen(AllowUsageIncrease(0)->context(), url
,
2353 base::File::FLAG_OPEN
| base::File::FLAG_WRITE
);
2354 ASSERT_TRUE(file
.IsValid());
2355 ASSERT_EQ(0, ComputeTotalFileSize());
2358 const int length
= 33;
2359 ASSERT_EQ(base::File::FILE_OK
,
2361 AllowUsageIncrease(length
)->context(), url
, length
));
2362 ASSERT_EQ(length
, ComputeTotalFileSize());
2364 // Opening it with CREATE_ALWAYS flag, which should truncate the file size.
2365 file
= ofu()->CreateOrOpen(
2366 AllowUsageIncrease(-length
)->context(), url
,
2367 base::File::FLAG_CREATE_ALWAYS
| base::File::FLAG_WRITE
);
2368 ASSERT_TRUE(file
.IsValid());
2369 ASSERT_EQ(0, ComputeTotalFileSize());
2372 // Extending the file again.
2373 ASSERT_EQ(base::File::FILE_OK
,
2375 AllowUsageIncrease(length
)->context(), url
, length
));
2376 ASSERT_EQ(length
, ComputeTotalFileSize());
2378 // Opening it with TRUNCATED flag, which should truncate the file size.
2379 file
= ofu()->CreateOrOpen(
2380 AllowUsageIncrease(-length
)->context(), url
,
2381 base::File::FLAG_OPEN_TRUNCATED
| base::File::FLAG_WRITE
);
2382 ASSERT_TRUE(file
.IsValid());
2383 ASSERT_EQ(0, ComputeTotalFileSize());
2387 TEST_F(ObfuscatedFileUtilTest
, MaybeDropDatabasesAliveCase
) {
2388 MaybeDropDatabasesAliveCaseTestBody();
2391 TEST_F(ObfuscatedFileUtilTest
, MaybeDropDatabasesAlreadyDeletedCase
) {
2392 MaybeDropDatabasesAlreadyDeletedCaseTestBody();
2395 TEST_F(ObfuscatedFileUtilTest
, DestroyDirectoryDatabase_Isolated
) {
2396 DestroyDirectoryDatabase_IsolatedTestBody();
2399 TEST_F(ObfuscatedFileUtilTest
, GetDirectoryDatabase_Isolated
) {
2400 GetDirectoryDatabase_IsolatedTestBody();
2403 TEST_F(ObfuscatedFileUtilTest
, MigrationBackFromIsolated
) {
2404 MigrationBackFromIsolatedTestBody();
2407 TEST_F(ObfuscatedFileUtilTest
, OpenPathInNonDirectory
) {
2408 FileSystemURL
url(CreateURLFromUTF8("file"));
2409 FileSystemURL
path_in_file(CreateURLFromUTF8("file/file"));
2412 ASSERT_EQ(base::File::FILE_OK
,
2413 ofu()->EnsureFileExists(UnlimitedContext().get(), url
, &created
));
2414 ASSERT_TRUE(created
);
2416 int file_flags
= base::File::FLAG_CREATE
| base::File::FLAG_WRITE
;
2418 ofu()->CreateOrOpen(UnlimitedContext().get(), path_in_file
, file_flags
);
2419 ASSERT_FALSE(file
.IsValid());
2420 ASSERT_EQ(base::File::FILE_ERROR_NOT_A_DIRECTORY
, file
.error_details());
2422 ASSERT_EQ(base::File::FILE_ERROR_NOT_A_DIRECTORY
,
2423 ofu()->CreateDirectory(UnlimitedContext().get(),
2425 false /* exclusive */,
2426 false /* recursive */));
2429 TEST_F(ObfuscatedFileUtilTest
, CreateDirectory_NotADirectoryInRecursive
) {
2430 FileSystemURL
file(CreateURLFromUTF8("file"));
2431 FileSystemURL
path_in_file(CreateURLFromUTF8("file/child"));
2432 FileSystemURL
path_in_file_in_file(
2433 CreateURLFromUTF8("file/child/grandchild"));
2436 ASSERT_EQ(base::File::FILE_OK
,
2437 ofu()->EnsureFileExists(UnlimitedContext().get(), file
, &created
));
2438 ASSERT_TRUE(created
);
2440 ASSERT_EQ(base::File::FILE_ERROR_NOT_A_DIRECTORY
,
2441 ofu()->CreateDirectory(UnlimitedContext().get(),
2443 false /* exclusive */,
2444 true /* recursive */));
2445 ASSERT_EQ(base::File::FILE_ERROR_NOT_A_DIRECTORY
,
2446 ofu()->CreateDirectory(UnlimitedContext().get(),
2447 path_in_file_in_file
,
2448 false /* exclusive */,
2449 true /* recursive */));
2452 TEST_F(ObfuscatedFileUtilTest
, DeleteDirectoryForOriginAndType
) {
2453 const GURL
origin1("http://www.example.com:12");
2454 const GURL
origin2("http://www.example.com:1234");
2456 // Create origin directories.
2457 scoped_ptr
<SandboxFileSystemTestHelper
> fs1(
2458 NewFileSystem(origin1
, kFileSystemTypeTemporary
));
2459 scoped_ptr
<SandboxFileSystemTestHelper
> fs2(
2460 NewFileSystem(origin1
, kFileSystemTypePersistent
));
2461 scoped_ptr
<SandboxFileSystemTestHelper
> fs3(
2462 NewFileSystem(origin2
, kFileSystemTypeTemporary
));
2463 scoped_ptr
<SandboxFileSystemTestHelper
> fs4(
2464 NewFileSystem(origin2
, kFileSystemTypePersistent
));
2466 // Make sure directories for origin1 exist.
2467 base::File::Error error
= base::File::FILE_ERROR_FAILED
;
2468 ofu()->GetDirectoryForOriginAndType(
2469 origin1
, GetTypeString(kFileSystemTypeTemporary
), false, &error
);
2470 ASSERT_EQ(base::File::FILE_OK
, error
);
2471 error
= base::File::FILE_ERROR_FAILED
;
2472 ofu()->GetDirectoryForOriginAndType(
2473 origin1
, GetTypeString(kFileSystemTypePersistent
), false, &error
);
2474 ASSERT_EQ(base::File::FILE_OK
, error
);
2476 // Make sure directories for origin2 exist.
2477 error
= base::File::FILE_ERROR_FAILED
;
2478 ofu()->GetDirectoryForOriginAndType(
2479 origin2
, GetTypeString(kFileSystemTypeTemporary
), false, &error
);
2480 ASSERT_EQ(base::File::FILE_OK
, error
);
2481 error
= base::File::FILE_ERROR_FAILED
;
2482 ofu()->GetDirectoryForOriginAndType(
2483 origin2
, GetTypeString(kFileSystemTypePersistent
), false, &error
);
2484 ASSERT_EQ(base::File::FILE_OK
, error
);
2486 // Delete a directory for origin1's persistent filesystem.
2487 ofu()->DeleteDirectoryForOriginAndType(
2488 origin1
, GetTypeString(kFileSystemTypePersistent
));
2490 // The directory for origin1's temporary filesystem should not be removed.
2491 error
= base::File::FILE_ERROR_FAILED
;
2492 ofu()->GetDirectoryForOriginAndType(
2493 origin1
, GetTypeString(kFileSystemTypeTemporary
), false, &error
);
2494 ASSERT_EQ(base::File::FILE_OK
, error
);
2496 // The directory for origin1's persistent filesystem should be removed.
2497 error
= base::File::FILE_ERROR_FAILED
;
2498 ofu()->GetDirectoryForOriginAndType(
2499 origin1
, GetTypeString(kFileSystemTypePersistent
), false, &error
);
2500 ASSERT_EQ(base::File::FILE_ERROR_NOT_FOUND
, error
);
2502 // The directories for origin2 should not be removed.
2503 error
= base::File::FILE_ERROR_FAILED
;
2504 ofu()->GetDirectoryForOriginAndType(
2505 origin2
, GetTypeString(kFileSystemTypeTemporary
), false, &error
);
2506 ASSERT_EQ(base::File::FILE_OK
, error
);
2507 error
= base::File::FILE_ERROR_FAILED
;
2508 ofu()->GetDirectoryForOriginAndType(
2509 origin2
, GetTypeString(kFileSystemTypePersistent
), false, &error
);
2510 ASSERT_EQ(base::File::FILE_OK
, error
);
2513 TEST_F(ObfuscatedFileUtilTest
, DeleteDirectoryForOriginAndType_DeleteAll
) {
2514 const GURL
origin1("http://www.example.com:12");
2515 const GURL
origin2("http://www.example.com:1234");
2517 // Create origin directories.
2518 scoped_ptr
<SandboxFileSystemTestHelper
> fs1(
2519 NewFileSystem(origin1
, kFileSystemTypeTemporary
));
2520 scoped_ptr
<SandboxFileSystemTestHelper
> fs2(
2521 NewFileSystem(origin1
, kFileSystemTypePersistent
));
2522 scoped_ptr
<SandboxFileSystemTestHelper
> fs3(
2523 NewFileSystem(origin2
, kFileSystemTypeTemporary
));
2524 scoped_ptr
<SandboxFileSystemTestHelper
> fs4(
2525 NewFileSystem(origin2
, kFileSystemTypePersistent
));
2527 // Make sure directories for origin1 exist.
2528 base::File::Error error
= base::File::FILE_ERROR_FAILED
;
2529 ofu()->GetDirectoryForOriginAndType(
2530 origin1
, GetTypeString(kFileSystemTypeTemporary
), false, &error
);
2531 ASSERT_EQ(base::File::FILE_OK
, error
);
2532 error
= base::File::FILE_ERROR_FAILED
;
2533 ofu()->GetDirectoryForOriginAndType(
2534 origin1
, GetTypeString(kFileSystemTypePersistent
), false, &error
);
2535 ASSERT_EQ(base::File::FILE_OK
, error
);
2537 // Make sure directories for origin2 exist.
2538 error
= base::File::FILE_ERROR_FAILED
;
2539 ofu()->GetDirectoryForOriginAndType(
2540 origin2
, GetTypeString(kFileSystemTypeTemporary
), false, &error
);
2541 ASSERT_EQ(base::File::FILE_OK
, error
);
2542 error
= base::File::FILE_ERROR_FAILED
;
2543 ofu()->GetDirectoryForOriginAndType(
2544 origin2
, GetTypeString(kFileSystemTypePersistent
), false, &error
);
2545 ASSERT_EQ(base::File::FILE_OK
, error
);
2547 // Delete all directories for origin1.
2548 ofu()->DeleteDirectoryForOriginAndType(origin1
, std::string());
2550 // The directories for origin1 should be removed.
2551 error
= base::File::FILE_ERROR_FAILED
;
2552 ofu()->GetDirectoryForOriginAndType(
2553 origin1
, GetTypeString(kFileSystemTypeTemporary
), false, &error
);
2554 ASSERT_EQ(base::File::FILE_ERROR_NOT_FOUND
, error
);
2555 error
= base::File::FILE_ERROR_FAILED
;
2556 ofu()->GetDirectoryForOriginAndType(
2557 origin1
, GetTypeString(kFileSystemTypePersistent
), false, &error
);
2558 ASSERT_EQ(base::File::FILE_ERROR_NOT_FOUND
, error
);
2560 // The directories for origin2 should not be removed.
2561 error
= base::File::FILE_ERROR_FAILED
;
2562 ofu()->GetDirectoryForOriginAndType(
2563 origin2
, GetTypeString(kFileSystemTypeTemporary
), false, &error
);
2564 ASSERT_EQ(base::File::FILE_OK
, error
);
2565 error
= base::File::FILE_ERROR_FAILED
;
2566 ofu()->GetDirectoryForOriginAndType(
2567 origin2
, GetTypeString(kFileSystemTypePersistent
), false, &error
);
2568 ASSERT_EQ(base::File::FILE_OK
, error
);
2571 } // namespace content