1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
10 #include "base/file_util.h"
11 #include "base/files/file_path.h"
12 #include "base/files/scoped_temp_dir.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/platform_file.h"
15 #include "base/run_loop.h"
16 #include "content/public/test/sandbox_file_system_test_helper.h"
17 #include "content/public/test/test_file_system_context.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19 #include "webkit/browser/fileapi/async_file_test_helper.h"
20 #include "webkit/browser/fileapi/external_mount_points.h"
21 #include "webkit/browser/fileapi/file_system_backend.h"
22 #include "webkit/browser/fileapi/file_system_context.h"
23 #include "webkit/browser/fileapi/file_system_operation_context.h"
24 #include "webkit/browser/fileapi/file_system_usage_cache.h"
25 #include "webkit/browser/fileapi/mock_file_change_observer.h"
26 #include "webkit/browser/fileapi/obfuscated_file_util.h"
27 #include "webkit/browser/fileapi/sandbox_directory_database.h"
28 #include "webkit/browser/fileapi/sandbox_file_system_backend_delegate.h"
29 #include "webkit/browser/fileapi/sandbox_isolated_origin_database.h"
30 #include "webkit/browser/fileapi/sandbox_origin_database.h"
31 #include "webkit/browser/fileapi/test_file_set.h"
32 #include "webkit/browser/quota/mock_special_storage_policy.h"
33 #include "webkit/browser/quota/quota_manager.h"
34 #include "webkit/common/database/database_identifier.h"
35 #include "webkit/common/quota/quota_types.h"
41 bool FileExists(const base::FilePath
& path
) {
42 return base::PathExists(path
) && !base::DirectoryExists(path
);
45 int64
GetSize(const base::FilePath
& path
) {
47 EXPECT_TRUE(base::GetFileSize(path
, &size
));
51 // After a move, the dest exists and the source doesn't.
52 // After a copy, both source and dest exist.
53 struct CopyMoveTestCaseRecord
{
54 bool is_copy_not_move
;
55 const char source_path
[64];
56 const char dest_path
[64];
60 const CopyMoveTestCaseRecord kCopyMoveTestCases
[] = {
61 // This is the combinatoric set of:
62 // rename vs. same-name
63 // different directory vs. same directory
64 // overwrite vs. no-overwrite
66 // We can never be called with source and destination paths identical, so
67 // those cases are omitted.
68 {true, "dir0/file0", "dir0/file1", false},
69 {false, "dir0/file0", "dir0/file1", false},
70 {true, "dir0/file0", "dir0/file1", true},
71 {false, "dir0/file0", "dir0/file1", true},
73 {true, "dir0/file0", "dir1/file0", false},
74 {false, "dir0/file0", "dir1/file0", false},
75 {true, "dir0/file0", "dir1/file0", true},
76 {false, "dir0/file0", "dir1/file0", true},
77 {true, "dir0/file0", "dir1/file1", false},
78 {false, "dir0/file0", "dir1/file1", false},
79 {true, "dir0/file0", "dir1/file1", true},
80 {false, "dir0/file0", "dir1/file1", true},
83 struct OriginEnumerationTestRecord
{
84 std::string origin_url
;
89 const OriginEnumerationTestRecord kOriginEnumerationTestRecords
[] = {
90 {"http://example.com", false, true},
91 {"http://example1.com", true, false},
92 {"https://example1.com", true, true},
93 {"file://", false, true},
94 {"http://example.com:8000", false, true},
97 FileSystemURL
FileSystemURLAppend(
98 const FileSystemURL
& url
, const base::FilePath::StringType
& child
) {
99 return FileSystemURL::CreateForTest(
100 url
.origin(), url
.mount_type(), url
.virtual_path().Append(child
));
103 FileSystemURL
FileSystemURLAppendUTF8(
104 const FileSystemURL
& url
, const std::string
& child
) {
105 return FileSystemURL::CreateForTest(
108 url
.virtual_path().Append(base::FilePath::FromUTF8Unsafe(child
)));
111 FileSystemURL
FileSystemURLDirName(const FileSystemURL
& url
) {
112 return FileSystemURL::CreateForTest(
113 url
.origin(), url
.mount_type(), VirtualPath::DirName(url
.virtual_path()));
116 std::string
GetTypeString(FileSystemType type
) {
117 return SandboxFileSystemBackendDelegate::GetTypeString(type
);
120 bool HasFileSystemType(
121 ObfuscatedFileUtil::AbstractOriginEnumerator
* enumerator
,
122 FileSystemType type
) {
123 return enumerator
->HasTypeDirectory(GetTypeString(type
));
128 // TODO(ericu): The vast majority of this and the other FSFU subclass tests
129 // could theoretically be shared. It would basically be a FSFU interface
130 // compliance test, and only the subclass-specific bits that look into the
131 // implementation would need to be written per-subclass.
132 class ObfuscatedFileUtilTest
: public testing::Test
{
134 ObfuscatedFileUtilTest()
135 : origin_(GURL("http://www.example.com")),
136 type_(kFileSystemTypeTemporary
),
138 sandbox_file_system_(origin_
, type_
),
139 quota_status_(quota::kQuotaStatusUnknown
),
143 virtual void SetUp() {
144 ASSERT_TRUE(data_dir_
.CreateUniqueTempDir());
146 storage_policy_
= new quota::MockSpecialStoragePolicy();
149 new quota::QuotaManager(false /* is_incognito */,
151 base::MessageLoopProxy::current().get(),
152 base::MessageLoopProxy::current().get(),
153 storage_policy_
.get());
155 // Every time we create a new sandbox_file_system helper,
156 // it creates another context, which creates another path manager,
157 // another sandbox_backend, and another OFU.
158 // We need to pass in the context to skip all that.
159 file_system_context_
= CreateFileSystemContextForTesting(
160 quota_manager_
->proxy(),
163 sandbox_file_system_
.SetUp(file_system_context_
.get());
165 change_observers_
= MockFileChangeObserver::CreateList(&change_observer_
);
168 virtual void TearDown() {
169 quota_manager_
= NULL
;
170 sandbox_file_system_
.TearDown();
173 scoped_ptr
<FileSystemOperationContext
> LimitedContext(
174 int64 allowed_bytes_growth
) {
175 scoped_ptr
<FileSystemOperationContext
> context(
176 sandbox_file_system_
.NewOperationContext());
177 context
->set_allowed_bytes_growth(allowed_bytes_growth
);
178 return context
.Pass();
181 scoped_ptr
<FileSystemOperationContext
> UnlimitedContext() {
182 return LimitedContext(kint64max
);
185 FileSystemOperationContext
* NewContext(
186 SandboxFileSystemTestHelper
* file_system
) {
187 change_observer()->ResetCount();
188 FileSystemOperationContext
* context
;
190 context
= file_system
->NewOperationContext();
192 context
= sandbox_file_system_
.NewOperationContext();
193 // Setting allowed_bytes_growth big enough for all tests.
194 context
->set_allowed_bytes_growth(1024 * 1024);
195 context
->set_change_observers(change_observers());
199 const ChangeObserverList
& change_observers() const {
200 return change_observers_
;
203 MockFileChangeObserver
* change_observer() {
204 return &change_observer_
;
207 // This can only be used after SetUp has run and created file_system_context_
208 // and obfuscated_file_util_.
209 // Use this for tests which need to run in multiple origins; we need a test
210 // helper per origin.
211 SandboxFileSystemTestHelper
* NewFileSystem(
212 const GURL
& origin
, fileapi::FileSystemType type
) {
213 SandboxFileSystemTestHelper
* file_system
=
214 new SandboxFileSystemTestHelper(origin
, type
);
216 file_system
->SetUp(file_system_context_
.get());
220 ObfuscatedFileUtil
* ofu() {
221 return static_cast<ObfuscatedFileUtil
*>(sandbox_file_system_
.file_util());
224 const base::FilePath
& test_directory() const {
225 return data_dir_
.path();
228 const GURL
& origin() const {
232 fileapi::FileSystemType
type() const {
236 std::string
type_string() const {
237 return GetTypeString(type_
);
240 int64
ComputeTotalFileSize() {
241 return sandbox_file_system_
.ComputeCurrentOriginUsage() -
242 sandbox_file_system_
.ComputeCurrentDirectoryDatabaseUsage();
245 void GetUsageFromQuotaManager() {
248 AsyncFileTestHelper::GetUsageAndQuota(quota_manager_
.get(),
250 sandbox_file_system_
.type(),
253 EXPECT_EQ(quota::kQuotaStatusOk
, quota_status_
);
256 void RevokeUsageCache() {
257 quota_manager_
->ResetUsageTracker(sandbox_file_system_
.storage_type());
258 usage_cache()->Delete(sandbox_file_system_
.GetUsageCachePath());
261 int64
SizeByQuotaUtil() {
262 return sandbox_file_system_
.GetCachedOriginUsage();
265 int64
SizeInUsageFile() {
266 base::RunLoop().RunUntilIdle();
268 return usage_cache()->GetUsage(
269 sandbox_file_system_
.GetUsageCachePath(), &usage
) ? usage
: -1;
272 bool PathExists(const FileSystemURL
& url
) {
273 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
274 base::PlatformFileInfo file_info
;
275 base::FilePath platform_path
;
276 base::PlatformFileError error
= ofu()->GetFileInfo(
277 context
.get(), url
, &file_info
, &platform_path
);
278 return error
== base::PLATFORM_FILE_OK
;
281 bool DirectoryExists(const FileSystemURL
& url
) {
282 return AsyncFileTestHelper::DirectoryExists(file_system_context(), url
);
285 int64
usage() const { return usage_
; }
286 FileSystemUsageCache
* usage_cache() {
287 return sandbox_file_system_
.usage_cache();
290 FileSystemURL
CreateURLFromUTF8(const std::string
& path
) {
291 return sandbox_file_system_
.CreateURLFromUTF8(path
);
294 int64
PathCost(const FileSystemURL
& url
) {
295 return ObfuscatedFileUtil::ComputeFilePathCost(url
.path());
298 FileSystemURL
CreateURL(const base::FilePath
& path
) {
299 return sandbox_file_system_
.CreateURL(path
);
302 void CheckFileAndCloseHandle(
303 const FileSystemURL
& url
, base::PlatformFile file_handle
) {
304 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
305 base::FilePath local_path
;
306 EXPECT_EQ(base::PLATFORM_FILE_OK
, ofu()->GetLocalFilePath(
307 context
.get(), url
, &local_path
));
309 base::PlatformFileInfo file_info0
;
310 base::FilePath data_path
;
311 EXPECT_EQ(base::PLATFORM_FILE_OK
, ofu()->GetFileInfo(
312 context
.get(), url
, &file_info0
, &data_path
));
313 EXPECT_EQ(data_path
, local_path
);
314 EXPECT_TRUE(FileExists(data_path
));
315 EXPECT_EQ(0, GetSize(data_path
));
317 const char data
[] = "test data";
318 const int length
= arraysize(data
) - 1;
320 if (base::kInvalidPlatformFileValue
== file_handle
) {
322 base::PlatformFileError error
;
323 file_handle
= base::CreatePlatformFile(
325 base::PLATFORM_FILE_OPEN
| base::PLATFORM_FILE_WRITE
,
328 ASSERT_NE(base::kInvalidPlatformFileValue
, file_handle
);
329 ASSERT_EQ(base::PLATFORM_FILE_OK
, error
);
330 EXPECT_FALSE(created
);
332 ASSERT_EQ(length
, base::WritePlatformFile(file_handle
, 0, data
, length
));
333 EXPECT_TRUE(base::ClosePlatformFile(file_handle
));
335 base::PlatformFileInfo file_info1
;
336 EXPECT_EQ(length
, GetSize(data_path
));
337 context
.reset(NewContext(NULL
));
338 EXPECT_EQ(base::PLATFORM_FILE_OK
, ofu()->GetFileInfo(
339 context
.get(), url
, &file_info1
, &data_path
));
340 EXPECT_EQ(data_path
, local_path
);
342 EXPECT_FALSE(file_info0
.is_directory
);
343 EXPECT_FALSE(file_info1
.is_directory
);
344 EXPECT_FALSE(file_info0
.is_symbolic_link
);
345 EXPECT_FALSE(file_info1
.is_symbolic_link
);
346 EXPECT_EQ(0, file_info0
.size
);
347 EXPECT_EQ(length
, file_info1
.size
);
348 EXPECT_LE(file_info0
.last_modified
, file_info1
.last_modified
);
350 context
.reset(NewContext(NULL
));
351 EXPECT_EQ(base::PLATFORM_FILE_OK
, ofu()->Truncate(
352 context
.get(), url
, length
* 2));
353 EXPECT_EQ(length
* 2, GetSize(data_path
));
355 context
.reset(NewContext(NULL
));
356 EXPECT_EQ(base::PLATFORM_FILE_OK
, ofu()->Truncate(
357 context
.get(), url
, 0));
358 EXPECT_EQ(0, GetSize(data_path
));
361 void ValidateTestDirectory(
362 const FileSystemURL
& root_url
,
363 const std::set
<base::FilePath::StringType
>& files
,
364 const std::set
<base::FilePath::StringType
>& directories
) {
365 scoped_ptr
<FileSystemOperationContext
> context
;
366 std::set
<base::FilePath::StringType
>::const_iterator iter
;
367 for (iter
= files
.begin(); iter
!= files
.end(); ++iter
) {
369 context
.reset(NewContext(NULL
));
370 ASSERT_EQ(base::PLATFORM_FILE_OK
,
371 ofu()->EnsureFileExists(
372 context
.get(), FileSystemURLAppend(root_url
, *iter
),
374 ASSERT_FALSE(created
);
376 for (iter
= directories
.begin(); iter
!= directories
.end(); ++iter
) {
377 context
.reset(NewContext(NULL
));
378 EXPECT_TRUE(DirectoryExists(
379 FileSystemURLAppend(root_url
, *iter
)));
383 class UsageVerifyHelper
{
385 UsageVerifyHelper(scoped_ptr
<FileSystemOperationContext
> context
,
386 SandboxFileSystemTestHelper
* file_system
,
387 int64 expected_usage
)
388 : context_(context
.Pass()),
389 sandbox_file_system_(file_system
),
390 expected_usage_(expected_usage
) {}
392 ~UsageVerifyHelper() {
393 base::RunLoop().RunUntilIdle();
397 FileSystemOperationContext
* context() {
398 return context_
.get();
403 ASSERT_EQ(expected_usage_
,
404 sandbox_file_system_
->GetCachedOriginUsage());
407 scoped_ptr
<FileSystemOperationContext
> context_
;
408 SandboxFileSystemTestHelper
* sandbox_file_system_
;
409 int64 expected_usage_
;
412 scoped_ptr
<UsageVerifyHelper
> AllowUsageIncrease(int64 requested_growth
) {
413 int64 usage
= sandbox_file_system_
.GetCachedOriginUsage();
414 return scoped_ptr
<UsageVerifyHelper
>(new UsageVerifyHelper(
415 LimitedContext(requested_growth
),
416 &sandbox_file_system_
, usage
+ requested_growth
));
419 scoped_ptr
<UsageVerifyHelper
> DisallowUsageIncrease(int64 requested_growth
) {
420 int64 usage
= sandbox_file_system_
.GetCachedOriginUsage();
421 return scoped_ptr
<UsageVerifyHelper
>(new UsageVerifyHelper(
422 LimitedContext(requested_growth
- 1), &sandbox_file_system_
, usage
));
425 void FillTestDirectory(
426 const FileSystemURL
& root_url
,
427 std::set
<base::FilePath::StringType
>* files
,
428 std::set
<base::FilePath::StringType
>* directories
) {
429 scoped_ptr
<FileSystemOperationContext
> context
;
430 std::vector
<DirectoryEntry
> entries
;
431 EXPECT_EQ(base::PLATFORM_FILE_OK
,
432 AsyncFileTestHelper::ReadDirectory(
433 file_system_context(), root_url
, &entries
));
434 EXPECT_EQ(0UL, entries
.size());
437 files
->insert(FILE_PATH_LITERAL("first"));
438 files
->insert(FILE_PATH_LITERAL("second"));
439 files
->insert(FILE_PATH_LITERAL("third"));
440 directories
->clear();
441 directories
->insert(FILE_PATH_LITERAL("fourth"));
442 directories
->insert(FILE_PATH_LITERAL("fifth"));
443 directories
->insert(FILE_PATH_LITERAL("sixth"));
444 std::set
<base::FilePath::StringType
>::iterator iter
;
445 for (iter
= files
->begin(); iter
!= files
->end(); ++iter
) {
446 bool created
= false;
447 context
.reset(NewContext(NULL
));
448 ASSERT_EQ(base::PLATFORM_FILE_OK
,
449 ofu()->EnsureFileExists(
451 FileSystemURLAppend(root_url
, *iter
),
453 ASSERT_TRUE(created
);
455 for (iter
= directories
->begin(); iter
!= directories
->end(); ++iter
) {
456 bool exclusive
= true;
457 bool recursive
= false;
458 context
.reset(NewContext(NULL
));
459 EXPECT_EQ(base::PLATFORM_FILE_OK
,
460 ofu()->CreateDirectory(
462 FileSystemURLAppend(root_url
, *iter
),
463 exclusive
, recursive
));
465 ValidateTestDirectory(root_url
, *files
, *directories
);
468 void TestReadDirectoryHelper(const FileSystemURL
& root_url
) {
469 std::set
<base::FilePath::StringType
> files
;
470 std::set
<base::FilePath::StringType
> directories
;
471 FillTestDirectory(root_url
, &files
, &directories
);
473 scoped_ptr
<FileSystemOperationContext
> context
;
474 std::vector
<DirectoryEntry
> entries
;
475 context
.reset(NewContext(NULL
));
476 EXPECT_EQ(base::PLATFORM_FILE_OK
,
477 AsyncFileTestHelper::ReadDirectory(
478 file_system_context(), root_url
, &entries
));
479 std::vector
<DirectoryEntry
>::iterator entry_iter
;
480 EXPECT_EQ(files
.size() + directories
.size(), entries
.size());
481 EXPECT_TRUE(change_observer()->HasNoChange());
482 for (entry_iter
= entries
.begin(); entry_iter
!= entries
.end();
484 const DirectoryEntry
& entry
= *entry_iter
;
485 std::set
<base::FilePath::StringType
>::iterator iter
=
486 files
.find(entry
.name
);
487 if (iter
!= files
.end()) {
488 EXPECT_FALSE(entry
.is_directory
);
492 iter
= directories
.find(entry
.name
);
493 EXPECT_FALSE(directories
.end() == iter
);
494 EXPECT_TRUE(entry
.is_directory
);
495 directories
.erase(iter
);
499 void TestTouchHelper(const FileSystemURL
& url
, bool is_file
) {
500 base::Time last_access_time
= base::Time::Now();
501 base::Time last_modified_time
= base::Time::Now();
503 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
504 EXPECT_EQ(base::PLATFORM_FILE_OK
,
506 context
.get(), url
, last_access_time
, last_modified_time
));
507 // Currently we fire no change notifications for Touch.
508 EXPECT_TRUE(change_observer()->HasNoChange());
509 base::FilePath local_path
;
510 base::PlatformFileInfo file_info
;
511 context
.reset(NewContext(NULL
));
512 EXPECT_EQ(base::PLATFORM_FILE_OK
, ofu()->GetFileInfo(
513 context
.get(), url
, &file_info
, &local_path
));
514 // We compare as time_t here to lower our resolution, to avoid false
515 // negatives caused by conversion to the local filesystem's native
516 // representation and back.
517 EXPECT_EQ(file_info
.last_modified
.ToTimeT(), last_modified_time
.ToTimeT());
519 context
.reset(NewContext(NULL
));
520 last_modified_time
+= base::TimeDelta::FromHours(1);
521 last_access_time
+= base::TimeDelta::FromHours(14);
522 EXPECT_EQ(base::PLATFORM_FILE_OK
,
524 context
.get(), url
, last_access_time
, last_modified_time
));
525 EXPECT_TRUE(change_observer()->HasNoChange());
526 context
.reset(NewContext(NULL
));
527 EXPECT_EQ(base::PLATFORM_FILE_OK
, ofu()->GetFileInfo(
528 context
.get(), url
, &file_info
, &local_path
));
529 EXPECT_EQ(file_info
.last_modified
.ToTimeT(), last_modified_time
.ToTimeT());
530 if (is_file
) // Directories in OFU don't support atime.
531 EXPECT_EQ(file_info
.last_accessed
.ToTimeT(), last_access_time
.ToTimeT());
534 void TestCopyInForeignFileHelper(bool overwrite
) {
535 base::ScopedTempDir source_dir
;
536 ASSERT_TRUE(source_dir
.CreateUniqueTempDir());
537 base::FilePath root_file_path
= source_dir
.path();
538 base::FilePath src_file_path
= root_file_path
.AppendASCII("file_name");
539 FileSystemURL dest_url
= CreateURLFromUTF8("new file");
540 int64 src_file_length
= 87;
542 base::PlatformFileError error_code
;
543 bool created
= false;
544 int file_flags
= base::PLATFORM_FILE_CREATE
| base::PLATFORM_FILE_WRITE
;
545 base::PlatformFile file_handle
=
546 base::CreatePlatformFile(
547 src_file_path
, file_flags
, &created
, &error_code
);
548 EXPECT_TRUE(created
);
549 ASSERT_EQ(base::PLATFORM_FILE_OK
, error_code
);
550 ASSERT_NE(base::kInvalidPlatformFileValue
, file_handle
);
551 ASSERT_TRUE(base::TruncatePlatformFile(file_handle
, src_file_length
));
552 EXPECT_TRUE(base::ClosePlatformFile(file_handle
));
554 scoped_ptr
<FileSystemOperationContext
> context
;
557 context
.reset(NewContext(NULL
));
558 EXPECT_EQ(base::PLATFORM_FILE_OK
,
559 ofu()->EnsureFileExists(context
.get(), dest_url
, &created
));
560 EXPECT_TRUE(created
);
562 // We must have observed one (and only one) create_file_count.
563 EXPECT_EQ(1, change_observer()->get_and_reset_create_file_count());
564 EXPECT_TRUE(change_observer()->HasNoChange());
567 const int64 path_cost
=
568 ObfuscatedFileUtil::ComputeFilePathCost(dest_url
.path());
570 // Verify that file creation requires sufficient quota for the path.
571 context
.reset(NewContext(NULL
));
572 context
->set_allowed_bytes_growth(path_cost
+ src_file_length
- 1);
573 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE
,
574 ofu()->CopyInForeignFile(context
.get(),
575 src_file_path
, dest_url
));
578 context
.reset(NewContext(NULL
));
579 context
->set_allowed_bytes_growth(path_cost
+ src_file_length
);
580 EXPECT_EQ(base::PLATFORM_FILE_OK
,
581 ofu()->CopyInForeignFile(context
.get(),
582 src_file_path
, dest_url
));
584 EXPECT_TRUE(PathExists(dest_url
));
585 EXPECT_FALSE(DirectoryExists(dest_url
));
587 context
.reset(NewContext(NULL
));
588 base::PlatformFileInfo file_info
;
589 base::FilePath data_path
;
590 EXPECT_EQ(base::PLATFORM_FILE_OK
, ofu()->GetFileInfo(
591 context
.get(), dest_url
, &file_info
, &data_path
));
592 EXPECT_NE(data_path
, src_file_path
);
593 EXPECT_TRUE(FileExists(data_path
));
594 EXPECT_EQ(src_file_length
, GetSize(data_path
));
596 EXPECT_EQ(base::PLATFORM_FILE_OK
,
597 ofu()->DeleteFile(context
.get(), dest_url
));
600 void ClearTimestamp(const FileSystemURL
& url
) {
601 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
602 EXPECT_EQ(base::PLATFORM_FILE_OK
,
603 ofu()->Touch(context
.get(), url
, base::Time(), base::Time()));
604 EXPECT_EQ(base::Time(), GetModifiedTime(url
));
607 base::Time
GetModifiedTime(const FileSystemURL
& url
) {
608 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
609 base::FilePath data_path
;
610 base::PlatformFileInfo file_info
;
611 context
.reset(NewContext(NULL
));
612 EXPECT_EQ(base::PLATFORM_FILE_OK
,
613 ofu()->GetFileInfo(context
.get(), url
, &file_info
, &data_path
));
614 EXPECT_TRUE(change_observer()->HasNoChange());
615 return file_info
.last_modified
;
618 void TestDirectoryTimestampHelper(const FileSystemURL
& base_dir
,
621 scoped_ptr
<FileSystemOperationContext
> context
;
622 const FileSystemURL
src_dir_url(
623 FileSystemURLAppendUTF8(base_dir
, "foo_dir"));
624 const FileSystemURL
dest_dir_url(
625 FileSystemURLAppendUTF8(base_dir
, "bar_dir"));
627 const FileSystemURL
src_file_url(
628 FileSystemURLAppendUTF8(src_dir_url
, "hoge"));
629 const FileSystemURL
dest_file_url(
630 FileSystemURLAppendUTF8(dest_dir_url
, "fuga"));
632 context
.reset(NewContext(NULL
));
633 EXPECT_EQ(base::PLATFORM_FILE_OK
,
634 ofu()->CreateDirectory(context
.get(), src_dir_url
, true, true));
635 context
.reset(NewContext(NULL
));
636 EXPECT_EQ(base::PLATFORM_FILE_OK
,
637 ofu()->CreateDirectory(context
.get(), dest_dir_url
, true, true));
639 bool created
= false;
640 context
.reset(NewContext(NULL
));
641 EXPECT_EQ(base::PLATFORM_FILE_OK
,
642 ofu()->EnsureFileExists(context
.get(), src_file_url
, &created
));
644 context
.reset(NewContext(NULL
));
645 EXPECT_EQ(base::PLATFORM_FILE_OK
,
646 ofu()->EnsureFileExists(context
.get(),
647 dest_file_url
, &created
));
650 ClearTimestamp(src_dir_url
);
651 ClearTimestamp(dest_dir_url
);
652 context
.reset(NewContext(NULL
));
653 EXPECT_EQ(base::PLATFORM_FILE_OK
,
654 ofu()->CopyOrMoveFile(context
.get(),
655 src_file_url
, dest_file_url
,
656 FileSystemOperation::OPTION_NONE
,
659 EXPECT_EQ(base::Time(), GetModifiedTime(src_dir_url
));
661 EXPECT_NE(base::Time(), GetModifiedTime(src_dir_url
));
662 EXPECT_NE(base::Time(), GetModifiedTime(dest_dir_url
));
665 int64
ComputeCurrentUsage() {
666 return sandbox_file_system_
.ComputeCurrentOriginUsage() -
667 sandbox_file_system_
.ComputeCurrentDirectoryDatabaseUsage();
670 FileSystemContext
* file_system_context() {
671 return sandbox_file_system_
.file_system_context();
674 const base::FilePath
& data_dir_path() const {
675 return data_dir_
.path();
679 base::ScopedTempDir data_dir_
;
680 base::MessageLoop message_loop_
;
681 scoped_refptr
<quota::MockSpecialStoragePolicy
> storage_policy_
;
682 scoped_refptr
<quota::QuotaManager
> quota_manager_
;
683 scoped_refptr
<FileSystemContext
> file_system_context_
;
685 fileapi::FileSystemType type_
;
686 base::WeakPtrFactory
<ObfuscatedFileUtilTest
> weak_factory_
;
687 SandboxFileSystemTestHelper sandbox_file_system_
;
688 quota::QuotaStatusCode quota_status_
;
690 MockFileChangeObserver change_observer_
;
691 ChangeObserverList change_observers_
;
694 DISALLOW_COPY_AND_ASSIGN(ObfuscatedFileUtilTest
);
697 TEST_F(ObfuscatedFileUtilTest
, TestCreateAndDeleteFile
) {
698 base::PlatformFile file_handle
= base::kInvalidPlatformFileValue
;
700 FileSystemURL url
= CreateURLFromUTF8("fake/file");
701 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
702 int file_flags
= base::PLATFORM_FILE_CREATE
| base::PLATFORM_FILE_WRITE
;
704 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND
,
706 context
.get(), url
, file_flags
, &file_handle
,
709 context
.reset(NewContext(NULL
));
710 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND
,
711 ofu()->DeleteFile(context
.get(), url
));
713 url
= CreateURLFromUTF8("test file");
715 EXPECT_TRUE(change_observer()->HasNoChange());
717 // Verify that file creation requires sufficient quota for the path.
718 context
.reset(NewContext(NULL
));
719 context
->set_allowed_bytes_growth(
720 ObfuscatedFileUtil::ComputeFilePathCost(url
.path()) - 1);
721 ASSERT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE
,
723 context
.get(), url
, file_flags
, &file_handle
, &created
));
725 context
.reset(NewContext(NULL
));
726 context
->set_allowed_bytes_growth(
727 ObfuscatedFileUtil::ComputeFilePathCost(url
.path()));
728 ASSERT_EQ(base::PLATFORM_FILE_OK
,
730 context
.get(), url
, file_flags
, &file_handle
, &created
));
731 ASSERT_TRUE(created
);
732 EXPECT_EQ(1, change_observer()->get_and_reset_create_file_count());
733 EXPECT_NE(base::kInvalidPlatformFileValue
, file_handle
);
735 CheckFileAndCloseHandle(url
, file_handle
);
737 context
.reset(NewContext(NULL
));
738 base::FilePath local_path
;
739 EXPECT_EQ(base::PLATFORM_FILE_OK
, ofu()->GetLocalFilePath(
740 context
.get(), url
, &local_path
));
741 EXPECT_TRUE(base::PathExists(local_path
));
743 // Verify that deleting a file isn't stopped by zero quota, and that it frees
744 // up quote from its path.
745 context
.reset(NewContext(NULL
));
746 context
->set_allowed_bytes_growth(0);
747 EXPECT_EQ(base::PLATFORM_FILE_OK
,
748 ofu()->DeleteFile(context
.get(), url
));
749 EXPECT_EQ(1, change_observer()->get_and_reset_remove_file_count());
750 EXPECT_FALSE(base::PathExists(local_path
));
751 EXPECT_EQ(ObfuscatedFileUtil::ComputeFilePathCost(url
.path()),
752 context
->allowed_bytes_growth());
754 context
.reset(NewContext(NULL
));
755 bool exclusive
= true;
756 bool recursive
= true;
757 FileSystemURL directory_url
= CreateURLFromUTF8(
758 "series/of/directories");
759 url
= FileSystemURLAppendUTF8(directory_url
, "file name");
760 EXPECT_EQ(base::PLATFORM_FILE_OK
, ofu()->CreateDirectory(
761 context
.get(), directory_url
, exclusive
, recursive
));
762 // The oepration created 3 directories recursively.
763 EXPECT_EQ(3, change_observer()->get_and_reset_create_directory_count());
765 context
.reset(NewContext(NULL
));
766 file_handle
= base::kInvalidPlatformFileValue
;
767 ASSERT_EQ(base::PLATFORM_FILE_OK
,
769 context
.get(), url
, file_flags
, &file_handle
, &created
));
770 ASSERT_TRUE(created
);
771 EXPECT_EQ(1, change_observer()->get_and_reset_create_file_count());
772 EXPECT_NE(base::kInvalidPlatformFileValue
, file_handle
);
774 CheckFileAndCloseHandle(url
, file_handle
);
776 context
.reset(NewContext(NULL
));
777 EXPECT_EQ(base::PLATFORM_FILE_OK
, ofu()->GetLocalFilePath(
778 context
.get(), url
, &local_path
));
779 EXPECT_TRUE(base::PathExists(local_path
));
781 context
.reset(NewContext(NULL
));
782 EXPECT_EQ(base::PLATFORM_FILE_OK
,
783 ofu()->DeleteFile(context
.get(), url
));
784 EXPECT_EQ(1, change_observer()->get_and_reset_remove_file_count());
785 EXPECT_FALSE(base::PathExists(local_path
));
787 // Make sure we have no unexpected changes.
788 EXPECT_TRUE(change_observer()->HasNoChange());
791 TEST_F(ObfuscatedFileUtilTest
, TestTruncate
) {
792 bool created
= false;
793 FileSystemURL url
= CreateURLFromUTF8("file");
794 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
796 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND
,
797 ofu()->Truncate(context
.get(), url
, 4));
799 context
.reset(NewContext(NULL
));
800 ASSERT_EQ(base::PLATFORM_FILE_OK
,
801 ofu()->EnsureFileExists(context
.get(), url
, &created
));
802 ASSERT_TRUE(created
);
803 EXPECT_EQ(1, change_observer()->get_and_reset_create_file_count());
805 context
.reset(NewContext(NULL
));
806 base::FilePath local_path
;
807 EXPECT_EQ(base::PLATFORM_FILE_OK
, ofu()->GetLocalFilePath(
808 context
.get(), url
, &local_path
));
809 EXPECT_EQ(0, GetSize(local_path
));
811 context
.reset(NewContext(NULL
));
812 EXPECT_EQ(base::PLATFORM_FILE_OK
, ofu()->Truncate(
813 context
.get(), url
, 10));
814 EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count());
815 EXPECT_EQ(10, GetSize(local_path
));
817 context
.reset(NewContext(NULL
));
818 EXPECT_EQ(base::PLATFORM_FILE_OK
, ofu()->Truncate(
819 context
.get(), url
, 1));
820 EXPECT_EQ(1, GetSize(local_path
));
821 EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count());
823 EXPECT_FALSE(DirectoryExists(url
));
824 EXPECT_TRUE(PathExists(url
));
826 // Make sure we have no unexpected changes.
827 EXPECT_TRUE(change_observer()->HasNoChange());
830 TEST_F(ObfuscatedFileUtilTest
, TestQuotaOnTruncation
) {
831 bool created
= false;
832 FileSystemURL url
= CreateURLFromUTF8("file");
834 ASSERT_EQ(base::PLATFORM_FILE_OK
,
835 ofu()->EnsureFileExists(
836 AllowUsageIncrease(PathCost(url
))->context(),
838 ASSERT_TRUE(created
);
839 ASSERT_EQ(0, ComputeTotalFileSize());
841 ASSERT_EQ(base::PLATFORM_FILE_OK
,
843 AllowUsageIncrease(1020)->context(),
845 ASSERT_EQ(1020, ComputeTotalFileSize());
847 ASSERT_EQ(base::PLATFORM_FILE_OK
,
849 AllowUsageIncrease(-1020)->context(),
851 ASSERT_EQ(0, ComputeTotalFileSize());
853 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE
,
855 DisallowUsageIncrease(1021)->context(),
857 ASSERT_EQ(0, ComputeTotalFileSize());
859 EXPECT_EQ(base::PLATFORM_FILE_OK
,
861 AllowUsageIncrease(1020)->context(),
863 ASSERT_EQ(1020, ComputeTotalFileSize());
865 EXPECT_EQ(base::PLATFORM_FILE_OK
,
867 AllowUsageIncrease(0)->context(),
869 ASSERT_EQ(1020, ComputeTotalFileSize());
873 scoped_ptr
<UsageVerifyHelper
> helper
= AllowUsageIncrease(-1);
874 helper
->context()->set_allowed_bytes_growth(
875 helper
->context()->allowed_bytes_growth() - 1);
876 EXPECT_EQ(base::PLATFORM_FILE_OK
,
877 ofu()->Truncate(helper
->context(), url
, 1019));
878 ASSERT_EQ(1019, ComputeTotalFileSize());
881 // Delete backing file to make following truncation fail.
882 base::FilePath local_path
;
883 ASSERT_EQ(base::PLATFORM_FILE_OK
,
884 ofu()->GetLocalFilePath(
885 UnlimitedContext().get(),
887 ASSERT_FALSE(local_path
.empty());
888 ASSERT_TRUE(base::DeleteFile(local_path
, false));
890 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND
,
892 LimitedContext(1234).get(),
894 ASSERT_EQ(0, ComputeTotalFileSize());
897 TEST_F(ObfuscatedFileUtilTest
, TestEnsureFileExists
) {
898 FileSystemURL url
= CreateURLFromUTF8("fake/file");
899 bool created
= false;
900 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
901 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND
,
902 ofu()->EnsureFileExists(
903 context
.get(), url
, &created
));
904 EXPECT_TRUE(change_observer()->HasNoChange());
906 // Verify that file creation requires sufficient quota for the path.
907 context
.reset(NewContext(NULL
));
908 url
= CreateURLFromUTF8("test file");
910 context
->set_allowed_bytes_growth(
911 ObfuscatedFileUtil::ComputeFilePathCost(url
.path()) - 1);
912 ASSERT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE
,
913 ofu()->EnsureFileExists(context
.get(), url
, &created
));
914 ASSERT_FALSE(created
);
915 EXPECT_TRUE(change_observer()->HasNoChange());
917 context
.reset(NewContext(NULL
));
918 context
->set_allowed_bytes_growth(
919 ObfuscatedFileUtil::ComputeFilePathCost(url
.path()));
920 ASSERT_EQ(base::PLATFORM_FILE_OK
,
921 ofu()->EnsureFileExists(context
.get(), url
, &created
));
922 ASSERT_TRUE(created
);
923 EXPECT_EQ(1, change_observer()->get_and_reset_create_file_count());
925 CheckFileAndCloseHandle(url
, base::kInvalidPlatformFileValue
);
927 context
.reset(NewContext(NULL
));
928 ASSERT_EQ(base::PLATFORM_FILE_OK
,
929 ofu()->EnsureFileExists(context
.get(), url
, &created
));
930 ASSERT_FALSE(created
);
931 EXPECT_TRUE(change_observer()->HasNoChange());
933 // Also test in a subdirectory.
934 url
= CreateURLFromUTF8("path/to/file.txt");
935 context
.reset(NewContext(NULL
));
936 bool exclusive
= true;
937 bool recursive
= true;
938 EXPECT_EQ(base::PLATFORM_FILE_OK
, ofu()->CreateDirectory(
940 FileSystemURLDirName(url
),
941 exclusive
, recursive
));
942 // 2 directories: path/ and path/to.
943 EXPECT_EQ(2, change_observer()->get_and_reset_create_directory_count());
945 context
.reset(NewContext(NULL
));
946 ASSERT_EQ(base::PLATFORM_FILE_OK
,
947 ofu()->EnsureFileExists(context
.get(), url
, &created
));
948 ASSERT_TRUE(created
);
949 EXPECT_FALSE(DirectoryExists(url
));
950 EXPECT_TRUE(PathExists(url
));
951 EXPECT_TRUE(change_observer()->HasNoChange());
954 TEST_F(ObfuscatedFileUtilTest
, TestDirectoryOps
) {
955 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
957 bool exclusive
= false;
958 bool recursive
= false;
959 FileSystemURL url
= CreateURLFromUTF8("foo/bar");
960 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND
, ofu()->CreateDirectory(
961 context
.get(), url
, exclusive
, recursive
));
963 context
.reset(NewContext(NULL
));
964 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND
,
965 ofu()->DeleteDirectory(context
.get(), url
));
967 FileSystemURL root
= CreateURLFromUTF8(std::string());
968 EXPECT_FALSE(DirectoryExists(url
));
969 EXPECT_FALSE(PathExists(url
));
970 context
.reset(NewContext(NULL
));
971 EXPECT_TRUE(ofu()->IsDirectoryEmpty(context
.get(), root
));
973 context
.reset(NewContext(NULL
));
976 EXPECT_EQ(base::PLATFORM_FILE_OK
, ofu()->CreateDirectory(
977 context
.get(), url
, exclusive
, recursive
));
978 EXPECT_EQ(2, change_observer()->get_and_reset_create_directory_count());
980 EXPECT_TRUE(DirectoryExists(url
));
981 EXPECT_TRUE(PathExists(url
));
983 context
.reset(NewContext(NULL
));
984 EXPECT_FALSE(ofu()->IsDirectoryEmpty(context
.get(), root
));
985 EXPECT_TRUE(DirectoryExists(FileSystemURLDirName(url
)));
987 context
.reset(NewContext(NULL
));
988 EXPECT_FALSE(ofu()->IsDirectoryEmpty(context
.get(),
989 FileSystemURLDirName(url
)));
991 // Can't remove a non-empty directory.
992 context
.reset(NewContext(NULL
));
993 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_EMPTY
,
994 ofu()->DeleteDirectory(context
.get(),
995 FileSystemURLDirName(url
)));
996 EXPECT_TRUE(change_observer()->HasNoChange());
998 base::PlatformFileInfo file_info
;
999 base::FilePath local_path
;
1000 EXPECT_EQ(base::PLATFORM_FILE_OK
, ofu()->GetFileInfo(
1001 context
.get(), url
, &file_info
, &local_path
));
1002 EXPECT_TRUE(local_path
.empty());
1003 EXPECT_TRUE(file_info
.is_directory
);
1004 EXPECT_FALSE(file_info
.is_symbolic_link
);
1006 // Same create again should succeed, since exclusive is false.
1007 context
.reset(NewContext(NULL
));
1008 EXPECT_EQ(base::PLATFORM_FILE_OK
, ofu()->CreateDirectory(
1009 context
.get(), url
, exclusive
, recursive
));
1010 EXPECT_TRUE(change_observer()->HasNoChange());
1014 context
.reset(NewContext(NULL
));
1015 EXPECT_EQ(base::PLATFORM_FILE_ERROR_EXISTS
, ofu()->CreateDirectory(
1016 context
.get(), url
, exclusive
, recursive
));
1017 EXPECT_TRUE(change_observer()->HasNoChange());
1019 // Verify that deleting a directory isn't stopped by zero quota, and that it
1020 // frees up quota from its path.
1021 context
.reset(NewContext(NULL
));
1022 context
->set_allowed_bytes_growth(0);
1023 EXPECT_EQ(base::PLATFORM_FILE_OK
, ofu()->DeleteDirectory(context
.get(), url
));
1024 EXPECT_EQ(1, change_observer()->get_and_reset_remove_directory_count());
1025 EXPECT_EQ(ObfuscatedFileUtil::ComputeFilePathCost(url
.path()),
1026 context
->allowed_bytes_growth());
1028 url
= CreateURLFromUTF8("foo/bop");
1030 EXPECT_FALSE(DirectoryExists(url
));
1031 EXPECT_FALSE(PathExists(url
));
1033 context
.reset(NewContext(NULL
));
1034 EXPECT_TRUE(ofu()->IsDirectoryEmpty(context
.get(), url
));
1035 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND
, ofu()->GetFileInfo(
1036 context
.get(), url
, &file_info
, &local_path
));
1038 // Verify that file creation requires sufficient quota for the path.
1041 context
.reset(NewContext(NULL
));
1042 context
->set_allowed_bytes_growth(
1043 ObfuscatedFileUtil::ComputeFilePathCost(url
.path()) - 1);
1044 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE
, ofu()->CreateDirectory(
1045 context
.get(), url
, exclusive
, recursive
));
1046 EXPECT_TRUE(change_observer()->HasNoChange());
1048 context
.reset(NewContext(NULL
));
1049 context
->set_allowed_bytes_growth(
1050 ObfuscatedFileUtil::ComputeFilePathCost(url
.path()));
1051 EXPECT_EQ(base::PLATFORM_FILE_OK
, ofu()->CreateDirectory(
1052 context
.get(), url
, exclusive
, recursive
));
1053 EXPECT_EQ(1, change_observer()->get_and_reset_create_directory_count());
1055 EXPECT_TRUE(DirectoryExists(url
));
1056 EXPECT_TRUE(PathExists(url
));
1060 context
.reset(NewContext(NULL
));
1061 EXPECT_EQ(base::PLATFORM_FILE_ERROR_EXISTS
, ofu()->CreateDirectory(
1062 context
.get(), url
, exclusive
, recursive
));
1063 EXPECT_TRUE(change_observer()->HasNoChange());
1067 url
= CreateURLFromUTF8("foo");
1068 context
.reset(NewContext(NULL
));
1069 EXPECT_EQ(base::PLATFORM_FILE_ERROR_EXISTS
, ofu()->CreateDirectory(
1070 context
.get(), url
, exclusive
, recursive
));
1071 EXPECT_TRUE(change_observer()->HasNoChange());
1073 url
= CreateURLFromUTF8("blah");
1075 EXPECT_FALSE(DirectoryExists(url
));
1076 EXPECT_FALSE(PathExists(url
));
1080 context
.reset(NewContext(NULL
));
1081 EXPECT_EQ(base::PLATFORM_FILE_OK
, ofu()->CreateDirectory(
1082 context
.get(), url
, exclusive
, recursive
));
1083 EXPECT_EQ(1, change_observer()->get_and_reset_create_directory_count());
1085 EXPECT_TRUE(DirectoryExists(url
));
1086 EXPECT_TRUE(PathExists(url
));
1090 context
.reset(NewContext(NULL
));
1091 EXPECT_EQ(base::PLATFORM_FILE_ERROR_EXISTS
, ofu()->CreateDirectory(
1092 context
.get(), url
, exclusive
, recursive
));
1093 EXPECT_TRUE(change_observer()->HasNoChange());
1096 TEST_F(ObfuscatedFileUtilTest
, TestReadDirectory
) {
1097 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
1098 bool exclusive
= true;
1099 bool recursive
= true;
1100 FileSystemURL url
= CreateURLFromUTF8("directory/to/use");
1101 EXPECT_EQ(base::PLATFORM_FILE_OK
, ofu()->CreateDirectory(
1102 context
.get(), url
, exclusive
, recursive
));
1103 TestReadDirectoryHelper(url
);
1106 TEST_F(ObfuscatedFileUtilTest
, TestReadRootWithSlash
) {
1107 TestReadDirectoryHelper(CreateURLFromUTF8(std::string()));
1110 TEST_F(ObfuscatedFileUtilTest
, TestReadRootWithEmptyString
) {
1111 TestReadDirectoryHelper(CreateURLFromUTF8("/"));
1114 TEST_F(ObfuscatedFileUtilTest
, TestReadDirectoryOnFile
) {
1115 FileSystemURL url
= CreateURLFromUTF8("file");
1116 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
1118 bool created
= false;
1119 ASSERT_EQ(base::PLATFORM_FILE_OK
,
1120 ofu()->EnsureFileExists(context
.get(), url
, &created
));
1121 ASSERT_TRUE(created
);
1123 std::vector
<DirectoryEntry
> entries
;
1124 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY
,
1125 AsyncFileTestHelper::ReadDirectory(
1126 file_system_context(), url
, &entries
));
1128 EXPECT_TRUE(ofu()->IsDirectoryEmpty(context
.get(), url
));
1131 TEST_F(ObfuscatedFileUtilTest
, TestTouch
) {
1132 FileSystemURL url
= CreateURLFromUTF8("file");
1133 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
1135 base::Time last_access_time
= base::Time::Now();
1136 base::Time last_modified_time
= base::Time::Now();
1138 // It's not there yet.
1139 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND
,
1141 context
.get(), url
, last_access_time
, last_modified_time
));
1143 // OK, now create it.
1144 context
.reset(NewContext(NULL
));
1145 bool created
= false;
1146 ASSERT_EQ(base::PLATFORM_FILE_OK
,
1147 ofu()->EnsureFileExists(context
.get(), url
, &created
));
1148 ASSERT_TRUE(created
);
1149 TestTouchHelper(url
, true);
1151 // Now test a directory:
1152 context
.reset(NewContext(NULL
));
1153 bool exclusive
= true;
1154 bool recursive
= false;
1155 url
= CreateURLFromUTF8("dir");
1156 ASSERT_EQ(base::PLATFORM_FILE_OK
, ofu()->CreateDirectory(context
.get(),
1157 url
, exclusive
, recursive
));
1158 TestTouchHelper(url
, false);
1161 TEST_F(ObfuscatedFileUtilTest
, TestPathQuotas
) {
1162 FileSystemURL url
= CreateURLFromUTF8("fake/file");
1163 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
1165 url
= CreateURLFromUTF8("file name");
1166 context
->set_allowed_bytes_growth(5);
1167 bool created
= false;
1168 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE
,
1169 ofu()->EnsureFileExists(context
.get(), url
, &created
));
1170 EXPECT_FALSE(created
);
1171 context
->set_allowed_bytes_growth(1024);
1172 EXPECT_EQ(base::PLATFORM_FILE_OK
,
1173 ofu()->EnsureFileExists(context
.get(), url
, &created
));
1174 EXPECT_TRUE(created
);
1175 int64 path_cost
= ObfuscatedFileUtil::ComputeFilePathCost(url
.path());
1176 EXPECT_EQ(1024 - path_cost
, context
->allowed_bytes_growth());
1178 context
->set_allowed_bytes_growth(1024);
1179 bool exclusive
= true;
1180 bool recursive
= true;
1181 url
= CreateURLFromUTF8("directory/to/use");
1182 std::vector
<base::FilePath::StringType
> components
;
1183 url
.path().GetComponents(&components
);
1185 typedef std::vector
<base::FilePath::StringType
>::iterator iterator
;
1186 for (iterator iter
= components
.begin();
1187 iter
!= components
.end(); ++iter
) {
1188 path_cost
+= ObfuscatedFileUtil::ComputeFilePathCost(
1189 base::FilePath(*iter
));
1191 context
.reset(NewContext(NULL
));
1192 context
->set_allowed_bytes_growth(1024);
1193 EXPECT_EQ(base::PLATFORM_FILE_OK
, ofu()->CreateDirectory(
1194 context
.get(), url
, exclusive
, recursive
));
1195 EXPECT_EQ(1024 - path_cost
, context
->allowed_bytes_growth());
1198 TEST_F(ObfuscatedFileUtilTest
, TestCopyOrMoveFileNotFound
) {
1199 FileSystemURL source_url
= CreateURLFromUTF8("path0.txt");
1200 FileSystemURL dest_url
= CreateURLFromUTF8("path1.txt");
1201 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
1203 bool is_copy_not_move
= false;
1204 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND
,
1205 ofu()->CopyOrMoveFile(context
.get(), source_url
, dest_url
,
1206 FileSystemOperation::OPTION_NONE
,
1208 EXPECT_TRUE(change_observer()->HasNoChange());
1209 context
.reset(NewContext(NULL
));
1210 is_copy_not_move
= true;
1211 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND
,
1212 ofu()->CopyOrMoveFile(context
.get(), source_url
, dest_url
,
1213 FileSystemOperation::OPTION_NONE
,
1215 EXPECT_TRUE(change_observer()->HasNoChange());
1216 source_url
= CreateURLFromUTF8("dir/dir/file");
1217 bool exclusive
= true;
1218 bool recursive
= true;
1219 context
.reset(NewContext(NULL
));
1220 ASSERT_EQ(base::PLATFORM_FILE_OK
, ofu()->CreateDirectory(
1222 FileSystemURLDirName(source_url
),
1223 exclusive
, recursive
));
1224 EXPECT_EQ(2, change_observer()->get_and_reset_create_directory_count());
1225 is_copy_not_move
= false;
1226 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND
,
1227 ofu()->CopyOrMoveFile(context
.get(), source_url
, dest_url
,
1228 FileSystemOperation::OPTION_NONE
,
1230 EXPECT_TRUE(change_observer()->HasNoChange());
1231 context
.reset(NewContext(NULL
));
1232 is_copy_not_move
= true;
1233 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND
,
1234 ofu()->CopyOrMoveFile(context
.get(), source_url
, dest_url
,
1235 FileSystemOperation::OPTION_NONE
,
1237 EXPECT_TRUE(change_observer()->HasNoChange());
1240 TEST_F(ObfuscatedFileUtilTest
, TestCopyOrMoveFileSuccess
) {
1241 const int64 kSourceLength
= 5;
1242 const int64 kDestLength
= 50;
1244 for (size_t i
= 0; i
< arraysize(kCopyMoveTestCases
); ++i
) {
1245 SCOPED_TRACE(testing::Message() << "kCopyMoveTestCase " << i
);
1246 const CopyMoveTestCaseRecord
& test_case
= kCopyMoveTestCases
[i
];
1247 SCOPED_TRACE(testing::Message() << "\t is_copy_not_move " <<
1248 test_case
.is_copy_not_move
);
1249 SCOPED_TRACE(testing::Message() << "\t source_path " <<
1250 test_case
.source_path
);
1251 SCOPED_TRACE(testing::Message() << "\t dest_path " <<
1252 test_case
.dest_path
);
1253 SCOPED_TRACE(testing::Message() << "\t cause_overwrite " <<
1254 test_case
.cause_overwrite
);
1255 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
1257 bool exclusive
= false;
1258 bool recursive
= true;
1259 FileSystemURL source_url
= CreateURLFromUTF8(test_case
.source_path
);
1260 FileSystemURL dest_url
= CreateURLFromUTF8(test_case
.dest_path
);
1262 context
.reset(NewContext(NULL
));
1263 ASSERT_EQ(base::PLATFORM_FILE_OK
, ofu()->CreateDirectory(
1265 FileSystemURLDirName(source_url
),
1266 exclusive
, recursive
));
1267 context
.reset(NewContext(NULL
));
1268 ASSERT_EQ(base::PLATFORM_FILE_OK
, ofu()->CreateDirectory(
1270 FileSystemURLDirName(dest_url
),
1271 exclusive
, recursive
));
1273 bool created
= false;
1274 context
.reset(NewContext(NULL
));
1275 ASSERT_EQ(base::PLATFORM_FILE_OK
,
1276 ofu()->EnsureFileExists(context
.get(), source_url
, &created
));
1277 ASSERT_TRUE(created
);
1278 context
.reset(NewContext(NULL
));
1279 ASSERT_EQ(base::PLATFORM_FILE_OK
,
1280 ofu()->Truncate(context
.get(), source_url
, kSourceLength
));
1282 if (test_case
.cause_overwrite
) {
1283 context
.reset(NewContext(NULL
));
1285 ASSERT_EQ(base::PLATFORM_FILE_OK
,
1286 ofu()->EnsureFileExists(context
.get(), dest_url
, &created
));
1287 ASSERT_TRUE(created
);
1288 context
.reset(NewContext(NULL
));
1289 ASSERT_EQ(base::PLATFORM_FILE_OK
,
1290 ofu()->Truncate(context
.get(), dest_url
, kDestLength
));
1293 context
.reset(NewContext(NULL
));
1294 EXPECT_EQ(base::PLATFORM_FILE_OK
, ofu()->CopyOrMoveFile(
1295 context
.get(), source_url
, dest_url
, FileSystemOperation::OPTION_NONE
,
1296 test_case
.is_copy_not_move
));
1298 if (test_case
.is_copy_not_move
) {
1299 base::PlatformFileInfo file_info
;
1300 base::FilePath local_path
;
1301 context
.reset(NewContext(NULL
));
1302 EXPECT_EQ(base::PLATFORM_FILE_OK
, ofu()->GetFileInfo(
1303 context
.get(), source_url
, &file_info
, &local_path
));
1304 EXPECT_EQ(kSourceLength
, file_info
.size
);
1305 EXPECT_EQ(base::PLATFORM_FILE_OK
,
1306 ofu()->DeleteFile(context
.get(), source_url
));
1308 base::PlatformFileInfo file_info
;
1309 base::FilePath local_path
;
1310 context
.reset(NewContext(NULL
));
1311 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND
, ofu()->GetFileInfo(
1312 context
.get(), source_url
, &file_info
, &local_path
));
1314 base::PlatformFileInfo file_info
;
1315 base::FilePath local_path
;
1316 EXPECT_EQ(base::PLATFORM_FILE_OK
, ofu()->GetFileInfo(
1317 context
.get(), dest_url
, &file_info
, &local_path
));
1318 EXPECT_EQ(kSourceLength
, file_info
.size
);
1320 EXPECT_EQ(base::PLATFORM_FILE_OK
,
1321 ofu()->DeleteFile(context
.get(), dest_url
));
1325 TEST_F(ObfuscatedFileUtilTest
, TestCopyPathQuotas
) {
1326 FileSystemURL src_url
= CreateURLFromUTF8("src path");
1327 FileSystemURL dest_url
= CreateURLFromUTF8("destination path");
1328 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
1329 bool created
= false;
1330 ASSERT_EQ(base::PLATFORM_FILE_OK
, ofu()->EnsureFileExists(
1331 context
.get(), src_url
, &created
));
1333 bool is_copy
= true;
1334 // Copy, no overwrite.
1335 context
->set_allowed_bytes_growth(
1336 ObfuscatedFileUtil::ComputeFilePathCost(dest_url
.path()) - 1);
1337 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE
,
1338 ofu()->CopyOrMoveFile(
1340 src_url
, dest_url
, FileSystemOperation::OPTION_NONE
, is_copy
));
1341 context
.reset(NewContext(NULL
));
1342 context
->set_allowed_bytes_growth(
1343 ObfuscatedFileUtil::ComputeFilePathCost(dest_url
.path()));
1344 EXPECT_EQ(base::PLATFORM_FILE_OK
,
1345 ofu()->CopyOrMoveFile(
1347 src_url
, dest_url
, FileSystemOperation::OPTION_NONE
, is_copy
));
1349 // Copy, with overwrite.
1350 context
.reset(NewContext(NULL
));
1351 context
->set_allowed_bytes_growth(0);
1352 EXPECT_EQ(base::PLATFORM_FILE_OK
,
1353 ofu()->CopyOrMoveFile(
1355 src_url
, dest_url
, FileSystemOperation::OPTION_NONE
, is_copy
));
1358 TEST_F(ObfuscatedFileUtilTest
, TestMovePathQuotasWithRename
) {
1359 FileSystemURL src_url
= CreateURLFromUTF8("src path");
1360 FileSystemURL dest_url
= CreateURLFromUTF8("destination path");
1361 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
1362 bool created
= false;
1363 ASSERT_EQ(base::PLATFORM_FILE_OK
, ofu()->EnsureFileExists(
1364 context
.get(), src_url
, &created
));
1366 bool is_copy
= false;
1367 // Move, rename, no overwrite.
1368 context
.reset(NewContext(NULL
));
1369 context
->set_allowed_bytes_growth(
1370 ObfuscatedFileUtil::ComputeFilePathCost(dest_url
.path()) -
1371 ObfuscatedFileUtil::ComputeFilePathCost(src_url
.path()) - 1);
1372 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE
,
1373 ofu()->CopyOrMoveFile(
1375 src_url
, dest_url
, FileSystemOperation::OPTION_NONE
, is_copy
));
1376 context
.reset(NewContext(NULL
));
1377 context
->set_allowed_bytes_growth(
1378 ObfuscatedFileUtil::ComputeFilePathCost(dest_url
.path()) -
1379 ObfuscatedFileUtil::ComputeFilePathCost(src_url
.path()));
1380 EXPECT_EQ(base::PLATFORM_FILE_OK
,
1381 ofu()->CopyOrMoveFile(
1383 src_url
, dest_url
, FileSystemOperation::OPTION_NONE
, is_copy
));
1385 context
.reset(NewContext(NULL
));
1386 ASSERT_EQ(base::PLATFORM_FILE_OK
, ofu()->EnsureFileExists(
1387 context
.get(), src_url
, &created
));
1389 // Move, rename, with overwrite.
1390 context
.reset(NewContext(NULL
));
1391 context
->set_allowed_bytes_growth(0);
1392 EXPECT_EQ(base::PLATFORM_FILE_OK
,
1393 ofu()->CopyOrMoveFile(
1395 src_url
, dest_url
, FileSystemOperation::OPTION_NONE
, is_copy
));
1398 TEST_F(ObfuscatedFileUtilTest
, TestMovePathQuotasWithoutRename
) {
1399 FileSystemURL src_url
= CreateURLFromUTF8("src path");
1400 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
1401 bool created
= false;
1402 ASSERT_EQ(base::PLATFORM_FILE_OK
, ofu()->EnsureFileExists(
1403 context
.get(), src_url
, &created
));
1405 bool exclusive
= true;
1406 bool recursive
= false;
1407 FileSystemURL dir_url
= CreateURLFromUTF8("directory path");
1408 context
.reset(NewContext(NULL
));
1409 ASSERT_EQ(base::PLATFORM_FILE_OK
, ofu()->CreateDirectory(
1410 context
.get(), dir_url
, exclusive
, recursive
));
1412 FileSystemURL dest_url
= FileSystemURLAppend(
1413 dir_url
, src_url
.path().value());
1415 bool is_copy
= false;
1416 int64 allowed_bytes_growth
= -1000; // Over quota, this should still work.
1417 // Move, no rename, no overwrite.
1418 context
.reset(NewContext(NULL
));
1419 context
->set_allowed_bytes_growth(allowed_bytes_growth
);
1420 EXPECT_EQ(base::PLATFORM_FILE_OK
,
1421 ofu()->CopyOrMoveFile(
1423 src_url
, dest_url
, FileSystemOperation::OPTION_NONE
, is_copy
));
1424 EXPECT_EQ(allowed_bytes_growth
, context
->allowed_bytes_growth());
1426 // Move, no rename, with overwrite.
1427 context
.reset(NewContext(NULL
));
1428 ASSERT_EQ(base::PLATFORM_FILE_OK
, ofu()->EnsureFileExists(
1429 context
.get(), src_url
, &created
));
1430 context
.reset(NewContext(NULL
));
1431 context
->set_allowed_bytes_growth(allowed_bytes_growth
);
1432 EXPECT_EQ(base::PLATFORM_FILE_OK
,
1433 ofu()->CopyOrMoveFile(
1435 src_url
, dest_url
, FileSystemOperation::OPTION_NONE
, is_copy
));
1437 allowed_bytes_growth
+
1438 ObfuscatedFileUtil::ComputeFilePathCost(src_url
.path()),
1439 context
->allowed_bytes_growth());
1442 TEST_F(ObfuscatedFileUtilTest
, TestCopyInForeignFile
) {
1443 TestCopyInForeignFileHelper(false /* overwrite */);
1444 TestCopyInForeignFileHelper(true /* overwrite */);
1447 TEST_F(ObfuscatedFileUtilTest
, TestEnumerator
) {
1448 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
1449 FileSystemURL src_url
= CreateURLFromUTF8("source dir");
1450 bool exclusive
= true;
1451 bool recursive
= false;
1452 ASSERT_EQ(base::PLATFORM_FILE_OK
, ofu()->CreateDirectory(
1453 context
.get(), src_url
, exclusive
, recursive
));
1455 std::set
<base::FilePath::StringType
> files
;
1456 std::set
<base::FilePath::StringType
> directories
;
1457 FillTestDirectory(src_url
, &files
, &directories
);
1459 FileSystemURL dest_url
= CreateURLFromUTF8("destination dir");
1461 EXPECT_FALSE(DirectoryExists(dest_url
));
1462 ASSERT_EQ(base::PLATFORM_FILE_OK
,
1463 AsyncFileTestHelper::Copy(
1464 file_system_context(), src_url
, dest_url
));
1466 ValidateTestDirectory(dest_url
, files
, directories
);
1467 EXPECT_TRUE(DirectoryExists(src_url
));
1468 EXPECT_TRUE(DirectoryExists(dest_url
));
1470 ASSERT_EQ(base::PLATFORM_FILE_OK
,
1471 AsyncFileTestHelper::Remove(
1472 file_system_context(), dest_url
, recursive
));
1473 EXPECT_FALSE(DirectoryExists(dest_url
));
1476 TEST_F(ObfuscatedFileUtilTest
, TestOriginEnumerator
) {
1477 scoped_ptr
<ObfuscatedFileUtil::AbstractOriginEnumerator
>
1478 enumerator(ofu()->CreateOriginEnumerator());
1479 // The test helper starts out with a single filesystem.
1480 EXPECT_TRUE(enumerator
.get());
1481 EXPECT_EQ(origin(), enumerator
->Next());
1482 ASSERT_TRUE(type() == kFileSystemTypeTemporary
);
1483 EXPECT_TRUE(HasFileSystemType(enumerator
.get(), kFileSystemTypeTemporary
));
1484 EXPECT_FALSE(HasFileSystemType(enumerator
.get(), kFileSystemTypePersistent
));
1485 EXPECT_EQ(GURL(), enumerator
->Next());
1486 EXPECT_FALSE(HasFileSystemType(enumerator
.get(), kFileSystemTypeTemporary
));
1487 EXPECT_FALSE(HasFileSystemType(enumerator
.get(), kFileSystemTypePersistent
));
1489 std::set
<GURL
> origins_expected
;
1490 origins_expected
.insert(origin());
1492 for (size_t i
= 0; i
< arraysize(kOriginEnumerationTestRecords
); ++i
) {
1493 SCOPED_TRACE(testing::Message() <<
1494 "Validating kOriginEnumerationTestRecords " << i
);
1495 const OriginEnumerationTestRecord
& record
=
1496 kOriginEnumerationTestRecords
[i
];
1497 GURL
origin_url(record
.origin_url
);
1498 origins_expected
.insert(origin_url
);
1499 if (record
.has_temporary
) {
1500 scoped_ptr
<SandboxFileSystemTestHelper
> file_system(
1501 NewFileSystem(origin_url
, kFileSystemTypeTemporary
));
1502 scoped_ptr
<FileSystemOperationContext
> context(
1503 NewContext(file_system
.get()));
1504 bool created
= false;
1505 ASSERT_EQ(base::PLATFORM_FILE_OK
,
1506 ofu()->EnsureFileExists(
1508 file_system
->CreateURLFromUTF8("file"),
1510 EXPECT_TRUE(created
);
1512 if (record
.has_persistent
) {
1513 scoped_ptr
<SandboxFileSystemTestHelper
> file_system(
1514 NewFileSystem(origin_url
, kFileSystemTypePersistent
));
1515 scoped_ptr
<FileSystemOperationContext
> context(
1516 NewContext(file_system
.get()));
1517 bool created
= false;
1518 ASSERT_EQ(base::PLATFORM_FILE_OK
,
1519 ofu()->EnsureFileExists(
1521 file_system
->CreateURLFromUTF8("file"),
1523 EXPECT_TRUE(created
);
1526 enumerator
.reset(ofu()->CreateOriginEnumerator());
1527 EXPECT_TRUE(enumerator
.get());
1528 std::set
<GURL
> origins_found
;
1530 while (!(origin_url
= enumerator
->Next()).is_empty()) {
1531 origins_found
.insert(origin_url
);
1532 SCOPED_TRACE(testing::Message() << "Handling " << origin_url
.spec());
1534 for (size_t i
= 0; !found
&& i
< arraysize(kOriginEnumerationTestRecords
);
1536 const OriginEnumerationTestRecord
& record
=
1537 kOriginEnumerationTestRecords
[i
];
1538 if (GURL(record
.origin_url
) != origin_url
)
1541 EXPECT_EQ(record
.has_temporary
,
1542 HasFileSystemType(enumerator
.get(), kFileSystemTypeTemporary
));
1543 EXPECT_EQ(record
.has_persistent
,
1544 HasFileSystemType(enumerator
.get(), kFileSystemTypePersistent
));
1546 // Deal with the default filesystem created by the test helper.
1547 if (!found
&& origin_url
== origin()) {
1548 ASSERT_TRUE(type() == kFileSystemTypeTemporary
);
1549 EXPECT_TRUE(HasFileSystemType(enumerator
.get(),
1550 kFileSystemTypeTemporary
));
1551 EXPECT_FALSE(HasFileSystemType(enumerator
.get(),
1552 kFileSystemTypePersistent
));
1558 std::set
<GURL
> diff
;
1559 std::set_symmetric_difference(origins_expected
.begin(),
1560 origins_expected
.end(), origins_found
.begin(), origins_found
.end(),
1561 inserter(diff
, diff
.begin()));
1562 EXPECT_TRUE(diff
.empty());
1565 TEST_F(ObfuscatedFileUtilTest
, TestRevokeUsageCache
) {
1566 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
1568 int64 expected_quota
= 0;
1570 for (size_t i
= 0; i
< test::kRegularTestCaseSize
; ++i
) {
1571 SCOPED_TRACE(testing::Message() << "Creating kRegularTestCase " << i
);
1572 const test::TestCaseRecord
& test_case
= test::kRegularTestCases
[i
];
1573 base::FilePath
file_path(test_case
.path
);
1574 expected_quota
+= ObfuscatedFileUtil::ComputeFilePathCost(file_path
);
1575 if (test_case
.is_directory
) {
1576 bool exclusive
= true;
1577 bool recursive
= false;
1578 ASSERT_EQ(base::PLATFORM_FILE_OK
,
1579 ofu()->CreateDirectory(context
.get(), CreateURL(file_path
),
1580 exclusive
, recursive
));
1582 bool created
= false;
1583 ASSERT_EQ(base::PLATFORM_FILE_OK
,
1584 ofu()->EnsureFileExists(context
.get(), CreateURL(file_path
),
1586 ASSERT_TRUE(created
);
1587 ASSERT_EQ(base::PLATFORM_FILE_OK
,
1588 ofu()->Truncate(context
.get(),
1589 CreateURL(file_path
),
1590 test_case
.data_file_size
));
1591 expected_quota
+= test_case
.data_file_size
;
1595 // Usually raw size in usage cache and the usage returned by QuotaUtil
1597 EXPECT_EQ(expected_quota
, SizeInUsageFile());
1598 EXPECT_EQ(expected_quota
, SizeByQuotaUtil());
1601 EXPECT_EQ(-1, SizeInUsageFile());
1602 EXPECT_EQ(expected_quota
, SizeByQuotaUtil());
1604 // This should reconstruct the cache.
1605 GetUsageFromQuotaManager();
1606 EXPECT_EQ(expected_quota
, SizeInUsageFile());
1607 EXPECT_EQ(expected_quota
, SizeByQuotaUtil());
1608 EXPECT_EQ(expected_quota
, usage());
1611 TEST_F(ObfuscatedFileUtilTest
, TestInconsistency
) {
1612 const FileSystemURL kPath1
= CreateURLFromUTF8("hoge");
1613 const FileSystemURL kPath2
= CreateURLFromUTF8("fuga");
1615 scoped_ptr
<FileSystemOperationContext
> context
;
1616 base::PlatformFile file
;
1617 base::PlatformFileInfo file_info
;
1618 base::FilePath data_path
;
1619 bool created
= false;
1621 // Create a non-empty file.
1622 context
.reset(NewContext(NULL
));
1623 EXPECT_EQ(base::PLATFORM_FILE_OK
,
1624 ofu()->EnsureFileExists(context
.get(), kPath1
, &created
));
1625 EXPECT_TRUE(created
);
1626 context
.reset(NewContext(NULL
));
1627 EXPECT_EQ(base::PLATFORM_FILE_OK
,
1628 ofu()->Truncate(context
.get(), kPath1
, 10));
1629 context
.reset(NewContext(NULL
));
1630 EXPECT_EQ(base::PLATFORM_FILE_OK
,
1632 context
.get(), kPath1
, &file_info
, &data_path
));
1633 EXPECT_EQ(10, file_info
.size
);
1635 // Destroy database to make inconsistency between database and filesystem.
1636 ofu()->DestroyDirectoryDatabase(origin(), type_string());
1638 // Try to get file info of broken file.
1639 EXPECT_FALSE(PathExists(kPath1
));
1640 context
.reset(NewContext(NULL
));
1641 EXPECT_EQ(base::PLATFORM_FILE_OK
,
1642 ofu()->EnsureFileExists(context
.get(), kPath1
, &created
));
1643 EXPECT_TRUE(created
);
1644 context
.reset(NewContext(NULL
));
1645 EXPECT_EQ(base::PLATFORM_FILE_OK
,
1647 context
.get(), kPath1
, &file_info
, &data_path
));
1648 EXPECT_EQ(0, file_info
.size
);
1650 // Make another broken file to |kPath2|.
1651 context
.reset(NewContext(NULL
));
1652 EXPECT_EQ(base::PLATFORM_FILE_OK
,
1653 ofu()->EnsureFileExists(context
.get(), kPath2
, &created
));
1654 EXPECT_TRUE(created
);
1657 ofu()->DestroyDirectoryDatabase(origin(), type_string());
1659 // Repair broken |kPath1|.
1660 context
.reset(NewContext(NULL
));
1661 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND
,
1662 ofu()->Touch(context
.get(), kPath1
, base::Time::Now(),
1663 base::Time::Now()));
1664 EXPECT_EQ(base::PLATFORM_FILE_OK
,
1665 ofu()->EnsureFileExists(context
.get(), kPath1
, &created
));
1666 EXPECT_TRUE(created
);
1668 // Copy from sound |kPath1| to broken |kPath2|.
1669 context
.reset(NewContext(NULL
));
1670 EXPECT_EQ(base::PLATFORM_FILE_OK
,
1671 ofu()->CopyOrMoveFile(context
.get(), kPath1
, kPath2
,
1672 FileSystemOperation::OPTION_NONE
,
1675 ofu()->DestroyDirectoryDatabase(origin(), type_string());
1676 context
.reset(NewContext(NULL
));
1677 EXPECT_EQ(base::PLATFORM_FILE_OK
,
1678 ofu()->CreateOrOpen(
1679 context
.get(), kPath1
,
1680 base::PLATFORM_FILE_READ
| base::PLATFORM_FILE_CREATE
,
1682 EXPECT_TRUE(created
);
1683 EXPECT_TRUE(base::GetPlatformFileInfo(file
, &file_info
));
1684 EXPECT_EQ(0, file_info
.size
);
1685 EXPECT_TRUE(base::ClosePlatformFile(file
));
1688 TEST_F(ObfuscatedFileUtilTest
, TestIncompleteDirectoryReading
) {
1689 const FileSystemURL kPath
[] = {
1690 CreateURLFromUTF8("foo"),
1691 CreateURLFromUTF8("bar"),
1692 CreateURLFromUTF8("baz")
1694 const FileSystemURL empty_path
= CreateURL(base::FilePath());
1695 scoped_ptr
<FileSystemOperationContext
> context
;
1697 for (size_t i
= 0; i
< ARRAYSIZE_UNSAFE(kPath
); ++i
) {
1698 bool created
= false;
1699 context
.reset(NewContext(NULL
));
1700 EXPECT_EQ(base::PLATFORM_FILE_OK
,
1701 ofu()->EnsureFileExists(context
.get(), kPath
[i
], &created
));
1702 EXPECT_TRUE(created
);
1705 std::vector
<DirectoryEntry
> entries
;
1706 EXPECT_EQ(base::PLATFORM_FILE_OK
,
1707 AsyncFileTestHelper::ReadDirectory(
1708 file_system_context(), empty_path
, &entries
));
1709 EXPECT_EQ(3u, entries
.size());
1711 base::FilePath local_path
;
1712 EXPECT_EQ(base::PLATFORM_FILE_OK
,
1713 ofu()->GetLocalFilePath(context
.get(), kPath
[0], &local_path
));
1714 EXPECT_TRUE(base::DeleteFile(local_path
, false));
1717 EXPECT_EQ(base::PLATFORM_FILE_OK
,
1718 AsyncFileTestHelper::ReadDirectory(
1719 file_system_context(), empty_path
, &entries
));
1720 EXPECT_EQ(ARRAYSIZE_UNSAFE(kPath
) - 1, entries
.size());
1723 TEST_F(ObfuscatedFileUtilTest
, TestDirectoryTimestampForCreation
) {
1724 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
1725 const FileSystemURL dir_url
= CreateURLFromUTF8("foo_dir");
1727 // Create working directory.
1728 EXPECT_EQ(base::PLATFORM_FILE_OK
,
1729 ofu()->CreateDirectory(context
.get(), dir_url
, false, false));
1731 // EnsureFileExists, create case.
1732 FileSystemURL
url(FileSystemURLAppendUTF8(
1733 dir_url
, "EnsureFileExists_file"));
1734 bool created
= false;
1735 ClearTimestamp(dir_url
);
1736 context
.reset(NewContext(NULL
));
1737 EXPECT_EQ(base::PLATFORM_FILE_OK
,
1738 ofu()->EnsureFileExists(context
.get(), url
, &created
));
1739 EXPECT_TRUE(created
);
1740 EXPECT_NE(base::Time(), GetModifiedTime(dir_url
));
1744 ClearTimestamp(dir_url
);
1745 context
.reset(NewContext(NULL
));
1746 EXPECT_EQ(base::PLATFORM_FILE_OK
,
1747 ofu()->EnsureFileExists(context
.get(), url
, &created
));
1748 EXPECT_FALSE(created
);
1749 EXPECT_EQ(base::Time(), GetModifiedTime(dir_url
));
1752 url
= FileSystemURLAppendUTF8(dir_url
, "EnsureFileExists_dir");
1753 context
.reset(NewContext(NULL
));
1754 EXPECT_EQ(base::PLATFORM_FILE_OK
,
1755 ofu()->CreateDirectory(context
.get(), url
, false, false));
1757 ClearTimestamp(dir_url
);
1758 context
.reset(NewContext(NULL
));
1759 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_A_FILE
,
1760 ofu()->EnsureFileExists(context
.get(), url
, &created
));
1761 EXPECT_EQ(base::Time(), GetModifiedTime(dir_url
));
1763 // CreateOrOpen, create case.
1764 url
= FileSystemURLAppendUTF8(dir_url
, "CreateOrOpen_file");
1765 base::PlatformFile file_handle
= base::kInvalidPlatformFileValue
;
1767 ClearTimestamp(dir_url
);
1768 context
.reset(NewContext(NULL
));
1769 EXPECT_EQ(base::PLATFORM_FILE_OK
,
1770 ofu()->CreateOrOpen(
1772 base::PLATFORM_FILE_CREATE
| base::PLATFORM_FILE_WRITE
,
1773 &file_handle
, &created
));
1774 EXPECT_NE(base::kInvalidPlatformFileValue
, file_handle
);
1775 EXPECT_TRUE(created
);
1776 EXPECT_TRUE(base::ClosePlatformFile(file_handle
));
1777 EXPECT_NE(base::Time(), GetModifiedTime(dir_url
));
1780 file_handle
= base::kInvalidPlatformFileValue
;
1782 ClearTimestamp(dir_url
);
1783 context
.reset(NewContext(NULL
));
1784 EXPECT_EQ(base::PLATFORM_FILE_OK
,
1785 ofu()->CreateOrOpen(
1787 base::PLATFORM_FILE_OPEN
| base::PLATFORM_FILE_WRITE
,
1788 &file_handle
, &created
));
1789 EXPECT_NE(base::kInvalidPlatformFileValue
, file_handle
);
1790 EXPECT_FALSE(created
);
1791 EXPECT_TRUE(base::ClosePlatformFile(file_handle
));
1792 EXPECT_EQ(base::Time(), GetModifiedTime(dir_url
));
1795 file_handle
= base::kInvalidPlatformFileValue
;
1796 ClearTimestamp(dir_url
);
1797 context
.reset(NewContext(NULL
));
1798 EXPECT_EQ(base::PLATFORM_FILE_ERROR_EXISTS
,
1799 ofu()->CreateOrOpen(
1801 base::PLATFORM_FILE_CREATE
| base::PLATFORM_FILE_WRITE
,
1802 &file_handle
, &created
));
1803 EXPECT_EQ(base::kInvalidPlatformFileValue
, file_handle
);
1804 EXPECT_EQ(base::Time(), GetModifiedTime(dir_url
));
1806 // CreateDirectory, create case.
1807 // Creating CreateDirectory_dir and CreateDirectory_dir/subdir.
1808 url
= FileSystemURLAppendUTF8(dir_url
, "CreateDirectory_dir");
1809 FileSystemURL
subdir_url(FileSystemURLAppendUTF8(url
, "subdir"));
1810 ClearTimestamp(dir_url
);
1811 context
.reset(NewContext(NULL
));
1812 EXPECT_EQ(base::PLATFORM_FILE_OK
,
1813 ofu()->CreateDirectory(context
.get(), subdir_url
,
1814 true /* exclusive */, true /* recursive */));
1815 EXPECT_NE(base::Time(), GetModifiedTime(dir_url
));
1817 // create subdir case.
1818 // Creating CreateDirectory_dir/subdir2.
1819 subdir_url
= FileSystemURLAppendUTF8(url
, "subdir2");
1820 ClearTimestamp(dir_url
);
1821 ClearTimestamp(url
);
1822 context
.reset(NewContext(NULL
));
1823 EXPECT_EQ(base::PLATFORM_FILE_OK
,
1824 ofu()->CreateDirectory(context
.get(), subdir_url
,
1825 true /* exclusive */, true /* recursive */));
1826 EXPECT_EQ(base::Time(), GetModifiedTime(dir_url
));
1827 EXPECT_NE(base::Time(), GetModifiedTime(url
));
1830 url
= FileSystemURLAppendUTF8(dir_url
, "CreateDirectory_dir");
1831 ClearTimestamp(dir_url
);
1832 context
.reset(NewContext(NULL
));
1833 EXPECT_EQ(base::PLATFORM_FILE_ERROR_EXISTS
,
1834 ofu()->CreateDirectory(context
.get(), url
,
1835 true /* exclusive */, true /* recursive */));
1836 EXPECT_EQ(base::Time(), GetModifiedTime(dir_url
));
1838 // CopyInForeignFile, create case.
1839 url
= FileSystemURLAppendUTF8(dir_url
, "CopyInForeignFile_file");
1840 FileSystemURL src_path
= FileSystemURLAppendUTF8(
1841 dir_url
, "CopyInForeignFile_src_file");
1842 context
.reset(NewContext(NULL
));
1843 EXPECT_EQ(base::PLATFORM_FILE_OK
,
1844 ofu()->EnsureFileExists(context
.get(), src_path
, &created
));
1845 EXPECT_TRUE(created
);
1846 base::FilePath src_local_path
;
1847 context
.reset(NewContext(NULL
));
1848 EXPECT_EQ(base::PLATFORM_FILE_OK
,
1849 ofu()->GetLocalFilePath(context
.get(), src_path
, &src_local_path
));
1851 ClearTimestamp(dir_url
);
1852 context
.reset(NewContext(NULL
));
1853 EXPECT_EQ(base::PLATFORM_FILE_OK
,
1854 ofu()->CopyInForeignFile(context
.get(),
1857 EXPECT_NE(base::Time(), GetModifiedTime(dir_url
));
1860 TEST_F(ObfuscatedFileUtilTest
, TestDirectoryTimestampForDeletion
) {
1861 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
1862 const FileSystemURL dir_url
= CreateURLFromUTF8("foo_dir");
1864 // Create working directory.
1865 EXPECT_EQ(base::PLATFORM_FILE_OK
,
1866 ofu()->CreateDirectory(context
.get(), dir_url
, false, false));
1868 // DeleteFile, delete case.
1869 FileSystemURL url
= FileSystemURLAppendUTF8(
1870 dir_url
, "DeleteFile_file");
1871 bool created
= false;
1872 context
.reset(NewContext(NULL
));
1873 EXPECT_EQ(base::PLATFORM_FILE_OK
,
1874 ofu()->EnsureFileExists(context
.get(), url
, &created
));
1875 EXPECT_TRUE(created
);
1877 ClearTimestamp(dir_url
);
1878 context
.reset(NewContext(NULL
));
1879 EXPECT_EQ(base::PLATFORM_FILE_OK
,
1880 ofu()->DeleteFile(context
.get(), url
));
1881 EXPECT_NE(base::Time(), GetModifiedTime(dir_url
));
1884 ClearTimestamp(dir_url
);
1885 context
.reset(NewContext(NULL
));
1886 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND
,
1887 ofu()->DeleteFile(context
.get(), url
));
1888 EXPECT_EQ(base::Time(), GetModifiedTime(dir_url
));
1890 // DeleteDirectory, fail case.
1891 url
= FileSystemURLAppendUTF8(dir_url
, "DeleteDirectory_dir");
1892 FileSystemURL
file_path(FileSystemURLAppendUTF8(url
, "pakeratta"));
1893 context
.reset(NewContext(NULL
));
1894 EXPECT_EQ(base::PLATFORM_FILE_OK
,
1895 ofu()->CreateDirectory(context
.get(), url
, true, true));
1897 context
.reset(NewContext(NULL
));
1898 EXPECT_EQ(base::PLATFORM_FILE_OK
,
1899 ofu()->EnsureFileExists(context
.get(), file_path
, &created
));
1900 EXPECT_TRUE(created
);
1902 ClearTimestamp(dir_url
);
1903 context
.reset(NewContext(NULL
));
1904 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_EMPTY
,
1905 ofu()->DeleteDirectory(context
.get(), url
));
1906 EXPECT_EQ(base::Time(), GetModifiedTime(dir_url
));
1909 context
.reset(NewContext(NULL
));
1910 EXPECT_EQ(base::PLATFORM_FILE_OK
,
1911 ofu()->DeleteFile(context
.get(), file_path
));
1913 ClearTimestamp(dir_url
);
1914 context
.reset(NewContext(NULL
));
1915 EXPECT_EQ(base::PLATFORM_FILE_OK
, ofu()->DeleteDirectory(context
.get(), url
));
1916 EXPECT_NE(base::Time(), GetModifiedTime(dir_url
));
1919 TEST_F(ObfuscatedFileUtilTest
, TestDirectoryTimestampForCopyAndMove
) {
1920 TestDirectoryTimestampHelper(
1921 CreateURLFromUTF8("copy overwrite"), true, true);
1922 TestDirectoryTimestampHelper(
1923 CreateURLFromUTF8("copy non-overwrite"), true, false);
1924 TestDirectoryTimestampHelper(
1925 CreateURLFromUTF8("move overwrite"), false, true);
1926 TestDirectoryTimestampHelper(
1927 CreateURLFromUTF8("move non-overwrite"), false, false);
1930 TEST_F(ObfuscatedFileUtilTest
, TestFileEnumeratorTimestamp
) {
1931 FileSystemURL dir
= CreateURLFromUTF8("foo");
1932 FileSystemURL url1
= FileSystemURLAppendUTF8(dir
, "bar");
1933 FileSystemURL url2
= FileSystemURLAppendUTF8(dir
, "baz");
1935 scoped_ptr
<FileSystemOperationContext
> context(NewContext(NULL
));
1936 EXPECT_EQ(base::PLATFORM_FILE_OK
,
1937 ofu()->CreateDirectory(context
.get(), dir
, false, false));
1939 bool created
= false;
1940 context
.reset(NewContext(NULL
));
1941 EXPECT_EQ(base::PLATFORM_FILE_OK
,
1942 ofu()->EnsureFileExists(context
.get(), url1
, &created
));
1943 EXPECT_TRUE(created
);
1945 context
.reset(NewContext(NULL
));
1946 EXPECT_EQ(base::PLATFORM_FILE_OK
,
1947 ofu()->CreateDirectory(context
.get(), url2
, false, false));
1949 base::FilePath file_path
;
1950 context
.reset(NewContext(NULL
));
1951 EXPECT_EQ(base::PLATFORM_FILE_OK
,
1952 ofu()->GetLocalFilePath(context
.get(), url1
, &file_path
));
1953 EXPECT_FALSE(file_path
.empty());
1955 context
.reset(NewContext(NULL
));
1956 EXPECT_EQ(base::PLATFORM_FILE_OK
,
1957 ofu()->Touch(context
.get(), url1
,
1958 base::Time::Now() + base::TimeDelta::FromHours(1),
1961 context
.reset(NewContext(NULL
));
1962 scoped_ptr
<FileSystemFileUtil::AbstractFileEnumerator
> file_enum(
1963 ofu()->CreateFileEnumerator(context
.get(), dir
, false));
1966 base::FilePath file_path_each
;
1967 while (!(file_path_each
= file_enum
->Next()).empty()) {
1968 context
.reset(NewContext(NULL
));
1969 base::PlatformFileInfo file_info
;
1970 base::FilePath file_path
;
1971 EXPECT_EQ(base::PLATFORM_FILE_OK
,
1972 ofu()->GetFileInfo(context
.get(),
1973 FileSystemURL::CreateForTest(
1977 &file_info
, &file_path
));
1978 EXPECT_EQ(file_info
.is_directory
, file_enum
->IsDirectory());
1979 EXPECT_EQ(file_info
.last_modified
, file_enum
->LastModifiedTime());
1980 EXPECT_EQ(file_info
.size
, file_enum
->Size());
1983 EXPECT_EQ(2, count
);
1987 #if defined(OS_WIN) || defined(OS_ANDROID)
1988 #define MAYBE_TestQuotaOnCopyFile DISABLED_TestQuotaOnCopyFile
1990 #define MAYBE_TestQuotaOnCopyFile TestQuotaOnCopyFile
1992 TEST_F(ObfuscatedFileUtilTest
, MAYBE_TestQuotaOnCopyFile
) {
1993 FileSystemURL
from_file(CreateURLFromUTF8("fromfile"));
1994 FileSystemURL
obstacle_file(CreateURLFromUTF8("obstaclefile"));
1995 FileSystemURL
to_file1(CreateURLFromUTF8("tofile1"));
1996 FileSystemURL
to_file2(CreateURLFromUTF8("tofile2"));
1999 int64 expected_total_file_size
= 0;
2000 ASSERT_EQ(base::PLATFORM_FILE_OK
,
2001 ofu()->EnsureFileExists(
2002 AllowUsageIncrease(PathCost(from_file
))->context(),
2003 from_file
, &created
));
2004 ASSERT_TRUE(created
);
2005 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2007 ASSERT_EQ(base::PLATFORM_FILE_OK
,
2008 ofu()->EnsureFileExists(
2009 AllowUsageIncrease(PathCost(obstacle_file
))->context(),
2010 obstacle_file
, &created
));
2011 ASSERT_TRUE(created
);
2012 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2014 int64 from_file_size
= 1020;
2015 expected_total_file_size
+= from_file_size
;
2016 ASSERT_EQ(base::PLATFORM_FILE_OK
,
2018 AllowUsageIncrease(from_file_size
)->context(),
2019 from_file
, from_file_size
));
2020 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2022 int64 obstacle_file_size
= 1;
2023 expected_total_file_size
+= obstacle_file_size
;
2024 ASSERT_EQ(base::PLATFORM_FILE_OK
,
2026 AllowUsageIncrease(obstacle_file_size
)->context(),
2027 obstacle_file
, obstacle_file_size
));
2028 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2030 int64 to_file1_size
= from_file_size
;
2031 expected_total_file_size
+= to_file1_size
;
2032 ASSERT_EQ(base::PLATFORM_FILE_OK
,
2033 ofu()->CopyOrMoveFile(
2035 PathCost(to_file1
) + to_file1_size
)->context(),
2036 from_file
, to_file1
,
2037 FileSystemOperation::OPTION_NONE
,
2039 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2041 ASSERT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE
,
2042 ofu()->CopyOrMoveFile(
2043 DisallowUsageIncrease(
2044 PathCost(to_file2
) + from_file_size
)->context(),
2045 from_file
, to_file2
, FileSystemOperation::OPTION_NONE
,
2047 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2049 int64 old_obstacle_file_size
= obstacle_file_size
;
2050 obstacle_file_size
= from_file_size
;
2051 expected_total_file_size
+= obstacle_file_size
- old_obstacle_file_size
;
2052 ASSERT_EQ(base::PLATFORM_FILE_OK
,
2053 ofu()->CopyOrMoveFile(
2055 obstacle_file_size
- old_obstacle_file_size
)->context(),
2056 from_file
, obstacle_file
,
2057 FileSystemOperation::OPTION_NONE
,
2059 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2061 int64 old_from_file_size
= from_file_size
;
2062 from_file_size
= old_from_file_size
- 1;
2063 expected_total_file_size
+= from_file_size
- old_from_file_size
;
2064 ASSERT_EQ(base::PLATFORM_FILE_OK
,
2067 from_file_size
- old_from_file_size
)->context(),
2068 from_file
, from_file_size
));
2069 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2073 old_obstacle_file_size
= obstacle_file_size
;
2074 obstacle_file_size
= from_file_size
;
2075 expected_total_file_size
+= obstacle_file_size
- old_obstacle_file_size
;
2076 scoped_ptr
<UsageVerifyHelper
> helper
= AllowUsageIncrease(
2077 obstacle_file_size
- old_obstacle_file_size
);
2078 helper
->context()->set_allowed_bytes_growth(
2079 helper
->context()->allowed_bytes_growth() - 1);
2080 ASSERT_EQ(base::PLATFORM_FILE_OK
,
2081 ofu()->CopyOrMoveFile(
2083 from_file
, obstacle_file
,
2084 FileSystemOperation::OPTION_NONE
,
2086 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2090 TEST_F(ObfuscatedFileUtilTest
, TestQuotaOnMoveFile
) {
2091 FileSystemURL
from_file(CreateURLFromUTF8("fromfile"));
2092 FileSystemURL
obstacle_file(CreateURLFromUTF8("obstaclefile"));
2093 FileSystemURL
to_file(CreateURLFromUTF8("tofile"));
2096 int64 expected_total_file_size
= 0;
2097 ASSERT_EQ(base::PLATFORM_FILE_OK
,
2098 ofu()->EnsureFileExists(
2099 AllowUsageIncrease(PathCost(from_file
))->context(),
2100 from_file
, &created
));
2101 ASSERT_TRUE(created
);
2102 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2104 int64 from_file_size
= 1020;
2105 expected_total_file_size
+= from_file_size
;
2106 ASSERT_EQ(base::PLATFORM_FILE_OK
,
2108 AllowUsageIncrease(from_file_size
)->context(),
2109 from_file
, from_file_size
));
2110 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2112 int64 to_file_size ALLOW_UNUSED
= from_file_size
;
2114 ASSERT_EQ(base::PLATFORM_FILE_OK
,
2115 ofu()->CopyOrMoveFile(
2116 AllowUsageIncrease(-PathCost(from_file
) +
2117 PathCost(to_file
))->context(),
2119 FileSystemOperation::OPTION_NONE
,
2121 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2123 ASSERT_EQ(base::PLATFORM_FILE_OK
,
2124 ofu()->EnsureFileExists(
2125 AllowUsageIncrease(PathCost(from_file
))->context(),
2126 from_file
, &created
));
2127 ASSERT_TRUE(created
);
2128 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2130 ASSERT_EQ(base::PLATFORM_FILE_OK
,
2131 ofu()->EnsureFileExists(
2132 AllowUsageIncrease(PathCost(obstacle_file
))->context(),
2133 obstacle_file
, &created
));
2134 ASSERT_TRUE(created
);
2135 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2137 from_file_size
= 1020;
2138 expected_total_file_size
+= from_file_size
;
2139 ASSERT_EQ(base::PLATFORM_FILE_OK
,
2141 AllowUsageIncrease(from_file_size
)->context(),
2142 from_file
, from_file_size
));
2143 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2145 int64 obstacle_file_size
= 1;
2146 expected_total_file_size
+= obstacle_file_size
;
2147 ASSERT_EQ(base::PLATFORM_FILE_OK
,
2149 AllowUsageIncrease(1)->context(),
2150 obstacle_file
, obstacle_file_size
));
2151 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2153 int64 old_obstacle_file_size
= obstacle_file_size
;
2154 obstacle_file_size
= from_file_size
;
2156 expected_total_file_size
-= old_obstacle_file_size
;
2157 ASSERT_EQ(base::PLATFORM_FILE_OK
,
2158 ofu()->CopyOrMoveFile(
2160 -old_obstacle_file_size
- PathCost(from_file
))->context(),
2161 from_file
, obstacle_file
,
2162 FileSystemOperation::OPTION_NONE
,
2164 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2166 ASSERT_EQ(base::PLATFORM_FILE_OK
,
2167 ofu()->EnsureFileExists(
2168 AllowUsageIncrease(PathCost(from_file
))->context(),
2169 from_file
, &created
));
2170 ASSERT_TRUE(created
);
2171 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2173 from_file_size
= 10;
2174 expected_total_file_size
+= from_file_size
;
2175 ASSERT_EQ(base::PLATFORM_FILE_OK
,
2177 AllowUsageIncrease(from_file_size
)->context(),
2178 from_file
, from_file_size
));
2179 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2181 // quota exceeded even after operation
2182 old_obstacle_file_size
= obstacle_file_size
;
2183 obstacle_file_size
= from_file_size
;
2185 expected_total_file_size
-= old_obstacle_file_size
;
2186 scoped_ptr
<FileSystemOperationContext
> context
=
2187 LimitedContext(-old_obstacle_file_size
- PathCost(from_file
) - 1);
2188 ASSERT_EQ(base::PLATFORM_FILE_OK
,
2189 ofu()->CopyOrMoveFile(
2190 context
.get(), from_file
, obstacle_file
,
2191 FileSystemOperation::OPTION_NONE
,
2193 ASSERT_EQ(expected_total_file_size
, ComputeTotalFileSize());
2197 TEST_F(ObfuscatedFileUtilTest
, TestQuotaOnRemove
) {
2198 FileSystemURL
dir(CreateURLFromUTF8("dir"));
2199 FileSystemURL
file(CreateURLFromUTF8("file"));
2200 FileSystemURL
dfile1(CreateURLFromUTF8("dir/dfile1"));
2201 FileSystemURL
dfile2(CreateURLFromUTF8("dir/dfile2"));
2204 ASSERT_EQ(base::PLATFORM_FILE_OK
,
2205 ofu()->EnsureFileExists(
2206 AllowUsageIncrease(PathCost(file
))->context(),
2208 ASSERT_TRUE(created
);
2209 ASSERT_EQ(0, ComputeTotalFileSize());
2211 ASSERT_EQ(base::PLATFORM_FILE_OK
,
2212 ofu()->CreateDirectory(
2213 AllowUsageIncrease(PathCost(dir
))->context(),
2214 dir
, false, false));
2215 ASSERT_EQ(0, ComputeTotalFileSize());
2217 ASSERT_EQ(base::PLATFORM_FILE_OK
,
2218 ofu()->EnsureFileExists(
2219 AllowUsageIncrease(PathCost(dfile1
))->context(),
2221 ASSERT_TRUE(created
);
2222 ASSERT_EQ(0, ComputeTotalFileSize());
2224 ASSERT_EQ(base::PLATFORM_FILE_OK
,
2225 ofu()->EnsureFileExists(
2226 AllowUsageIncrease(PathCost(dfile2
))->context(),
2228 ASSERT_TRUE(created
);
2229 ASSERT_EQ(0, ComputeTotalFileSize());
2231 ASSERT_EQ(base::PLATFORM_FILE_OK
,
2233 AllowUsageIncrease(340)->context(),
2235 ASSERT_EQ(340, ComputeTotalFileSize());
2237 ASSERT_EQ(base::PLATFORM_FILE_OK
,
2239 AllowUsageIncrease(1020)->context(),
2241 ASSERT_EQ(1360, ComputeTotalFileSize());
2243 ASSERT_EQ(base::PLATFORM_FILE_OK
,
2245 AllowUsageIncrease(120)->context(),
2247 ASSERT_EQ(1480, ComputeTotalFileSize());
2249 ASSERT_EQ(base::PLATFORM_FILE_OK
,
2251 AllowUsageIncrease(-PathCost(file
) - 340)->context(),
2253 ASSERT_EQ(1140, ComputeTotalFileSize());
2255 ASSERT_EQ(base::PLATFORM_FILE_OK
,
2256 AsyncFileTestHelper::Remove(
2257 file_system_context(), dir
, true /* recursive */));
2258 ASSERT_EQ(0, ComputeTotalFileSize());
2261 TEST_F(ObfuscatedFileUtilTest
, TestQuotaOnOpen
) {
2262 FileSystemURL
file(CreateURLFromUTF8("file"));
2263 base::PlatformFile file_handle
;
2267 ASSERT_EQ(base::PLATFORM_FILE_OK
,
2268 ofu()->EnsureFileExists(
2269 AllowUsageIncrease(PathCost(file
))->context(),
2271 ASSERT_TRUE(created
);
2272 ASSERT_EQ(0, ComputeTotalFileSize());
2274 // Opening it, which shouldn't change the usage.
2275 ASSERT_EQ(base::PLATFORM_FILE_OK
,
2276 ofu()->CreateOrOpen(
2277 AllowUsageIncrease(0)->context(), file
,
2278 base::PLATFORM_FILE_OPEN
| base::PLATFORM_FILE_WRITE
,
2279 &file_handle
, &created
));
2280 ASSERT_EQ(0, ComputeTotalFileSize());
2281 EXPECT_TRUE(base::ClosePlatformFile(file_handle
));
2283 const int length
= 33;
2284 ASSERT_EQ(base::PLATFORM_FILE_OK
,
2286 AllowUsageIncrease(length
)->context(), file
, length
));
2287 ASSERT_EQ(length
, ComputeTotalFileSize());
2289 // Opening it with CREATE_ALWAYS flag, which should truncate the file size.
2290 ASSERT_EQ(base::PLATFORM_FILE_OK
,
2291 ofu()->CreateOrOpen(
2292 AllowUsageIncrease(-length
)->context(), file
,
2293 base::PLATFORM_FILE_CREATE_ALWAYS
| base::PLATFORM_FILE_WRITE
,
2294 &file_handle
, &created
));
2295 ASSERT_EQ(0, ComputeTotalFileSize());
2296 EXPECT_TRUE(base::ClosePlatformFile(file_handle
));
2298 // Extending the file again.
2299 ASSERT_EQ(base::PLATFORM_FILE_OK
,
2301 AllowUsageIncrease(length
)->context(), file
, length
));
2302 ASSERT_EQ(length
, ComputeTotalFileSize());
2304 // Opening it with TRUNCATED flag, which should truncate the file size.
2305 ASSERT_EQ(base::PLATFORM_FILE_OK
,
2306 ofu()->CreateOrOpen(
2307 AllowUsageIncrease(-length
)->context(), file
,
2308 base::PLATFORM_FILE_OPEN_TRUNCATED
| base::PLATFORM_FILE_WRITE
,
2309 &file_handle
, &created
));
2310 ASSERT_EQ(0, ComputeTotalFileSize());
2311 EXPECT_TRUE(base::ClosePlatformFile(file_handle
));
2314 TEST_F(ObfuscatedFileUtilTest
, MaybeDropDatabasesAliveCase
) {
2315 scoped_ptr
<ObfuscatedFileUtil
> file_util(
2316 ObfuscatedFileUtil::CreateForTesting(
2317 NULL
, data_dir_path(),
2318 base::MessageLoopProxy::current().get()));
2319 file_util
->InitOriginDatabase(GURL(), true /*create*/);
2320 ASSERT_TRUE(file_util
->origin_database_
!= NULL
);
2322 // Callback to Drop DB is called while ObfuscatedFileUtilTest is still alive.
2323 file_util
->db_flush_delay_seconds_
= 0;
2324 file_util
->MarkUsed();
2325 base::RunLoop().RunUntilIdle();
2327 ASSERT_TRUE(file_util
->origin_database_
== NULL
);
2330 TEST_F(ObfuscatedFileUtilTest
, MaybeDropDatabasesAlreadyDeletedCase
) {
2331 // Run message loop after OFU is already deleted to make sure callback doesn't
2332 // cause a crash for use after free.
2334 scoped_ptr
<ObfuscatedFileUtil
> file_util(
2335 ObfuscatedFileUtil::CreateForTesting(
2336 NULL
, data_dir_path(),
2337 base::MessageLoopProxy::current().get()));
2338 file_util
->InitOriginDatabase(GURL(), true /*create*/);
2339 file_util
->db_flush_delay_seconds_
= 0;
2340 file_util
->MarkUsed();
2343 // At this point the callback is still in the message queue but OFU is gone.
2344 base::RunLoop().RunUntilIdle();
2347 TEST_F(ObfuscatedFileUtilTest
, DestroyDirectoryDatabase_Isolated
) {
2348 storage_policy_
->AddIsolated(origin_
);
2349 scoped_ptr
<ObfuscatedFileUtil
> file_util(
2350 ObfuscatedFileUtil::CreateForTesting(
2351 storage_policy_
.get(), data_dir_path(),
2352 base::MessageLoopProxy::current().get()));
2353 const FileSystemURL url
= FileSystemURL::CreateForTest(
2354 origin_
, kFileSystemTypePersistent
, base::FilePath());
2356 // Create DirectoryDatabase for isolated origin.
2357 SandboxDirectoryDatabase
* db
=
2358 file_util
->GetDirectoryDatabase(url
, true /* create */);
2359 ASSERT_TRUE(db
!= NULL
);
2362 ASSERT_TRUE(file_util
->DestroyDirectoryDatabase(
2363 url
.origin(), GetTypeString(url
.type())));
2364 ASSERT_TRUE(file_util
->directories_
.empty());
2367 TEST_F(ObfuscatedFileUtilTest
, GetDirectoryDatabase_Isolated
) {
2368 storage_policy_
->AddIsolated(origin_
);
2369 scoped_ptr
<ObfuscatedFileUtil
> file_util(
2370 ObfuscatedFileUtil::CreateForTesting(
2371 storage_policy_
.get(), data_dir_path(),
2372 base::MessageLoopProxy::current().get()));
2373 const FileSystemURL url
= FileSystemURL::CreateForTest(
2374 origin_
, kFileSystemTypePersistent
, base::FilePath());
2376 // Create DirectoryDatabase for isolated origin.
2377 SandboxDirectoryDatabase
* db
=
2378 file_util
->GetDirectoryDatabase(url
, true /* create */);
2379 ASSERT_TRUE(db
!= NULL
);
2380 ASSERT_EQ(1U, file_util
->directories_
.size());
2383 storage_policy_
->RemoveIsolated(url
.origin());
2385 // This should still get the same database.
2386 SandboxDirectoryDatabase
* db2
=
2387 file_util
->GetDirectoryDatabase(url
, false /* create */);
2391 TEST_F(ObfuscatedFileUtilTest
, MigrationBackFromIsolated
) {
2392 std::string
kFakeDirectoryData("0123456789");
2393 base::FilePath old_directory_db_path
;
2395 // Initialize the directory with one origin using
2396 // SandboxIsolatedOriginDatabase.
2398 std::string origin_string
=
2399 webkit_database::GetIdentifierFromOrigin(origin_
);
2400 SandboxIsolatedOriginDatabase
database_old(
2401 origin_string
, data_dir_path(),
2403 SandboxIsolatedOriginDatabase::kObsoleteOriginDirectory
));
2404 base::FilePath path
;
2405 EXPECT_TRUE(database_old
.GetPathForOrigin(origin_string
, &path
));
2406 EXPECT_FALSE(path
.empty());
2408 // Populate the origin directory with some fake data.
2409 old_directory_db_path
= data_dir_path().Append(path
);
2410 ASSERT_TRUE(base::CreateDirectory(old_directory_db_path
));
2411 EXPECT_EQ(static_cast<int>(kFakeDirectoryData
.size()),
2412 file_util::WriteFile(old_directory_db_path
.AppendASCII("dummy"),
2413 kFakeDirectoryData
.data(),
2414 kFakeDirectoryData
.size()));
2417 storage_policy_
->AddIsolated(origin_
);
2418 scoped_ptr
<ObfuscatedFileUtil
> file_util(
2419 ObfuscatedFileUtil::CreateForTesting(
2420 storage_policy_
.get(), data_dir_path(),
2421 base::MessageLoopProxy::current().get()));
2422 base::PlatformFileError error
= base::PLATFORM_FILE_ERROR_FAILED
;
2423 base::FilePath origin_directory
= file_util
->GetDirectoryForOrigin(
2424 origin_
, true /* create */, &error
);
2425 EXPECT_EQ(base::PLATFORM_FILE_OK
, error
);
2427 // The database is migrated from the old one.
2428 EXPECT_TRUE(base::DirectoryExists(origin_directory
));
2429 EXPECT_FALSE(base::DirectoryExists(old_directory_db_path
));
2431 // Check we see the same contents in the new origin directory.
2432 std::string origin_db_data
;
2433 EXPECT_TRUE(base::PathExists(origin_directory
.AppendASCII("dummy")));
2434 EXPECT_TRUE(base::ReadFileToString(
2435 origin_directory
.AppendASCII("dummy"), &origin_db_data
));
2436 EXPECT_EQ(kFakeDirectoryData
, origin_db_data
);
2439 TEST_F(ObfuscatedFileUtilTest
, OpenPathInNonDirectory
) {
2440 FileSystemURL
file(CreateURLFromUTF8("file"));
2441 FileSystemURL
path_in_file(CreateURLFromUTF8("file/file"));
2444 ASSERT_EQ(base::PLATFORM_FILE_OK
,
2445 ofu()->EnsureFileExists(UnlimitedContext().get(), file
, &created
));
2446 ASSERT_TRUE(created
);
2449 base::PlatformFile file_handle
= base::kInvalidPlatformFileValue
;
2450 int file_flags
= base::PLATFORM_FILE_CREATE
| base::PLATFORM_FILE_WRITE
;
2451 ASSERT_EQ(base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY
,
2452 ofu()->CreateOrOpen(UnlimitedContext().get(),
2457 ASSERT_FALSE(created
);
2458 ASSERT_EQ(base::kInvalidPlatformFileValue
, file_handle
);
2460 ASSERT_EQ(base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY
,
2461 ofu()->CreateDirectory(UnlimitedContext().get(),
2463 false /* exclusive */,
2464 false /* recursive */));
2467 TEST_F(ObfuscatedFileUtilTest
, CreateDirectory_NotADirectoryInRecursive
) {
2468 FileSystemURL
file(CreateURLFromUTF8("file"));
2469 FileSystemURL
path_in_file(CreateURLFromUTF8("file/child"));
2470 FileSystemURL
path_in_file_in_file(
2471 CreateURLFromUTF8("file/child/grandchild"));
2474 ASSERT_EQ(base::PLATFORM_FILE_OK
,
2475 ofu()->EnsureFileExists(UnlimitedContext().get(), file
, &created
));
2476 ASSERT_TRUE(created
);
2478 ASSERT_EQ(base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY
,
2479 ofu()->CreateDirectory(UnlimitedContext().get(),
2481 false /* exclusive */,
2482 true /* recursive */));
2483 ASSERT_EQ(base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY
,
2484 ofu()->CreateDirectory(UnlimitedContext().get(),
2485 path_in_file_in_file
,
2486 false /* exclusive */,
2487 true /* recursive */));
2490 } // namespace fileapi