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 "base/thread_task_runner_handle.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 "storage/browser/fileapi/external_mount_points.h"
24 #include "storage/browser/fileapi/file_system_backend.h"
25 #include "storage/browser/fileapi/file_system_context.h"
26 #include "storage/browser/fileapi/file_system_operation_context.h"
27 #include "storage/browser/fileapi/file_system_usage_cache.h"
28 #include "storage/browser/fileapi/obfuscated_file_util.h"
29 #include "storage/browser/fileapi/sandbox_directory_database.h"
30 #include "storage/browser/fileapi/sandbox_file_system_backend_delegate.h"
31 #include "storage/browser/fileapi/sandbox_isolated_origin_database.h"
32 #include "storage/browser/fileapi/sandbox_origin_database.h"
33 #include "storage/browser/quota/quota_manager.h"
34 #include "storage/common/database/database_identifier.h"
35 #include "storage/common/quota/quota_types.h"
36 #include "testing/gtest/include/gtest/gtest.h"
38 using content::AsyncFileTestHelper
;
39 using storage::FileSystemContext
;
40 using storage::FileSystemOperation
;
41 using storage::FileSystemOperationContext
;
42 using storage::FileSystemURL
;
43 using storage::ObfuscatedFileUtil
;
44 using storage::SandboxDirectoryDatabase
;
45 using storage::SandboxIsolatedOriginDatabase
;
46 using storage::kFileSystemTypeTemporary
;
47 using storage::kFileSystemTypePersistent
;
53 bool FileExists(const base::FilePath
& path
) {
54 return base::PathExists(path
) && !base::DirectoryExists(path
);
57 int64
GetSize(const base::FilePath
& path
) {
59 EXPECT_TRUE(base::GetFileSize(path
, &size
));
63 // After a move, the dest exists and the source doesn't.
64 // After a copy, both source and dest exist.
65 struct CopyMoveTestCaseRecord
{
66 bool is_copy_not_move
;
67 const char source_path
[64];
68 const char dest_path
[64];
72 const CopyMoveTestCaseRecord kCopyMoveTestCases
[] = {
73 // This is the combinatoric set of:
74 // rename vs. same-name
75 // different directory vs. same directory
76 // overwrite vs. no-overwrite
78 // We can never be called with source and destination paths identical, so
79 // those cases are omitted.
80 {true, "dir0/file0", "dir0/file1", false},
81 {false, "dir0/file0", "dir0/file1", false},
82 {true, "dir0/file0", "dir0/file1", true},
83 {false, "dir0/file0", "dir0/file1", true},
85 {true, "dir0/file0", "dir1/file0", false},
86 {false, "dir0/file0", "dir1/file0", false},
87 {true, "dir0/file0", "dir1/file0", true},
88 {false, "dir0/file0", "dir1/file0", true},
89 {true, "dir0/file0", "dir1/file1", false},
90 {false, "dir0/file0", "dir1/file1", false},
91 {true, "dir0/file0", "dir1/file1", true},
92 {false, "dir0/file0", "dir1/file1", true},
95 struct OriginEnumerationTestRecord
{
96 std::string origin_url
;
101 const OriginEnumerationTestRecord kOriginEnumerationTestRecords
[] = {
102 {"http://example.com", false, true},
103 {"http://example1.com", true, false},
104 {"https://example1.com", true, true},
105 {"file://", false, true},
106 {"http://example.com:8000", false, true},
109 FileSystemURL
FileSystemURLAppend(
110 const FileSystemURL
& url
, const base::FilePath::StringType
& child
) {
111 return FileSystemURL::CreateForTest(
112 url
.origin(), url
.mount_type(), url
.virtual_path().Append(child
));
115 FileSystemURL
FileSystemURLAppendUTF8(
116 const FileSystemURL
& url
, const std::string
& child
) {
117 return FileSystemURL::CreateForTest(
120 url
.virtual_path().Append(base::FilePath::FromUTF8Unsafe(child
)));
123 FileSystemURL
FileSystemURLDirName(const FileSystemURL
& url
) {
124 return FileSystemURL::CreateForTest(
127 storage::VirtualPath::DirName(url
.virtual_path()));
130 std::string
GetTypeString(storage::FileSystemType type
) {
131 return storage::SandboxFileSystemBackendDelegate::GetTypeString(type
);
134 bool HasFileSystemType(ObfuscatedFileUtil::AbstractOriginEnumerator
* enumerator
,
135 storage::FileSystemType type
) {
136 return enumerator
->HasTypeDirectory(GetTypeString(type
));
141 // TODO(ericu): The vast majority of this and the other FSFU subclass tests
142 // could theoretically be shared. It would basically be a FSFU interface
143 // compliance test, and only the subclass-specific bits that look into the
144 // implementation would need to be written per-subclass.
145 class ObfuscatedFileUtilTest
: public testing::Test
{
147 ObfuscatedFileUtilTest()
148 : origin_(GURL("http://www.example.com")),
149 type_(storage::kFileSystemTypeTemporary
),
150 sandbox_file_system_(origin_
, type_
),
151 quota_status_(storage::kQuotaStatusUnknown
),
153 weak_factory_(this) {}
155 void SetUp() override
{
156 ASSERT_TRUE(data_dir_
.CreateUniqueTempDir());
158 storage_policy_
= new MockSpecialStoragePolicy();
160 quota_manager_
= new storage::QuotaManager(
161 false /* is_incognito */, data_dir_
.path(),
162 base::ThreadTaskRunnerHandle::Get().get(),
163 base::ThreadTaskRunnerHandle::Get().get(), storage_policy_
.get());
165 // Every time we create a new sandbox_file_system helper,
166 // it creates another context, which creates another path manager,
167 // another sandbox_backend, and another OFU.
168 // We need to pass in the context to skip all that.
169 file_system_context_
= CreateFileSystemContextForTesting(
170 quota_manager_
->proxy(),
173 sandbox_file_system_
.SetUp(file_system_context_
.get());
176 storage::MockFileChangeObserver::CreateList(&change_observer_
);
179 void TearDown() override
{
180 quota_manager_
= NULL
;
181 sandbox_file_system_
.TearDown();
184 scoped_ptr
<FileSystemOperationContext
> LimitedContext(
185 int64 allowed_bytes_growth
) {
186 scoped_ptr
<FileSystemOperationContext
> context(
187 sandbox_file_system_
.NewOperationContext());
188 context
->set_allowed_bytes_growth(allowed_bytes_growth
);
189 return context
.Pass();
192 scoped_ptr
<FileSystemOperationContext
> UnlimitedContext() {
193 return LimitedContext(kint64max
);
196 FileSystemOperationContext
* NewContext(
197 SandboxFileSystemTestHelper
* file_system
) {
198 change_observer()->ResetCount();
199 FileSystemOperationContext
* context
;
201 context
= file_system
->NewOperationContext();
203 context
= sandbox_file_system_
.NewOperationContext();
204 // Setting allowed_bytes_growth big enough for all tests.
205 context
->set_allowed_bytes_growth(1024 * 1024);
206 context
->set_change_observers(change_observers());
210 const storage::ChangeObserverList
& change_observers() const {
211 return change_observers_
;
214 storage::MockFileChangeObserver
* change_observer() {
215 return &change_observer_
;
218 // This can only be used after SetUp has run and created file_system_context_
219 // and obfuscated_file_util_.
220 // Use this for tests which need to run in multiple origins; we need a test
221 // helper per origin.
222 SandboxFileSystemTestHelper
* NewFileSystem(const GURL
& origin
,
223 storage::FileSystemType type
) {
224 SandboxFileSystemTestHelper
* file_system
=
225 new SandboxFileSystemTestHelper(origin
, type
);
227 file_system
->SetUp(file_system_context_
.get());
231 scoped_ptr
<ObfuscatedFileUtil
> CreateObfuscatedFileUtil(
232 storage::SpecialStoragePolicy
* storage_policy
) {
233 return scoped_ptr
<ObfuscatedFileUtil
>(ObfuscatedFileUtil::CreateForTesting(
234 storage_policy
, data_dir_path(), NULL
,
235 base::ThreadTaskRunnerHandle::Get().get()));
238 ObfuscatedFileUtil
* ofu() {
239 return static_cast<ObfuscatedFileUtil
*>(sandbox_file_system_
.file_util());
242 const base::FilePath
& test_directory() const {
243 return data_dir_
.path();
246 const GURL
& origin() const {
250 storage::FileSystemType
type() const { return type_
; }
252 std::string
type_string() const {
253 return GetTypeString(type_
);
256 int64
ComputeTotalFileSize() {
257 return sandbox_file_system_
.ComputeCurrentOriginUsage() -
258 sandbox_file_system_
.ComputeCurrentDirectoryDatabaseUsage();
261 void GetUsageFromQuotaManager() {
264 AsyncFileTestHelper::GetUsageAndQuota(quota_manager_
.get(),
266 sandbox_file_system_
.type(),
269 EXPECT_EQ(storage::kQuotaStatusOk
, quota_status_
);
272 void RevokeUsageCache() {
273 quota_manager_
->ResetUsageTracker(sandbox_file_system_
.storage_type());
274 usage_cache()->Delete(sandbox_file_system_
.GetUsageCachePath());
277 int64
SizeByQuotaUtil() {
278 return sandbox_file_system_
.GetCachedOriginUsage();
281 int64
SizeInUsageFile() {
282 base::RunLoop().RunUntilIdle();
284 return usage_cache()->GetUsage(
285 sandbox_file_system_
.GetUsageCachePath(), &usage
) ? usage
: -1;
288 bool PathExists(const FileSystemURL
& url
) {
289 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
290 base::File::Info file_info
;
291 base::FilePath platform_path
;
292 base::File::Error error
= ofu()->GetFileInfo(
293 context
.get(), url
, &file_info
, &platform_path
);
294 return error
== base::File::FILE_OK
;
297 bool DirectoryExists(const FileSystemURL
& url
) {
298 return AsyncFileTestHelper::DirectoryExists(file_system_context(), url
);
301 int64
usage() const { return usage_
; }
302 storage::FileSystemUsageCache
* usage_cache() {
303 return sandbox_file_system_
.usage_cache();
306 FileSystemURL
CreateURLFromUTF8(const std::string
& path
) {
307 return sandbox_file_system_
.CreateURLFromUTF8(path
);
310 int64
PathCost(const FileSystemURL
& url
) {
311 return ObfuscatedFileUtil::ComputeFilePathCost(url
.path());
314 FileSystemURL
CreateURL(const base::FilePath
& path
) {
315 return sandbox_file_system_
.CreateURL(path
);
318 void CheckFileAndCloseHandle(const FileSystemURL
& url
, base::File file
) {
319 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
320 base::FilePath local_path
;
321 EXPECT_EQ(base::File::FILE_OK
,
322 ofu()->GetLocalFilePath(context
.get(), url
, &local_path
));
324 base::File::Info file_info0
;
325 base::FilePath data_path
;
326 EXPECT_EQ(base::File::FILE_OK
,
327 ofu()->GetFileInfo(context
.get(), url
, &file_info0
, &data_path
));
328 EXPECT_EQ(data_path
, local_path
);
329 EXPECT_TRUE(FileExists(data_path
));
330 EXPECT_EQ(0, GetSize(data_path
));
332 const char data
[] = "test data";
333 const int length
= arraysize(data
) - 1;
335 if (!file
.IsValid()) {
336 file
.Initialize(data_path
,
337 base::File::FLAG_OPEN
| base::File::FLAG_WRITE
);
338 ASSERT_TRUE(file
.IsValid());
339 EXPECT_FALSE(file
.created());
341 ASSERT_EQ(length
, file
.Write(0, data
, length
));
344 base::File::Info file_info1
;
345 EXPECT_EQ(length
, GetSize(data_path
));
346 context
.reset(NewContext(NULL
));
347 EXPECT_EQ(base::File::FILE_OK
,
348 ofu()->GetFileInfo(context
.get(), url
, &file_info1
, &data_path
));
349 EXPECT_EQ(data_path
, local_path
);
351 EXPECT_FALSE(file_info0
.is_directory
);
352 EXPECT_FALSE(file_info1
.is_directory
);
353 EXPECT_FALSE(file_info0
.is_symbolic_link
);
354 EXPECT_FALSE(file_info1
.is_symbolic_link
);
355 EXPECT_EQ(0, file_info0
.size
);
356 EXPECT_EQ(length
, file_info1
.size
);
357 EXPECT_LE(file_info0
.last_modified
, file_info1
.last_modified
);
359 context
.reset(NewContext(NULL
));
360 EXPECT_EQ(base::File::FILE_OK
,
361 ofu()->Truncate(context
.get(), url
, length
* 2));
362 EXPECT_EQ(length
* 2, GetSize(data_path
));
364 context
.reset(NewContext(NULL
));
365 EXPECT_EQ(base::File::FILE_OK
,
366 ofu()->Truncate(context
.get(), url
, 0));
367 EXPECT_EQ(0, GetSize(data_path
));
370 void ValidateTestDirectory(
371 const FileSystemURL
& root_url
,
372 const std::set
<base::FilePath::StringType
>& files
,
373 const std::set
<base::FilePath::StringType
>& directories
) {
374 scoped_ptr
<FileSystemOperationContext
> context
;
375 std::set
<base::FilePath::StringType
>::const_iterator iter
;
376 for (iter
= files
.begin(); iter
!= files
.end(); ++iter
) {
378 context
.reset(NewContext(NULL
));
379 ASSERT_EQ(base::File::FILE_OK
,
380 ofu()->EnsureFileExists(context
.get(),
381 FileSystemURLAppend(root_url
, *iter
),
383 ASSERT_FALSE(created
);
385 for (iter
= directories
.begin(); iter
!= directories
.end(); ++iter
) {
386 context
.reset(NewContext(NULL
));
387 EXPECT_TRUE(DirectoryExists(
388 FileSystemURLAppend(root_url
, *iter
)));
392 class UsageVerifyHelper
{
394 UsageVerifyHelper(scoped_ptr
<FileSystemOperationContext
> context
,
395 SandboxFileSystemTestHelper
* file_system
,
396 int64 expected_usage
)
397 : context_(context
.Pass()),
398 sandbox_file_system_(file_system
),
399 expected_usage_(expected_usage
) {}
401 ~UsageVerifyHelper() {
402 base::RunLoop().RunUntilIdle();
406 FileSystemOperationContext
* context() {
407 return context_
.get();
412 ASSERT_EQ(expected_usage_
,
413 sandbox_file_system_
->GetCachedOriginUsage());
416 scoped_ptr
<FileSystemOperationContext
> context_
;
417 SandboxFileSystemTestHelper
* sandbox_file_system_
;
418 int64 expected_usage_
;
421 scoped_ptr
<UsageVerifyHelper
> AllowUsageIncrease(int64 requested_growth
) {
422 int64 usage
= sandbox_file_system_
.GetCachedOriginUsage();
423 return scoped_ptr
<UsageVerifyHelper
>(new UsageVerifyHelper(
424 LimitedContext(requested_growth
),
425 &sandbox_file_system_
, usage
+ requested_growth
));
428 scoped_ptr
<UsageVerifyHelper
> DisallowUsageIncrease(int64 requested_growth
) {
429 int64 usage
= sandbox_file_system_
.GetCachedOriginUsage();
430 return scoped_ptr
<UsageVerifyHelper
>(new UsageVerifyHelper(
431 LimitedContext(requested_growth
- 1), &sandbox_file_system_
, usage
));
434 void FillTestDirectory(
435 const FileSystemURL
& root_url
,
436 std::set
<base::FilePath::StringType
>* files
,
437 std::set
<base::FilePath::StringType
>* directories
) {
438 scoped_ptr
<FileSystemOperationContext
> context
;
439 std::vector
<storage::DirectoryEntry
> entries
;
440 EXPECT_EQ(base::File::FILE_OK
,
441 AsyncFileTestHelper::ReadDirectory(file_system_context(),
442 root_url
, &entries
));
443 EXPECT_EQ(0UL, entries
.size());
446 files
->insert(FILE_PATH_LITERAL("first"));
447 files
->insert(FILE_PATH_LITERAL("second"));
448 files
->insert(FILE_PATH_LITERAL("third"));
449 directories
->clear();
450 directories
->insert(FILE_PATH_LITERAL("fourth"));
451 directories
->insert(FILE_PATH_LITERAL("fifth"));
452 directories
->insert(FILE_PATH_LITERAL("sixth"));
453 std::set
<base::FilePath::StringType
>::iterator iter
;
454 for (iter
= files
->begin(); iter
!= files
->end(); ++iter
) {
455 bool created
= false;
456 context
.reset(NewContext(NULL
));
457 ASSERT_EQ(base::File::FILE_OK
,
458 ofu()->EnsureFileExists(context
.get(),
459 FileSystemURLAppend(root_url
, *iter
),
461 ASSERT_TRUE(created
);
463 for (iter
= directories
->begin(); iter
!= directories
->end(); ++iter
) {
464 bool exclusive
= true;
465 bool recursive
= false;
466 context
.reset(NewContext(NULL
));
467 EXPECT_EQ(base::File::FILE_OK
,
468 ofu()->CreateDirectory(context
.get(),
469 FileSystemURLAppend(root_url
, *iter
),
470 exclusive
, recursive
));
472 ValidateTestDirectory(root_url
, *files
, *directories
);
475 void TestReadDirectoryHelper(const FileSystemURL
& root_url
) {
476 std::set
<base::FilePath::StringType
> files
;
477 std::set
<base::FilePath::StringType
> directories
;
478 FillTestDirectory(root_url
, &files
, &directories
);
480 scoped_ptr
<FileSystemOperationContext
> context
;
481 std::vector
<storage::DirectoryEntry
> entries
;
482 context
.reset(NewContext(NULL
));
483 EXPECT_EQ(base::File::FILE_OK
,
484 AsyncFileTestHelper::ReadDirectory(
485 file_system_context(), root_url
, &entries
));
486 std::vector
<storage::DirectoryEntry
>::iterator entry_iter
;
487 EXPECT_EQ(files
.size() + directories
.size(), entries
.size());
488 EXPECT_TRUE(change_observer()->HasNoChange());
489 for (entry_iter
= entries
.begin(); entry_iter
!= entries
.end();
491 const storage::DirectoryEntry
& entry
= *entry_iter
;
492 std::set
<base::FilePath::StringType
>::iterator iter
=
493 files
.find(entry
.name
);
494 if (iter
!= files
.end()) {
495 EXPECT_FALSE(entry
.is_directory
);
499 iter
= directories
.find(entry
.name
);
500 EXPECT_FALSE(directories
.end() == iter
);
501 EXPECT_TRUE(entry
.is_directory
);
502 directories
.erase(iter
);
506 void TestTouchHelper(const FileSystemURL
& url
, bool is_file
) {
507 base::Time last_access_time
= base::Time::Now();
508 base::Time last_modified_time
= base::Time::Now();
510 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
511 EXPECT_EQ(base::File::FILE_OK
,
512 ofu()->Touch(context
.get(), url
, last_access_time
,
513 last_modified_time
));
514 // Currently we fire no change notifications for Touch.
515 EXPECT_TRUE(change_observer()->HasNoChange());
516 base::FilePath local_path
;
517 base::File::Info file_info
;
518 context
.reset(NewContext(NULL
));
519 EXPECT_EQ(base::File::FILE_OK
, ofu()->GetFileInfo(
520 context
.get(), url
, &file_info
, &local_path
));
521 // We compare as time_t here to lower our resolution, to avoid false
522 // negatives caused by conversion to the local filesystem's native
523 // representation and back.
524 EXPECT_EQ(file_info
.last_modified
.ToTimeT(), last_modified_time
.ToTimeT());
526 context
.reset(NewContext(NULL
));
527 last_modified_time
+= base::TimeDelta::FromHours(1);
528 last_access_time
+= base::TimeDelta::FromHours(14);
529 EXPECT_EQ(base::File::FILE_OK
,
530 ofu()->Touch(context
.get(), url
, last_access_time
,
531 last_modified_time
));
532 EXPECT_TRUE(change_observer()->HasNoChange());
533 context
.reset(NewContext(NULL
));
534 EXPECT_EQ(base::File::FILE_OK
,
535 ofu()->GetFileInfo(context
.get(), url
, &file_info
, &local_path
));
536 EXPECT_EQ(file_info
.last_modified
.ToTimeT(), last_modified_time
.ToTimeT());
537 if (is_file
) // Directories in OFU don't support atime.
538 EXPECT_EQ(file_info
.last_accessed
.ToTimeT(), last_access_time
.ToTimeT());
541 void TestCopyInForeignFileHelper(bool overwrite
) {
542 base::ScopedTempDir source_dir
;
543 ASSERT_TRUE(source_dir
.CreateUniqueTempDir());
544 base::FilePath root_file_path
= source_dir
.path();
545 base::FilePath src_file_path
= root_file_path
.AppendASCII("file_name");
546 FileSystemURL dest_url
= CreateURLFromUTF8("new file");
547 int64 src_file_length
= 87;
549 base::File
file(src_file_path
,
550 base::File::FLAG_CREATE
| base::File::FLAG_WRITE
);
551 ASSERT_TRUE(file
.IsValid());
552 EXPECT_TRUE(file
.created());
553 ASSERT_TRUE(file
.SetLength(src_file_length
));
556 scoped_ptr
<FileSystemOperationContext
> context
;
559 context
.reset(NewContext(NULL
));
560 bool created
= false;
561 EXPECT_EQ(base::File::FILE_OK
,
562 ofu()->EnsureFileExists(context
.get(), dest_url
, &created
));
563 EXPECT_TRUE(created
);
565 // We must have observed one (and only one) create_file_count.
566 EXPECT_EQ(1, change_observer()->get_and_reset_create_file_count());
567 EXPECT_TRUE(change_observer()->HasNoChange());
570 const int64 path_cost
=
571 ObfuscatedFileUtil::ComputeFilePathCost(dest_url
.path());
573 // Verify that file creation requires sufficient quota for the path.
574 context
.reset(NewContext(NULL
));
575 context
->set_allowed_bytes_growth(path_cost
+ src_file_length
- 1);
576 EXPECT_EQ(base::File::FILE_ERROR_NO_SPACE
,
577 ofu()->CopyInForeignFile(context
.get(),
578 src_file_path
, dest_url
));
581 context
.reset(NewContext(NULL
));
582 context
->set_allowed_bytes_growth(path_cost
+ src_file_length
);
583 EXPECT_EQ(base::File::FILE_OK
,
584 ofu()->CopyInForeignFile(context
.get(),
585 src_file_path
, dest_url
));
587 EXPECT_TRUE(PathExists(dest_url
));
588 EXPECT_FALSE(DirectoryExists(dest_url
));
590 context
.reset(NewContext(NULL
));
591 base::File::Info file_info
;
592 base::FilePath data_path
;
593 EXPECT_EQ(base::File::FILE_OK
,
594 ofu()->GetFileInfo(context
.get(), dest_url
, &file_info
,
596 EXPECT_NE(data_path
, src_file_path
);
597 EXPECT_TRUE(FileExists(data_path
));
598 EXPECT_EQ(src_file_length
, GetSize(data_path
));
600 EXPECT_EQ(base::File::FILE_OK
,
601 ofu()->DeleteFile(context
.get(), dest_url
));
604 void ClearTimestamp(const FileSystemURL
& url
) {
605 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
606 EXPECT_EQ(base::File::FILE_OK
,
607 ofu()->Touch(context
.get(), url
, base::Time(), base::Time()));
608 EXPECT_EQ(base::Time(), GetModifiedTime(url
));
611 base::Time
GetModifiedTime(const FileSystemURL
& url
) {
612 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
613 base::FilePath data_path
;
614 base::File::Info file_info
;
615 context
.reset(NewContext(NULL
));
616 EXPECT_EQ(base::File::FILE_OK
,
617 ofu()->GetFileInfo(context
.get(), url
, &file_info
, &data_path
));
618 EXPECT_TRUE(change_observer()->HasNoChange());
619 return file_info
.last_modified
;
622 void TestDirectoryTimestampHelper(const FileSystemURL
& base_dir
,
625 scoped_ptr
<FileSystemOperationContext
> context
;
626 const FileSystemURL
src_dir_url(
627 FileSystemURLAppendUTF8(base_dir
, "foo_dir"));
628 const FileSystemURL
dest_dir_url(
629 FileSystemURLAppendUTF8(base_dir
, "bar_dir"));
631 const FileSystemURL
src_file_url(
632 FileSystemURLAppendUTF8(src_dir_url
, "hoge"));
633 const FileSystemURL
dest_file_url(
634 FileSystemURLAppendUTF8(dest_dir_url
, "fuga"));
636 context
.reset(NewContext(NULL
));
637 EXPECT_EQ(base::File::FILE_OK
,
638 ofu()->CreateDirectory(context
.get(), src_dir_url
, true, true));
639 context
.reset(NewContext(NULL
));
640 EXPECT_EQ(base::File::FILE_OK
,
641 ofu()->CreateDirectory(context
.get(), dest_dir_url
, true, true));
643 bool created
= false;
644 context
.reset(NewContext(NULL
));
645 EXPECT_EQ(base::File::FILE_OK
,
646 ofu()->EnsureFileExists(context
.get(), src_file_url
, &created
));
648 context
.reset(NewContext(NULL
));
649 EXPECT_EQ(base::File::FILE_OK
,
650 ofu()->EnsureFileExists(context
.get(),
651 dest_file_url
, &created
));
654 ClearTimestamp(src_dir_url
);
655 ClearTimestamp(dest_dir_url
);
656 context
.reset(NewContext(NULL
));
657 EXPECT_EQ(base::File::FILE_OK
,
658 ofu()->CopyOrMoveFile(context
.get(),
659 src_file_url
, dest_file_url
,
660 FileSystemOperation::OPTION_NONE
,
663 EXPECT_EQ(base::Time(), GetModifiedTime(src_dir_url
));
665 EXPECT_NE(base::Time(), GetModifiedTime(src_dir_url
));
666 EXPECT_NE(base::Time(), GetModifiedTime(dest_dir_url
));
669 void MaybeDropDatabasesAliveCaseTestBody() {
670 scoped_ptr
<ObfuscatedFileUtil
> file_util
= CreateObfuscatedFileUtil(NULL
);
671 file_util
->InitOriginDatabase(GURL(), true /*create*/);
672 ASSERT_TRUE(file_util
->origin_database_
!= NULL
);
674 // Callback to Drop DB is called while ObfuscatedFileUtilTest is
676 file_util
->db_flush_delay_seconds_
= 0;
677 file_util
->MarkUsed();
678 base::RunLoop().RunUntilIdle();
680 ASSERT_TRUE(file_util
->origin_database_
== NULL
);
683 void MaybeDropDatabasesAlreadyDeletedCaseTestBody() {
684 // Run message loop after OFU is already deleted to make sure callback
685 // doesn't cause a crash for use after free.
687 scoped_ptr
<ObfuscatedFileUtil
> file_util
= CreateObfuscatedFileUtil(NULL
);
688 file_util
->InitOriginDatabase(GURL(), true /*create*/);
689 file_util
->db_flush_delay_seconds_
= 0;
690 file_util
->MarkUsed();
693 // At this point the callback is still in the message queue but OFU is gone.
694 base::RunLoop().RunUntilIdle();
697 void DestroyDirectoryDatabase_IsolatedTestBody() {
698 storage_policy_
->AddIsolated(origin_
);
699 scoped_ptr
<ObfuscatedFileUtil
> file_util
= CreateObfuscatedFileUtil(
700 storage_policy_
.get());
701 const FileSystemURL url
= FileSystemURL::CreateForTest(
702 origin_
, kFileSystemTypePersistent
, base::FilePath());
704 // Create DirectoryDatabase for isolated origin.
705 SandboxDirectoryDatabase
* db
=
706 file_util
->GetDirectoryDatabase(url
, true /* create */);
707 ASSERT_TRUE(db
!= NULL
);
710 file_util
->DestroyDirectoryDatabase(
711 url
.origin(), GetTypeString(url
.type()));
712 ASSERT_TRUE(file_util
->directories_
.empty());
715 void GetDirectoryDatabase_IsolatedTestBody() {
716 storage_policy_
->AddIsolated(origin_
);
717 scoped_ptr
<ObfuscatedFileUtil
> file_util
= CreateObfuscatedFileUtil(
718 storage_policy_
.get());
719 const FileSystemURL url
= FileSystemURL::CreateForTest(
720 origin_
, kFileSystemTypePersistent
, base::FilePath());
722 // Create DirectoryDatabase for isolated origin.
723 SandboxDirectoryDatabase
* db
=
724 file_util
->GetDirectoryDatabase(url
, true /* create */);
725 ASSERT_TRUE(db
!= NULL
);
726 ASSERT_EQ(1U, file_util
->directories_
.size());
729 storage_policy_
->RemoveIsolated(url
.origin());
731 // This should still get the same database.
732 SandboxDirectoryDatabase
* db2
=
733 file_util
->GetDirectoryDatabase(url
, false /* create */);
737 void MigrationBackFromIsolatedTestBody() {
738 std::string
kFakeDirectoryData("0123456789");
739 base::FilePath old_directory_db_path
;
741 // Initialize the directory with one origin using
742 // SandboxIsolatedOriginDatabase.
744 std::string origin_string
= storage::GetIdentifierFromOrigin(origin_
);
745 SandboxIsolatedOriginDatabase
database_old(
746 origin_string
, data_dir_path(),
748 SandboxIsolatedOriginDatabase::kObsoleteOriginDirectory
));
750 EXPECT_TRUE(database_old
.GetPathForOrigin(origin_string
, &path
));
751 EXPECT_FALSE(path
.empty());
753 // Populate the origin directory with some fake data.
754 old_directory_db_path
= data_dir_path().Append(path
);
755 ASSERT_TRUE(base::CreateDirectory(old_directory_db_path
));
756 EXPECT_EQ(static_cast<int>(kFakeDirectoryData
.size()),
757 base::WriteFile(old_directory_db_path
.AppendASCII("dummy"),
758 kFakeDirectoryData
.data(),
759 kFakeDirectoryData
.size()));
762 storage_policy_
->AddIsolated(origin_
);
763 scoped_ptr
<ObfuscatedFileUtil
> file_util
= CreateObfuscatedFileUtil(
764 storage_policy_
.get());
765 base::File::Error error
= base::File::FILE_ERROR_FAILED
;
766 base::FilePath origin_directory
= file_util
->GetDirectoryForOrigin(
767 origin_
, true /* create */, &error
);
768 EXPECT_EQ(base::File::FILE_OK
, error
);
770 // The database is migrated from the old one.
771 EXPECT_TRUE(base::DirectoryExists(origin_directory
));
772 EXPECT_FALSE(base::DirectoryExists(old_directory_db_path
));
774 // Check we see the same contents in the new origin directory.
775 std::string origin_db_data
;
776 EXPECT_TRUE(base::PathExists(origin_directory
.AppendASCII("dummy")));
777 EXPECT_TRUE(base::ReadFileToString(
778 origin_directory
.AppendASCII("dummy"), &origin_db_data
));
779 EXPECT_EQ(kFakeDirectoryData
, origin_db_data
);
782 int64
ComputeCurrentUsage() {
783 return sandbox_file_system_
.ComputeCurrentOriginUsage() -
784 sandbox_file_system_
.ComputeCurrentDirectoryDatabaseUsage();
787 FileSystemContext
* file_system_context() {
788 return sandbox_file_system_
.file_system_context();
791 const base::FilePath
& data_dir_path() const {
792 return data_dir_
.path();
796 base::ScopedTempDir data_dir_
;
797 base::MessageLoopForIO message_loop_
;
798 scoped_refptr
<MockSpecialStoragePolicy
> storage_policy_
;
799 scoped_refptr
<storage::QuotaManager
> quota_manager_
;
800 scoped_refptr
<FileSystemContext
> file_system_context_
;
802 storage::FileSystemType type_
;
803 SandboxFileSystemTestHelper sandbox_file_system_
;
804 storage::QuotaStatusCode quota_status_
;
806 storage::MockFileChangeObserver change_observer_
;
807 storage::ChangeObserverList change_observers_
;
808 base::WeakPtrFactory
<ObfuscatedFileUtilTest
> weak_factory_
;
811 DISALLOW_COPY_AND_ASSIGN(ObfuscatedFileUtilTest
);
814 TEST_F(ObfuscatedFileUtilTest
, TestCreateAndDeleteFile
) {
815 FileSystemURL url
= CreateURLFromUTF8("fake/file");
816 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
817 int file_flags
= base::File::FLAG_CREATE
| base::File::FLAG_WRITE
;
819 base::File file
= ofu()->CreateOrOpen(context
.get(), url
, file_flags
);
820 EXPECT_FALSE(file
.IsValid());
821 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
, file
.error_details());
823 context
.reset(NewContext(NULL
));
824 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
,
825 ofu()->DeleteFile(context
.get(), url
));
827 url
= CreateURLFromUTF8("test file");
829 EXPECT_TRUE(change_observer()->HasNoChange());
831 // Verify that file creation requires sufficient quota for the path.
832 context
.reset(NewContext(NULL
));
833 context
->set_allowed_bytes_growth(
834 ObfuscatedFileUtil::ComputeFilePathCost(url
.path()) - 1);
835 file
= ofu()->CreateOrOpen(context
.get(), url
, file_flags
);
836 EXPECT_FALSE(file
.IsValid());
837 ASSERT_EQ(base::File::FILE_ERROR_NO_SPACE
, file
.error_details());
839 context
.reset(NewContext(NULL
));
840 context
->set_allowed_bytes_growth(
841 ObfuscatedFileUtil::ComputeFilePathCost(url
.path()));
842 file
= ofu()->CreateOrOpen(context
.get(), url
, file_flags
);
843 EXPECT_TRUE(file
.IsValid());
844 ASSERT_TRUE(file
.created());
845 EXPECT_EQ(1, change_observer()->get_and_reset_create_file_count());
847 CheckFileAndCloseHandle(url
, file
.Pass());
849 context
.reset(NewContext(NULL
));
850 base::FilePath local_path
;
851 EXPECT_EQ(base::File::FILE_OK
,
852 ofu()->GetLocalFilePath(context
.get(), url
, &local_path
));
853 EXPECT_TRUE(base::PathExists(local_path
));
855 // Verify that deleting a file isn't stopped by zero quota, and that it frees
856 // up quote from its path.
857 context
.reset(NewContext(NULL
));
858 context
->set_allowed_bytes_growth(0);
859 EXPECT_EQ(base::File::FILE_OK
, ofu()->DeleteFile(context
.get(), url
));
860 EXPECT_EQ(1, change_observer()->get_and_reset_remove_file_count());
861 EXPECT_FALSE(base::PathExists(local_path
));
862 EXPECT_EQ(ObfuscatedFileUtil::ComputeFilePathCost(url
.path()),
863 context
->allowed_bytes_growth());
865 context
.reset(NewContext(NULL
));
866 bool exclusive
= true;
867 bool recursive
= true;
868 FileSystemURL directory_url
= CreateURLFromUTF8(
869 "series/of/directories");
870 url
= FileSystemURLAppendUTF8(directory_url
, "file name");
871 EXPECT_EQ(base::File::FILE_OK
,
872 ofu()->CreateDirectory(context
.get(), directory_url
, exclusive
,
874 // The oepration created 3 directories recursively.
875 EXPECT_EQ(3, change_observer()->get_and_reset_create_directory_count());
877 context
.reset(NewContext(NULL
));
878 file
= ofu()->CreateOrOpen(context
.get(), url
, file_flags
);
879 ASSERT_TRUE(file
.IsValid());
880 ASSERT_TRUE(file
.created());
881 EXPECT_EQ(1, change_observer()->get_and_reset_create_file_count());
883 CheckFileAndCloseHandle(url
, file
.Pass());
885 context
.reset(NewContext(NULL
));
886 EXPECT_EQ(base::File::FILE_OK
,
887 ofu()->GetLocalFilePath(context
.get(), url
, &local_path
));
888 EXPECT_TRUE(base::PathExists(local_path
));
890 context
.reset(NewContext(NULL
));
891 EXPECT_EQ(base::File::FILE_OK
, ofu()->DeleteFile(context
.get(), url
));
892 EXPECT_EQ(1, change_observer()->get_and_reset_remove_file_count());
893 EXPECT_FALSE(base::PathExists(local_path
));
895 // Make sure we have no unexpected changes.
896 EXPECT_TRUE(change_observer()->HasNoChange());
899 TEST_F(ObfuscatedFileUtilTest
, TestTruncate
) {
900 bool created
= false;
901 FileSystemURL url
= CreateURLFromUTF8("file");
902 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
904 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
,
905 ofu()->Truncate(context
.get(), url
, 4));
907 context
.reset(NewContext(NULL
));
908 ASSERT_EQ(base::File::FILE_OK
,
909 ofu()->EnsureFileExists(context
.get(), url
, &created
));
910 ASSERT_TRUE(created
);
911 EXPECT_EQ(1, change_observer()->get_and_reset_create_file_count());
913 context
.reset(NewContext(NULL
));
914 base::FilePath local_path
;
915 EXPECT_EQ(base::File::FILE_OK
,
916 ofu()->GetLocalFilePath(context
.get(), url
, &local_path
));
917 EXPECT_EQ(0, GetSize(local_path
));
919 context
.reset(NewContext(NULL
));
920 EXPECT_EQ(base::File::FILE_OK
, ofu()->Truncate(context
.get(), url
, 10));
921 EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count());
922 EXPECT_EQ(10, GetSize(local_path
));
924 context
.reset(NewContext(NULL
));
925 EXPECT_EQ(base::File::FILE_OK
, ofu()->Truncate(context
.get(), url
, 1));
926 EXPECT_EQ(1, GetSize(local_path
));
927 EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count());
929 EXPECT_FALSE(DirectoryExists(url
));
930 EXPECT_TRUE(PathExists(url
));
932 // Make sure we have no unexpected changes.
933 EXPECT_TRUE(change_observer()->HasNoChange());
936 TEST_F(ObfuscatedFileUtilTest
, TestQuotaOnTruncation
) {
937 bool created
= false;
938 FileSystemURL url
= CreateURLFromUTF8("file");
940 ASSERT_EQ(base::File::FILE_OK
,
941 ofu()->EnsureFileExists(
942 AllowUsageIncrease(PathCost(url
))->context(),
944 ASSERT_TRUE(created
);
945 ASSERT_EQ(0, ComputeTotalFileSize());
947 ASSERT_EQ(base::File::FILE_OK
,
948 ofu()->Truncate(AllowUsageIncrease(1020)->context(), url
, 1020));
949 ASSERT_EQ(1020, ComputeTotalFileSize());
951 ASSERT_EQ(base::File::FILE_OK
,
952 ofu()->Truncate(AllowUsageIncrease(-1020)->context(), url
, 0));
953 ASSERT_EQ(0, ComputeTotalFileSize());
955 EXPECT_EQ(base::File::FILE_ERROR_NO_SPACE
,
956 ofu()->Truncate(DisallowUsageIncrease(1021)->context(),
958 ASSERT_EQ(0, ComputeTotalFileSize());
960 EXPECT_EQ(base::File::FILE_OK
,
961 ofu()->Truncate(AllowUsageIncrease(1020)->context(), url
, 1020));
962 ASSERT_EQ(1020, ComputeTotalFileSize());
964 EXPECT_EQ(base::File::FILE_OK
,
965 ofu()->Truncate(AllowUsageIncrease(0)->context(), url
, 1020));
966 ASSERT_EQ(1020, ComputeTotalFileSize());
970 scoped_ptr
<UsageVerifyHelper
> helper
= AllowUsageIncrease(-1);
971 helper
->context()->set_allowed_bytes_growth(
972 helper
->context()->allowed_bytes_growth() - 1);
973 EXPECT_EQ(base::File::FILE_OK
,
974 ofu()->Truncate(helper
->context(), url
, 1019));
975 ASSERT_EQ(1019, ComputeTotalFileSize());
978 // Delete backing file to make following truncation fail.
979 base::FilePath local_path
;
980 ASSERT_EQ(base::File::FILE_OK
,
981 ofu()->GetLocalFilePath(UnlimitedContext().get(), url
,
983 ASSERT_FALSE(local_path
.empty());
984 ASSERT_TRUE(base::DeleteFile(local_path
, false));
986 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
,
987 ofu()->Truncate(LimitedContext(1234).get(), url
, 1234));
988 ASSERT_EQ(0, ComputeTotalFileSize());
991 TEST_F(ObfuscatedFileUtilTest
, TestEnsureFileExists
) {
992 FileSystemURL url
= CreateURLFromUTF8("fake/file");
993 bool created
= false;
994 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
995 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
,
996 ofu()->EnsureFileExists(context
.get(), url
, &created
));
997 EXPECT_TRUE(change_observer()->HasNoChange());
999 // Verify that file creation requires sufficient quota for the path.
1000 context
.reset(NewContext(NULL
));
1001 url
= CreateURLFromUTF8("test file");
1003 context
->set_allowed_bytes_growth(
1004 ObfuscatedFileUtil::ComputeFilePathCost(url
.path()) - 1);
1005 ASSERT_EQ(base::File::FILE_ERROR_NO_SPACE
,
1006 ofu()->EnsureFileExists(context
.get(), url
, &created
));
1007 ASSERT_FALSE(created
);
1008 EXPECT_TRUE(change_observer()->HasNoChange());
1010 context
.reset(NewContext(NULL
));
1011 context
->set_allowed_bytes_growth(
1012 ObfuscatedFileUtil::ComputeFilePathCost(url
.path()));
1013 ASSERT_EQ(base::File::FILE_OK
,
1014 ofu()->EnsureFileExists(context
.get(), url
, &created
));
1015 ASSERT_TRUE(created
);
1016 EXPECT_EQ(1, change_observer()->get_and_reset_create_file_count());
1018 CheckFileAndCloseHandle(url
, base::File());
1020 context
.reset(NewContext(NULL
));
1021 ASSERT_EQ(base::File::FILE_OK
,
1022 ofu()->EnsureFileExists(context
.get(), url
, &created
));
1023 ASSERT_FALSE(created
);
1024 EXPECT_TRUE(change_observer()->HasNoChange());
1026 // Also test in a subdirectory.
1027 url
= CreateURLFromUTF8("path/to/file.txt");
1028 context
.reset(NewContext(NULL
));
1029 bool exclusive
= true;
1030 bool recursive
= true;
1031 EXPECT_EQ(base::File::FILE_OK
,
1032 ofu()->CreateDirectory(context
.get(), FileSystemURLDirName(url
),
1033 exclusive
, recursive
));
1034 // 2 directories: path/ and path/to.
1035 EXPECT_EQ(2, change_observer()->get_and_reset_create_directory_count());
1037 context
.reset(NewContext(NULL
));
1038 ASSERT_EQ(base::File::FILE_OK
,
1039 ofu()->EnsureFileExists(context
.get(), url
, &created
));
1040 ASSERT_TRUE(created
);
1041 EXPECT_FALSE(DirectoryExists(url
));
1042 EXPECT_TRUE(PathExists(url
));
1043 EXPECT_TRUE(change_observer()->HasNoChange());
1046 TEST_F(ObfuscatedFileUtilTest
, TestDirectoryOps
) {
1047 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
1049 bool exclusive
= false;
1050 bool recursive
= false;
1051 FileSystemURL url
= CreateURLFromUTF8("foo/bar");
1052 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
,
1053 ofu()->CreateDirectory(context
.get(), url
, exclusive
, recursive
));
1055 context
.reset(NewContext(NULL
));
1056 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
,
1057 ofu()->DeleteDirectory(context
.get(), url
));
1059 FileSystemURL root
= CreateURLFromUTF8(std::string());
1060 EXPECT_FALSE(DirectoryExists(url
));
1061 EXPECT_FALSE(PathExists(url
));
1062 context
.reset(NewContext(NULL
));
1063 EXPECT_TRUE(ofu()->IsDirectoryEmpty(context
.get(), root
));
1065 context
.reset(NewContext(NULL
));
1068 EXPECT_EQ(base::File::FILE_OK
,
1069 ofu()->CreateDirectory(context
.get(), url
, exclusive
, recursive
));
1070 EXPECT_EQ(2, change_observer()->get_and_reset_create_directory_count());
1072 EXPECT_TRUE(DirectoryExists(url
));
1073 EXPECT_TRUE(PathExists(url
));
1075 context
.reset(NewContext(NULL
));
1076 EXPECT_FALSE(ofu()->IsDirectoryEmpty(context
.get(), root
));
1077 EXPECT_TRUE(DirectoryExists(FileSystemURLDirName(url
)));
1079 context
.reset(NewContext(NULL
));
1080 EXPECT_FALSE(ofu()->IsDirectoryEmpty(context
.get(),
1081 FileSystemURLDirName(url
)));
1083 // Can't remove a non-empty directory.
1084 context
.reset(NewContext(NULL
));
1085 EXPECT_EQ(base::File::FILE_ERROR_NOT_EMPTY
,
1086 ofu()->DeleteDirectory(context
.get(),
1087 FileSystemURLDirName(url
)));
1088 EXPECT_TRUE(change_observer()->HasNoChange());
1090 base::File::Info file_info
;
1091 base::FilePath local_path
;
1092 EXPECT_EQ(base::File::FILE_OK
,
1093 ofu()->GetFileInfo(context
.get(), url
, &file_info
, &local_path
));
1094 EXPECT_TRUE(local_path
.empty());
1095 EXPECT_TRUE(file_info
.is_directory
);
1096 EXPECT_FALSE(file_info
.is_symbolic_link
);
1098 // Same create again should succeed, since exclusive is false.
1099 context
.reset(NewContext(NULL
));
1100 EXPECT_EQ(base::File::FILE_OK
,
1101 ofu()->CreateDirectory(context
.get(), url
, exclusive
, recursive
));
1102 EXPECT_TRUE(change_observer()->HasNoChange());
1106 context
.reset(NewContext(NULL
));
1107 EXPECT_EQ(base::File::FILE_ERROR_EXISTS
,
1108 ofu()->CreateDirectory(context
.get(), url
, exclusive
, recursive
));
1109 EXPECT_TRUE(change_observer()->HasNoChange());
1111 // Verify that deleting a directory isn't stopped by zero quota, and that it
1112 // frees up quota from its path.
1113 context
.reset(NewContext(NULL
));
1114 context
->set_allowed_bytes_growth(0);
1115 EXPECT_EQ(base::File::FILE_OK
, ofu()->DeleteDirectory(context
.get(), url
));
1116 EXPECT_EQ(1, change_observer()->get_and_reset_remove_directory_count());
1117 EXPECT_EQ(ObfuscatedFileUtil::ComputeFilePathCost(url
.path()),
1118 context
->allowed_bytes_growth());
1120 url
= CreateURLFromUTF8("foo/bop");
1122 EXPECT_FALSE(DirectoryExists(url
));
1123 EXPECT_FALSE(PathExists(url
));
1125 context
.reset(NewContext(NULL
));
1126 EXPECT_TRUE(ofu()->IsDirectoryEmpty(context
.get(), url
));
1127 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
,
1128 ofu()->GetFileInfo(context
.get(), url
, &file_info
, &local_path
));
1130 // Verify that file creation requires sufficient quota for the path.
1133 context
.reset(NewContext(NULL
));
1134 context
->set_allowed_bytes_growth(
1135 ObfuscatedFileUtil::ComputeFilePathCost(url
.path()) - 1);
1136 EXPECT_EQ(base::File::FILE_ERROR_NO_SPACE
,
1137 ofu()->CreateDirectory(context
.get(), url
, exclusive
, recursive
));
1138 EXPECT_TRUE(change_observer()->HasNoChange());
1140 context
.reset(NewContext(NULL
));
1141 context
->set_allowed_bytes_growth(
1142 ObfuscatedFileUtil::ComputeFilePathCost(url
.path()));
1143 EXPECT_EQ(base::File::FILE_OK
,
1144 ofu()->CreateDirectory(context
.get(), url
, exclusive
, recursive
));
1145 EXPECT_EQ(1, change_observer()->get_and_reset_create_directory_count());
1147 EXPECT_TRUE(DirectoryExists(url
));
1148 EXPECT_TRUE(PathExists(url
));
1152 context
.reset(NewContext(NULL
));
1153 EXPECT_EQ(base::File::FILE_ERROR_EXISTS
,
1154 ofu()->CreateDirectory(context
.get(), url
, exclusive
, recursive
));
1155 EXPECT_TRUE(change_observer()->HasNoChange());
1159 url
= CreateURLFromUTF8("foo");
1160 context
.reset(NewContext(NULL
));
1161 EXPECT_EQ(base::File::FILE_ERROR_EXISTS
,
1162 ofu()->CreateDirectory(context
.get(), url
, exclusive
, recursive
));
1163 EXPECT_TRUE(change_observer()->HasNoChange());
1165 url
= CreateURLFromUTF8("blah");
1167 EXPECT_FALSE(DirectoryExists(url
));
1168 EXPECT_FALSE(PathExists(url
));
1172 context
.reset(NewContext(NULL
));
1173 EXPECT_EQ(base::File::FILE_OK
,
1174 ofu()->CreateDirectory(context
.get(), url
, exclusive
, recursive
));
1175 EXPECT_EQ(1, change_observer()->get_and_reset_create_directory_count());
1177 EXPECT_TRUE(DirectoryExists(url
));
1178 EXPECT_TRUE(PathExists(url
));
1182 context
.reset(NewContext(NULL
));
1183 EXPECT_EQ(base::File::FILE_ERROR_EXISTS
,
1184 ofu()->CreateDirectory(context
.get(), url
, exclusive
, recursive
));
1185 EXPECT_TRUE(change_observer()->HasNoChange());
1188 TEST_F(ObfuscatedFileUtilTest
, TestReadDirectory
) {
1189 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
1190 bool exclusive
= true;
1191 bool recursive
= true;
1192 FileSystemURL url
= CreateURLFromUTF8("directory/to/use");
1193 EXPECT_EQ(base::File::FILE_OK
,
1194 ofu()->CreateDirectory(context
.get(), url
, exclusive
, recursive
));
1195 TestReadDirectoryHelper(url
);
1198 TEST_F(ObfuscatedFileUtilTest
, TestReadRootWithSlash
) {
1199 TestReadDirectoryHelper(CreateURLFromUTF8(std::string()));
1202 TEST_F(ObfuscatedFileUtilTest
, TestReadRootWithEmptyString
) {
1203 TestReadDirectoryHelper(CreateURLFromUTF8("/"));
1206 TEST_F(ObfuscatedFileUtilTest
, TestReadDirectoryOnFile
) {
1207 FileSystemURL url
= CreateURLFromUTF8("file");
1208 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
1210 bool created
= false;
1211 ASSERT_EQ(base::File::FILE_OK
,
1212 ofu()->EnsureFileExists(context
.get(), url
, &created
));
1213 ASSERT_TRUE(created
);
1215 std::vector
<storage::DirectoryEntry
> entries
;
1216 EXPECT_EQ(base::File::FILE_ERROR_NOT_A_DIRECTORY
,
1217 AsyncFileTestHelper::ReadDirectory(file_system_context(), url
,
1220 EXPECT_TRUE(ofu()->IsDirectoryEmpty(context
.get(), url
));
1223 TEST_F(ObfuscatedFileUtilTest
, TestTouch
) {
1224 FileSystemURL url
= CreateURLFromUTF8("file");
1225 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
1227 base::Time last_access_time
= base::Time::Now();
1228 base::Time last_modified_time
= base::Time::Now();
1230 // It's not there yet.
1231 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
,
1232 ofu()->Touch(context
.get(), url
, last_access_time
,
1233 last_modified_time
));
1235 // OK, now create it.
1236 context
.reset(NewContext(NULL
));
1237 bool created
= false;
1238 ASSERT_EQ(base::File::FILE_OK
,
1239 ofu()->EnsureFileExists(context
.get(), url
, &created
));
1240 ASSERT_TRUE(created
);
1241 TestTouchHelper(url
, true);
1243 // Now test a directory:
1244 context
.reset(NewContext(NULL
));
1245 bool exclusive
= true;
1246 bool recursive
= false;
1247 url
= CreateURLFromUTF8("dir");
1248 ASSERT_EQ(base::File::FILE_OK
,
1249 ofu()->CreateDirectory(context
.get(), url
, exclusive
, recursive
));
1250 TestTouchHelper(url
, false);
1253 TEST_F(ObfuscatedFileUtilTest
, TestPathQuotas
) {
1254 FileSystemURL url
= CreateURLFromUTF8("fake/file");
1255 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
1257 url
= CreateURLFromUTF8("file name");
1258 context
->set_allowed_bytes_growth(5);
1259 bool created
= false;
1260 EXPECT_EQ(base::File::FILE_ERROR_NO_SPACE
,
1261 ofu()->EnsureFileExists(context
.get(), url
, &created
));
1262 EXPECT_FALSE(created
);
1263 context
->set_allowed_bytes_growth(1024);
1264 EXPECT_EQ(base::File::FILE_OK
,
1265 ofu()->EnsureFileExists(context
.get(), url
, &created
));
1266 EXPECT_TRUE(created
);
1267 int64 path_cost
= ObfuscatedFileUtil::ComputeFilePathCost(url
.path());
1268 EXPECT_EQ(1024 - path_cost
, context
->allowed_bytes_growth());
1270 context
->set_allowed_bytes_growth(1024);
1271 bool exclusive
= true;
1272 bool recursive
= true;
1273 url
= CreateURLFromUTF8("directory/to/use");
1274 std::vector
<base::FilePath::StringType
> components
;
1275 url
.path().GetComponents(&components
);
1277 typedef std::vector
<base::FilePath::StringType
>::iterator iterator
;
1278 for (iterator iter
= components
.begin();
1279 iter
!= components
.end(); ++iter
) {
1280 path_cost
+= ObfuscatedFileUtil::ComputeFilePathCost(
1281 base::FilePath(*iter
));
1283 context
.reset(NewContext(NULL
));
1284 context
->set_allowed_bytes_growth(1024);
1285 EXPECT_EQ(base::File::FILE_OK
,
1286 ofu()->CreateDirectory(context
.get(), url
, exclusive
, recursive
));
1287 EXPECT_EQ(1024 - path_cost
, context
->allowed_bytes_growth());
1290 TEST_F(ObfuscatedFileUtilTest
, TestCopyOrMoveFileNotFound
) {
1291 FileSystemURL source_url
= CreateURLFromUTF8("path0.txt");
1292 FileSystemURL dest_url
= CreateURLFromUTF8("path1.txt");
1293 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
1295 bool is_copy_not_move
= false;
1296 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
,
1297 ofu()->CopyOrMoveFile(context
.get(), source_url
, dest_url
,
1298 FileSystemOperation::OPTION_NONE
,
1300 EXPECT_TRUE(change_observer()->HasNoChange());
1301 context
.reset(NewContext(NULL
));
1302 is_copy_not_move
= true;
1303 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
,
1304 ofu()->CopyOrMoveFile(context
.get(), source_url
, dest_url
,
1305 FileSystemOperation::OPTION_NONE
,
1307 EXPECT_TRUE(change_observer()->HasNoChange());
1308 source_url
= CreateURLFromUTF8("dir/dir/file");
1309 bool exclusive
= true;
1310 bool recursive
= true;
1311 context
.reset(NewContext(NULL
));
1312 ASSERT_EQ(base::File::FILE_OK
,
1313 ofu()->CreateDirectory(context
.get(),
1314 FileSystemURLDirName(source_url
),
1315 exclusive
, recursive
));
1316 EXPECT_EQ(2, change_observer()->get_and_reset_create_directory_count());
1317 is_copy_not_move
= false;
1318 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
,
1319 ofu()->CopyOrMoveFile(context
.get(), source_url
, dest_url
,
1320 FileSystemOperation::OPTION_NONE
,
1322 EXPECT_TRUE(change_observer()->HasNoChange());
1323 context
.reset(NewContext(NULL
));
1324 is_copy_not_move
= true;
1325 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
,
1326 ofu()->CopyOrMoveFile(context
.get(), source_url
, dest_url
,
1327 FileSystemOperation::OPTION_NONE
,
1329 EXPECT_TRUE(change_observer()->HasNoChange());
1332 TEST_F(ObfuscatedFileUtilTest
, TestCopyOrMoveFileSuccess
) {
1333 const int64 kSourceLength
= 5;
1334 const int64 kDestLength
= 50;
1336 for (size_t i
= 0; i
< arraysize(kCopyMoveTestCases
); ++i
) {
1337 SCOPED_TRACE(testing::Message() << "kCopyMoveTestCase " << i
);
1338 const CopyMoveTestCaseRecord
& test_case
= kCopyMoveTestCases
[i
];
1339 SCOPED_TRACE(testing::Message() << "\t is_copy_not_move " <<
1340 test_case
.is_copy_not_move
);
1341 SCOPED_TRACE(testing::Message() << "\t source_path " <<
1342 test_case
.source_path
);
1343 SCOPED_TRACE(testing::Message() << "\t dest_path " <<
1344 test_case
.dest_path
);
1345 SCOPED_TRACE(testing::Message() << "\t cause_overwrite " <<
1346 test_case
.cause_overwrite
);
1347 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
1349 bool exclusive
= false;
1350 bool recursive
= true;
1351 FileSystemURL source_url
= CreateURLFromUTF8(test_case
.source_path
);
1352 FileSystemURL dest_url
= CreateURLFromUTF8(test_case
.dest_path
);
1354 context
.reset(NewContext(NULL
));
1355 ASSERT_EQ(base::File::FILE_OK
,
1356 ofu()->CreateDirectory(context
.get(),
1357 FileSystemURLDirName(source_url
),
1358 exclusive
, recursive
));
1359 context
.reset(NewContext(NULL
));
1360 ASSERT_EQ(base::File::FILE_OK
,
1361 ofu()->CreateDirectory(context
.get(),
1362 FileSystemURLDirName(dest_url
),
1363 exclusive
, recursive
));
1365 bool created
= false;
1366 context
.reset(NewContext(NULL
));
1367 ASSERT_EQ(base::File::FILE_OK
,
1368 ofu()->EnsureFileExists(context
.get(), source_url
, &created
));
1369 ASSERT_TRUE(created
);
1370 context
.reset(NewContext(NULL
));
1371 ASSERT_EQ(base::File::FILE_OK
,
1372 ofu()->Truncate(context
.get(), source_url
, kSourceLength
));
1374 if (test_case
.cause_overwrite
) {
1375 context
.reset(NewContext(NULL
));
1377 ASSERT_EQ(base::File::FILE_OK
,
1378 ofu()->EnsureFileExists(context
.get(), dest_url
, &created
));
1379 ASSERT_TRUE(created
);
1380 context
.reset(NewContext(NULL
));
1381 ASSERT_EQ(base::File::FILE_OK
,
1382 ofu()->Truncate(context
.get(), dest_url
, kDestLength
));
1385 context
.reset(NewContext(NULL
));
1386 EXPECT_EQ(base::File::FILE_OK
,
1387 ofu()->CopyOrMoveFile(context
.get(), source_url
, dest_url
,
1388 FileSystemOperation::OPTION_NONE
,
1389 test_case
.is_copy_not_move
));
1391 if (test_case
.is_copy_not_move
) {
1392 base::File::Info file_info
;
1393 base::FilePath local_path
;
1394 context
.reset(NewContext(NULL
));
1395 EXPECT_EQ(base::File::FILE_OK
,
1396 ofu()->GetFileInfo(context
.get(), source_url
, &file_info
,
1398 EXPECT_EQ(kSourceLength
, file_info
.size
);
1399 EXPECT_EQ(base::File::FILE_OK
,
1400 ofu()->DeleteFile(context
.get(), source_url
));
1402 base::File::Info file_info
;
1403 base::FilePath local_path
;
1404 context
.reset(NewContext(NULL
));
1405 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
,
1406 ofu()->GetFileInfo(context
.get(), source_url
, &file_info
,
1409 base::File::Info file_info
;
1410 base::FilePath local_path
;
1411 EXPECT_EQ(base::File::FILE_OK
,
1412 ofu()->GetFileInfo(context
.get(), dest_url
, &file_info
,
1414 EXPECT_EQ(kSourceLength
, file_info
.size
);
1416 EXPECT_EQ(base::File::FILE_OK
,
1417 ofu()->DeleteFile(context
.get(), dest_url
));
1421 TEST_F(ObfuscatedFileUtilTest
, TestCopyPathQuotas
) {
1422 FileSystemURL src_url
= CreateURLFromUTF8("src path");
1423 FileSystemURL dest_url
= CreateURLFromUTF8("destination path");
1424 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
1425 bool created
= false;
1426 ASSERT_EQ(base::File::FILE_OK
,
1427 ofu()->EnsureFileExists(context
.get(), src_url
, &created
));
1429 bool is_copy
= true;
1430 // Copy, no overwrite.
1431 context
->set_allowed_bytes_growth(
1432 ObfuscatedFileUtil::ComputeFilePathCost(dest_url
.path()) - 1);
1433 EXPECT_EQ(base::File::FILE_ERROR_NO_SPACE
,
1434 ofu()->CopyOrMoveFile(context
.get(), src_url
, dest_url
,
1435 FileSystemOperation::OPTION_NONE
, is_copy
));
1436 context
.reset(NewContext(NULL
));
1437 context
->set_allowed_bytes_growth(
1438 ObfuscatedFileUtil::ComputeFilePathCost(dest_url
.path()));
1439 EXPECT_EQ(base::File::FILE_OK
,
1440 ofu()->CopyOrMoveFile(context
.get(), src_url
, dest_url
,
1441 FileSystemOperation::OPTION_NONE
, is_copy
));
1443 // Copy, with overwrite.
1444 context
.reset(NewContext(NULL
));
1445 context
->set_allowed_bytes_growth(0);
1446 EXPECT_EQ(base::File::FILE_OK
,
1447 ofu()->CopyOrMoveFile(context
.get(), src_url
, dest_url
,
1448 FileSystemOperation::OPTION_NONE
, is_copy
));
1451 TEST_F(ObfuscatedFileUtilTest
, TestMovePathQuotasWithRename
) {
1452 FileSystemURL src_url
= CreateURLFromUTF8("src path");
1453 FileSystemURL dest_url
= CreateURLFromUTF8("destination path");
1454 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
1455 bool created
= false;
1456 ASSERT_EQ(base::File::FILE_OK
,
1457 ofu()->EnsureFileExists(context
.get(), src_url
, &created
));
1459 bool is_copy
= false;
1460 // Move, rename, no overwrite.
1461 context
.reset(NewContext(NULL
));
1462 context
->set_allowed_bytes_growth(
1463 ObfuscatedFileUtil::ComputeFilePathCost(dest_url
.path()) -
1464 ObfuscatedFileUtil::ComputeFilePathCost(src_url
.path()) - 1);
1465 EXPECT_EQ(base::File::FILE_ERROR_NO_SPACE
,
1466 ofu()->CopyOrMoveFile(context
.get(), src_url
, dest_url
,
1467 FileSystemOperation::OPTION_NONE
, is_copy
));
1468 context
.reset(NewContext(NULL
));
1469 context
->set_allowed_bytes_growth(
1470 ObfuscatedFileUtil::ComputeFilePathCost(dest_url
.path()) -
1471 ObfuscatedFileUtil::ComputeFilePathCost(src_url
.path()));
1472 EXPECT_EQ(base::File::FILE_OK
,
1473 ofu()->CopyOrMoveFile(context
.get(), src_url
, dest_url
,
1474 FileSystemOperation::OPTION_NONE
, is_copy
));
1476 context
.reset(NewContext(NULL
));
1477 ASSERT_EQ(base::File::FILE_OK
,
1478 ofu()->EnsureFileExists(context
.get(), src_url
, &created
));
1480 // Move, rename, with overwrite.
1481 context
.reset(NewContext(NULL
));
1482 context
->set_allowed_bytes_growth(0);
1483 EXPECT_EQ(base::File::FILE_OK
,
1484 ofu()->CopyOrMoveFile(context
.get(), src_url
, dest_url
,
1485 FileSystemOperation::OPTION_NONE
, is_copy
));
1488 TEST_F(ObfuscatedFileUtilTest
, TestMovePathQuotasWithoutRename
) {
1489 FileSystemURL src_url
= CreateURLFromUTF8("src path");
1490 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
1491 bool created
= false;
1492 ASSERT_EQ(base::File::FILE_OK
,
1493 ofu()->EnsureFileExists(context
.get(), src_url
, &created
));
1495 bool exclusive
= true;
1496 bool recursive
= false;
1497 FileSystemURL dir_url
= CreateURLFromUTF8("directory path");
1498 context
.reset(NewContext(NULL
));
1499 ASSERT_EQ(base::File::FILE_OK
,
1500 ofu()->CreateDirectory(context
.get(), dir_url
, exclusive
,
1503 FileSystemURL dest_url
= FileSystemURLAppend(
1504 dir_url
, src_url
.path().value());
1506 bool is_copy
= false;
1507 int64 allowed_bytes_growth
= -1000; // Over quota, this should still work.
1508 // Move, no rename, no overwrite.
1509 context
.reset(NewContext(NULL
));
1510 context
->set_allowed_bytes_growth(allowed_bytes_growth
);
1511 EXPECT_EQ(base::File::FILE_OK
,
1512 ofu()->CopyOrMoveFile(context
.get(), src_url
, dest_url
,
1513 FileSystemOperation::OPTION_NONE
, is_copy
));
1514 EXPECT_EQ(allowed_bytes_growth
, context
->allowed_bytes_growth());
1516 // Move, no rename, with overwrite.
1517 context
.reset(NewContext(NULL
));
1518 ASSERT_EQ(base::File::FILE_OK
,
1519 ofu()->EnsureFileExists(context
.get(), src_url
, &created
));
1520 context
.reset(NewContext(NULL
));
1521 context
->set_allowed_bytes_growth(allowed_bytes_growth
);
1522 EXPECT_EQ(base::File::FILE_OK
,
1523 ofu()->CopyOrMoveFile(context
.get(), src_url
, dest_url
,
1524 FileSystemOperation::OPTION_NONE
, is_copy
));
1526 allowed_bytes_growth
+
1527 ObfuscatedFileUtil::ComputeFilePathCost(src_url
.path()),
1528 context
->allowed_bytes_growth());
1531 TEST_F(ObfuscatedFileUtilTest
, TestCopyInForeignFile
) {
1532 TestCopyInForeignFileHelper(false /* overwrite */);
1533 TestCopyInForeignFileHelper(true /* overwrite */);
1536 TEST_F(ObfuscatedFileUtilTest
, TestEnumerator
) {
1537 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
1538 FileSystemURL src_url
= CreateURLFromUTF8("source dir");
1539 bool exclusive
= true;
1540 bool recursive
= false;
1541 ASSERT_EQ(base::File::FILE_OK
,
1542 ofu()->CreateDirectory(context
.get(), src_url
, exclusive
,
1545 std::set
<base::FilePath::StringType
> files
;
1546 std::set
<base::FilePath::StringType
> directories
;
1547 FillTestDirectory(src_url
, &files
, &directories
);
1549 FileSystemURL dest_url
= CreateURLFromUTF8("destination dir");
1551 EXPECT_FALSE(DirectoryExists(dest_url
));
1552 ASSERT_EQ(base::File::FILE_OK
,
1553 AsyncFileTestHelper::Copy(
1554 file_system_context(), src_url
, dest_url
));
1556 ValidateTestDirectory(dest_url
, files
, directories
);
1557 EXPECT_TRUE(DirectoryExists(src_url
));
1558 EXPECT_TRUE(DirectoryExists(dest_url
));
1560 ASSERT_EQ(base::File::FILE_OK
,
1561 AsyncFileTestHelper::Remove(
1562 file_system_context(), dest_url
, recursive
));
1563 EXPECT_FALSE(DirectoryExists(dest_url
));
1566 TEST_F(ObfuscatedFileUtilTest
, TestOriginEnumerator
) {
1567 scoped_ptr
<ObfuscatedFileUtil::AbstractOriginEnumerator
>
1568 enumerator(ofu()->CreateOriginEnumerator());
1569 // The test helper starts out with a single filesystem.
1570 EXPECT_TRUE(enumerator
.get());
1571 EXPECT_EQ(origin(), enumerator
->Next());
1572 ASSERT_TRUE(type() == kFileSystemTypeTemporary
);
1573 EXPECT_TRUE(HasFileSystemType(enumerator
.get(), kFileSystemTypeTemporary
));
1574 EXPECT_FALSE(HasFileSystemType(enumerator
.get(), kFileSystemTypePersistent
));
1575 EXPECT_EQ(GURL(), enumerator
->Next());
1576 EXPECT_FALSE(HasFileSystemType(enumerator
.get(), kFileSystemTypeTemporary
));
1577 EXPECT_FALSE(HasFileSystemType(enumerator
.get(), kFileSystemTypePersistent
));
1579 std::set
<GURL
> origins_expected
;
1580 origins_expected
.insert(origin());
1582 for (size_t i
= 0; i
< arraysize(kOriginEnumerationTestRecords
); ++i
) {
1583 SCOPED_TRACE(testing::Message() <<
1584 "Validating kOriginEnumerationTestRecords " << i
);
1585 const OriginEnumerationTestRecord
& record
=
1586 kOriginEnumerationTestRecords
[i
];
1587 GURL
origin_url(record
.origin_url
);
1588 origins_expected
.insert(origin_url
);
1589 if (record
.has_temporary
) {
1590 scoped_ptr
<SandboxFileSystemTestHelper
> file_system(
1591 NewFileSystem(origin_url
, kFileSystemTypeTemporary
));
1592 scoped_ptr
<FileSystemOperationContext
> context(
1593 NewContext(file_system
.get()));
1594 bool created
= false;
1595 ASSERT_EQ(base::File::FILE_OK
,
1596 ofu()->EnsureFileExists(
1598 file_system
->CreateURLFromUTF8("file"),
1600 EXPECT_TRUE(created
);
1602 if (record
.has_persistent
) {
1603 scoped_ptr
<SandboxFileSystemTestHelper
> file_system(
1604 NewFileSystem(origin_url
, kFileSystemTypePersistent
));
1605 scoped_ptr
<FileSystemOperationContext
> context(
1606 NewContext(file_system
.get()));
1607 bool created
= false;
1608 ASSERT_EQ(base::File::FILE_OK
,
1609 ofu()->EnsureFileExists(
1611 file_system
->CreateURLFromUTF8("file"),
1613 EXPECT_TRUE(created
);
1616 enumerator
.reset(ofu()->CreateOriginEnumerator());
1617 EXPECT_TRUE(enumerator
.get());
1618 std::set
<GURL
> origins_found
;
1620 while (!(origin_url
= enumerator
->Next()).is_empty()) {
1621 origins_found
.insert(origin_url
);
1622 SCOPED_TRACE(testing::Message() << "Handling " << origin_url
.spec());
1624 for (size_t i
= 0; !found
&& i
< arraysize(kOriginEnumerationTestRecords
);
1626 const OriginEnumerationTestRecord
& record
=
1627 kOriginEnumerationTestRecords
[i
];
1628 if (GURL(record
.origin_url
) != origin_url
)
1631 EXPECT_EQ(record
.has_temporary
,
1632 HasFileSystemType(enumerator
.get(), kFileSystemTypeTemporary
));
1633 EXPECT_EQ(record
.has_persistent
,
1634 HasFileSystemType(enumerator
.get(), kFileSystemTypePersistent
));
1636 // Deal with the default filesystem created by the test helper.
1637 if (!found
&& origin_url
== origin()) {
1638 ASSERT_TRUE(type() == kFileSystemTypeTemporary
);
1639 EXPECT_TRUE(HasFileSystemType(enumerator
.get(),
1640 kFileSystemTypeTemporary
));
1641 EXPECT_FALSE(HasFileSystemType(enumerator
.get(),
1642 kFileSystemTypePersistent
));
1648 std::set
<GURL
> diff
;
1649 std::set_symmetric_difference(origins_expected
.begin(),
1650 origins_expected
.end(), origins_found
.begin(), origins_found
.end(),
1651 inserter(diff
, diff
.begin()));
1652 EXPECT_TRUE(diff
.empty());
1655 TEST_F(ObfuscatedFileUtilTest
, TestRevokeUsageCache
) {
1656 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
1658 int64 expected_quota
= 0;
1660 for (size_t i
= 0; i
< kRegularFileSystemTestCaseSize
; ++i
) {
1661 SCOPED_TRACE(testing::Message() << "Creating kRegularTestCase " << i
);
1662 const FileSystemTestCaseRecord
& test_case
=
1663 kRegularFileSystemTestCases
[i
];
1664 base::FilePath
file_path(test_case
.path
);
1665 expected_quota
+= ObfuscatedFileUtil::ComputeFilePathCost(file_path
);
1666 if (test_case
.is_directory
) {
1667 bool exclusive
= true;
1668 bool recursive
= false;
1669 ASSERT_EQ(base::File::FILE_OK
,
1670 ofu()->CreateDirectory(context
.get(), CreateURL(file_path
),
1671 exclusive
, recursive
));
1673 bool created
= false;
1674 ASSERT_EQ(base::File::FILE_OK
,
1675 ofu()->EnsureFileExists(context
.get(), CreateURL(file_path
),
1677 ASSERT_TRUE(created
);
1678 ASSERT_EQ(base::File::FILE_OK
,
1679 ofu()->Truncate(context
.get(), CreateURL(file_path
),
1680 test_case
.data_file_size
));
1681 expected_quota
+= test_case
.data_file_size
;
1685 // Usually raw size in usage cache and the usage returned by QuotaUtil
1687 EXPECT_EQ(expected_quota
, SizeInUsageFile());
1688 EXPECT_EQ(expected_quota
, SizeByQuotaUtil());
1691 EXPECT_EQ(-1, SizeInUsageFile());
1692 EXPECT_EQ(expected_quota
, SizeByQuotaUtil());
1694 // This should reconstruct the cache.
1695 GetUsageFromQuotaManager();
1696 EXPECT_EQ(expected_quota
, SizeInUsageFile());
1697 EXPECT_EQ(expected_quota
, SizeByQuotaUtil());
1698 EXPECT_EQ(expected_quota
, usage());
1701 TEST_F(ObfuscatedFileUtilTest
, TestInconsistency
) {
1702 const FileSystemURL kPath1
= CreateURLFromUTF8("hoge");
1703 const FileSystemURL kPath2
= CreateURLFromUTF8("fuga");
1705 scoped_ptr
<FileSystemOperationContext
> context
;
1706 base::File::Info file_info
;
1707 base::FilePath data_path
;
1708 bool created
= false;
1710 // Create a non-empty file.
1711 context
.reset(NewContext(NULL
));
1712 EXPECT_EQ(base::File::FILE_OK
,
1713 ofu()->EnsureFileExists(context
.get(), kPath1
, &created
));
1714 EXPECT_TRUE(created
);
1715 context
.reset(NewContext(NULL
));
1716 EXPECT_EQ(base::File::FILE_OK
,
1717 ofu()->Truncate(context
.get(), kPath1
, 10));
1718 context
.reset(NewContext(NULL
));
1719 EXPECT_EQ(base::File::FILE_OK
,
1721 context
.get(), kPath1
, &file_info
, &data_path
));
1722 EXPECT_EQ(10, file_info
.size
);
1724 // Destroy database to make inconsistency between database and filesystem.
1725 ofu()->DestroyDirectoryDatabase(origin(), type_string());
1727 // Try to get file info of broken file.
1728 EXPECT_FALSE(PathExists(kPath1
));
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
,
1736 context
.get(), kPath1
, &file_info
, &data_path
));
1737 EXPECT_EQ(0, file_info
.size
);
1739 // Make another broken file to |kPath2|.
1740 context
.reset(NewContext(NULL
));
1741 EXPECT_EQ(base::File::FILE_OK
,
1742 ofu()->EnsureFileExists(context
.get(), kPath2
, &created
));
1743 EXPECT_TRUE(created
);
1746 ofu()->DestroyDirectoryDatabase(origin(), type_string());
1748 // Repair broken |kPath1|.
1749 context
.reset(NewContext(NULL
));
1750 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
,
1751 ofu()->Touch(context
.get(), kPath1
, base::Time::Now(),
1752 base::Time::Now()));
1753 EXPECT_EQ(base::File::FILE_OK
,
1754 ofu()->EnsureFileExists(context
.get(), kPath1
, &created
));
1755 EXPECT_TRUE(created
);
1757 // Copy from sound |kPath1| to broken |kPath2|.
1758 context
.reset(NewContext(NULL
));
1759 EXPECT_EQ(base::File::FILE_OK
,
1760 ofu()->CopyOrMoveFile(context
.get(), kPath1
, kPath2
,
1761 FileSystemOperation::OPTION_NONE
,
1764 ofu()->DestroyDirectoryDatabase(origin(), type_string());
1765 context
.reset(NewContext(NULL
));
1767 ofu()->CreateOrOpen(context
.get(), kPath1
,
1768 base::File::FLAG_READ
| base::File::FLAG_CREATE
);
1769 EXPECT_TRUE(file
.IsValid());
1770 EXPECT_TRUE(file
.created());
1772 EXPECT_TRUE(file
.GetInfo(&file_info
));
1773 EXPECT_EQ(0, file_info
.size
);
1776 TEST_F(ObfuscatedFileUtilTest
, TestIncompleteDirectoryReading
) {
1777 const FileSystemURL kPath
[] = {
1778 CreateURLFromUTF8("foo"),
1779 CreateURLFromUTF8("bar"),
1780 CreateURLFromUTF8("baz")
1782 const FileSystemURL empty_path
= CreateURL(base::FilePath());
1783 scoped_ptr
<FileSystemOperationContext
> context
;
1785 for (size_t i
= 0; i
< arraysize(kPath
); ++i
) {
1786 bool created
= false;
1787 context
.reset(NewContext(NULL
));
1788 EXPECT_EQ(base::File::FILE_OK
,
1789 ofu()->EnsureFileExists(context
.get(), kPath
[i
], &created
));
1790 EXPECT_TRUE(created
);
1793 std::vector
<storage::DirectoryEntry
> entries
;
1794 EXPECT_EQ(base::File::FILE_OK
,
1795 AsyncFileTestHelper::ReadDirectory(
1796 file_system_context(), empty_path
, &entries
));
1797 EXPECT_EQ(3u, entries
.size());
1799 base::FilePath local_path
;
1800 EXPECT_EQ(base::File::FILE_OK
,
1801 ofu()->GetLocalFilePath(context
.get(), kPath
[0], &local_path
));
1802 EXPECT_TRUE(base::DeleteFile(local_path
, false));
1805 EXPECT_EQ(base::File::FILE_OK
,
1806 AsyncFileTestHelper::ReadDirectory(
1807 file_system_context(), empty_path
, &entries
));
1808 EXPECT_EQ(arraysize(kPath
) - 1, entries
.size());
1811 TEST_F(ObfuscatedFileUtilTest
, TestDirectoryTimestampForCreation
) {
1812 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
1813 const FileSystemURL dir_url
= CreateURLFromUTF8("foo_dir");
1815 // Create working directory.
1816 EXPECT_EQ(base::File::FILE_OK
,
1817 ofu()->CreateDirectory(context
.get(), dir_url
, false, false));
1819 // EnsureFileExists, create case.
1820 FileSystemURL
url(FileSystemURLAppendUTF8(dir_url
, "EnsureFileExists_file"));
1821 bool created
= false;
1822 ClearTimestamp(dir_url
);
1823 context
.reset(NewContext(NULL
));
1824 EXPECT_EQ(base::File::FILE_OK
,
1825 ofu()->EnsureFileExists(context
.get(), url
, &created
));
1826 EXPECT_TRUE(created
);
1827 EXPECT_NE(base::Time(), GetModifiedTime(dir_url
));
1831 ClearTimestamp(dir_url
);
1832 context
.reset(NewContext(NULL
));
1833 EXPECT_EQ(base::File::FILE_OK
,
1834 ofu()->EnsureFileExists(context
.get(), url
, &created
));
1835 EXPECT_FALSE(created
);
1836 EXPECT_EQ(base::Time(), GetModifiedTime(dir_url
));
1839 url
= FileSystemURLAppendUTF8(dir_url
, "EnsureFileExists_dir");
1840 context
.reset(NewContext(NULL
));
1841 EXPECT_EQ(base::File::FILE_OK
,
1842 ofu()->CreateDirectory(context
.get(), url
, false, false));
1844 ClearTimestamp(dir_url
);
1845 context
.reset(NewContext(NULL
));
1846 EXPECT_EQ(base::File::FILE_ERROR_NOT_A_FILE
,
1847 ofu()->EnsureFileExists(context
.get(), url
, &created
));
1848 EXPECT_EQ(base::Time(), GetModifiedTime(dir_url
));
1850 // CreateOrOpen, create case.
1851 url
= FileSystemURLAppendUTF8(dir_url
, "CreateOrOpen_file");
1852 ClearTimestamp(dir_url
);
1853 context
.reset(NewContext(NULL
));
1855 ofu()->CreateOrOpen(context
.get(), url
,
1856 base::File::FLAG_CREATE
| base::File::FLAG_WRITE
);
1858 EXPECT_TRUE(file
.IsValid());
1859 EXPECT_TRUE(file
.created());
1861 EXPECT_NE(base::Time(), GetModifiedTime(dir_url
));
1864 ClearTimestamp(dir_url
);
1865 context
.reset(NewContext(NULL
));
1866 file
= ofu()->CreateOrOpen(context
.get(), url
,
1867 base::File::FLAG_OPEN
| base::File::FLAG_WRITE
);
1868 EXPECT_TRUE(file
.IsValid());
1869 EXPECT_FALSE(file
.created());
1871 EXPECT_EQ(base::Time(), GetModifiedTime(dir_url
));
1874 ClearTimestamp(dir_url
);
1875 context
.reset(NewContext(NULL
));
1876 file
= ofu()->CreateOrOpen(context
.get(), url
,
1877 base::File::FLAG_CREATE
| base::File::FLAG_WRITE
);
1878 EXPECT_FALSE(file
.IsValid());
1879 EXPECT_EQ(base::File::FILE_ERROR_EXISTS
, file
.error_details());
1880 EXPECT_EQ(base::Time(), GetModifiedTime(dir_url
));
1882 // CreateDirectory, create case.
1883 // Creating CreateDirectory_dir and CreateDirectory_dir/subdir.
1884 url
= FileSystemURLAppendUTF8(dir_url
, "CreateDirectory_dir");
1885 FileSystemURL
subdir_url(FileSystemURLAppendUTF8(url
, "subdir"));
1886 ClearTimestamp(dir_url
);
1887 context
.reset(NewContext(NULL
));
1888 EXPECT_EQ(base::File::FILE_OK
,
1889 ofu()->CreateDirectory(context
.get(), subdir_url
,
1890 true /* exclusive */, true /* recursive */));
1891 EXPECT_NE(base::Time(), GetModifiedTime(dir_url
));
1893 // create subdir case.
1894 // Creating CreateDirectory_dir/subdir2.
1895 subdir_url
= FileSystemURLAppendUTF8(url
, "subdir2");
1896 ClearTimestamp(dir_url
);
1897 ClearTimestamp(url
);
1898 context
.reset(NewContext(NULL
));
1899 EXPECT_EQ(base::File::FILE_OK
,
1900 ofu()->CreateDirectory(context
.get(), subdir_url
,
1901 true /* exclusive */, true /* recursive */));
1902 EXPECT_EQ(base::Time(), GetModifiedTime(dir_url
));
1903 EXPECT_NE(base::Time(), GetModifiedTime(url
));
1906 url
= FileSystemURLAppendUTF8(dir_url
, "CreateDirectory_dir");
1907 ClearTimestamp(dir_url
);
1908 context
.reset(NewContext(NULL
));
1909 EXPECT_EQ(base::File::FILE_ERROR_EXISTS
,
1910 ofu()->CreateDirectory(context
.get(), url
,
1911 true /* exclusive */, true /* recursive */));
1912 EXPECT_EQ(base::Time(), GetModifiedTime(dir_url
));
1914 // CopyInForeignFile, create case.
1915 url
= FileSystemURLAppendUTF8(dir_url
, "CopyInForeignFile_file");
1916 FileSystemURL src_path
= FileSystemURLAppendUTF8(
1917 dir_url
, "CopyInForeignFile_src_file");
1918 context
.reset(NewContext(NULL
));
1919 EXPECT_EQ(base::File::FILE_OK
,
1920 ofu()->EnsureFileExists(context
.get(), src_path
, &created
));
1921 EXPECT_TRUE(created
);
1922 base::FilePath src_local_path
;
1923 context
.reset(NewContext(NULL
));
1924 EXPECT_EQ(base::File::FILE_OK
,
1925 ofu()->GetLocalFilePath(context
.get(), src_path
, &src_local_path
));
1927 ClearTimestamp(dir_url
);
1928 context
.reset(NewContext(NULL
));
1929 EXPECT_EQ(base::File::FILE_OK
,
1930 ofu()->CopyInForeignFile(context
.get(),
1933 EXPECT_NE(base::Time(), GetModifiedTime(dir_url
));
1936 TEST_F(ObfuscatedFileUtilTest
, TestDirectoryTimestampForDeletion
) {
1937 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
1938 const FileSystemURL dir_url
= CreateURLFromUTF8("foo_dir");
1940 // Create working directory.
1941 EXPECT_EQ(base::File::FILE_OK
,
1942 ofu()->CreateDirectory(context
.get(), dir_url
, false, false));
1944 // DeleteFile, delete case.
1945 FileSystemURL url
= FileSystemURLAppendUTF8(
1946 dir_url
, "DeleteFile_file");
1947 bool created
= false;
1948 context
.reset(NewContext(NULL
));
1949 EXPECT_EQ(base::File::FILE_OK
,
1950 ofu()->EnsureFileExists(context
.get(), url
, &created
));
1951 EXPECT_TRUE(created
);
1953 ClearTimestamp(dir_url
);
1954 context
.reset(NewContext(NULL
));
1955 EXPECT_EQ(base::File::FILE_OK
,
1956 ofu()->DeleteFile(context
.get(), url
));
1957 EXPECT_NE(base::Time(), GetModifiedTime(dir_url
));
1960 ClearTimestamp(dir_url
);
1961 context
.reset(NewContext(NULL
));
1962 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
,
1963 ofu()->DeleteFile(context
.get(), url
));
1964 EXPECT_EQ(base::Time(), GetModifiedTime(dir_url
));
1966 // DeleteDirectory, fail case.
1967 url
= FileSystemURLAppendUTF8(dir_url
, "DeleteDirectory_dir");
1968 FileSystemURL
file_path(FileSystemURLAppendUTF8(url
, "pakeratta"));
1969 context
.reset(NewContext(NULL
));
1970 EXPECT_EQ(base::File::FILE_OK
,
1971 ofu()->CreateDirectory(context
.get(), url
, true, true));
1973 context
.reset(NewContext(NULL
));
1974 EXPECT_EQ(base::File::FILE_OK
,
1975 ofu()->EnsureFileExists(context
.get(), file_path
, &created
));
1976 EXPECT_TRUE(created
);
1978 ClearTimestamp(dir_url
);
1979 context
.reset(NewContext(NULL
));
1980 EXPECT_EQ(base::File::FILE_ERROR_NOT_EMPTY
,
1981 ofu()->DeleteDirectory(context
.get(), url
));
1982 EXPECT_EQ(base::Time(), GetModifiedTime(dir_url
));
1985 context
.reset(NewContext(NULL
));
1986 EXPECT_EQ(base::File::FILE_OK
,
1987 ofu()->DeleteFile(context
.get(), file_path
));
1989 ClearTimestamp(dir_url
);
1990 context
.reset(NewContext(NULL
));
1991 EXPECT_EQ(base::File::FILE_OK
, ofu()->DeleteDirectory(context
.get(), url
));
1992 EXPECT_NE(base::Time(), GetModifiedTime(dir_url
));
1995 TEST_F(ObfuscatedFileUtilTest
, TestDirectoryTimestampForCopyAndMove
) {
1996 TestDirectoryTimestampHelper(
1997 CreateURLFromUTF8("copy overwrite"), true, true);
1998 TestDirectoryTimestampHelper(
1999 CreateURLFromUTF8("copy non-overwrite"), true, false);
2000 TestDirectoryTimestampHelper(
2001 CreateURLFromUTF8("move overwrite"), false, true);
2002 TestDirectoryTimestampHelper(
2003 CreateURLFromUTF8("move non-overwrite"), false, false);
2006 TEST_F(ObfuscatedFileUtilTest
, TestFileEnumeratorTimestamp
) {
2007 FileSystemURL dir
= CreateURLFromUTF8("foo");
2008 FileSystemURL url1
= FileSystemURLAppendUTF8(dir
, "bar");
2009 FileSystemURL url2
= FileSystemURLAppendUTF8(dir
, "baz");
2011 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
2012 EXPECT_EQ(base::File::FILE_OK
,
2013 ofu()->CreateDirectory(context
.get(), dir
, false, false));
2015 bool created
= false;
2016 context
.reset(NewContext(NULL
));
2017 EXPECT_EQ(base::File::FILE_OK
,
2018 ofu()->EnsureFileExists(context
.get(), url1
, &created
));
2019 EXPECT_TRUE(created
);
2021 context
.reset(NewContext(NULL
));
2022 EXPECT_EQ(base::File::FILE_OK
,
2023 ofu()->CreateDirectory(context
.get(), url2
, false, false));
2025 base::FilePath file_path
;
2026 context
.reset(NewContext(NULL
));
2027 EXPECT_EQ(base::File::FILE_OK
,
2028 ofu()->GetLocalFilePath(context
.get(), url1
, &file_path
));
2029 EXPECT_FALSE(file_path
.empty());
2031 context
.reset(NewContext(NULL
));
2032 EXPECT_EQ(base::File::FILE_OK
,
2033 ofu()->Touch(context
.get(), url1
,
2034 base::Time::Now() + base::TimeDelta::FromHours(1),
2037 context
.reset(NewContext(NULL
));
2038 scoped_ptr
<storage::FileSystemFileUtil::AbstractFileEnumerator
> file_enum(
2039 ofu()->CreateFileEnumerator(context
.get(), dir
, false));
2042 base::FilePath file_path_each
;
2043 while (!(file_path_each
= file_enum
->Next()).empty()) {
2044 context
.reset(NewContext(NULL
));
2045 base::File::Info file_info
;
2046 base::FilePath file_path
;
2047 EXPECT_EQ(base::File::FILE_OK
,
2048 ofu()->GetFileInfo(context
.get(),
2049 FileSystemURL::CreateForTest(
2053 &file_info
, &file_path
));
2054 EXPECT_EQ(file_info
.is_directory
, file_enum
->IsDirectory());
2055 EXPECT_EQ(file_info
.last_modified
, file_enum
->LastModifiedTime());
2056 EXPECT_EQ(file_info
.size
, file_enum
->Size());
2059 EXPECT_EQ(2, count
);
2063 #if defined(OS_WIN) || defined(OS_ANDROID)
2064 #define MAYBE_TestQuotaOnCopyFile DISABLED_TestQuotaOnCopyFile
2066 #define MAYBE_TestQuotaOnCopyFile TestQuotaOnCopyFile
2068 TEST_F(ObfuscatedFileUtilTest
, MAYBE_TestQuotaOnCopyFile
) {
2069 FileSystemURL
from_file(CreateURLFromUTF8("fromfile"));
2070 FileSystemURL
obstacle_file(CreateURLFromUTF8("obstaclefile"));
2071 FileSystemURL
to_file1(CreateURLFromUTF8("tofile1"));
2072 FileSystemURL
to_file2(CreateURLFromUTF8("tofile2"));
2075 int64 expected_total_file_size
= 0;
2076 ASSERT_EQ(base::File::FILE_OK
,
2077 ofu()->EnsureFileExists(
2078 AllowUsageIncrease(PathCost(from_file
))->context(),
2079 from_file
, &created
));
2080 ASSERT_TRUE(created
);
2081 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2083 ASSERT_EQ(base::File::FILE_OK
,
2084 ofu()->EnsureFileExists(
2085 AllowUsageIncrease(PathCost(obstacle_file
))->context(),
2086 obstacle_file
, &created
));
2087 ASSERT_TRUE(created
);
2088 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2090 int64 from_file_size
= 1020;
2091 expected_total_file_size
+= from_file_size
;
2092 ASSERT_EQ(base::File::FILE_OK
,
2094 AllowUsageIncrease(from_file_size
)->context(),
2095 from_file
, from_file_size
));
2096 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2098 int64 obstacle_file_size
= 1;
2099 expected_total_file_size
+= obstacle_file_size
;
2100 ASSERT_EQ(base::File::FILE_OK
,
2102 AllowUsageIncrease(obstacle_file_size
)->context(),
2103 obstacle_file
, obstacle_file_size
));
2104 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2106 int64 to_file1_size
= from_file_size
;
2107 expected_total_file_size
+= to_file1_size
;
2108 ASSERT_EQ(base::File::FILE_OK
,
2109 ofu()->CopyOrMoveFile(
2111 PathCost(to_file1
) + to_file1_size
)->context(),
2112 from_file
, to_file1
,
2113 FileSystemOperation::OPTION_NONE
,
2115 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2117 ASSERT_EQ(base::File::FILE_ERROR_NO_SPACE
,
2118 ofu()->CopyOrMoveFile(
2119 DisallowUsageIncrease(
2120 PathCost(to_file2
) + from_file_size
)->context(),
2121 from_file
, to_file2
, FileSystemOperation::OPTION_NONE
,
2123 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2125 int64 old_obstacle_file_size
= obstacle_file_size
;
2126 obstacle_file_size
= from_file_size
;
2127 expected_total_file_size
+= obstacle_file_size
- old_obstacle_file_size
;
2128 ASSERT_EQ(base::File::FILE_OK
,
2129 ofu()->CopyOrMoveFile(
2131 obstacle_file_size
- old_obstacle_file_size
)->context(),
2132 from_file
, obstacle_file
,
2133 FileSystemOperation::OPTION_NONE
,
2135 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2137 int64 old_from_file_size
= from_file_size
;
2138 from_file_size
= old_from_file_size
- 1;
2139 expected_total_file_size
+= from_file_size
- old_from_file_size
;
2140 ASSERT_EQ(base::File::FILE_OK
,
2143 from_file_size
- old_from_file_size
)->context(),
2144 from_file
, from_file_size
));
2145 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2149 old_obstacle_file_size
= obstacle_file_size
;
2150 obstacle_file_size
= from_file_size
;
2151 expected_total_file_size
+= obstacle_file_size
- old_obstacle_file_size
;
2152 scoped_ptr
<UsageVerifyHelper
> helper
= AllowUsageIncrease(
2153 obstacle_file_size
- old_obstacle_file_size
);
2154 helper
->context()->set_allowed_bytes_growth(
2155 helper
->context()->allowed_bytes_growth() - 1);
2156 ASSERT_EQ(base::File::FILE_OK
,
2157 ofu()->CopyOrMoveFile(
2159 from_file
, obstacle_file
,
2160 FileSystemOperation::OPTION_NONE
,
2162 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2166 TEST_F(ObfuscatedFileUtilTest
, TestQuotaOnMoveFile
) {
2167 FileSystemURL
from_file(CreateURLFromUTF8("fromfile"));
2168 FileSystemURL
obstacle_file(CreateURLFromUTF8("obstaclefile"));
2169 FileSystemURL
to_file(CreateURLFromUTF8("tofile"));
2172 int64 expected_total_file_size
= 0;
2173 ASSERT_EQ(base::File::FILE_OK
,
2174 ofu()->EnsureFileExists(
2175 AllowUsageIncrease(PathCost(from_file
))->context(),
2176 from_file
, &created
));
2177 ASSERT_TRUE(created
);
2178 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2180 int64 from_file_size
= 1020;
2181 expected_total_file_size
+= from_file_size
;
2182 ASSERT_EQ(base::File::FILE_OK
,
2184 AllowUsageIncrease(from_file_size
)->context(),
2185 from_file
, from_file_size
));
2186 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2189 ASSERT_EQ(base::File::FILE_OK
,
2190 ofu()->CopyOrMoveFile(
2191 AllowUsageIncrease(-PathCost(from_file
) +
2192 PathCost(to_file
))->context(),
2194 FileSystemOperation::OPTION_NONE
,
2196 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2198 ASSERT_EQ(base::File::FILE_OK
,
2199 ofu()->EnsureFileExists(
2200 AllowUsageIncrease(PathCost(from_file
))->context(),
2201 from_file
, &created
));
2202 ASSERT_TRUE(created
);
2203 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2205 ASSERT_EQ(base::File::FILE_OK
,
2206 ofu()->EnsureFileExists(
2207 AllowUsageIncrease(PathCost(obstacle_file
))->context(),
2208 obstacle_file
, &created
));
2209 ASSERT_TRUE(created
);
2210 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2212 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 obstacle_file_size
= 1;
2221 expected_total_file_size
+= obstacle_file_size
;
2222 ASSERT_EQ(base::File::FILE_OK
,
2224 AllowUsageIncrease(1)->context(),
2225 obstacle_file
, obstacle_file_size
));
2226 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2228 int64 old_obstacle_file_size
= obstacle_file_size
;
2229 obstacle_file_size
= from_file_size
;
2231 expected_total_file_size
-= old_obstacle_file_size
;
2232 ASSERT_EQ(base::File::FILE_OK
,
2233 ofu()->CopyOrMoveFile(
2235 -old_obstacle_file_size
- PathCost(from_file
))->context(),
2236 from_file
, obstacle_file
,
2237 FileSystemOperation::OPTION_NONE
,
2239 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2241 ASSERT_EQ(base::File::FILE_OK
,
2242 ofu()->EnsureFileExists(
2243 AllowUsageIncrease(PathCost(from_file
))->context(),
2244 from_file
, &created
));
2245 ASSERT_TRUE(created
);
2246 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2248 from_file_size
= 10;
2249 expected_total_file_size
+= from_file_size
;
2250 ASSERT_EQ(base::File::FILE_OK
,
2252 AllowUsageIncrease(from_file_size
)->context(),
2253 from_file
, from_file_size
));
2254 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2256 // quota exceeded even after operation
2257 old_obstacle_file_size
= obstacle_file_size
;
2258 obstacle_file_size
= from_file_size
;
2260 expected_total_file_size
-= old_obstacle_file_size
;
2261 scoped_ptr
<FileSystemOperationContext
> context
=
2262 LimitedContext(-old_obstacle_file_size
- PathCost(from_file
) - 1);
2263 ASSERT_EQ(base::File::FILE_OK
,
2264 ofu()->CopyOrMoveFile(
2265 context
.get(), from_file
, obstacle_file
,
2266 FileSystemOperation::OPTION_NONE
,
2268 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2272 TEST_F(ObfuscatedFileUtilTest
, TestQuotaOnRemove
) {
2273 FileSystemURL
dir(CreateURLFromUTF8("dir"));
2274 FileSystemURL
file(CreateURLFromUTF8("file"));
2275 FileSystemURL
dfile1(CreateURLFromUTF8("dir/dfile1"));
2276 FileSystemURL
dfile2(CreateURLFromUTF8("dir/dfile2"));
2279 ASSERT_EQ(base::File::FILE_OK
,
2280 ofu()->EnsureFileExists(
2281 AllowUsageIncrease(PathCost(file
))->context(),
2283 ASSERT_TRUE(created
);
2284 ASSERT_EQ(0, ComputeTotalFileSize());
2286 ASSERT_EQ(base::File::FILE_OK
,
2287 ofu()->CreateDirectory(
2288 AllowUsageIncrease(PathCost(dir
))->context(),
2289 dir
, false, false));
2290 ASSERT_EQ(0, ComputeTotalFileSize());
2292 ASSERT_EQ(base::File::FILE_OK
,
2293 ofu()->EnsureFileExists(
2294 AllowUsageIncrease(PathCost(dfile1
))->context(),
2296 ASSERT_TRUE(created
);
2297 ASSERT_EQ(0, ComputeTotalFileSize());
2299 ASSERT_EQ(base::File::FILE_OK
,
2300 ofu()->EnsureFileExists(
2301 AllowUsageIncrease(PathCost(dfile2
))->context(),
2303 ASSERT_TRUE(created
);
2304 ASSERT_EQ(0, ComputeTotalFileSize());
2306 ASSERT_EQ(base::File::FILE_OK
,
2308 AllowUsageIncrease(340)->context(),
2310 ASSERT_EQ(340, ComputeTotalFileSize());
2312 ASSERT_EQ(base::File::FILE_OK
,
2314 AllowUsageIncrease(1020)->context(),
2316 ASSERT_EQ(1360, ComputeTotalFileSize());
2318 ASSERT_EQ(base::File::FILE_OK
,
2320 AllowUsageIncrease(120)->context(),
2322 ASSERT_EQ(1480, ComputeTotalFileSize());
2324 ASSERT_EQ(base::File::FILE_OK
,
2326 AllowUsageIncrease(-PathCost(file
) - 340)->context(),
2328 ASSERT_EQ(1140, ComputeTotalFileSize());
2330 ASSERT_EQ(base::File::FILE_OK
,
2331 AsyncFileTestHelper::Remove(
2332 file_system_context(), dir
, true /* recursive */));
2333 ASSERT_EQ(0, ComputeTotalFileSize());
2336 TEST_F(ObfuscatedFileUtilTest
, TestQuotaOnOpen
) {
2337 FileSystemURL
url(CreateURLFromUTF8("file"));
2341 ASSERT_EQ(base::File::FILE_OK
,
2342 ofu()->EnsureFileExists(
2343 AllowUsageIncrease(PathCost(url
))->context(),
2345 ASSERT_TRUE(created
);
2346 ASSERT_EQ(0, ComputeTotalFileSize());
2348 // Opening it, which shouldn't change the usage.
2350 ofu()->CreateOrOpen(AllowUsageIncrease(0)->context(), url
,
2351 base::File::FLAG_OPEN
| base::File::FLAG_WRITE
);
2352 ASSERT_TRUE(file
.IsValid());
2353 ASSERT_EQ(0, ComputeTotalFileSize());
2356 const int length
= 33;
2357 ASSERT_EQ(base::File::FILE_OK
,
2359 AllowUsageIncrease(length
)->context(), url
, length
));
2360 ASSERT_EQ(length
, ComputeTotalFileSize());
2362 // Opening it with CREATE_ALWAYS flag, which should truncate the file size.
2363 file
= ofu()->CreateOrOpen(
2364 AllowUsageIncrease(-length
)->context(), url
,
2365 base::File::FLAG_CREATE_ALWAYS
| base::File::FLAG_WRITE
);
2366 ASSERT_TRUE(file
.IsValid());
2367 ASSERT_EQ(0, ComputeTotalFileSize());
2370 // Extending the file again.
2371 ASSERT_EQ(base::File::FILE_OK
,
2373 AllowUsageIncrease(length
)->context(), url
, length
));
2374 ASSERT_EQ(length
, ComputeTotalFileSize());
2376 // Opening it with TRUNCATED flag, which should truncate the file size.
2377 file
= ofu()->CreateOrOpen(
2378 AllowUsageIncrease(-length
)->context(), url
,
2379 base::File::FLAG_OPEN_TRUNCATED
| base::File::FLAG_WRITE
);
2380 ASSERT_TRUE(file
.IsValid());
2381 ASSERT_EQ(0, ComputeTotalFileSize());
2385 TEST_F(ObfuscatedFileUtilTest
, MaybeDropDatabasesAliveCase
) {
2386 MaybeDropDatabasesAliveCaseTestBody();
2389 TEST_F(ObfuscatedFileUtilTest
, MaybeDropDatabasesAlreadyDeletedCase
) {
2390 MaybeDropDatabasesAlreadyDeletedCaseTestBody();
2393 TEST_F(ObfuscatedFileUtilTest
, DestroyDirectoryDatabase_Isolated
) {
2394 DestroyDirectoryDatabase_IsolatedTestBody();
2397 TEST_F(ObfuscatedFileUtilTest
, GetDirectoryDatabase_Isolated
) {
2398 GetDirectoryDatabase_IsolatedTestBody();
2401 TEST_F(ObfuscatedFileUtilTest
, MigrationBackFromIsolated
) {
2402 MigrationBackFromIsolatedTestBody();
2405 TEST_F(ObfuscatedFileUtilTest
, OpenPathInNonDirectory
) {
2406 FileSystemURL
url(CreateURLFromUTF8("file"));
2407 FileSystemURL
path_in_file(CreateURLFromUTF8("file/file"));
2410 ASSERT_EQ(base::File::FILE_OK
,
2411 ofu()->EnsureFileExists(UnlimitedContext().get(), url
, &created
));
2412 ASSERT_TRUE(created
);
2414 int file_flags
= base::File::FLAG_CREATE
| base::File::FLAG_WRITE
;
2416 ofu()->CreateOrOpen(UnlimitedContext().get(), path_in_file
, file_flags
);
2417 ASSERT_FALSE(file
.IsValid());
2418 ASSERT_EQ(base::File::FILE_ERROR_NOT_A_DIRECTORY
, file
.error_details());
2420 ASSERT_EQ(base::File::FILE_ERROR_NOT_A_DIRECTORY
,
2421 ofu()->CreateDirectory(UnlimitedContext().get(),
2423 false /* exclusive */,
2424 false /* recursive */));
2427 TEST_F(ObfuscatedFileUtilTest
, CreateDirectory_NotADirectoryInRecursive
) {
2428 FileSystemURL
file(CreateURLFromUTF8("file"));
2429 FileSystemURL
path_in_file(CreateURLFromUTF8("file/child"));
2430 FileSystemURL
path_in_file_in_file(
2431 CreateURLFromUTF8("file/child/grandchild"));
2434 ASSERT_EQ(base::File::FILE_OK
,
2435 ofu()->EnsureFileExists(UnlimitedContext().get(), file
, &created
));
2436 ASSERT_TRUE(created
);
2438 ASSERT_EQ(base::File::FILE_ERROR_NOT_A_DIRECTORY
,
2439 ofu()->CreateDirectory(UnlimitedContext().get(),
2441 false /* exclusive */,
2442 true /* recursive */));
2443 ASSERT_EQ(base::File::FILE_ERROR_NOT_A_DIRECTORY
,
2444 ofu()->CreateDirectory(UnlimitedContext().get(),
2445 path_in_file_in_file
,
2446 false /* exclusive */,
2447 true /* recursive */));
2450 TEST_F(ObfuscatedFileUtilTest
, DeleteDirectoryForOriginAndType
) {
2451 const GURL
origin1("http://www.example.com:12");
2452 const GURL
origin2("http://www.example.com:1234");
2454 // Create origin directories.
2455 scoped_ptr
<SandboxFileSystemTestHelper
> fs1(
2456 NewFileSystem(origin1
, kFileSystemTypeTemporary
));
2457 scoped_ptr
<SandboxFileSystemTestHelper
> fs2(
2458 NewFileSystem(origin1
, kFileSystemTypePersistent
));
2459 scoped_ptr
<SandboxFileSystemTestHelper
> fs3(
2460 NewFileSystem(origin2
, kFileSystemTypeTemporary
));
2461 scoped_ptr
<SandboxFileSystemTestHelper
> fs4(
2462 NewFileSystem(origin2
, kFileSystemTypePersistent
));
2464 // Make sure directories for origin1 exist.
2465 base::File::Error error
= base::File::FILE_ERROR_FAILED
;
2466 ofu()->GetDirectoryForOriginAndType(
2467 origin1
, GetTypeString(kFileSystemTypeTemporary
), false, &error
);
2468 ASSERT_EQ(base::File::FILE_OK
, error
);
2469 error
= base::File::FILE_ERROR_FAILED
;
2470 ofu()->GetDirectoryForOriginAndType(
2471 origin1
, GetTypeString(kFileSystemTypePersistent
), false, &error
);
2472 ASSERT_EQ(base::File::FILE_OK
, error
);
2474 // Make sure directories for origin2 exist.
2475 error
= base::File::FILE_ERROR_FAILED
;
2476 ofu()->GetDirectoryForOriginAndType(
2477 origin2
, GetTypeString(kFileSystemTypeTemporary
), false, &error
);
2478 ASSERT_EQ(base::File::FILE_OK
, error
);
2479 error
= base::File::FILE_ERROR_FAILED
;
2480 ofu()->GetDirectoryForOriginAndType(
2481 origin2
, GetTypeString(kFileSystemTypePersistent
), false, &error
);
2482 ASSERT_EQ(base::File::FILE_OK
, error
);
2484 // Delete a directory for origin1's persistent filesystem.
2485 ofu()->DeleteDirectoryForOriginAndType(
2486 origin1
, GetTypeString(kFileSystemTypePersistent
));
2488 // The directory for origin1's temporary filesystem should not be removed.
2489 error
= base::File::FILE_ERROR_FAILED
;
2490 ofu()->GetDirectoryForOriginAndType(
2491 origin1
, GetTypeString(kFileSystemTypeTemporary
), false, &error
);
2492 ASSERT_EQ(base::File::FILE_OK
, error
);
2494 // The directory for origin1's persistent filesystem should be removed.
2495 error
= base::File::FILE_ERROR_FAILED
;
2496 ofu()->GetDirectoryForOriginAndType(
2497 origin1
, GetTypeString(kFileSystemTypePersistent
), false, &error
);
2498 ASSERT_EQ(base::File::FILE_ERROR_NOT_FOUND
, error
);
2500 // The directories for origin2 should not be removed.
2501 error
= base::File::FILE_ERROR_FAILED
;
2502 ofu()->GetDirectoryForOriginAndType(
2503 origin2
, GetTypeString(kFileSystemTypeTemporary
), false, &error
);
2504 ASSERT_EQ(base::File::FILE_OK
, error
);
2505 error
= base::File::FILE_ERROR_FAILED
;
2506 ofu()->GetDirectoryForOriginAndType(
2507 origin2
, GetTypeString(kFileSystemTypePersistent
), false, &error
);
2508 ASSERT_EQ(base::File::FILE_OK
, error
);
2511 TEST_F(ObfuscatedFileUtilTest
, DeleteDirectoryForOriginAndType_DeleteAll
) {
2512 const GURL
origin1("http://www.example.com:12");
2513 const GURL
origin2("http://www.example.com:1234");
2515 // Create origin directories.
2516 scoped_ptr
<SandboxFileSystemTestHelper
> fs1(
2517 NewFileSystem(origin1
, kFileSystemTypeTemporary
));
2518 scoped_ptr
<SandboxFileSystemTestHelper
> fs2(
2519 NewFileSystem(origin1
, kFileSystemTypePersistent
));
2520 scoped_ptr
<SandboxFileSystemTestHelper
> fs3(
2521 NewFileSystem(origin2
, kFileSystemTypeTemporary
));
2522 scoped_ptr
<SandboxFileSystemTestHelper
> fs4(
2523 NewFileSystem(origin2
, kFileSystemTypePersistent
));
2525 // Make sure directories for origin1 exist.
2526 base::File::Error error
= base::File::FILE_ERROR_FAILED
;
2527 ofu()->GetDirectoryForOriginAndType(
2528 origin1
, GetTypeString(kFileSystemTypeTemporary
), false, &error
);
2529 ASSERT_EQ(base::File::FILE_OK
, error
);
2530 error
= base::File::FILE_ERROR_FAILED
;
2531 ofu()->GetDirectoryForOriginAndType(
2532 origin1
, GetTypeString(kFileSystemTypePersistent
), false, &error
);
2533 ASSERT_EQ(base::File::FILE_OK
, error
);
2535 // Make sure directories for origin2 exist.
2536 error
= base::File::FILE_ERROR_FAILED
;
2537 ofu()->GetDirectoryForOriginAndType(
2538 origin2
, GetTypeString(kFileSystemTypeTemporary
), false, &error
);
2539 ASSERT_EQ(base::File::FILE_OK
, error
);
2540 error
= base::File::FILE_ERROR_FAILED
;
2541 ofu()->GetDirectoryForOriginAndType(
2542 origin2
, GetTypeString(kFileSystemTypePersistent
), false, &error
);
2543 ASSERT_EQ(base::File::FILE_OK
, error
);
2545 // Delete all directories for origin1.
2546 ofu()->DeleteDirectoryForOriginAndType(origin1
, std::string());
2548 // The directories for origin1 should be removed.
2549 error
= base::File::FILE_ERROR_FAILED
;
2550 ofu()->GetDirectoryForOriginAndType(
2551 origin1
, GetTypeString(kFileSystemTypeTemporary
), false, &error
);
2552 ASSERT_EQ(base::File::FILE_ERROR_NOT_FOUND
, error
);
2553 error
= base::File::FILE_ERROR_FAILED
;
2554 ofu()->GetDirectoryForOriginAndType(
2555 origin1
, GetTypeString(kFileSystemTypePersistent
), false, &error
);
2556 ASSERT_EQ(base::File::FILE_ERROR_NOT_FOUND
, error
);
2558 // The directories for origin2 should not be removed.
2559 error
= base::File::FILE_ERROR_FAILED
;
2560 ofu()->GetDirectoryForOriginAndType(
2561 origin2
, GetTypeString(kFileSystemTypeTemporary
), false, &error
);
2562 ASSERT_EQ(base::File::FILE_OK
, error
);
2563 error
= base::File::FILE_ERROR_FAILED
;
2564 ofu()->GetDirectoryForOriginAndType(
2565 origin2
, GetTypeString(kFileSystemTypePersistent
), false, &error
);
2566 ASSERT_EQ(base::File::FILE_OK
, error
);
2569 } // namespace content