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/file_util.h"
11 #include "base/files/file.h"
12 #include "base/files/file_path.h"
13 #include "base/files/scoped_temp_dir.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/platform_file.h"
16 #include "base/run_loop.h"
17 #include "content/browser/fileapi/mock_file_change_observer.h"
18 #include "content/public/test/async_file_test_helper.h"
19 #include "content/public/test/mock_special_storage_policy.h"
20 #include "content/public/test/sandbox_file_system_test_helper.h"
21 #include "content/public/test/test_file_system_context.h"
22 #include "content/test/fileapi_test_file_set.h"
23 #include "testing/gtest/include/gtest/gtest.h"
24 #include "webkit/browser/fileapi/external_mount_points.h"
25 #include "webkit/browser/fileapi/file_system_backend.h"
26 #include "webkit/browser/fileapi/file_system_context.h"
27 #include "webkit/browser/fileapi/file_system_operation_context.h"
28 #include "webkit/browser/fileapi/file_system_usage_cache.h"
29 #include "webkit/browser/fileapi/obfuscated_file_util.h"
30 #include "webkit/browser/fileapi/sandbox_directory_database.h"
31 #include "webkit/browser/fileapi/sandbox_file_system_backend_delegate.h"
32 #include "webkit/browser/fileapi/sandbox_isolated_origin_database.h"
33 #include "webkit/browser/fileapi/sandbox_origin_database.h"
34 #include "webkit/browser/quota/quota_manager.h"
35 #include "webkit/common/database/database_identifier.h"
36 #include "webkit/common/quota/quota_types.h"
38 using content::AsyncFileTestHelper
;
39 using fileapi::FileSystemContext
;
40 using fileapi::FileSystemOperation
;
41 using fileapi::FileSystemOperationContext
;
42 using fileapi::FileSystemType
;
43 using fileapi::FileSystemURL
;
44 using fileapi::ObfuscatedFileUtil
;
45 using fileapi::SandboxDirectoryDatabase
;
46 using fileapi::SandboxIsolatedOriginDatabase
;
47 using fileapi::kFileSystemTypeTemporary
;
48 using fileapi::kFileSystemTypePersistent
;
54 bool FileExists(const base::FilePath
& path
) {
55 return base::PathExists(path
) && !base::DirectoryExists(path
);
58 int64
GetSize(const base::FilePath
& path
) {
60 EXPECT_TRUE(base::GetFileSize(path
, &size
));
64 // After a move, the dest exists and the source doesn't.
65 // After a copy, both source and dest exist.
66 struct CopyMoveTestCaseRecord
{
67 bool is_copy_not_move
;
68 const char source_path
[64];
69 const char dest_path
[64];
73 const CopyMoveTestCaseRecord kCopyMoveTestCases
[] = {
74 // This is the combinatoric set of:
75 // rename vs. same-name
76 // different directory vs. same directory
77 // overwrite vs. no-overwrite
79 // We can never be called with source and destination paths identical, so
80 // those cases are omitted.
81 {true, "dir0/file0", "dir0/file1", false},
82 {false, "dir0/file0", "dir0/file1", false},
83 {true, "dir0/file0", "dir0/file1", true},
84 {false, "dir0/file0", "dir0/file1", true},
86 {true, "dir0/file0", "dir1/file0", false},
87 {false, "dir0/file0", "dir1/file0", false},
88 {true, "dir0/file0", "dir1/file0", true},
89 {false, "dir0/file0", "dir1/file0", true},
90 {true, "dir0/file0", "dir1/file1", false},
91 {false, "dir0/file0", "dir1/file1", false},
92 {true, "dir0/file0", "dir1/file1", true},
93 {false, "dir0/file0", "dir1/file1", true},
96 struct OriginEnumerationTestRecord
{
97 std::string origin_url
;
102 const OriginEnumerationTestRecord kOriginEnumerationTestRecords
[] = {
103 {"http://example.com", false, true},
104 {"http://example1.com", true, false},
105 {"https://example1.com", true, true},
106 {"file://", false, true},
107 {"http://example.com:8000", false, true},
110 FileSystemURL
FileSystemURLAppend(
111 const FileSystemURL
& url
, const base::FilePath::StringType
& child
) {
112 return FileSystemURL::CreateForTest(
113 url
.origin(), url
.mount_type(), url
.virtual_path().Append(child
));
116 FileSystemURL
FileSystemURLAppendUTF8(
117 const FileSystemURL
& url
, const std::string
& child
) {
118 return FileSystemURL::CreateForTest(
121 url
.virtual_path().Append(base::FilePath::FromUTF8Unsafe(child
)));
124 FileSystemURL
FileSystemURLDirName(const FileSystemURL
& url
) {
125 return FileSystemURL::CreateForTest(
126 url
.origin(), url
.mount_type(),
127 fileapi::VirtualPath::DirName(url
.virtual_path()));
130 std::string
GetTypeString(FileSystemType type
) {
131 return fileapi::SandboxFileSystemBackendDelegate::GetTypeString(type
);
134 bool HasFileSystemType(
135 ObfuscatedFileUtil::AbstractOriginEnumerator
* enumerator
,
136 FileSystemType type
) {
137 return enumerator
->HasTypeDirectory(GetTypeString(type
));
142 // TODO(ericu): The vast majority of this and the other FSFU subclass tests
143 // could theoretically be shared. It would basically be a FSFU interface
144 // compliance test, and only the subclass-specific bits that look into the
145 // implementation would need to be written per-subclass.
146 class ObfuscatedFileUtilTest
: public testing::Test
{
148 ObfuscatedFileUtilTest()
149 : origin_(GURL("http://www.example.com")),
150 type_(fileapi::kFileSystemTypeTemporary
),
152 sandbox_file_system_(origin_
, type_
),
153 quota_status_(quota::kQuotaStatusUnknown
),
157 virtual void SetUp() {
158 ASSERT_TRUE(data_dir_
.CreateUniqueTempDir());
160 storage_policy_
= new MockSpecialStoragePolicy();
163 new quota::QuotaManager(false /* is_incognito */,
165 base::MessageLoopProxy::current().get(),
166 base::MessageLoopProxy::current().get(),
167 storage_policy_
.get());
169 // Every time we create a new sandbox_file_system helper,
170 // it creates another context, which creates another path manager,
171 // another sandbox_backend, and another OFU.
172 // We need to pass in the context to skip all that.
173 file_system_context_
= CreateFileSystemContextForTesting(
174 quota_manager_
->proxy(),
177 sandbox_file_system_
.SetUp(file_system_context_
.get());
179 change_observers_
= fileapi::MockFileChangeObserver::CreateList(
183 virtual void TearDown() {
184 quota_manager_
= NULL
;
185 sandbox_file_system_
.TearDown();
188 scoped_ptr
<FileSystemOperationContext
> LimitedContext(
189 int64 allowed_bytes_growth
) {
190 scoped_ptr
<FileSystemOperationContext
> context(
191 sandbox_file_system_
.NewOperationContext());
192 context
->set_allowed_bytes_growth(allowed_bytes_growth
);
193 return context
.Pass();
196 scoped_ptr
<FileSystemOperationContext
> UnlimitedContext() {
197 return LimitedContext(kint64max
);
200 FileSystemOperationContext
* NewContext(
201 SandboxFileSystemTestHelper
* file_system
) {
202 change_observer()->ResetCount();
203 FileSystemOperationContext
* context
;
205 context
= file_system
->NewOperationContext();
207 context
= sandbox_file_system_
.NewOperationContext();
208 // Setting allowed_bytes_growth big enough for all tests.
209 context
->set_allowed_bytes_growth(1024 * 1024);
210 context
->set_change_observers(change_observers());
214 const fileapi::ChangeObserverList
& change_observers() const {
215 return change_observers_
;
218 fileapi::MockFileChangeObserver
* change_observer() {
219 return &change_observer_
;
222 // This can only be used after SetUp has run and created file_system_context_
223 // and obfuscated_file_util_.
224 // Use this for tests which need to run in multiple origins; we need a test
225 // helper per origin.
226 SandboxFileSystemTestHelper
* NewFileSystem(
227 const GURL
& origin
, fileapi::FileSystemType type
) {
228 SandboxFileSystemTestHelper
* file_system
=
229 new SandboxFileSystemTestHelper(origin
, type
);
231 file_system
->SetUp(file_system_context_
.get());
235 scoped_ptr
<ObfuscatedFileUtil
> CreateObfuscatedFileUtil(
236 quota::SpecialStoragePolicy
* storage_policy
) {
237 return scoped_ptr
<ObfuscatedFileUtil
>(
238 ObfuscatedFileUtil::CreateForTesting(
239 storage_policy
, data_dir_path(), NULL
,
240 base::MessageLoopProxy::current().get()));
243 ObfuscatedFileUtil
* ofu() {
244 return static_cast<ObfuscatedFileUtil
*>(sandbox_file_system_
.file_util());
247 const base::FilePath
& test_directory() const {
248 return data_dir_
.path();
251 const GURL
& origin() const {
255 fileapi::FileSystemType
type() const {
259 std::string
type_string() const {
260 return GetTypeString(type_
);
263 int64
ComputeTotalFileSize() {
264 return sandbox_file_system_
.ComputeCurrentOriginUsage() -
265 sandbox_file_system_
.ComputeCurrentDirectoryDatabaseUsage();
268 void GetUsageFromQuotaManager() {
271 AsyncFileTestHelper::GetUsageAndQuota(quota_manager_
.get(),
273 sandbox_file_system_
.type(),
276 EXPECT_EQ(quota::kQuotaStatusOk
, quota_status_
);
279 void RevokeUsageCache() {
280 quota_manager_
->ResetUsageTracker(sandbox_file_system_
.storage_type());
281 usage_cache()->Delete(sandbox_file_system_
.GetUsageCachePath());
284 int64
SizeByQuotaUtil() {
285 return sandbox_file_system_
.GetCachedOriginUsage();
288 int64
SizeInUsageFile() {
289 base::RunLoop().RunUntilIdle();
291 return usage_cache()->GetUsage(
292 sandbox_file_system_
.GetUsageCachePath(), &usage
) ? usage
: -1;
295 bool PathExists(const FileSystemURL
& url
) {
296 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
297 base::File::Info file_info
;
298 base::FilePath platform_path
;
299 base::File::Error error
= ofu()->GetFileInfo(
300 context
.get(), url
, &file_info
, &platform_path
);
301 return error
== base::File::FILE_OK
;
304 bool DirectoryExists(const FileSystemURL
& url
) {
305 return AsyncFileTestHelper::DirectoryExists(file_system_context(), url
);
308 int64
usage() const { return usage_
; }
309 fileapi::FileSystemUsageCache
* usage_cache() {
310 return sandbox_file_system_
.usage_cache();
313 FileSystemURL
CreateURLFromUTF8(const std::string
& path
) {
314 return sandbox_file_system_
.CreateURLFromUTF8(path
);
317 int64
PathCost(const FileSystemURL
& url
) {
318 return ObfuscatedFileUtil::ComputeFilePathCost(url
.path());
321 FileSystemURL
CreateURL(const base::FilePath
& path
) {
322 return sandbox_file_system_
.CreateURL(path
);
325 void CheckFileAndCloseHandle(
326 const FileSystemURL
& url
, base::PlatformFile file_handle
) {
327 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
328 base::FilePath local_path
;
329 EXPECT_EQ(base::File::FILE_OK
,
330 ofu()->GetLocalFilePath(context
.get(), url
, &local_path
));
332 base::File::Info file_info0
;
333 base::FilePath data_path
;
334 EXPECT_EQ(base::File::FILE_OK
,
335 ofu()->GetFileInfo(context
.get(), url
, &file_info0
, &data_path
));
336 EXPECT_EQ(data_path
, local_path
);
337 EXPECT_TRUE(FileExists(data_path
));
338 EXPECT_EQ(0, GetSize(data_path
));
340 const char data
[] = "test data";
341 const int length
= arraysize(data
) - 1;
343 if (base::kInvalidPlatformFileValue
== file_handle
) {
344 base::File
file(data_path
,
345 base::File::FLAG_OPEN
| base::File::FLAG_WRITE
);
346 ASSERT_TRUE(file
.IsValid());
347 EXPECT_FALSE(file
.created());
348 file_handle
= file
.TakePlatformFile();
350 ASSERT_EQ(length
, base::WritePlatformFile(file_handle
, 0, data
, length
));
351 EXPECT_TRUE(base::ClosePlatformFile(file_handle
));
353 base::File::Info file_info1
;
354 EXPECT_EQ(length
, GetSize(data_path
));
355 context
.reset(NewContext(NULL
));
356 EXPECT_EQ(base::File::FILE_OK
,
357 ofu()->GetFileInfo(context
.get(), url
, &file_info1
, &data_path
));
358 EXPECT_EQ(data_path
, local_path
);
360 EXPECT_FALSE(file_info0
.is_directory
);
361 EXPECT_FALSE(file_info1
.is_directory
);
362 EXPECT_FALSE(file_info0
.is_symbolic_link
);
363 EXPECT_FALSE(file_info1
.is_symbolic_link
);
364 EXPECT_EQ(0, file_info0
.size
);
365 EXPECT_EQ(length
, file_info1
.size
);
366 EXPECT_LE(file_info0
.last_modified
, file_info1
.last_modified
);
368 context
.reset(NewContext(NULL
));
369 EXPECT_EQ(base::File::FILE_OK
,
370 ofu()->Truncate(context
.get(), url
, length
* 2));
371 EXPECT_EQ(length
* 2, GetSize(data_path
));
373 context
.reset(NewContext(NULL
));
374 EXPECT_EQ(base::File::FILE_OK
,
375 ofu()->Truncate(context
.get(), url
, 0));
376 EXPECT_EQ(0, GetSize(data_path
));
379 void ValidateTestDirectory(
380 const FileSystemURL
& root_url
,
381 const std::set
<base::FilePath::StringType
>& files
,
382 const std::set
<base::FilePath::StringType
>& directories
) {
383 scoped_ptr
<FileSystemOperationContext
> context
;
384 std::set
<base::FilePath::StringType
>::const_iterator iter
;
385 for (iter
= files
.begin(); iter
!= files
.end(); ++iter
) {
387 context
.reset(NewContext(NULL
));
388 ASSERT_EQ(base::File::FILE_OK
,
389 ofu()->EnsureFileExists(context
.get(),
390 FileSystemURLAppend(root_url
, *iter
),
392 ASSERT_FALSE(created
);
394 for (iter
= directories
.begin(); iter
!= directories
.end(); ++iter
) {
395 context
.reset(NewContext(NULL
));
396 EXPECT_TRUE(DirectoryExists(
397 FileSystemURLAppend(root_url
, *iter
)));
401 class UsageVerifyHelper
{
403 UsageVerifyHelper(scoped_ptr
<FileSystemOperationContext
> context
,
404 SandboxFileSystemTestHelper
* file_system
,
405 int64 expected_usage
)
406 : context_(context
.Pass()),
407 sandbox_file_system_(file_system
),
408 expected_usage_(expected_usage
) {}
410 ~UsageVerifyHelper() {
411 base::RunLoop().RunUntilIdle();
415 FileSystemOperationContext
* context() {
416 return context_
.get();
421 ASSERT_EQ(expected_usage_
,
422 sandbox_file_system_
->GetCachedOriginUsage());
425 scoped_ptr
<FileSystemOperationContext
> context_
;
426 SandboxFileSystemTestHelper
* sandbox_file_system_
;
427 int64 expected_usage_
;
430 scoped_ptr
<UsageVerifyHelper
> AllowUsageIncrease(int64 requested_growth
) {
431 int64 usage
= sandbox_file_system_
.GetCachedOriginUsage();
432 return scoped_ptr
<UsageVerifyHelper
>(new UsageVerifyHelper(
433 LimitedContext(requested_growth
),
434 &sandbox_file_system_
, usage
+ requested_growth
));
437 scoped_ptr
<UsageVerifyHelper
> DisallowUsageIncrease(int64 requested_growth
) {
438 int64 usage
= sandbox_file_system_
.GetCachedOriginUsage();
439 return scoped_ptr
<UsageVerifyHelper
>(new UsageVerifyHelper(
440 LimitedContext(requested_growth
- 1), &sandbox_file_system_
, usage
));
443 void FillTestDirectory(
444 const FileSystemURL
& root_url
,
445 std::set
<base::FilePath::StringType
>* files
,
446 std::set
<base::FilePath::StringType
>* directories
) {
447 scoped_ptr
<FileSystemOperationContext
> context
;
448 std::vector
<fileapi::DirectoryEntry
> entries
;
449 EXPECT_EQ(base::File::FILE_OK
,
450 AsyncFileTestHelper::ReadDirectory(file_system_context(),
451 root_url
, &entries
));
452 EXPECT_EQ(0UL, entries
.size());
455 files
->insert(FILE_PATH_LITERAL("first"));
456 files
->insert(FILE_PATH_LITERAL("second"));
457 files
->insert(FILE_PATH_LITERAL("third"));
458 directories
->clear();
459 directories
->insert(FILE_PATH_LITERAL("fourth"));
460 directories
->insert(FILE_PATH_LITERAL("fifth"));
461 directories
->insert(FILE_PATH_LITERAL("sixth"));
462 std::set
<base::FilePath::StringType
>::iterator iter
;
463 for (iter
= files
->begin(); iter
!= files
->end(); ++iter
) {
464 bool created
= false;
465 context
.reset(NewContext(NULL
));
466 ASSERT_EQ(base::File::FILE_OK
,
467 ofu()->EnsureFileExists(context
.get(),
468 FileSystemURLAppend(root_url
, *iter
),
470 ASSERT_TRUE(created
);
472 for (iter
= directories
->begin(); iter
!= directories
->end(); ++iter
) {
473 bool exclusive
= true;
474 bool recursive
= false;
475 context
.reset(NewContext(NULL
));
476 EXPECT_EQ(base::File::FILE_OK
,
477 ofu()->CreateDirectory(context
.get(),
478 FileSystemURLAppend(root_url
, *iter
),
479 exclusive
, recursive
));
481 ValidateTestDirectory(root_url
, *files
, *directories
);
484 void TestReadDirectoryHelper(const FileSystemURL
& root_url
) {
485 std::set
<base::FilePath::StringType
> files
;
486 std::set
<base::FilePath::StringType
> directories
;
487 FillTestDirectory(root_url
, &files
, &directories
);
489 scoped_ptr
<FileSystemOperationContext
> context
;
490 std::vector
<fileapi::DirectoryEntry
> entries
;
491 context
.reset(NewContext(NULL
));
492 EXPECT_EQ(base::File::FILE_OK
,
493 AsyncFileTestHelper::ReadDirectory(
494 file_system_context(), root_url
, &entries
));
495 std::vector
<fileapi::DirectoryEntry
>::iterator entry_iter
;
496 EXPECT_EQ(files
.size() + directories
.size(), entries
.size());
497 EXPECT_TRUE(change_observer()->HasNoChange());
498 for (entry_iter
= entries
.begin(); entry_iter
!= entries
.end();
500 const fileapi::DirectoryEntry
& entry
= *entry_iter
;
501 std::set
<base::FilePath::StringType
>::iterator iter
=
502 files
.find(entry
.name
);
503 if (iter
!= files
.end()) {
504 EXPECT_FALSE(entry
.is_directory
);
508 iter
= directories
.find(entry
.name
);
509 EXPECT_FALSE(directories
.end() == iter
);
510 EXPECT_TRUE(entry
.is_directory
);
511 directories
.erase(iter
);
515 void TestTouchHelper(const FileSystemURL
& url
, bool is_file
) {
516 base::Time last_access_time
= base::Time::Now();
517 base::Time last_modified_time
= base::Time::Now();
519 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
520 EXPECT_EQ(base::File::FILE_OK
,
521 ofu()->Touch(context
.get(), url
, last_access_time
,
522 last_modified_time
));
523 // Currently we fire no change notifications for Touch.
524 EXPECT_TRUE(change_observer()->HasNoChange());
525 base::FilePath local_path
;
526 base::File::Info file_info
;
527 context
.reset(NewContext(NULL
));
528 EXPECT_EQ(base::File::FILE_OK
, ofu()->GetFileInfo(
529 context
.get(), url
, &file_info
, &local_path
));
530 // We compare as time_t here to lower our resolution, to avoid false
531 // negatives caused by conversion to the local filesystem's native
532 // representation and back.
533 EXPECT_EQ(file_info
.last_modified
.ToTimeT(), last_modified_time
.ToTimeT());
535 context
.reset(NewContext(NULL
));
536 last_modified_time
+= base::TimeDelta::FromHours(1);
537 last_access_time
+= base::TimeDelta::FromHours(14);
538 EXPECT_EQ(base::File::FILE_OK
,
539 ofu()->Touch(context
.get(), url
, last_access_time
,
540 last_modified_time
));
541 EXPECT_TRUE(change_observer()->HasNoChange());
542 context
.reset(NewContext(NULL
));
543 EXPECT_EQ(base::File::FILE_OK
,
544 ofu()->GetFileInfo(context
.get(), url
, &file_info
, &local_path
));
545 EXPECT_EQ(file_info
.last_modified
.ToTimeT(), last_modified_time
.ToTimeT());
546 if (is_file
) // Directories in OFU don't support atime.
547 EXPECT_EQ(file_info
.last_accessed
.ToTimeT(), last_access_time
.ToTimeT());
550 void TestCopyInForeignFileHelper(bool overwrite
) {
551 base::ScopedTempDir source_dir
;
552 ASSERT_TRUE(source_dir
.CreateUniqueTempDir());
553 base::FilePath root_file_path
= source_dir
.path();
554 base::FilePath src_file_path
= root_file_path
.AppendASCII("file_name");
555 FileSystemURL dest_url
= CreateURLFromUTF8("new file");
556 int64 src_file_length
= 87;
558 base::File
file(src_file_path
,
559 base::File::FLAG_CREATE
| base::File::FLAG_WRITE
);
560 ASSERT_TRUE(file
.IsValid());
561 EXPECT_TRUE(file
.created());
562 ASSERT_TRUE(file
.SetLength(src_file_length
));
565 scoped_ptr
<FileSystemOperationContext
> context
;
568 context
.reset(NewContext(NULL
));
569 bool created
= false;
570 EXPECT_EQ(base::File::FILE_OK
,
571 ofu()->EnsureFileExists(context
.get(), dest_url
, &created
));
572 EXPECT_TRUE(created
);
574 // We must have observed one (and only one) create_file_count.
575 EXPECT_EQ(1, change_observer()->get_and_reset_create_file_count());
576 EXPECT_TRUE(change_observer()->HasNoChange());
579 const int64 path_cost
=
580 ObfuscatedFileUtil::ComputeFilePathCost(dest_url
.path());
582 // Verify that file creation requires sufficient quota for the path.
583 context
.reset(NewContext(NULL
));
584 context
->set_allowed_bytes_growth(path_cost
+ src_file_length
- 1);
585 EXPECT_EQ(base::File::FILE_ERROR_NO_SPACE
,
586 ofu()->CopyInForeignFile(context
.get(),
587 src_file_path
, dest_url
));
590 context
.reset(NewContext(NULL
));
591 context
->set_allowed_bytes_growth(path_cost
+ src_file_length
);
592 EXPECT_EQ(base::File::FILE_OK
,
593 ofu()->CopyInForeignFile(context
.get(),
594 src_file_path
, dest_url
));
596 EXPECT_TRUE(PathExists(dest_url
));
597 EXPECT_FALSE(DirectoryExists(dest_url
));
599 context
.reset(NewContext(NULL
));
600 base::File::Info file_info
;
601 base::FilePath data_path
;
602 EXPECT_EQ(base::File::FILE_OK
,
603 ofu()->GetFileInfo(context
.get(), dest_url
, &file_info
,
605 EXPECT_NE(data_path
, src_file_path
);
606 EXPECT_TRUE(FileExists(data_path
));
607 EXPECT_EQ(src_file_length
, GetSize(data_path
));
609 EXPECT_EQ(base::File::FILE_OK
,
610 ofu()->DeleteFile(context
.get(), dest_url
));
613 void ClearTimestamp(const FileSystemURL
& url
) {
614 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
615 EXPECT_EQ(base::File::FILE_OK
,
616 ofu()->Touch(context
.get(), url
, base::Time(), base::Time()));
617 EXPECT_EQ(base::Time(), GetModifiedTime(url
));
620 base::Time
GetModifiedTime(const FileSystemURL
& url
) {
621 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
622 base::FilePath data_path
;
623 base::File::Info file_info
;
624 context
.reset(NewContext(NULL
));
625 EXPECT_EQ(base::File::FILE_OK
,
626 ofu()->GetFileInfo(context
.get(), url
, &file_info
, &data_path
));
627 EXPECT_TRUE(change_observer()->HasNoChange());
628 return file_info
.last_modified
;
631 void TestDirectoryTimestampHelper(const FileSystemURL
& base_dir
,
634 scoped_ptr
<FileSystemOperationContext
> context
;
635 const FileSystemURL
src_dir_url(
636 FileSystemURLAppendUTF8(base_dir
, "foo_dir"));
637 const FileSystemURL
dest_dir_url(
638 FileSystemURLAppendUTF8(base_dir
, "bar_dir"));
640 const FileSystemURL
src_file_url(
641 FileSystemURLAppendUTF8(src_dir_url
, "hoge"));
642 const FileSystemURL
dest_file_url(
643 FileSystemURLAppendUTF8(dest_dir_url
, "fuga"));
645 context
.reset(NewContext(NULL
));
646 EXPECT_EQ(base::File::FILE_OK
,
647 ofu()->CreateDirectory(context
.get(), src_dir_url
, true, true));
648 context
.reset(NewContext(NULL
));
649 EXPECT_EQ(base::File::FILE_OK
,
650 ofu()->CreateDirectory(context
.get(), dest_dir_url
, true, true));
652 bool created
= false;
653 context
.reset(NewContext(NULL
));
654 EXPECT_EQ(base::File::FILE_OK
,
655 ofu()->EnsureFileExists(context
.get(), src_file_url
, &created
));
657 context
.reset(NewContext(NULL
));
658 EXPECT_EQ(base::File::FILE_OK
,
659 ofu()->EnsureFileExists(context
.get(),
660 dest_file_url
, &created
));
663 ClearTimestamp(src_dir_url
);
664 ClearTimestamp(dest_dir_url
);
665 context
.reset(NewContext(NULL
));
666 EXPECT_EQ(base::File::FILE_OK
,
667 ofu()->CopyOrMoveFile(context
.get(),
668 src_file_url
, dest_file_url
,
669 FileSystemOperation::OPTION_NONE
,
672 EXPECT_EQ(base::Time(), GetModifiedTime(src_dir_url
));
674 EXPECT_NE(base::Time(), GetModifiedTime(src_dir_url
));
675 EXPECT_NE(base::Time(), GetModifiedTime(dest_dir_url
));
678 void MaybeDropDatabasesAliveCaseTestBody() {
679 scoped_ptr
<ObfuscatedFileUtil
> file_util
= CreateObfuscatedFileUtil(NULL
);
680 file_util
->InitOriginDatabase(GURL(), true /*create*/);
681 ASSERT_TRUE(file_util
->origin_database_
!= NULL
);
683 // Callback to Drop DB is called while ObfuscatedFileUtilTest is
685 file_util
->db_flush_delay_seconds_
= 0;
686 file_util
->MarkUsed();
687 base::RunLoop().RunUntilIdle();
689 ASSERT_TRUE(file_util
->origin_database_
== NULL
);
692 void MaybeDropDatabasesAlreadyDeletedCaseTestBody() {
693 // Run message loop after OFU is already deleted to make sure callback
694 // doesn't cause a crash for use after free.
696 scoped_ptr
<ObfuscatedFileUtil
> file_util
= CreateObfuscatedFileUtil(NULL
);
697 file_util
->InitOriginDatabase(GURL(), true /*create*/);
698 file_util
->db_flush_delay_seconds_
= 0;
699 file_util
->MarkUsed();
702 // At this point the callback is still in the message queue but OFU is gone.
703 base::RunLoop().RunUntilIdle();
706 void DestroyDirectoryDatabase_IsolatedTestBody() {
707 storage_policy_
->AddIsolated(origin_
);
708 scoped_ptr
<ObfuscatedFileUtil
> file_util
= CreateObfuscatedFileUtil(
709 storage_policy_
.get());
710 const FileSystemURL url
= FileSystemURL::CreateForTest(
711 origin_
, kFileSystemTypePersistent
, base::FilePath());
713 // Create DirectoryDatabase for isolated origin.
714 SandboxDirectoryDatabase
* db
=
715 file_util
->GetDirectoryDatabase(url
, true /* create */);
716 ASSERT_TRUE(db
!= NULL
);
719 ASSERT_TRUE(file_util
->DestroyDirectoryDatabase(
720 url
.origin(), GetTypeString(url
.type())));
721 ASSERT_TRUE(file_util
->directories_
.empty());
724 void GetDirectoryDatabase_IsolatedTestBody() {
725 storage_policy_
->AddIsolated(origin_
);
726 scoped_ptr
<ObfuscatedFileUtil
> file_util
= CreateObfuscatedFileUtil(
727 storage_policy_
.get());
728 const FileSystemURL url
= FileSystemURL::CreateForTest(
729 origin_
, kFileSystemTypePersistent
, base::FilePath());
731 // Create DirectoryDatabase for isolated origin.
732 SandboxDirectoryDatabase
* db
=
733 file_util
->GetDirectoryDatabase(url
, true /* create */);
734 ASSERT_TRUE(db
!= NULL
);
735 ASSERT_EQ(1U, file_util
->directories_
.size());
738 storage_policy_
->RemoveIsolated(url
.origin());
740 // This should still get the same database.
741 SandboxDirectoryDatabase
* db2
=
742 file_util
->GetDirectoryDatabase(url
, false /* create */);
746 void MigrationBackFromIsolatedTestBody() {
747 std::string
kFakeDirectoryData("0123456789");
748 base::FilePath old_directory_db_path
;
750 // Initialize the directory with one origin using
751 // SandboxIsolatedOriginDatabase.
753 std::string origin_string
=
754 webkit_database::GetIdentifierFromOrigin(origin_
);
755 SandboxIsolatedOriginDatabase
database_old(
756 origin_string
, data_dir_path(),
758 SandboxIsolatedOriginDatabase::kObsoleteOriginDirectory
));
760 EXPECT_TRUE(database_old
.GetPathForOrigin(origin_string
, &path
));
761 EXPECT_FALSE(path
.empty());
763 // Populate the origin directory with some fake data.
764 old_directory_db_path
= data_dir_path().Append(path
);
765 ASSERT_TRUE(base::CreateDirectory(old_directory_db_path
));
766 EXPECT_EQ(static_cast<int>(kFakeDirectoryData
.size()),
767 base::WriteFile(old_directory_db_path
.AppendASCII("dummy"),
768 kFakeDirectoryData
.data(),
769 kFakeDirectoryData
.size()));
772 storage_policy_
->AddIsolated(origin_
);
773 scoped_ptr
<ObfuscatedFileUtil
> file_util
= CreateObfuscatedFileUtil(
774 storage_policy_
.get());
775 base::File::Error error
= base::File::FILE_ERROR_FAILED
;
776 base::FilePath origin_directory
= file_util
->GetDirectoryForOrigin(
777 origin_
, true /* create */, &error
);
778 EXPECT_EQ(base::File::FILE_OK
, error
);
780 // The database is migrated from the old one.
781 EXPECT_TRUE(base::DirectoryExists(origin_directory
));
782 EXPECT_FALSE(base::DirectoryExists(old_directory_db_path
));
784 // Check we see the same contents in the new origin directory.
785 std::string origin_db_data
;
786 EXPECT_TRUE(base::PathExists(origin_directory
.AppendASCII("dummy")));
787 EXPECT_TRUE(base::ReadFileToString(
788 origin_directory
.AppendASCII("dummy"), &origin_db_data
));
789 EXPECT_EQ(kFakeDirectoryData
, origin_db_data
);
792 int64
ComputeCurrentUsage() {
793 return sandbox_file_system_
.ComputeCurrentOriginUsage() -
794 sandbox_file_system_
.ComputeCurrentDirectoryDatabaseUsage();
797 FileSystemContext
* file_system_context() {
798 return sandbox_file_system_
.file_system_context();
801 const base::FilePath
& data_dir_path() const {
802 return data_dir_
.path();
806 base::ScopedTempDir data_dir_
;
807 base::MessageLoop message_loop_
;
808 scoped_refptr
<MockSpecialStoragePolicy
> storage_policy_
;
809 scoped_refptr
<quota::QuotaManager
> quota_manager_
;
810 scoped_refptr
<FileSystemContext
> file_system_context_
;
812 fileapi::FileSystemType type_
;
813 base::WeakPtrFactory
<ObfuscatedFileUtilTest
> weak_factory_
;
814 SandboxFileSystemTestHelper sandbox_file_system_
;
815 quota::QuotaStatusCode quota_status_
;
817 fileapi::MockFileChangeObserver change_observer_
;
818 fileapi::ChangeObserverList change_observers_
;
821 DISALLOW_COPY_AND_ASSIGN(ObfuscatedFileUtilTest
);
824 TEST_F(ObfuscatedFileUtilTest
, TestCreateAndDeleteFile
) {
825 base::PlatformFile file_handle
= base::kInvalidPlatformFileValue
;
827 FileSystemURL url
= CreateURLFromUTF8("fake/file");
828 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
829 int file_flags
= base::PLATFORM_FILE_CREATE
| base::PLATFORM_FILE_WRITE
;
831 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
,
832 ofu()->CreateOrOpen(context
.get(), url
, file_flags
, &file_handle
,
835 context
.reset(NewContext(NULL
));
836 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
,
837 ofu()->DeleteFile(context
.get(), url
));
839 url
= CreateURLFromUTF8("test file");
841 EXPECT_TRUE(change_observer()->HasNoChange());
843 // Verify that file creation requires sufficient quota for the path.
844 context
.reset(NewContext(NULL
));
845 context
->set_allowed_bytes_growth(
846 ObfuscatedFileUtil::ComputeFilePathCost(url
.path()) - 1);
847 ASSERT_EQ(base::File::FILE_ERROR_NO_SPACE
,
848 ofu()->CreateOrOpen(context
.get(), url
, file_flags
,
849 &file_handle
, &created
));
851 context
.reset(NewContext(NULL
));
852 context
->set_allowed_bytes_growth(
853 ObfuscatedFileUtil::ComputeFilePathCost(url
.path()));
854 ASSERT_EQ(base::File::FILE_OK
,
855 ofu()->CreateOrOpen(context
.get(), url
, file_flags
, &file_handle
,
857 ASSERT_TRUE(created
);
858 EXPECT_EQ(1, change_observer()->get_and_reset_create_file_count());
859 EXPECT_NE(base::kInvalidPlatformFileValue
, file_handle
);
861 CheckFileAndCloseHandle(url
, file_handle
);
863 context
.reset(NewContext(NULL
));
864 base::FilePath local_path
;
865 EXPECT_EQ(base::File::FILE_OK
,
866 ofu()->GetLocalFilePath(context
.get(), url
, &local_path
));
867 EXPECT_TRUE(base::PathExists(local_path
));
869 // Verify that deleting a file isn't stopped by zero quota, and that it frees
870 // up quote from its path.
871 context
.reset(NewContext(NULL
));
872 context
->set_allowed_bytes_growth(0);
873 EXPECT_EQ(base::File::FILE_OK
, ofu()->DeleteFile(context
.get(), url
));
874 EXPECT_EQ(1, change_observer()->get_and_reset_remove_file_count());
875 EXPECT_FALSE(base::PathExists(local_path
));
876 EXPECT_EQ(ObfuscatedFileUtil::ComputeFilePathCost(url
.path()),
877 context
->allowed_bytes_growth());
879 context
.reset(NewContext(NULL
));
880 bool exclusive
= true;
881 bool recursive
= true;
882 FileSystemURL directory_url
= CreateURLFromUTF8(
883 "series/of/directories");
884 url
= FileSystemURLAppendUTF8(directory_url
, "file name");
885 EXPECT_EQ(base::File::FILE_OK
,
886 ofu()->CreateDirectory(context
.get(), directory_url
, exclusive
,
888 // The oepration created 3 directories recursively.
889 EXPECT_EQ(3, change_observer()->get_and_reset_create_directory_count());
891 context
.reset(NewContext(NULL
));
892 file_handle
= base::kInvalidPlatformFileValue
;
893 ASSERT_EQ(base::File::FILE_OK
,
894 ofu()->CreateOrOpen(context
.get(), url
, file_flags
, &file_handle
,
896 ASSERT_TRUE(created
);
897 EXPECT_EQ(1, change_observer()->get_and_reset_create_file_count());
898 EXPECT_NE(base::kInvalidPlatformFileValue
, file_handle
);
900 CheckFileAndCloseHandle(url
, file_handle
);
902 context
.reset(NewContext(NULL
));
903 EXPECT_EQ(base::File::FILE_OK
,
904 ofu()->GetLocalFilePath(context
.get(), url
, &local_path
));
905 EXPECT_TRUE(base::PathExists(local_path
));
907 context
.reset(NewContext(NULL
));
908 EXPECT_EQ(base::File::FILE_OK
, ofu()->DeleteFile(context
.get(), url
));
909 EXPECT_EQ(1, change_observer()->get_and_reset_remove_file_count());
910 EXPECT_FALSE(base::PathExists(local_path
));
912 // Make sure we have no unexpected changes.
913 EXPECT_TRUE(change_observer()->HasNoChange());
916 TEST_F(ObfuscatedFileUtilTest
, TestTruncate
) {
917 bool created
= false;
918 FileSystemURL url
= CreateURLFromUTF8("file");
919 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
921 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
,
922 ofu()->Truncate(context
.get(), url
, 4));
924 context
.reset(NewContext(NULL
));
925 ASSERT_EQ(base::File::FILE_OK
,
926 ofu()->EnsureFileExists(context
.get(), url
, &created
));
927 ASSERT_TRUE(created
);
928 EXPECT_EQ(1, change_observer()->get_and_reset_create_file_count());
930 context
.reset(NewContext(NULL
));
931 base::FilePath local_path
;
932 EXPECT_EQ(base::File::FILE_OK
,
933 ofu()->GetLocalFilePath(context
.get(), url
, &local_path
));
934 EXPECT_EQ(0, GetSize(local_path
));
936 context
.reset(NewContext(NULL
));
937 EXPECT_EQ(base::File::FILE_OK
, ofu()->Truncate(context
.get(), url
, 10));
938 EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count());
939 EXPECT_EQ(10, GetSize(local_path
));
941 context
.reset(NewContext(NULL
));
942 EXPECT_EQ(base::File::FILE_OK
, ofu()->Truncate(context
.get(), url
, 1));
943 EXPECT_EQ(1, GetSize(local_path
));
944 EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count());
946 EXPECT_FALSE(DirectoryExists(url
));
947 EXPECT_TRUE(PathExists(url
));
949 // Make sure we have no unexpected changes.
950 EXPECT_TRUE(change_observer()->HasNoChange());
953 TEST_F(ObfuscatedFileUtilTest
, TestQuotaOnTruncation
) {
954 bool created
= false;
955 FileSystemURL url
= CreateURLFromUTF8("file");
957 ASSERT_EQ(base::File::FILE_OK
,
958 ofu()->EnsureFileExists(
959 AllowUsageIncrease(PathCost(url
))->context(),
961 ASSERT_TRUE(created
);
962 ASSERT_EQ(0, ComputeTotalFileSize());
964 ASSERT_EQ(base::File::FILE_OK
,
965 ofu()->Truncate(AllowUsageIncrease(1020)->context(), url
, 1020));
966 ASSERT_EQ(1020, ComputeTotalFileSize());
968 ASSERT_EQ(base::File::FILE_OK
,
969 ofu()->Truncate(AllowUsageIncrease(-1020)->context(), url
, 0));
970 ASSERT_EQ(0, ComputeTotalFileSize());
972 EXPECT_EQ(base::File::FILE_ERROR_NO_SPACE
,
973 ofu()->Truncate(DisallowUsageIncrease(1021)->context(),
975 ASSERT_EQ(0, ComputeTotalFileSize());
977 EXPECT_EQ(base::File::FILE_OK
,
978 ofu()->Truncate(AllowUsageIncrease(1020)->context(), url
, 1020));
979 ASSERT_EQ(1020, ComputeTotalFileSize());
981 EXPECT_EQ(base::File::FILE_OK
,
982 ofu()->Truncate(AllowUsageIncrease(0)->context(), url
, 1020));
983 ASSERT_EQ(1020, ComputeTotalFileSize());
987 scoped_ptr
<UsageVerifyHelper
> helper
= AllowUsageIncrease(-1);
988 helper
->context()->set_allowed_bytes_growth(
989 helper
->context()->allowed_bytes_growth() - 1);
990 EXPECT_EQ(base::File::FILE_OK
,
991 ofu()->Truncate(helper
->context(), url
, 1019));
992 ASSERT_EQ(1019, ComputeTotalFileSize());
995 // Delete backing file to make following truncation fail.
996 base::FilePath local_path
;
997 ASSERT_EQ(base::File::FILE_OK
,
998 ofu()->GetLocalFilePath(UnlimitedContext().get(), url
,
1000 ASSERT_FALSE(local_path
.empty());
1001 ASSERT_TRUE(base::DeleteFile(local_path
, false));
1003 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
,
1004 ofu()->Truncate(LimitedContext(1234).get(), url
, 1234));
1005 ASSERT_EQ(0, ComputeTotalFileSize());
1008 TEST_F(ObfuscatedFileUtilTest
, TestEnsureFileExists
) {
1009 FileSystemURL url
= CreateURLFromUTF8("fake/file");
1010 bool created
= false;
1011 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
1012 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
,
1013 ofu()->EnsureFileExists(context
.get(), url
, &created
));
1014 EXPECT_TRUE(change_observer()->HasNoChange());
1016 // Verify that file creation requires sufficient quota for the path.
1017 context
.reset(NewContext(NULL
));
1018 url
= CreateURLFromUTF8("test file");
1020 context
->set_allowed_bytes_growth(
1021 ObfuscatedFileUtil::ComputeFilePathCost(url
.path()) - 1);
1022 ASSERT_EQ(base::File::FILE_ERROR_NO_SPACE
,
1023 ofu()->EnsureFileExists(context
.get(), url
, &created
));
1024 ASSERT_FALSE(created
);
1025 EXPECT_TRUE(change_observer()->HasNoChange());
1027 context
.reset(NewContext(NULL
));
1028 context
->set_allowed_bytes_growth(
1029 ObfuscatedFileUtil::ComputeFilePathCost(url
.path()));
1030 ASSERT_EQ(base::File::FILE_OK
,
1031 ofu()->EnsureFileExists(context
.get(), url
, &created
));
1032 ASSERT_TRUE(created
);
1033 EXPECT_EQ(1, change_observer()->get_and_reset_create_file_count());
1035 CheckFileAndCloseHandle(url
, base::kInvalidPlatformFileValue
);
1037 context
.reset(NewContext(NULL
));
1038 ASSERT_EQ(base::File::FILE_OK
,
1039 ofu()->EnsureFileExists(context
.get(), url
, &created
));
1040 ASSERT_FALSE(created
);
1041 EXPECT_TRUE(change_observer()->HasNoChange());
1043 // Also test in a subdirectory.
1044 url
= CreateURLFromUTF8("path/to/file.txt");
1045 context
.reset(NewContext(NULL
));
1046 bool exclusive
= true;
1047 bool recursive
= true;
1048 EXPECT_EQ(base::File::FILE_OK
,
1049 ofu()->CreateDirectory(context
.get(), FileSystemURLDirName(url
),
1050 exclusive
, recursive
));
1051 // 2 directories: path/ and path/to.
1052 EXPECT_EQ(2, change_observer()->get_and_reset_create_directory_count());
1054 context
.reset(NewContext(NULL
));
1055 ASSERT_EQ(base::File::FILE_OK
,
1056 ofu()->EnsureFileExists(context
.get(), url
, &created
));
1057 ASSERT_TRUE(created
);
1058 EXPECT_FALSE(DirectoryExists(url
));
1059 EXPECT_TRUE(PathExists(url
));
1060 EXPECT_TRUE(change_observer()->HasNoChange());
1063 TEST_F(ObfuscatedFileUtilTest
, TestDirectoryOps
) {
1064 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
1066 bool exclusive
= false;
1067 bool recursive
= false;
1068 FileSystemURL url
= CreateURLFromUTF8("foo/bar");
1069 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
,
1070 ofu()->CreateDirectory(context
.get(), url
, exclusive
, recursive
));
1072 context
.reset(NewContext(NULL
));
1073 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
,
1074 ofu()->DeleteDirectory(context
.get(), url
));
1076 FileSystemURL root
= CreateURLFromUTF8(std::string());
1077 EXPECT_FALSE(DirectoryExists(url
));
1078 EXPECT_FALSE(PathExists(url
));
1079 context
.reset(NewContext(NULL
));
1080 EXPECT_TRUE(ofu()->IsDirectoryEmpty(context
.get(), root
));
1082 context
.reset(NewContext(NULL
));
1085 EXPECT_EQ(base::File::FILE_OK
,
1086 ofu()->CreateDirectory(context
.get(), url
, exclusive
, recursive
));
1087 EXPECT_EQ(2, change_observer()->get_and_reset_create_directory_count());
1089 EXPECT_TRUE(DirectoryExists(url
));
1090 EXPECT_TRUE(PathExists(url
));
1092 context
.reset(NewContext(NULL
));
1093 EXPECT_FALSE(ofu()->IsDirectoryEmpty(context
.get(), root
));
1094 EXPECT_TRUE(DirectoryExists(FileSystemURLDirName(url
)));
1096 context
.reset(NewContext(NULL
));
1097 EXPECT_FALSE(ofu()->IsDirectoryEmpty(context
.get(),
1098 FileSystemURLDirName(url
)));
1100 // Can't remove a non-empty directory.
1101 context
.reset(NewContext(NULL
));
1102 EXPECT_EQ(base::File::FILE_ERROR_NOT_EMPTY
,
1103 ofu()->DeleteDirectory(context
.get(),
1104 FileSystemURLDirName(url
)));
1105 EXPECT_TRUE(change_observer()->HasNoChange());
1107 base::File::Info file_info
;
1108 base::FilePath local_path
;
1109 EXPECT_EQ(base::File::FILE_OK
,
1110 ofu()->GetFileInfo(context
.get(), url
, &file_info
, &local_path
));
1111 EXPECT_TRUE(local_path
.empty());
1112 EXPECT_TRUE(file_info
.is_directory
);
1113 EXPECT_FALSE(file_info
.is_symbolic_link
);
1115 // Same create again should succeed, since exclusive is false.
1116 context
.reset(NewContext(NULL
));
1117 EXPECT_EQ(base::File::FILE_OK
,
1118 ofu()->CreateDirectory(context
.get(), url
, exclusive
, recursive
));
1119 EXPECT_TRUE(change_observer()->HasNoChange());
1123 context
.reset(NewContext(NULL
));
1124 EXPECT_EQ(base::File::FILE_ERROR_EXISTS
,
1125 ofu()->CreateDirectory(context
.get(), url
, exclusive
, recursive
));
1126 EXPECT_TRUE(change_observer()->HasNoChange());
1128 // Verify that deleting a directory isn't stopped by zero quota, and that it
1129 // frees up quota from its path.
1130 context
.reset(NewContext(NULL
));
1131 context
->set_allowed_bytes_growth(0);
1132 EXPECT_EQ(base::File::FILE_OK
, ofu()->DeleteDirectory(context
.get(), url
));
1133 EXPECT_EQ(1, change_observer()->get_and_reset_remove_directory_count());
1134 EXPECT_EQ(ObfuscatedFileUtil::ComputeFilePathCost(url
.path()),
1135 context
->allowed_bytes_growth());
1137 url
= CreateURLFromUTF8("foo/bop");
1139 EXPECT_FALSE(DirectoryExists(url
));
1140 EXPECT_FALSE(PathExists(url
));
1142 context
.reset(NewContext(NULL
));
1143 EXPECT_TRUE(ofu()->IsDirectoryEmpty(context
.get(), url
));
1144 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
,
1145 ofu()->GetFileInfo(context
.get(), url
, &file_info
, &local_path
));
1147 // Verify that file creation requires sufficient quota for the path.
1150 context
.reset(NewContext(NULL
));
1151 context
->set_allowed_bytes_growth(
1152 ObfuscatedFileUtil::ComputeFilePathCost(url
.path()) - 1);
1153 EXPECT_EQ(base::File::FILE_ERROR_NO_SPACE
,
1154 ofu()->CreateDirectory(context
.get(), url
, exclusive
, recursive
));
1155 EXPECT_TRUE(change_observer()->HasNoChange());
1157 context
.reset(NewContext(NULL
));
1158 context
->set_allowed_bytes_growth(
1159 ObfuscatedFileUtil::ComputeFilePathCost(url
.path()));
1160 EXPECT_EQ(base::File::FILE_OK
,
1161 ofu()->CreateDirectory(context
.get(), url
, exclusive
, recursive
));
1162 EXPECT_EQ(1, change_observer()->get_and_reset_create_directory_count());
1164 EXPECT_TRUE(DirectoryExists(url
));
1165 EXPECT_TRUE(PathExists(url
));
1169 context
.reset(NewContext(NULL
));
1170 EXPECT_EQ(base::File::FILE_ERROR_EXISTS
,
1171 ofu()->CreateDirectory(context
.get(), url
, exclusive
, recursive
));
1172 EXPECT_TRUE(change_observer()->HasNoChange());
1176 url
= CreateURLFromUTF8("foo");
1177 context
.reset(NewContext(NULL
));
1178 EXPECT_EQ(base::File::FILE_ERROR_EXISTS
,
1179 ofu()->CreateDirectory(context
.get(), url
, exclusive
, recursive
));
1180 EXPECT_TRUE(change_observer()->HasNoChange());
1182 url
= CreateURLFromUTF8("blah");
1184 EXPECT_FALSE(DirectoryExists(url
));
1185 EXPECT_FALSE(PathExists(url
));
1189 context
.reset(NewContext(NULL
));
1190 EXPECT_EQ(base::File::FILE_OK
,
1191 ofu()->CreateDirectory(context
.get(), url
, exclusive
, recursive
));
1192 EXPECT_EQ(1, change_observer()->get_and_reset_create_directory_count());
1194 EXPECT_TRUE(DirectoryExists(url
));
1195 EXPECT_TRUE(PathExists(url
));
1199 context
.reset(NewContext(NULL
));
1200 EXPECT_EQ(base::File::FILE_ERROR_EXISTS
,
1201 ofu()->CreateDirectory(context
.get(), url
, exclusive
, recursive
));
1202 EXPECT_TRUE(change_observer()->HasNoChange());
1205 TEST_F(ObfuscatedFileUtilTest
, TestReadDirectory
) {
1206 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
1207 bool exclusive
= true;
1208 bool recursive
= true;
1209 FileSystemURL url
= CreateURLFromUTF8("directory/to/use");
1210 EXPECT_EQ(base::File::FILE_OK
,
1211 ofu()->CreateDirectory(context
.get(), url
, exclusive
, recursive
));
1212 TestReadDirectoryHelper(url
);
1215 TEST_F(ObfuscatedFileUtilTest
, TestReadRootWithSlash
) {
1216 TestReadDirectoryHelper(CreateURLFromUTF8(std::string()));
1219 TEST_F(ObfuscatedFileUtilTest
, TestReadRootWithEmptyString
) {
1220 TestReadDirectoryHelper(CreateURLFromUTF8("/"));
1223 TEST_F(ObfuscatedFileUtilTest
, TestReadDirectoryOnFile
) {
1224 FileSystemURL url
= CreateURLFromUTF8("file");
1225 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
1227 bool created
= false;
1228 ASSERT_EQ(base::File::FILE_OK
,
1229 ofu()->EnsureFileExists(context
.get(), url
, &created
));
1230 ASSERT_TRUE(created
);
1232 std::vector
<fileapi::DirectoryEntry
> entries
;
1233 EXPECT_EQ(base::File::FILE_ERROR_NOT_A_DIRECTORY
,
1234 AsyncFileTestHelper::ReadDirectory(file_system_context(), url
,
1237 EXPECT_TRUE(ofu()->IsDirectoryEmpty(context
.get(), url
));
1240 TEST_F(ObfuscatedFileUtilTest
, TestTouch
) {
1241 FileSystemURL url
= CreateURLFromUTF8("file");
1242 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
1244 base::Time last_access_time
= base::Time::Now();
1245 base::Time last_modified_time
= base::Time::Now();
1247 // It's not there yet.
1248 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
,
1249 ofu()->Touch(context
.get(), url
, last_access_time
,
1250 last_modified_time
));
1252 // OK, now create it.
1253 context
.reset(NewContext(NULL
));
1254 bool created
= false;
1255 ASSERT_EQ(base::File::FILE_OK
,
1256 ofu()->EnsureFileExists(context
.get(), url
, &created
));
1257 ASSERT_TRUE(created
);
1258 TestTouchHelper(url
, true);
1260 // Now test a directory:
1261 context
.reset(NewContext(NULL
));
1262 bool exclusive
= true;
1263 bool recursive
= false;
1264 url
= CreateURLFromUTF8("dir");
1265 ASSERT_EQ(base::File::FILE_OK
,
1266 ofu()->CreateDirectory(context
.get(), url
, exclusive
, recursive
));
1267 TestTouchHelper(url
, false);
1270 TEST_F(ObfuscatedFileUtilTest
, TestPathQuotas
) {
1271 FileSystemURL url
= CreateURLFromUTF8("fake/file");
1272 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
1274 url
= CreateURLFromUTF8("file name");
1275 context
->set_allowed_bytes_growth(5);
1276 bool created
= false;
1277 EXPECT_EQ(base::File::FILE_ERROR_NO_SPACE
,
1278 ofu()->EnsureFileExists(context
.get(), url
, &created
));
1279 EXPECT_FALSE(created
);
1280 context
->set_allowed_bytes_growth(1024);
1281 EXPECT_EQ(base::File::FILE_OK
,
1282 ofu()->EnsureFileExists(context
.get(), url
, &created
));
1283 EXPECT_TRUE(created
);
1284 int64 path_cost
= ObfuscatedFileUtil::ComputeFilePathCost(url
.path());
1285 EXPECT_EQ(1024 - path_cost
, context
->allowed_bytes_growth());
1287 context
->set_allowed_bytes_growth(1024);
1288 bool exclusive
= true;
1289 bool recursive
= true;
1290 url
= CreateURLFromUTF8("directory/to/use");
1291 std::vector
<base::FilePath::StringType
> components
;
1292 url
.path().GetComponents(&components
);
1294 typedef std::vector
<base::FilePath::StringType
>::iterator iterator
;
1295 for (iterator iter
= components
.begin();
1296 iter
!= components
.end(); ++iter
) {
1297 path_cost
+= ObfuscatedFileUtil::ComputeFilePathCost(
1298 base::FilePath(*iter
));
1300 context
.reset(NewContext(NULL
));
1301 context
->set_allowed_bytes_growth(1024);
1302 EXPECT_EQ(base::File::FILE_OK
,
1303 ofu()->CreateDirectory(context
.get(), url
, exclusive
, recursive
));
1304 EXPECT_EQ(1024 - path_cost
, context
->allowed_bytes_growth());
1307 TEST_F(ObfuscatedFileUtilTest
, TestCopyOrMoveFileNotFound
) {
1308 FileSystemURL source_url
= CreateURLFromUTF8("path0.txt");
1309 FileSystemURL dest_url
= CreateURLFromUTF8("path1.txt");
1310 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
1312 bool is_copy_not_move
= false;
1313 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
,
1314 ofu()->CopyOrMoveFile(context
.get(), source_url
, dest_url
,
1315 FileSystemOperation::OPTION_NONE
,
1317 EXPECT_TRUE(change_observer()->HasNoChange());
1318 context
.reset(NewContext(NULL
));
1319 is_copy_not_move
= true;
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 source_url
= CreateURLFromUTF8("dir/dir/file");
1326 bool exclusive
= true;
1327 bool recursive
= true;
1328 context
.reset(NewContext(NULL
));
1329 ASSERT_EQ(base::File::FILE_OK
,
1330 ofu()->CreateDirectory(context
.get(),
1331 FileSystemURLDirName(source_url
),
1332 exclusive
, recursive
));
1333 EXPECT_EQ(2, change_observer()->get_and_reset_create_directory_count());
1334 is_copy_not_move
= false;
1335 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
,
1336 ofu()->CopyOrMoveFile(context
.get(), source_url
, dest_url
,
1337 FileSystemOperation::OPTION_NONE
,
1339 EXPECT_TRUE(change_observer()->HasNoChange());
1340 context
.reset(NewContext(NULL
));
1341 is_copy_not_move
= true;
1342 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
,
1343 ofu()->CopyOrMoveFile(context
.get(), source_url
, dest_url
,
1344 FileSystemOperation::OPTION_NONE
,
1346 EXPECT_TRUE(change_observer()->HasNoChange());
1349 TEST_F(ObfuscatedFileUtilTest
, TestCopyOrMoveFileSuccess
) {
1350 const int64 kSourceLength
= 5;
1351 const int64 kDestLength
= 50;
1353 for (size_t i
= 0; i
< arraysize(kCopyMoveTestCases
); ++i
) {
1354 SCOPED_TRACE(testing::Message() << "kCopyMoveTestCase " << i
);
1355 const CopyMoveTestCaseRecord
& test_case
= kCopyMoveTestCases
[i
];
1356 SCOPED_TRACE(testing::Message() << "\t is_copy_not_move " <<
1357 test_case
.is_copy_not_move
);
1358 SCOPED_TRACE(testing::Message() << "\t source_path " <<
1359 test_case
.source_path
);
1360 SCOPED_TRACE(testing::Message() << "\t dest_path " <<
1361 test_case
.dest_path
);
1362 SCOPED_TRACE(testing::Message() << "\t cause_overwrite " <<
1363 test_case
.cause_overwrite
);
1364 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
1366 bool exclusive
= false;
1367 bool recursive
= true;
1368 FileSystemURL source_url
= CreateURLFromUTF8(test_case
.source_path
);
1369 FileSystemURL dest_url
= CreateURLFromUTF8(test_case
.dest_path
);
1371 context
.reset(NewContext(NULL
));
1372 ASSERT_EQ(base::File::FILE_OK
,
1373 ofu()->CreateDirectory(context
.get(),
1374 FileSystemURLDirName(source_url
),
1375 exclusive
, recursive
));
1376 context
.reset(NewContext(NULL
));
1377 ASSERT_EQ(base::File::FILE_OK
,
1378 ofu()->CreateDirectory(context
.get(),
1379 FileSystemURLDirName(dest_url
),
1380 exclusive
, recursive
));
1382 bool created
= false;
1383 context
.reset(NewContext(NULL
));
1384 ASSERT_EQ(base::File::FILE_OK
,
1385 ofu()->EnsureFileExists(context
.get(), source_url
, &created
));
1386 ASSERT_TRUE(created
);
1387 context
.reset(NewContext(NULL
));
1388 ASSERT_EQ(base::File::FILE_OK
,
1389 ofu()->Truncate(context
.get(), source_url
, kSourceLength
));
1391 if (test_case
.cause_overwrite
) {
1392 context
.reset(NewContext(NULL
));
1394 ASSERT_EQ(base::File::FILE_OK
,
1395 ofu()->EnsureFileExists(context
.get(), dest_url
, &created
));
1396 ASSERT_TRUE(created
);
1397 context
.reset(NewContext(NULL
));
1398 ASSERT_EQ(base::File::FILE_OK
,
1399 ofu()->Truncate(context
.get(), dest_url
, kDestLength
));
1402 context
.reset(NewContext(NULL
));
1403 EXPECT_EQ(base::File::FILE_OK
,
1404 ofu()->CopyOrMoveFile(context
.get(), source_url
, dest_url
,
1405 FileSystemOperation::OPTION_NONE
,
1406 test_case
.is_copy_not_move
));
1408 if (test_case
.is_copy_not_move
) {
1409 base::File::Info file_info
;
1410 base::FilePath local_path
;
1411 context
.reset(NewContext(NULL
));
1412 EXPECT_EQ(base::File::FILE_OK
,
1413 ofu()->GetFileInfo(context
.get(), source_url
, &file_info
,
1415 EXPECT_EQ(kSourceLength
, file_info
.size
);
1416 EXPECT_EQ(base::File::FILE_OK
,
1417 ofu()->DeleteFile(context
.get(), source_url
));
1419 base::File::Info file_info
;
1420 base::FilePath local_path
;
1421 context
.reset(NewContext(NULL
));
1422 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
,
1423 ofu()->GetFileInfo(context
.get(), source_url
, &file_info
,
1426 base::File::Info file_info
;
1427 base::FilePath local_path
;
1428 EXPECT_EQ(base::File::FILE_OK
,
1429 ofu()->GetFileInfo(context
.get(), dest_url
, &file_info
,
1431 EXPECT_EQ(kSourceLength
, file_info
.size
);
1433 EXPECT_EQ(base::File::FILE_OK
,
1434 ofu()->DeleteFile(context
.get(), dest_url
));
1438 TEST_F(ObfuscatedFileUtilTest
, TestCopyPathQuotas
) {
1439 FileSystemURL src_url
= CreateURLFromUTF8("src path");
1440 FileSystemURL dest_url
= CreateURLFromUTF8("destination path");
1441 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
1442 bool created
= false;
1443 ASSERT_EQ(base::File::FILE_OK
,
1444 ofu()->EnsureFileExists(context
.get(), src_url
, &created
));
1446 bool is_copy
= true;
1447 // Copy, no overwrite.
1448 context
->set_allowed_bytes_growth(
1449 ObfuscatedFileUtil::ComputeFilePathCost(dest_url
.path()) - 1);
1450 EXPECT_EQ(base::File::FILE_ERROR_NO_SPACE
,
1451 ofu()->CopyOrMoveFile(context
.get(), src_url
, dest_url
,
1452 FileSystemOperation::OPTION_NONE
, is_copy
));
1453 context
.reset(NewContext(NULL
));
1454 context
->set_allowed_bytes_growth(
1455 ObfuscatedFileUtil::ComputeFilePathCost(dest_url
.path()));
1456 EXPECT_EQ(base::File::FILE_OK
,
1457 ofu()->CopyOrMoveFile(context
.get(), src_url
, dest_url
,
1458 FileSystemOperation::OPTION_NONE
, is_copy
));
1460 // Copy, with overwrite.
1461 context
.reset(NewContext(NULL
));
1462 context
->set_allowed_bytes_growth(0);
1463 EXPECT_EQ(base::File::FILE_OK
,
1464 ofu()->CopyOrMoveFile(context
.get(), src_url
, dest_url
,
1465 FileSystemOperation::OPTION_NONE
, is_copy
));
1468 TEST_F(ObfuscatedFileUtilTest
, TestMovePathQuotasWithRename
) {
1469 FileSystemURL src_url
= CreateURLFromUTF8("src path");
1470 FileSystemURL dest_url
= CreateURLFromUTF8("destination path");
1471 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
1472 bool created
= false;
1473 ASSERT_EQ(base::File::FILE_OK
,
1474 ofu()->EnsureFileExists(context
.get(), src_url
, &created
));
1476 bool is_copy
= false;
1477 // Move, rename, no overwrite.
1478 context
.reset(NewContext(NULL
));
1479 context
->set_allowed_bytes_growth(
1480 ObfuscatedFileUtil::ComputeFilePathCost(dest_url
.path()) -
1481 ObfuscatedFileUtil::ComputeFilePathCost(src_url
.path()) - 1);
1482 EXPECT_EQ(base::File::FILE_ERROR_NO_SPACE
,
1483 ofu()->CopyOrMoveFile(context
.get(), src_url
, dest_url
,
1484 FileSystemOperation::OPTION_NONE
, is_copy
));
1485 context
.reset(NewContext(NULL
));
1486 context
->set_allowed_bytes_growth(
1487 ObfuscatedFileUtil::ComputeFilePathCost(dest_url
.path()) -
1488 ObfuscatedFileUtil::ComputeFilePathCost(src_url
.path()));
1489 EXPECT_EQ(base::File::FILE_OK
,
1490 ofu()->CopyOrMoveFile(context
.get(), src_url
, dest_url
,
1491 FileSystemOperation::OPTION_NONE
, is_copy
));
1493 context
.reset(NewContext(NULL
));
1494 ASSERT_EQ(base::File::FILE_OK
,
1495 ofu()->EnsureFileExists(context
.get(), src_url
, &created
));
1497 // Move, rename, with overwrite.
1498 context
.reset(NewContext(NULL
));
1499 context
->set_allowed_bytes_growth(0);
1500 EXPECT_EQ(base::File::FILE_OK
,
1501 ofu()->CopyOrMoveFile(context
.get(), src_url
, dest_url
,
1502 FileSystemOperation::OPTION_NONE
, is_copy
));
1505 TEST_F(ObfuscatedFileUtilTest
, TestMovePathQuotasWithoutRename
) {
1506 FileSystemURL src_url
= CreateURLFromUTF8("src path");
1507 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
1508 bool created
= false;
1509 ASSERT_EQ(base::File::FILE_OK
,
1510 ofu()->EnsureFileExists(context
.get(), src_url
, &created
));
1512 bool exclusive
= true;
1513 bool recursive
= false;
1514 FileSystemURL dir_url
= CreateURLFromUTF8("directory path");
1515 context
.reset(NewContext(NULL
));
1516 ASSERT_EQ(base::File::FILE_OK
,
1517 ofu()->CreateDirectory(context
.get(), dir_url
, exclusive
,
1520 FileSystemURL dest_url
= FileSystemURLAppend(
1521 dir_url
, src_url
.path().value());
1523 bool is_copy
= false;
1524 int64 allowed_bytes_growth
= -1000; // Over quota, this should still work.
1525 // Move, no rename, no overwrite.
1526 context
.reset(NewContext(NULL
));
1527 context
->set_allowed_bytes_growth(allowed_bytes_growth
);
1528 EXPECT_EQ(base::File::FILE_OK
,
1529 ofu()->CopyOrMoveFile(context
.get(), src_url
, dest_url
,
1530 FileSystemOperation::OPTION_NONE
, is_copy
));
1531 EXPECT_EQ(allowed_bytes_growth
, context
->allowed_bytes_growth());
1533 // Move, no rename, with overwrite.
1534 context
.reset(NewContext(NULL
));
1535 ASSERT_EQ(base::File::FILE_OK
,
1536 ofu()->EnsureFileExists(context
.get(), src_url
, &created
));
1537 context
.reset(NewContext(NULL
));
1538 context
->set_allowed_bytes_growth(allowed_bytes_growth
);
1539 EXPECT_EQ(base::File::FILE_OK
,
1540 ofu()->CopyOrMoveFile(context
.get(), src_url
, dest_url
,
1541 FileSystemOperation::OPTION_NONE
, is_copy
));
1543 allowed_bytes_growth
+
1544 ObfuscatedFileUtil::ComputeFilePathCost(src_url
.path()),
1545 context
->allowed_bytes_growth());
1548 TEST_F(ObfuscatedFileUtilTest
, TestCopyInForeignFile
) {
1549 TestCopyInForeignFileHelper(false /* overwrite */);
1550 TestCopyInForeignFileHelper(true /* overwrite */);
1553 TEST_F(ObfuscatedFileUtilTest
, TestEnumerator
) {
1554 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
1555 FileSystemURL src_url
= CreateURLFromUTF8("source dir");
1556 bool exclusive
= true;
1557 bool recursive
= false;
1558 ASSERT_EQ(base::File::FILE_OK
,
1559 ofu()->CreateDirectory(context
.get(), src_url
, exclusive
,
1562 std::set
<base::FilePath::StringType
> files
;
1563 std::set
<base::FilePath::StringType
> directories
;
1564 FillTestDirectory(src_url
, &files
, &directories
);
1566 FileSystemURL dest_url
= CreateURLFromUTF8("destination dir");
1568 EXPECT_FALSE(DirectoryExists(dest_url
));
1569 ASSERT_EQ(base::File::FILE_OK
,
1570 AsyncFileTestHelper::Copy(
1571 file_system_context(), src_url
, dest_url
));
1573 ValidateTestDirectory(dest_url
, files
, directories
);
1574 EXPECT_TRUE(DirectoryExists(src_url
));
1575 EXPECT_TRUE(DirectoryExists(dest_url
));
1577 ASSERT_EQ(base::File::FILE_OK
,
1578 AsyncFileTestHelper::Remove(
1579 file_system_context(), dest_url
, recursive
));
1580 EXPECT_FALSE(DirectoryExists(dest_url
));
1583 TEST_F(ObfuscatedFileUtilTest
, TestOriginEnumerator
) {
1584 scoped_ptr
<ObfuscatedFileUtil::AbstractOriginEnumerator
>
1585 enumerator(ofu()->CreateOriginEnumerator());
1586 // The test helper starts out with a single filesystem.
1587 EXPECT_TRUE(enumerator
.get());
1588 EXPECT_EQ(origin(), enumerator
->Next());
1589 ASSERT_TRUE(type() == kFileSystemTypeTemporary
);
1590 EXPECT_TRUE(HasFileSystemType(enumerator
.get(), kFileSystemTypeTemporary
));
1591 EXPECT_FALSE(HasFileSystemType(enumerator
.get(), kFileSystemTypePersistent
));
1592 EXPECT_EQ(GURL(), enumerator
->Next());
1593 EXPECT_FALSE(HasFileSystemType(enumerator
.get(), kFileSystemTypeTemporary
));
1594 EXPECT_FALSE(HasFileSystemType(enumerator
.get(), kFileSystemTypePersistent
));
1596 std::set
<GURL
> origins_expected
;
1597 origins_expected
.insert(origin());
1599 for (size_t i
= 0; i
< arraysize(kOriginEnumerationTestRecords
); ++i
) {
1600 SCOPED_TRACE(testing::Message() <<
1601 "Validating kOriginEnumerationTestRecords " << i
);
1602 const OriginEnumerationTestRecord
& record
=
1603 kOriginEnumerationTestRecords
[i
];
1604 GURL
origin_url(record
.origin_url
);
1605 origins_expected
.insert(origin_url
);
1606 if (record
.has_temporary
) {
1607 scoped_ptr
<SandboxFileSystemTestHelper
> file_system(
1608 NewFileSystem(origin_url
, kFileSystemTypeTemporary
));
1609 scoped_ptr
<FileSystemOperationContext
> context(
1610 NewContext(file_system
.get()));
1611 bool created
= false;
1612 ASSERT_EQ(base::File::FILE_OK
,
1613 ofu()->EnsureFileExists(
1615 file_system
->CreateURLFromUTF8("file"),
1617 EXPECT_TRUE(created
);
1619 if (record
.has_persistent
) {
1620 scoped_ptr
<SandboxFileSystemTestHelper
> file_system(
1621 NewFileSystem(origin_url
, kFileSystemTypePersistent
));
1622 scoped_ptr
<FileSystemOperationContext
> context(
1623 NewContext(file_system
.get()));
1624 bool created
= false;
1625 ASSERT_EQ(base::File::FILE_OK
,
1626 ofu()->EnsureFileExists(
1628 file_system
->CreateURLFromUTF8("file"),
1630 EXPECT_TRUE(created
);
1633 enumerator
.reset(ofu()->CreateOriginEnumerator());
1634 EXPECT_TRUE(enumerator
.get());
1635 std::set
<GURL
> origins_found
;
1637 while (!(origin_url
= enumerator
->Next()).is_empty()) {
1638 origins_found
.insert(origin_url
);
1639 SCOPED_TRACE(testing::Message() << "Handling " << origin_url
.spec());
1641 for (size_t i
= 0; !found
&& i
< arraysize(kOriginEnumerationTestRecords
);
1643 const OriginEnumerationTestRecord
& record
=
1644 kOriginEnumerationTestRecords
[i
];
1645 if (GURL(record
.origin_url
) != origin_url
)
1648 EXPECT_EQ(record
.has_temporary
,
1649 HasFileSystemType(enumerator
.get(), kFileSystemTypeTemporary
));
1650 EXPECT_EQ(record
.has_persistent
,
1651 HasFileSystemType(enumerator
.get(), kFileSystemTypePersistent
));
1653 // Deal with the default filesystem created by the test helper.
1654 if (!found
&& origin_url
== origin()) {
1655 ASSERT_TRUE(type() == kFileSystemTypeTemporary
);
1656 EXPECT_TRUE(HasFileSystemType(enumerator
.get(),
1657 kFileSystemTypeTemporary
));
1658 EXPECT_FALSE(HasFileSystemType(enumerator
.get(),
1659 kFileSystemTypePersistent
));
1665 std::set
<GURL
> diff
;
1666 std::set_symmetric_difference(origins_expected
.begin(),
1667 origins_expected
.end(), origins_found
.begin(), origins_found
.end(),
1668 inserter(diff
, diff
.begin()));
1669 EXPECT_TRUE(diff
.empty());
1672 TEST_F(ObfuscatedFileUtilTest
, TestRevokeUsageCache
) {
1673 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
1675 int64 expected_quota
= 0;
1677 for (size_t i
= 0; i
< kRegularFileSystemTestCaseSize
; ++i
) {
1678 SCOPED_TRACE(testing::Message() << "Creating kRegularTestCase " << i
);
1679 const FileSystemTestCaseRecord
& test_case
=
1680 kRegularFileSystemTestCases
[i
];
1681 base::FilePath
file_path(test_case
.path
);
1682 expected_quota
+= ObfuscatedFileUtil::ComputeFilePathCost(file_path
);
1683 if (test_case
.is_directory
) {
1684 bool exclusive
= true;
1685 bool recursive
= false;
1686 ASSERT_EQ(base::File::FILE_OK
,
1687 ofu()->CreateDirectory(context
.get(), CreateURL(file_path
),
1688 exclusive
, recursive
));
1690 bool created
= false;
1691 ASSERT_EQ(base::File::FILE_OK
,
1692 ofu()->EnsureFileExists(context
.get(), CreateURL(file_path
),
1694 ASSERT_TRUE(created
);
1695 ASSERT_EQ(base::File::FILE_OK
,
1696 ofu()->Truncate(context
.get(), CreateURL(file_path
),
1697 test_case
.data_file_size
));
1698 expected_quota
+= test_case
.data_file_size
;
1702 // Usually raw size in usage cache and the usage returned by QuotaUtil
1704 EXPECT_EQ(expected_quota
, SizeInUsageFile());
1705 EXPECT_EQ(expected_quota
, SizeByQuotaUtil());
1708 EXPECT_EQ(-1, SizeInUsageFile());
1709 EXPECT_EQ(expected_quota
, SizeByQuotaUtil());
1711 // This should reconstruct the cache.
1712 GetUsageFromQuotaManager();
1713 EXPECT_EQ(expected_quota
, SizeInUsageFile());
1714 EXPECT_EQ(expected_quota
, SizeByQuotaUtil());
1715 EXPECT_EQ(expected_quota
, usage());
1718 TEST_F(ObfuscatedFileUtilTest
, TestInconsistency
) {
1719 const FileSystemURL kPath1
= CreateURLFromUTF8("hoge");
1720 const FileSystemURL kPath2
= CreateURLFromUTF8("fuga");
1722 scoped_ptr
<FileSystemOperationContext
> context
;
1723 base::PlatformFile file
;
1724 base::File::Info file_info
;
1725 base::FilePath data_path
;
1726 bool created
= false;
1728 // Create a non-empty file.
1729 context
.reset(NewContext(NULL
));
1730 EXPECT_EQ(base::File::FILE_OK
,
1731 ofu()->EnsureFileExists(context
.get(), kPath1
, &created
));
1732 EXPECT_TRUE(created
);
1733 context
.reset(NewContext(NULL
));
1734 EXPECT_EQ(base::File::FILE_OK
,
1735 ofu()->Truncate(context
.get(), kPath1
, 10));
1736 context
.reset(NewContext(NULL
));
1737 EXPECT_EQ(base::File::FILE_OK
,
1739 context
.get(), kPath1
, &file_info
, &data_path
));
1740 EXPECT_EQ(10, file_info
.size
);
1742 // Destroy database to make inconsistency between database and filesystem.
1743 ofu()->DestroyDirectoryDatabase(origin(), type_string());
1745 // Try to get file info of broken file.
1746 EXPECT_FALSE(PathExists(kPath1
));
1747 context
.reset(NewContext(NULL
));
1748 EXPECT_EQ(base::File::FILE_OK
,
1749 ofu()->EnsureFileExists(context
.get(), kPath1
, &created
));
1750 EXPECT_TRUE(created
);
1751 context
.reset(NewContext(NULL
));
1752 EXPECT_EQ(base::File::FILE_OK
,
1754 context
.get(), kPath1
, &file_info
, &data_path
));
1755 EXPECT_EQ(0, file_info
.size
);
1757 // Make another broken file to |kPath2|.
1758 context
.reset(NewContext(NULL
));
1759 EXPECT_EQ(base::File::FILE_OK
,
1760 ofu()->EnsureFileExists(context
.get(), kPath2
, &created
));
1761 EXPECT_TRUE(created
);
1764 ofu()->DestroyDirectoryDatabase(origin(), type_string());
1766 // Repair broken |kPath1|.
1767 context
.reset(NewContext(NULL
));
1768 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
,
1769 ofu()->Touch(context
.get(), kPath1
, base::Time::Now(),
1770 base::Time::Now()));
1771 EXPECT_EQ(base::File::FILE_OK
,
1772 ofu()->EnsureFileExists(context
.get(), kPath1
, &created
));
1773 EXPECT_TRUE(created
);
1775 // Copy from sound |kPath1| to broken |kPath2|.
1776 context
.reset(NewContext(NULL
));
1777 EXPECT_EQ(base::File::FILE_OK
,
1778 ofu()->CopyOrMoveFile(context
.get(), kPath1
, kPath2
,
1779 FileSystemOperation::OPTION_NONE
,
1782 ofu()->DestroyDirectoryDatabase(origin(), type_string());
1783 context
.reset(NewContext(NULL
));
1784 EXPECT_EQ(base::File::FILE_OK
,
1785 ofu()->CreateOrOpen(
1786 context
.get(), kPath1
,
1787 base::PLATFORM_FILE_READ
| base::PLATFORM_FILE_CREATE
,
1789 EXPECT_TRUE(created
);
1791 base::File
base_file(file
);
1792 EXPECT_TRUE(base_file
.GetInfo(&file_info
));
1793 EXPECT_EQ(0, file_info
.size
);
1796 TEST_F(ObfuscatedFileUtilTest
, TestIncompleteDirectoryReading
) {
1797 const FileSystemURL kPath
[] = {
1798 CreateURLFromUTF8("foo"),
1799 CreateURLFromUTF8("bar"),
1800 CreateURLFromUTF8("baz")
1802 const FileSystemURL empty_path
= CreateURL(base::FilePath());
1803 scoped_ptr
<FileSystemOperationContext
> context
;
1805 for (size_t i
= 0; i
< ARRAYSIZE_UNSAFE(kPath
); ++i
) {
1806 bool created
= false;
1807 context
.reset(NewContext(NULL
));
1808 EXPECT_EQ(base::File::FILE_OK
,
1809 ofu()->EnsureFileExists(context
.get(), kPath
[i
], &created
));
1810 EXPECT_TRUE(created
);
1813 std::vector
<fileapi::DirectoryEntry
> entries
;
1814 EXPECT_EQ(base::File::FILE_OK
,
1815 AsyncFileTestHelper::ReadDirectory(
1816 file_system_context(), empty_path
, &entries
));
1817 EXPECT_EQ(3u, entries
.size());
1819 base::FilePath local_path
;
1820 EXPECT_EQ(base::File::FILE_OK
,
1821 ofu()->GetLocalFilePath(context
.get(), kPath
[0], &local_path
));
1822 EXPECT_TRUE(base::DeleteFile(local_path
, false));
1825 EXPECT_EQ(base::File::FILE_OK
,
1826 AsyncFileTestHelper::ReadDirectory(
1827 file_system_context(), empty_path
, &entries
));
1828 EXPECT_EQ(ARRAYSIZE_UNSAFE(kPath
) - 1, entries
.size());
1831 TEST_F(ObfuscatedFileUtilTest
, TestDirectoryTimestampForCreation
) {
1832 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
1833 const FileSystemURL dir_url
= CreateURLFromUTF8("foo_dir");
1835 // Create working directory.
1836 EXPECT_EQ(base::File::FILE_OK
,
1837 ofu()->CreateDirectory(context
.get(), dir_url
, false, false));
1839 // EnsureFileExists, create case.
1840 FileSystemURL
url(FileSystemURLAppendUTF8(
1841 dir_url
, "EnsureFileExists_file"));
1842 bool created
= false;
1843 ClearTimestamp(dir_url
);
1844 context
.reset(NewContext(NULL
));
1845 EXPECT_EQ(base::File::FILE_OK
,
1846 ofu()->EnsureFileExists(context
.get(), url
, &created
));
1847 EXPECT_TRUE(created
);
1848 EXPECT_NE(base::Time(), GetModifiedTime(dir_url
));
1852 ClearTimestamp(dir_url
);
1853 context
.reset(NewContext(NULL
));
1854 EXPECT_EQ(base::File::FILE_OK
,
1855 ofu()->EnsureFileExists(context
.get(), url
, &created
));
1856 EXPECT_FALSE(created
);
1857 EXPECT_EQ(base::Time(), GetModifiedTime(dir_url
));
1860 url
= FileSystemURLAppendUTF8(dir_url
, "EnsureFileExists_dir");
1861 context
.reset(NewContext(NULL
));
1862 EXPECT_EQ(base::File::FILE_OK
,
1863 ofu()->CreateDirectory(context
.get(), url
, false, false));
1865 ClearTimestamp(dir_url
);
1866 context
.reset(NewContext(NULL
));
1867 EXPECT_EQ(base::File::FILE_ERROR_NOT_A_FILE
,
1868 ofu()->EnsureFileExists(context
.get(), url
, &created
));
1869 EXPECT_EQ(base::Time(), GetModifiedTime(dir_url
));
1871 // CreateOrOpen, create case.
1872 url
= FileSystemURLAppendUTF8(dir_url
, "CreateOrOpen_file");
1873 base::PlatformFile file_handle
= base::kInvalidPlatformFileValue
;
1875 ClearTimestamp(dir_url
);
1876 context
.reset(NewContext(NULL
));
1877 EXPECT_EQ(base::File::FILE_OK
,
1878 ofu()->CreateOrOpen(
1880 base::PLATFORM_FILE_CREATE
| base::PLATFORM_FILE_WRITE
,
1881 &file_handle
, &created
));
1882 EXPECT_NE(base::kInvalidPlatformFileValue
, file_handle
);
1883 EXPECT_TRUE(created
);
1884 EXPECT_TRUE(base::ClosePlatformFile(file_handle
));
1885 EXPECT_NE(base::Time(), GetModifiedTime(dir_url
));
1888 file_handle
= base::kInvalidPlatformFileValue
;
1890 ClearTimestamp(dir_url
);
1891 context
.reset(NewContext(NULL
));
1892 EXPECT_EQ(base::File::FILE_OK
,
1893 ofu()->CreateOrOpen(
1895 base::PLATFORM_FILE_OPEN
| base::PLATFORM_FILE_WRITE
,
1896 &file_handle
, &created
));
1897 EXPECT_NE(base::kInvalidPlatformFileValue
, file_handle
);
1898 EXPECT_FALSE(created
);
1899 EXPECT_TRUE(base::ClosePlatformFile(file_handle
));
1900 EXPECT_EQ(base::Time(), GetModifiedTime(dir_url
));
1903 file_handle
= base::kInvalidPlatformFileValue
;
1904 ClearTimestamp(dir_url
);
1905 context
.reset(NewContext(NULL
));
1906 EXPECT_EQ(base::File::FILE_ERROR_EXISTS
,
1907 ofu()->CreateOrOpen(
1909 base::PLATFORM_FILE_CREATE
| base::PLATFORM_FILE_WRITE
,
1910 &file_handle
, &created
));
1911 EXPECT_EQ(base::kInvalidPlatformFileValue
, file_handle
);
1912 EXPECT_EQ(base::Time(), GetModifiedTime(dir_url
));
1914 // CreateDirectory, create case.
1915 // Creating CreateDirectory_dir and CreateDirectory_dir/subdir.
1916 url
= FileSystemURLAppendUTF8(dir_url
, "CreateDirectory_dir");
1917 FileSystemURL
subdir_url(FileSystemURLAppendUTF8(url
, "subdir"));
1918 ClearTimestamp(dir_url
);
1919 context
.reset(NewContext(NULL
));
1920 EXPECT_EQ(base::File::FILE_OK
,
1921 ofu()->CreateDirectory(context
.get(), subdir_url
,
1922 true /* exclusive */, true /* recursive */));
1923 EXPECT_NE(base::Time(), GetModifiedTime(dir_url
));
1925 // create subdir case.
1926 // Creating CreateDirectory_dir/subdir2.
1927 subdir_url
= FileSystemURLAppendUTF8(url
, "subdir2");
1928 ClearTimestamp(dir_url
);
1929 ClearTimestamp(url
);
1930 context
.reset(NewContext(NULL
));
1931 EXPECT_EQ(base::File::FILE_OK
,
1932 ofu()->CreateDirectory(context
.get(), subdir_url
,
1933 true /* exclusive */, true /* recursive */));
1934 EXPECT_EQ(base::Time(), GetModifiedTime(dir_url
));
1935 EXPECT_NE(base::Time(), GetModifiedTime(url
));
1938 url
= FileSystemURLAppendUTF8(dir_url
, "CreateDirectory_dir");
1939 ClearTimestamp(dir_url
);
1940 context
.reset(NewContext(NULL
));
1941 EXPECT_EQ(base::File::FILE_ERROR_EXISTS
,
1942 ofu()->CreateDirectory(context
.get(), url
,
1943 true /* exclusive */, true /* recursive */));
1944 EXPECT_EQ(base::Time(), GetModifiedTime(dir_url
));
1946 // CopyInForeignFile, create case.
1947 url
= FileSystemURLAppendUTF8(dir_url
, "CopyInForeignFile_file");
1948 FileSystemURL src_path
= FileSystemURLAppendUTF8(
1949 dir_url
, "CopyInForeignFile_src_file");
1950 context
.reset(NewContext(NULL
));
1951 EXPECT_EQ(base::File::FILE_OK
,
1952 ofu()->EnsureFileExists(context
.get(), src_path
, &created
));
1953 EXPECT_TRUE(created
);
1954 base::FilePath src_local_path
;
1955 context
.reset(NewContext(NULL
));
1956 EXPECT_EQ(base::File::FILE_OK
,
1957 ofu()->GetLocalFilePath(context
.get(), src_path
, &src_local_path
));
1959 ClearTimestamp(dir_url
);
1960 context
.reset(NewContext(NULL
));
1961 EXPECT_EQ(base::File::FILE_OK
,
1962 ofu()->CopyInForeignFile(context
.get(),
1965 EXPECT_NE(base::Time(), GetModifiedTime(dir_url
));
1968 TEST_F(ObfuscatedFileUtilTest
, TestDirectoryTimestampForDeletion
) {
1969 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
1970 const FileSystemURL dir_url
= CreateURLFromUTF8("foo_dir");
1972 // Create working directory.
1973 EXPECT_EQ(base::File::FILE_OK
,
1974 ofu()->CreateDirectory(context
.get(), dir_url
, false, false));
1976 // DeleteFile, delete case.
1977 FileSystemURL url
= FileSystemURLAppendUTF8(
1978 dir_url
, "DeleteFile_file");
1979 bool created
= false;
1980 context
.reset(NewContext(NULL
));
1981 EXPECT_EQ(base::File::FILE_OK
,
1982 ofu()->EnsureFileExists(context
.get(), url
, &created
));
1983 EXPECT_TRUE(created
);
1985 ClearTimestamp(dir_url
);
1986 context
.reset(NewContext(NULL
));
1987 EXPECT_EQ(base::File::FILE_OK
,
1988 ofu()->DeleteFile(context
.get(), url
));
1989 EXPECT_NE(base::Time(), GetModifiedTime(dir_url
));
1992 ClearTimestamp(dir_url
);
1993 context
.reset(NewContext(NULL
));
1994 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
,
1995 ofu()->DeleteFile(context
.get(), url
));
1996 EXPECT_EQ(base::Time(), GetModifiedTime(dir_url
));
1998 // DeleteDirectory, fail case.
1999 url
= FileSystemURLAppendUTF8(dir_url
, "DeleteDirectory_dir");
2000 FileSystemURL
file_path(FileSystemURLAppendUTF8(url
, "pakeratta"));
2001 context
.reset(NewContext(NULL
));
2002 EXPECT_EQ(base::File::FILE_OK
,
2003 ofu()->CreateDirectory(context
.get(), url
, true, true));
2005 context
.reset(NewContext(NULL
));
2006 EXPECT_EQ(base::File::FILE_OK
,
2007 ofu()->EnsureFileExists(context
.get(), file_path
, &created
));
2008 EXPECT_TRUE(created
);
2010 ClearTimestamp(dir_url
);
2011 context
.reset(NewContext(NULL
));
2012 EXPECT_EQ(base::File::FILE_ERROR_NOT_EMPTY
,
2013 ofu()->DeleteDirectory(context
.get(), url
));
2014 EXPECT_EQ(base::Time(), GetModifiedTime(dir_url
));
2017 context
.reset(NewContext(NULL
));
2018 EXPECT_EQ(base::File::FILE_OK
,
2019 ofu()->DeleteFile(context
.get(), file_path
));
2021 ClearTimestamp(dir_url
);
2022 context
.reset(NewContext(NULL
));
2023 EXPECT_EQ(base::File::FILE_OK
, ofu()->DeleteDirectory(context
.get(), url
));
2024 EXPECT_NE(base::Time(), GetModifiedTime(dir_url
));
2027 TEST_F(ObfuscatedFileUtilTest
, TestDirectoryTimestampForCopyAndMove
) {
2028 TestDirectoryTimestampHelper(
2029 CreateURLFromUTF8("copy overwrite"), true, true);
2030 TestDirectoryTimestampHelper(
2031 CreateURLFromUTF8("copy non-overwrite"), true, false);
2032 TestDirectoryTimestampHelper(
2033 CreateURLFromUTF8("move overwrite"), false, true);
2034 TestDirectoryTimestampHelper(
2035 CreateURLFromUTF8("move non-overwrite"), false, false);
2038 TEST_F(ObfuscatedFileUtilTest
, TestFileEnumeratorTimestamp
) {
2039 FileSystemURL dir
= CreateURLFromUTF8("foo");
2040 FileSystemURL url1
= FileSystemURLAppendUTF8(dir
, "bar");
2041 FileSystemURL url2
= FileSystemURLAppendUTF8(dir
, "baz");
2043 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
2044 EXPECT_EQ(base::File::FILE_OK
,
2045 ofu()->CreateDirectory(context
.get(), dir
, false, false));
2047 bool created
= false;
2048 context
.reset(NewContext(NULL
));
2049 EXPECT_EQ(base::File::FILE_OK
,
2050 ofu()->EnsureFileExists(context
.get(), url1
, &created
));
2051 EXPECT_TRUE(created
);
2053 context
.reset(NewContext(NULL
));
2054 EXPECT_EQ(base::File::FILE_OK
,
2055 ofu()->CreateDirectory(context
.get(), url2
, false, false));
2057 base::FilePath file_path
;
2058 context
.reset(NewContext(NULL
));
2059 EXPECT_EQ(base::File::FILE_OK
,
2060 ofu()->GetLocalFilePath(context
.get(), url1
, &file_path
));
2061 EXPECT_FALSE(file_path
.empty());
2063 context
.reset(NewContext(NULL
));
2064 EXPECT_EQ(base::File::FILE_OK
,
2065 ofu()->Touch(context
.get(), url1
,
2066 base::Time::Now() + base::TimeDelta::FromHours(1),
2069 context
.reset(NewContext(NULL
));
2070 scoped_ptr
<fileapi::FileSystemFileUtil::AbstractFileEnumerator
> file_enum(
2071 ofu()->CreateFileEnumerator(context
.get(), dir
, false));
2074 base::FilePath file_path_each
;
2075 while (!(file_path_each
= file_enum
->Next()).empty()) {
2076 context
.reset(NewContext(NULL
));
2077 base::File::Info file_info
;
2078 base::FilePath file_path
;
2079 EXPECT_EQ(base::File::FILE_OK
,
2080 ofu()->GetFileInfo(context
.get(),
2081 FileSystemURL::CreateForTest(
2085 &file_info
, &file_path
));
2086 EXPECT_EQ(file_info
.is_directory
, file_enum
->IsDirectory());
2087 EXPECT_EQ(file_info
.last_modified
, file_enum
->LastModifiedTime());
2088 EXPECT_EQ(file_info
.size
, file_enum
->Size());
2091 EXPECT_EQ(2, count
);
2095 #if defined(OS_WIN) || defined(OS_ANDROID)
2096 #define MAYBE_TestQuotaOnCopyFile DISABLED_TestQuotaOnCopyFile
2098 #define MAYBE_TestQuotaOnCopyFile TestQuotaOnCopyFile
2100 TEST_F(ObfuscatedFileUtilTest
, MAYBE_TestQuotaOnCopyFile
) {
2101 FileSystemURL
from_file(CreateURLFromUTF8("fromfile"));
2102 FileSystemURL
obstacle_file(CreateURLFromUTF8("obstaclefile"));
2103 FileSystemURL
to_file1(CreateURLFromUTF8("tofile1"));
2104 FileSystemURL
to_file2(CreateURLFromUTF8("tofile2"));
2107 int64 expected_total_file_size
= 0;
2108 ASSERT_EQ(base::File::FILE_OK
,
2109 ofu()->EnsureFileExists(
2110 AllowUsageIncrease(PathCost(from_file
))->context(),
2111 from_file
, &created
));
2112 ASSERT_TRUE(created
);
2113 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2115 ASSERT_EQ(base::File::FILE_OK
,
2116 ofu()->EnsureFileExists(
2117 AllowUsageIncrease(PathCost(obstacle_file
))->context(),
2118 obstacle_file
, &created
));
2119 ASSERT_TRUE(created
);
2120 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2122 int64 from_file_size
= 1020;
2123 expected_total_file_size
+= from_file_size
;
2124 ASSERT_EQ(base::File::FILE_OK
,
2126 AllowUsageIncrease(from_file_size
)->context(),
2127 from_file
, from_file_size
));
2128 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2130 int64 obstacle_file_size
= 1;
2131 expected_total_file_size
+= obstacle_file_size
;
2132 ASSERT_EQ(base::File::FILE_OK
,
2134 AllowUsageIncrease(obstacle_file_size
)->context(),
2135 obstacle_file
, obstacle_file_size
));
2136 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2138 int64 to_file1_size
= from_file_size
;
2139 expected_total_file_size
+= to_file1_size
;
2140 ASSERT_EQ(base::File::FILE_OK
,
2141 ofu()->CopyOrMoveFile(
2143 PathCost(to_file1
) + to_file1_size
)->context(),
2144 from_file
, to_file1
,
2145 FileSystemOperation::OPTION_NONE
,
2147 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2149 ASSERT_EQ(base::File::FILE_ERROR_NO_SPACE
,
2150 ofu()->CopyOrMoveFile(
2151 DisallowUsageIncrease(
2152 PathCost(to_file2
) + from_file_size
)->context(),
2153 from_file
, to_file2
, FileSystemOperation::OPTION_NONE
,
2155 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2157 int64 old_obstacle_file_size
= obstacle_file_size
;
2158 obstacle_file_size
= from_file_size
;
2159 expected_total_file_size
+= obstacle_file_size
- old_obstacle_file_size
;
2160 ASSERT_EQ(base::File::FILE_OK
,
2161 ofu()->CopyOrMoveFile(
2163 obstacle_file_size
- old_obstacle_file_size
)->context(),
2164 from_file
, obstacle_file
,
2165 FileSystemOperation::OPTION_NONE
,
2167 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2169 int64 old_from_file_size
= from_file_size
;
2170 from_file_size
= old_from_file_size
- 1;
2171 expected_total_file_size
+= from_file_size
- old_from_file_size
;
2172 ASSERT_EQ(base::File::FILE_OK
,
2175 from_file_size
- old_from_file_size
)->context(),
2176 from_file
, from_file_size
));
2177 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2181 old_obstacle_file_size
= obstacle_file_size
;
2182 obstacle_file_size
= from_file_size
;
2183 expected_total_file_size
+= obstacle_file_size
- old_obstacle_file_size
;
2184 scoped_ptr
<UsageVerifyHelper
> helper
= AllowUsageIncrease(
2185 obstacle_file_size
- old_obstacle_file_size
);
2186 helper
->context()->set_allowed_bytes_growth(
2187 helper
->context()->allowed_bytes_growth() - 1);
2188 ASSERT_EQ(base::File::FILE_OK
,
2189 ofu()->CopyOrMoveFile(
2191 from_file
, obstacle_file
,
2192 FileSystemOperation::OPTION_NONE
,
2194 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2198 TEST_F(ObfuscatedFileUtilTest
, TestQuotaOnMoveFile
) {
2199 FileSystemURL
from_file(CreateURLFromUTF8("fromfile"));
2200 FileSystemURL
obstacle_file(CreateURLFromUTF8("obstaclefile"));
2201 FileSystemURL
to_file(CreateURLFromUTF8("tofile"));
2204 int64 expected_total_file_size
= 0;
2205 ASSERT_EQ(base::File::FILE_OK
,
2206 ofu()->EnsureFileExists(
2207 AllowUsageIncrease(PathCost(from_file
))->context(),
2208 from_file
, &created
));
2209 ASSERT_TRUE(created
);
2210 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2212 int64 from_file_size
= 1020;
2213 expected_total_file_size
+= from_file_size
;
2214 ASSERT_EQ(base::File::FILE_OK
,
2216 AllowUsageIncrease(from_file_size
)->context(),
2217 from_file
, from_file_size
));
2218 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2220 int64 to_file_size ALLOW_UNUSED
= from_file_size
;
2222 ASSERT_EQ(base::File::FILE_OK
,
2223 ofu()->CopyOrMoveFile(
2224 AllowUsageIncrease(-PathCost(from_file
) +
2225 PathCost(to_file
))->context(),
2227 FileSystemOperation::OPTION_NONE
,
2229 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2231 ASSERT_EQ(base::File::FILE_OK
,
2232 ofu()->EnsureFileExists(
2233 AllowUsageIncrease(PathCost(from_file
))->context(),
2234 from_file
, &created
));
2235 ASSERT_TRUE(created
);
2236 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2238 ASSERT_EQ(base::File::FILE_OK
,
2239 ofu()->EnsureFileExists(
2240 AllowUsageIncrease(PathCost(obstacle_file
))->context(),
2241 obstacle_file
, &created
));
2242 ASSERT_TRUE(created
);
2243 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2245 from_file_size
= 1020;
2246 expected_total_file_size
+= from_file_size
;
2247 ASSERT_EQ(base::File::FILE_OK
,
2249 AllowUsageIncrease(from_file_size
)->context(),
2250 from_file
, from_file_size
));
2251 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2253 int64 obstacle_file_size
= 1;
2254 expected_total_file_size
+= obstacle_file_size
;
2255 ASSERT_EQ(base::File::FILE_OK
,
2257 AllowUsageIncrease(1)->context(),
2258 obstacle_file
, obstacle_file_size
));
2259 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2261 int64 old_obstacle_file_size
= obstacle_file_size
;
2262 obstacle_file_size
= from_file_size
;
2264 expected_total_file_size
-= old_obstacle_file_size
;
2265 ASSERT_EQ(base::File::FILE_OK
,
2266 ofu()->CopyOrMoveFile(
2268 -old_obstacle_file_size
- PathCost(from_file
))->context(),
2269 from_file
, obstacle_file
,
2270 FileSystemOperation::OPTION_NONE
,
2272 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2274 ASSERT_EQ(base::File::FILE_OK
,
2275 ofu()->EnsureFileExists(
2276 AllowUsageIncrease(PathCost(from_file
))->context(),
2277 from_file
, &created
));
2278 ASSERT_TRUE(created
);
2279 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2281 from_file_size
= 10;
2282 expected_total_file_size
+= from_file_size
;
2283 ASSERT_EQ(base::File::FILE_OK
,
2285 AllowUsageIncrease(from_file_size
)->context(),
2286 from_file
, from_file_size
));
2287 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2289 // quota exceeded even after operation
2290 old_obstacle_file_size
= obstacle_file_size
;
2291 obstacle_file_size
= from_file_size
;
2293 expected_total_file_size
-= old_obstacle_file_size
;
2294 scoped_ptr
<FileSystemOperationContext
> context
=
2295 LimitedContext(-old_obstacle_file_size
- PathCost(from_file
) - 1);
2296 ASSERT_EQ(base::File::FILE_OK
,
2297 ofu()->CopyOrMoveFile(
2298 context
.get(), from_file
, obstacle_file
,
2299 FileSystemOperation::OPTION_NONE
,
2301 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2305 TEST_F(ObfuscatedFileUtilTest
, TestQuotaOnRemove
) {
2306 FileSystemURL
dir(CreateURLFromUTF8("dir"));
2307 FileSystemURL
file(CreateURLFromUTF8("file"));
2308 FileSystemURL
dfile1(CreateURLFromUTF8("dir/dfile1"));
2309 FileSystemURL
dfile2(CreateURLFromUTF8("dir/dfile2"));
2312 ASSERT_EQ(base::File::FILE_OK
,
2313 ofu()->EnsureFileExists(
2314 AllowUsageIncrease(PathCost(file
))->context(),
2316 ASSERT_TRUE(created
);
2317 ASSERT_EQ(0, ComputeTotalFileSize());
2319 ASSERT_EQ(base::File::FILE_OK
,
2320 ofu()->CreateDirectory(
2321 AllowUsageIncrease(PathCost(dir
))->context(),
2322 dir
, false, false));
2323 ASSERT_EQ(0, ComputeTotalFileSize());
2325 ASSERT_EQ(base::File::FILE_OK
,
2326 ofu()->EnsureFileExists(
2327 AllowUsageIncrease(PathCost(dfile1
))->context(),
2329 ASSERT_TRUE(created
);
2330 ASSERT_EQ(0, ComputeTotalFileSize());
2332 ASSERT_EQ(base::File::FILE_OK
,
2333 ofu()->EnsureFileExists(
2334 AllowUsageIncrease(PathCost(dfile2
))->context(),
2336 ASSERT_TRUE(created
);
2337 ASSERT_EQ(0, ComputeTotalFileSize());
2339 ASSERT_EQ(base::File::FILE_OK
,
2341 AllowUsageIncrease(340)->context(),
2343 ASSERT_EQ(340, ComputeTotalFileSize());
2345 ASSERT_EQ(base::File::FILE_OK
,
2347 AllowUsageIncrease(1020)->context(),
2349 ASSERT_EQ(1360, ComputeTotalFileSize());
2351 ASSERT_EQ(base::File::FILE_OK
,
2353 AllowUsageIncrease(120)->context(),
2355 ASSERT_EQ(1480, ComputeTotalFileSize());
2357 ASSERT_EQ(base::File::FILE_OK
,
2359 AllowUsageIncrease(-PathCost(file
) - 340)->context(),
2361 ASSERT_EQ(1140, ComputeTotalFileSize());
2363 ASSERT_EQ(base::File::FILE_OK
,
2364 AsyncFileTestHelper::Remove(
2365 file_system_context(), dir
, true /* recursive */));
2366 ASSERT_EQ(0, ComputeTotalFileSize());
2369 TEST_F(ObfuscatedFileUtilTest
, TestQuotaOnOpen
) {
2370 FileSystemURL
file(CreateURLFromUTF8("file"));
2371 base::PlatformFile file_handle
;
2375 ASSERT_EQ(base::File::FILE_OK
,
2376 ofu()->EnsureFileExists(
2377 AllowUsageIncrease(PathCost(file
))->context(),
2379 ASSERT_TRUE(created
);
2380 ASSERT_EQ(0, ComputeTotalFileSize());
2382 // Opening it, which shouldn't change the usage.
2383 ASSERT_EQ(base::File::FILE_OK
,
2384 ofu()->CreateOrOpen(
2385 AllowUsageIncrease(0)->context(), file
,
2386 base::PLATFORM_FILE_OPEN
| base::PLATFORM_FILE_WRITE
,
2387 &file_handle
, &created
));
2388 ASSERT_EQ(0, ComputeTotalFileSize());
2389 EXPECT_TRUE(base::ClosePlatformFile(file_handle
));
2391 const int length
= 33;
2392 ASSERT_EQ(base::File::FILE_OK
,
2394 AllowUsageIncrease(length
)->context(), file
, length
));
2395 ASSERT_EQ(length
, ComputeTotalFileSize());
2397 // Opening it with CREATE_ALWAYS flag, which should truncate the file size.
2398 ASSERT_EQ(base::File::FILE_OK
,
2399 ofu()->CreateOrOpen(
2400 AllowUsageIncrease(-length
)->context(), file
,
2401 base::PLATFORM_FILE_CREATE_ALWAYS
| base::PLATFORM_FILE_WRITE
,
2402 &file_handle
, &created
));
2403 ASSERT_EQ(0, ComputeTotalFileSize());
2404 EXPECT_TRUE(base::ClosePlatformFile(file_handle
));
2406 // Extending the file again.
2407 ASSERT_EQ(base::File::FILE_OK
,
2409 AllowUsageIncrease(length
)->context(), file
, length
));
2410 ASSERT_EQ(length
, ComputeTotalFileSize());
2412 // Opening it with TRUNCATED flag, which should truncate the file size.
2413 ASSERT_EQ(base::File::FILE_OK
,
2414 ofu()->CreateOrOpen(
2415 AllowUsageIncrease(-length
)->context(), file
,
2416 base::PLATFORM_FILE_OPEN_TRUNCATED
| base::PLATFORM_FILE_WRITE
,
2417 &file_handle
, &created
));
2418 ASSERT_EQ(0, ComputeTotalFileSize());
2419 EXPECT_TRUE(base::ClosePlatformFile(file_handle
));
2422 TEST_F(ObfuscatedFileUtilTest
, MaybeDropDatabasesAliveCase
) {
2423 MaybeDropDatabasesAliveCaseTestBody();
2426 TEST_F(ObfuscatedFileUtilTest
, MaybeDropDatabasesAlreadyDeletedCase
) {
2427 MaybeDropDatabasesAlreadyDeletedCaseTestBody();
2430 TEST_F(ObfuscatedFileUtilTest
, DestroyDirectoryDatabase_Isolated
) {
2431 DestroyDirectoryDatabase_IsolatedTestBody();
2434 TEST_F(ObfuscatedFileUtilTest
, GetDirectoryDatabase_Isolated
) {
2435 GetDirectoryDatabase_IsolatedTestBody();
2438 TEST_F(ObfuscatedFileUtilTest
, MigrationBackFromIsolated
) {
2439 MigrationBackFromIsolatedTestBody();
2442 TEST_F(ObfuscatedFileUtilTest
, OpenPathInNonDirectory
) {
2443 FileSystemURL
file(CreateURLFromUTF8("file"));
2444 FileSystemURL
path_in_file(CreateURLFromUTF8("file/file"));
2447 ASSERT_EQ(base::File::FILE_OK
,
2448 ofu()->EnsureFileExists(UnlimitedContext().get(), file
, &created
));
2449 ASSERT_TRUE(created
);
2452 base::PlatformFile file_handle
= base::kInvalidPlatformFileValue
;
2453 int file_flags
= base::PLATFORM_FILE_CREATE
| base::PLATFORM_FILE_WRITE
;
2454 ASSERT_EQ(base::File::FILE_ERROR_NOT_A_DIRECTORY
,
2455 ofu()->CreateOrOpen(UnlimitedContext().get(),
2460 ASSERT_FALSE(created
);
2461 ASSERT_EQ(base::kInvalidPlatformFileValue
, file_handle
);
2463 ASSERT_EQ(base::File::FILE_ERROR_NOT_A_DIRECTORY
,
2464 ofu()->CreateDirectory(UnlimitedContext().get(),
2466 false /* exclusive */,
2467 false /* recursive */));
2470 TEST_F(ObfuscatedFileUtilTest
, CreateDirectory_NotADirectoryInRecursive
) {
2471 FileSystemURL
file(CreateURLFromUTF8("file"));
2472 FileSystemURL
path_in_file(CreateURLFromUTF8("file/child"));
2473 FileSystemURL
path_in_file_in_file(
2474 CreateURLFromUTF8("file/child/grandchild"));
2477 ASSERT_EQ(base::File::FILE_OK
,
2478 ofu()->EnsureFileExists(UnlimitedContext().get(), file
, &created
));
2479 ASSERT_TRUE(created
);
2481 ASSERT_EQ(base::File::FILE_ERROR_NOT_A_DIRECTORY
,
2482 ofu()->CreateDirectory(UnlimitedContext().get(),
2484 false /* exclusive */,
2485 true /* recursive */));
2486 ASSERT_EQ(base::File::FILE_ERROR_NOT_A_DIRECTORY
,
2487 ofu()->CreateDirectory(UnlimitedContext().get(),
2488 path_in_file_in_file
,
2489 false /* exclusive */,
2490 true /* recursive */));
2493 } // namespace content