Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(277)

Side by Side Diff: webkit/browser/fileapi/obfuscated_file_util_unittest.cc

Issue 23440033: Move FileAPI test code from webkit to content (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <set>
6 #include <string>
7 #include <vector>
8
9 #include "base/bind.h"
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 "testing/gtest/include/gtest/gtest.h"
17 #include "webkit/browser/fileapi/async_file_test_helper.h"
18 #include "webkit/browser/fileapi/external_mount_points.h"
19 #include "webkit/browser/fileapi/file_system_backend.h"
20 #include "webkit/browser/fileapi/file_system_context.h"
21 #include "webkit/browser/fileapi/file_system_operation_context.h"
22 #include "webkit/browser/fileapi/file_system_usage_cache.h"
23 #include "webkit/browser/fileapi/mock_file_change_observer.h"
24 #include "webkit/browser/fileapi/mock_file_system_context.h"
25 #include "webkit/browser/fileapi/obfuscated_file_util.h"
26 #include "webkit/browser/fileapi/sandbox_directory_database.h"
27 #include "webkit/browser/fileapi/sandbox_file_system_test_helper.h"
28 #include "webkit/browser/fileapi/sandbox_isolated_origin_database.h"
29 #include "webkit/browser/fileapi/sandbox_origin_database.h"
30 #include "webkit/browser/fileapi/test_file_set.h"
31 #include "webkit/browser/quota/mock_special_storage_policy.h"
32 #include "webkit/browser/quota/quota_manager.h"
33 #include "webkit/common/database/database_identifier.h"
34 #include "webkit/common/quota/quota_types.h"
35
36 namespace fileapi {
37
38 namespace {
39
40 bool FileExists(const base::FilePath& path) {
41 return base::PathExists(path) && !base::DirectoryExists(path);
42 }
43
44 int64 GetSize(const base::FilePath& path) {
45 int64 size;
46 EXPECT_TRUE(file_util::GetFileSize(path, &size));
47 return size;
48 }
49
50 // After a move, the dest exists and the source doesn't.
51 // After a copy, both source and dest exist.
52 struct CopyMoveTestCaseRecord {
53 bool is_copy_not_move;
54 const char source_path[64];
55 const char dest_path[64];
56 bool cause_overwrite;
57 };
58
59 const CopyMoveTestCaseRecord kCopyMoveTestCases[] = {
60 // This is the combinatoric set of:
61 // rename vs. same-name
62 // different directory vs. same directory
63 // overwrite vs. no-overwrite
64 // copy vs. move
65 // We can never be called with source and destination paths identical, so
66 // those cases are omitted.
67 {true, "dir0/file0", "dir0/file1", false},
68 {false, "dir0/file0", "dir0/file1", false},
69 {true, "dir0/file0", "dir0/file1", true},
70 {false, "dir0/file0", "dir0/file1", true},
71
72 {true, "dir0/file0", "dir1/file0", false},
73 {false, "dir0/file0", "dir1/file0", false},
74 {true, "dir0/file0", "dir1/file0", true},
75 {false, "dir0/file0", "dir1/file0", true},
76 {true, "dir0/file0", "dir1/file1", false},
77 {false, "dir0/file0", "dir1/file1", false},
78 {true, "dir0/file0", "dir1/file1", true},
79 {false, "dir0/file0", "dir1/file1", true},
80 };
81
82 struct OriginEnumerationTestRecord {
83 std::string origin_url;
84 bool has_temporary;
85 bool has_persistent;
86 };
87
88 const OriginEnumerationTestRecord kOriginEnumerationTestRecords[] = {
89 {"http://example.com", false, true},
90 {"http://example1.com", true, false},
91 {"https://example1.com", true, true},
92 {"file://", false, true},
93 {"http://example.com:8000", false, true},
94 };
95
96 FileSystemURL FileSystemURLAppend(
97 const FileSystemURL& url, const base::FilePath::StringType& child) {
98 return FileSystemURL::CreateForTest(
99 url.origin(), url.mount_type(), url.virtual_path().Append(child));
100 }
101
102 FileSystemURL FileSystemURLAppendUTF8(
103 const FileSystemURL& url, const std::string& child) {
104 return FileSystemURL::CreateForTest(
105 url.origin(),
106 url.mount_type(),
107 url.virtual_path().Append(base::FilePath::FromUTF8Unsafe(child)));
108 }
109
110 FileSystemURL FileSystemURLDirName(const FileSystemURL& url) {
111 return FileSystemURL::CreateForTest(
112 url.origin(), url.mount_type(), VirtualPath::DirName(url.virtual_path()));
113 }
114
115 } // namespace (anonymous)
116
117 // TODO(ericu): The vast majority of this and the other FSFU subclass tests
118 // could theoretically be shared. It would basically be a FSFU interface
119 // compliance test, and only the subclass-specific bits that look into the
120 // implementation would need to be written per-subclass.
121 class ObfuscatedFileUtilTest : public testing::Test {
122 public:
123 ObfuscatedFileUtilTest()
124 : origin_(GURL("http://www.example.com")),
125 type_(kFileSystemTypeTemporary),
126 weak_factory_(this),
127 sandbox_file_system_(origin_, type_),
128 quota_status_(quota::kQuotaStatusUnknown),
129 usage_(-1) {
130 }
131
132 virtual void SetUp() {
133 ASSERT_TRUE(data_dir_.CreateUniqueTempDir());
134
135 storage_policy_ = new quota::MockSpecialStoragePolicy();
136
137 quota_manager_ =
138 new quota::QuotaManager(false /* is_incognito */,
139 data_dir_.path(),
140 base::MessageLoopProxy::current().get(),
141 base::MessageLoopProxy::current().get(),
142 storage_policy_.get());
143
144 // Every time we create a new sandbox_file_system helper,
145 // it creates another context, which creates another path manager,
146 // another sandbox_backend, and another OFU.
147 // We need to pass in the context to skip all that.
148 file_system_context_ = CreateFileSystemContextForTesting(
149 quota_manager_->proxy(),
150 data_dir_.path());
151
152 sandbox_file_system_.SetUp(file_system_context_.get());
153
154 change_observers_ = MockFileChangeObserver::CreateList(&change_observer_);
155 }
156
157 virtual void TearDown() {
158 quota_manager_ = NULL;
159 sandbox_file_system_.TearDown();
160 }
161
162 scoped_ptr<FileSystemOperationContext> LimitedContext(
163 int64 allowed_bytes_growth) {
164 scoped_ptr<FileSystemOperationContext> context(
165 sandbox_file_system_.NewOperationContext());
166 context->set_allowed_bytes_growth(allowed_bytes_growth);
167 return context.Pass();
168 }
169
170 scoped_ptr<FileSystemOperationContext> UnlimitedContext() {
171 return LimitedContext(kint64max);
172 }
173
174 FileSystemOperationContext* NewContext(
175 SandboxFileSystemTestHelper* file_system) {
176 change_observer()->ResetCount();
177 FileSystemOperationContext* context;
178 if (file_system)
179 context = file_system->NewOperationContext();
180 else
181 context = sandbox_file_system_.NewOperationContext();
182 // Setting allowed_bytes_growth big enough for all tests.
183 context->set_allowed_bytes_growth(1024 * 1024);
184 context->set_change_observers(change_observers());
185 return context;
186 }
187
188 const ChangeObserverList& change_observers() const {
189 return change_observers_;
190 }
191
192 MockFileChangeObserver* change_observer() {
193 return &change_observer_;
194 }
195
196 // This can only be used after SetUp has run and created file_system_context_
197 // and obfuscated_file_util_.
198 // Use this for tests which need to run in multiple origins; we need a test
199 // helper per origin.
200 SandboxFileSystemTestHelper* NewFileSystem(
201 const GURL& origin, fileapi::FileSystemType type) {
202 SandboxFileSystemTestHelper* file_system =
203 new SandboxFileSystemTestHelper(origin, type);
204
205 file_system->SetUp(file_system_context_.get());
206 return file_system;
207 }
208
209 ObfuscatedFileUtil* ofu() {
210 return static_cast<ObfuscatedFileUtil*>(sandbox_file_system_.file_util());
211 }
212
213 const base::FilePath& test_directory() const {
214 return data_dir_.path();
215 }
216
217 const GURL& origin() const {
218 return origin_;
219 }
220
221 fileapi::FileSystemType type() const {
222 return type_;
223 }
224
225 int64 ComputeTotalFileSize() {
226 return sandbox_file_system_.ComputeCurrentOriginUsage() -
227 sandbox_file_system_.ComputeCurrentDirectoryDatabaseUsage();
228 }
229
230 void GetUsageFromQuotaManager() {
231 int64 quota = -1;
232 quota_status_ =
233 AsyncFileTestHelper::GetUsageAndQuota(quota_manager_.get(),
234 origin(),
235 sandbox_file_system_.type(),
236 &usage_,
237 &quota);
238 EXPECT_EQ(quota::kQuotaStatusOk, quota_status_);
239 }
240
241 void RevokeUsageCache() {
242 quota_manager_->ResetUsageTracker(sandbox_file_system_.storage_type());
243 usage_cache()->Delete(sandbox_file_system_.GetUsageCachePath());
244 }
245
246 int64 SizeByQuotaUtil() {
247 return sandbox_file_system_.GetCachedOriginUsage();
248 }
249
250 int64 SizeInUsageFile() {
251 base::RunLoop().RunUntilIdle();
252 int64 usage = 0;
253 return usage_cache()->GetUsage(
254 sandbox_file_system_.GetUsageCachePath(), &usage) ? usage : -1;
255 }
256
257 bool PathExists(const FileSystemURL& url) {
258 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL));
259 base::PlatformFileInfo file_info;
260 base::FilePath platform_path;
261 base::PlatformFileError error = ofu()->GetFileInfo(
262 context.get(), url, &file_info, &platform_path);
263 return error == base::PLATFORM_FILE_OK;
264 }
265
266 bool DirectoryExists(const FileSystemURL& url) {
267 return AsyncFileTestHelper::DirectoryExists(file_system_context(), url);
268 }
269
270 int64 usage() const { return usage_; }
271 FileSystemUsageCache* usage_cache() {
272 return sandbox_file_system_.usage_cache();
273 }
274
275 FileSystemURL CreateURLFromUTF8(const std::string& path) {
276 return sandbox_file_system_.CreateURLFromUTF8(path);
277 }
278
279 int64 PathCost(const FileSystemURL& url) {
280 return ObfuscatedFileUtil::ComputeFilePathCost(url.path());
281 }
282
283 FileSystemURL CreateURL(const base::FilePath& path) {
284 return sandbox_file_system_.CreateURL(path);
285 }
286
287 void CheckFileAndCloseHandle(
288 const FileSystemURL& url, base::PlatformFile file_handle) {
289 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL));
290 base::FilePath local_path;
291 EXPECT_EQ(base::PLATFORM_FILE_OK, ofu()->GetLocalFilePath(
292 context.get(), url, &local_path));
293
294 base::PlatformFileInfo file_info0;
295 base::FilePath data_path;
296 EXPECT_EQ(base::PLATFORM_FILE_OK, ofu()->GetFileInfo(
297 context.get(), url, &file_info0, &data_path));
298 EXPECT_EQ(data_path, local_path);
299 EXPECT_TRUE(FileExists(data_path));
300 EXPECT_EQ(0, GetSize(data_path));
301
302 const char data[] = "test data";
303 const int length = arraysize(data) - 1;
304
305 if (base::kInvalidPlatformFileValue == file_handle) {
306 bool created = true;
307 base::PlatformFileError error;
308 file_handle = base::CreatePlatformFile(
309 data_path,
310 base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_WRITE,
311 &created,
312 &error);
313 ASSERT_NE(base::kInvalidPlatformFileValue, file_handle);
314 ASSERT_EQ(base::PLATFORM_FILE_OK, error);
315 EXPECT_FALSE(created);
316 }
317 ASSERT_EQ(length, base::WritePlatformFile(file_handle, 0, data, length));
318 EXPECT_TRUE(base::ClosePlatformFile(file_handle));
319
320 base::PlatformFileInfo file_info1;
321 EXPECT_EQ(length, GetSize(data_path));
322 context.reset(NewContext(NULL));
323 EXPECT_EQ(base::PLATFORM_FILE_OK, ofu()->GetFileInfo(
324 context.get(), url, &file_info1, &data_path));
325 EXPECT_EQ(data_path, local_path);
326
327 EXPECT_FALSE(file_info0.is_directory);
328 EXPECT_FALSE(file_info1.is_directory);
329 EXPECT_FALSE(file_info0.is_symbolic_link);
330 EXPECT_FALSE(file_info1.is_symbolic_link);
331 EXPECT_EQ(0, file_info0.size);
332 EXPECT_EQ(length, file_info1.size);
333 EXPECT_LE(file_info0.last_modified, file_info1.last_modified);
334
335 context.reset(NewContext(NULL));
336 EXPECT_EQ(base::PLATFORM_FILE_OK, ofu()->Truncate(
337 context.get(), url, length * 2));
338 EXPECT_EQ(length * 2, GetSize(data_path));
339
340 context.reset(NewContext(NULL));
341 EXPECT_EQ(base::PLATFORM_FILE_OK, ofu()->Truncate(
342 context.get(), url, 0));
343 EXPECT_EQ(0, GetSize(data_path));
344 }
345
346 void ValidateTestDirectory(
347 const FileSystemURL& root_url,
348 const std::set<base::FilePath::StringType>& files,
349 const std::set<base::FilePath::StringType>& directories) {
350 scoped_ptr<FileSystemOperationContext> context;
351 std::set<base::FilePath::StringType>::const_iterator iter;
352 for (iter = files.begin(); iter != files.end(); ++iter) {
353 bool created = true;
354 context.reset(NewContext(NULL));
355 ASSERT_EQ(base::PLATFORM_FILE_OK,
356 ofu()->EnsureFileExists(
357 context.get(), FileSystemURLAppend(root_url, *iter),
358 &created));
359 ASSERT_FALSE(created);
360 }
361 for (iter = directories.begin(); iter != directories.end(); ++iter) {
362 context.reset(NewContext(NULL));
363 EXPECT_TRUE(DirectoryExists(
364 FileSystemURLAppend(root_url, *iter)));
365 }
366 }
367
368 class UsageVerifyHelper {
369 public:
370 UsageVerifyHelper(scoped_ptr<FileSystemOperationContext> context,
371 SandboxFileSystemTestHelper* file_system,
372 int64 expected_usage)
373 : context_(context.Pass()),
374 sandbox_file_system_(file_system),
375 expected_usage_(expected_usage) {}
376
377 ~UsageVerifyHelper() {
378 base::RunLoop().RunUntilIdle();
379 Check();
380 }
381
382 FileSystemOperationContext* context() {
383 return context_.get();
384 }
385
386 private:
387 void Check() {
388 ASSERT_EQ(expected_usage_,
389 sandbox_file_system_->GetCachedOriginUsage());
390 }
391
392 scoped_ptr<FileSystemOperationContext> context_;
393 SandboxFileSystemTestHelper* sandbox_file_system_;
394 int64 expected_usage_;
395 };
396
397 scoped_ptr<UsageVerifyHelper> AllowUsageIncrease(int64 requested_growth) {
398 int64 usage = sandbox_file_system_.GetCachedOriginUsage();
399 return scoped_ptr<UsageVerifyHelper>(new UsageVerifyHelper(
400 LimitedContext(requested_growth),
401 &sandbox_file_system_, usage + requested_growth));
402 }
403
404 scoped_ptr<UsageVerifyHelper> DisallowUsageIncrease(int64 requested_growth) {
405 int64 usage = sandbox_file_system_.GetCachedOriginUsage();
406 return scoped_ptr<UsageVerifyHelper>(new UsageVerifyHelper(
407 LimitedContext(requested_growth - 1), &sandbox_file_system_, usage));
408 }
409
410 void FillTestDirectory(
411 const FileSystemURL& root_url,
412 std::set<base::FilePath::StringType>* files,
413 std::set<base::FilePath::StringType>* directories) {
414 scoped_ptr<FileSystemOperationContext> context;
415 std::vector<DirectoryEntry> entries;
416 EXPECT_EQ(base::PLATFORM_FILE_OK,
417 AsyncFileTestHelper::ReadDirectory(
418 file_system_context(), root_url, &entries));
419 EXPECT_EQ(0UL, entries.size());
420
421 files->clear();
422 files->insert(FILE_PATH_LITERAL("first"));
423 files->insert(FILE_PATH_LITERAL("second"));
424 files->insert(FILE_PATH_LITERAL("third"));
425 directories->clear();
426 directories->insert(FILE_PATH_LITERAL("fourth"));
427 directories->insert(FILE_PATH_LITERAL("fifth"));
428 directories->insert(FILE_PATH_LITERAL("sixth"));
429 std::set<base::FilePath::StringType>::iterator iter;
430 for (iter = files->begin(); iter != files->end(); ++iter) {
431 bool created = false;
432 context.reset(NewContext(NULL));
433 ASSERT_EQ(base::PLATFORM_FILE_OK,
434 ofu()->EnsureFileExists(
435 context.get(),
436 FileSystemURLAppend(root_url, *iter),
437 &created));
438 ASSERT_TRUE(created);
439 }
440 for (iter = directories->begin(); iter != directories->end(); ++iter) {
441 bool exclusive = true;
442 bool recursive = false;
443 context.reset(NewContext(NULL));
444 EXPECT_EQ(base::PLATFORM_FILE_OK,
445 ofu()->CreateDirectory(
446 context.get(),
447 FileSystemURLAppend(root_url, *iter),
448 exclusive, recursive));
449 }
450 ValidateTestDirectory(root_url, *files, *directories);
451 }
452
453 void TestReadDirectoryHelper(const FileSystemURL& root_url) {
454 std::set<base::FilePath::StringType> files;
455 std::set<base::FilePath::StringType> directories;
456 FillTestDirectory(root_url, &files, &directories);
457
458 scoped_ptr<FileSystemOperationContext> context;
459 std::vector<DirectoryEntry> entries;
460 context.reset(NewContext(NULL));
461 EXPECT_EQ(base::PLATFORM_FILE_OK,
462 AsyncFileTestHelper::ReadDirectory(
463 file_system_context(), root_url, &entries));
464 std::vector<DirectoryEntry>::iterator entry_iter;
465 EXPECT_EQ(files.size() + directories.size(), entries.size());
466 EXPECT_TRUE(change_observer()->HasNoChange());
467 for (entry_iter = entries.begin(); entry_iter != entries.end();
468 ++entry_iter) {
469 const DirectoryEntry& entry = *entry_iter;
470 std::set<base::FilePath::StringType>::iterator iter =
471 files.find(entry.name);
472 if (iter != files.end()) {
473 EXPECT_FALSE(entry.is_directory);
474 files.erase(iter);
475 continue;
476 }
477 iter = directories.find(entry.name);
478 EXPECT_FALSE(directories.end() == iter);
479 EXPECT_TRUE(entry.is_directory);
480 directories.erase(iter);
481 }
482 }
483
484 void TestTouchHelper(const FileSystemURL& url, bool is_file) {
485 base::Time last_access_time = base::Time::Now();
486 base::Time last_modified_time = base::Time::Now();
487
488 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL));
489 EXPECT_EQ(base::PLATFORM_FILE_OK,
490 ofu()->Touch(
491 context.get(), url, last_access_time, last_modified_time));
492 // Currently we fire no change notifications for Touch.
493 EXPECT_TRUE(change_observer()->HasNoChange());
494 base::FilePath local_path;
495 base::PlatformFileInfo file_info;
496 context.reset(NewContext(NULL));
497 EXPECT_EQ(base::PLATFORM_FILE_OK, ofu()->GetFileInfo(
498 context.get(), url, &file_info, &local_path));
499 // We compare as time_t here to lower our resolution, to avoid false
500 // negatives caused by conversion to the local filesystem's native
501 // representation and back.
502 EXPECT_EQ(file_info.last_modified.ToTimeT(), last_modified_time.ToTimeT());
503
504 context.reset(NewContext(NULL));
505 last_modified_time += base::TimeDelta::FromHours(1);
506 last_access_time += base::TimeDelta::FromHours(14);
507 EXPECT_EQ(base::PLATFORM_FILE_OK,
508 ofu()->Touch(
509 context.get(), url, last_access_time, last_modified_time));
510 EXPECT_TRUE(change_observer()->HasNoChange());
511 context.reset(NewContext(NULL));
512 EXPECT_EQ(base::PLATFORM_FILE_OK, ofu()->GetFileInfo(
513 context.get(), url, &file_info, &local_path));
514 EXPECT_EQ(file_info.last_modified.ToTimeT(), last_modified_time.ToTimeT());
515 if (is_file) // Directories in OFU don't support atime.
516 EXPECT_EQ(file_info.last_accessed.ToTimeT(), last_access_time.ToTimeT());
517 }
518
519 void TestCopyInForeignFileHelper(bool overwrite) {
520 base::ScopedTempDir source_dir;
521 ASSERT_TRUE(source_dir.CreateUniqueTempDir());
522 base::FilePath root_file_path = source_dir.path();
523 base::FilePath src_file_path = root_file_path.AppendASCII("file_name");
524 FileSystemURL dest_url = CreateURLFromUTF8("new file");
525 int64 src_file_length = 87;
526
527 base::PlatformFileError error_code;
528 bool created = false;
529 int file_flags = base::PLATFORM_FILE_CREATE | base::PLATFORM_FILE_WRITE;
530 base::PlatformFile file_handle =
531 base::CreatePlatformFile(
532 src_file_path, file_flags, &created, &error_code);
533 EXPECT_TRUE(created);
534 ASSERT_EQ(base::PLATFORM_FILE_OK, error_code);
535 ASSERT_NE(base::kInvalidPlatformFileValue, file_handle);
536 ASSERT_TRUE(base::TruncatePlatformFile(file_handle, src_file_length));
537 EXPECT_TRUE(base::ClosePlatformFile(file_handle));
538
539 scoped_ptr<FileSystemOperationContext> context;
540
541 if (overwrite) {
542 context.reset(NewContext(NULL));
543 EXPECT_EQ(base::PLATFORM_FILE_OK,
544 ofu()->EnsureFileExists(context.get(), dest_url, &created));
545 EXPECT_TRUE(created);
546
547 // We must have observed one (and only one) create_file_count.
548 EXPECT_EQ(1, change_observer()->get_and_reset_create_file_count());
549 EXPECT_TRUE(change_observer()->HasNoChange());
550 }
551
552 const int64 path_cost =
553 ObfuscatedFileUtil::ComputeFilePathCost(dest_url.path());
554 if (!overwrite) {
555 // Verify that file creation requires sufficient quota for the path.
556 context.reset(NewContext(NULL));
557 context->set_allowed_bytes_growth(path_cost + src_file_length - 1);
558 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE,
559 ofu()->CopyInForeignFile(context.get(),
560 src_file_path, dest_url));
561 }
562
563 context.reset(NewContext(NULL));
564 context->set_allowed_bytes_growth(path_cost + src_file_length);
565 EXPECT_EQ(base::PLATFORM_FILE_OK,
566 ofu()->CopyInForeignFile(context.get(),
567 src_file_path, dest_url));
568
569 EXPECT_TRUE(PathExists(dest_url));
570 EXPECT_FALSE(DirectoryExists(dest_url));
571
572 context.reset(NewContext(NULL));
573 base::PlatformFileInfo file_info;
574 base::FilePath data_path;
575 EXPECT_EQ(base::PLATFORM_FILE_OK, ofu()->GetFileInfo(
576 context.get(), dest_url, &file_info, &data_path));
577 EXPECT_NE(data_path, src_file_path);
578 EXPECT_TRUE(FileExists(data_path));
579 EXPECT_EQ(src_file_length, GetSize(data_path));
580
581 EXPECT_EQ(base::PLATFORM_FILE_OK,
582 ofu()->DeleteFile(context.get(), dest_url));
583 }
584
585 void ClearTimestamp(const FileSystemURL& url) {
586 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL));
587 EXPECT_EQ(base::PLATFORM_FILE_OK,
588 ofu()->Touch(context.get(), url, base::Time(), base::Time()));
589 EXPECT_EQ(base::Time(), GetModifiedTime(url));
590 }
591
592 base::Time GetModifiedTime(const FileSystemURL& url) {
593 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL));
594 base::FilePath data_path;
595 base::PlatformFileInfo file_info;
596 context.reset(NewContext(NULL));
597 EXPECT_EQ(base::PLATFORM_FILE_OK,
598 ofu()->GetFileInfo(context.get(), url, &file_info, &data_path));
599 EXPECT_TRUE(change_observer()->HasNoChange());
600 return file_info.last_modified;
601 }
602
603 void TestDirectoryTimestampHelper(const FileSystemURL& base_dir,
604 bool copy,
605 bool overwrite) {
606 scoped_ptr<FileSystemOperationContext> context;
607 const FileSystemURL src_dir_url(
608 FileSystemURLAppendUTF8(base_dir, "foo_dir"));
609 const FileSystemURL dest_dir_url(
610 FileSystemURLAppendUTF8(base_dir, "bar_dir"));
611
612 const FileSystemURL src_file_url(
613 FileSystemURLAppendUTF8(src_dir_url, "hoge"));
614 const FileSystemURL dest_file_url(
615 FileSystemURLAppendUTF8(dest_dir_url, "fuga"));
616
617 context.reset(NewContext(NULL));
618 EXPECT_EQ(base::PLATFORM_FILE_OK,
619 ofu()->CreateDirectory(context.get(), src_dir_url, true, true));
620 context.reset(NewContext(NULL));
621 EXPECT_EQ(base::PLATFORM_FILE_OK,
622 ofu()->CreateDirectory(context.get(), dest_dir_url, true, true));
623
624 bool created = false;
625 context.reset(NewContext(NULL));
626 EXPECT_EQ(base::PLATFORM_FILE_OK,
627 ofu()->EnsureFileExists(context.get(), src_file_url, &created));
628 if (overwrite) {
629 context.reset(NewContext(NULL));
630 EXPECT_EQ(base::PLATFORM_FILE_OK,
631 ofu()->EnsureFileExists(context.get(),
632 dest_file_url, &created));
633 }
634
635 ClearTimestamp(src_dir_url);
636 ClearTimestamp(dest_dir_url);
637 context.reset(NewContext(NULL));
638 EXPECT_EQ(base::PLATFORM_FILE_OK,
639 ofu()->CopyOrMoveFile(context.get(),
640 src_file_url, dest_file_url,
641 FileSystemOperation::OPTION_NONE,
642 copy));
643 if (copy)
644 EXPECT_EQ(base::Time(), GetModifiedTime(src_dir_url));
645 else
646 EXPECT_NE(base::Time(), GetModifiedTime(src_dir_url));
647 EXPECT_NE(base::Time(), GetModifiedTime(dest_dir_url));
648 }
649
650 int64 ComputeCurrentUsage() {
651 return sandbox_file_system_.ComputeCurrentOriginUsage() -
652 sandbox_file_system_.ComputeCurrentDirectoryDatabaseUsage();
653 }
654
655 FileSystemContext* file_system_context() {
656 return sandbox_file_system_.file_system_context();
657 }
658
659 const base::FilePath& data_dir_path() const {
660 return data_dir_.path();
661 }
662
663 protected:
664 base::ScopedTempDir data_dir_;
665 base::MessageLoop message_loop_;
666 scoped_refptr<quota::MockSpecialStoragePolicy> storage_policy_;
667 scoped_refptr<quota::QuotaManager> quota_manager_;
668 scoped_refptr<FileSystemContext> file_system_context_;
669 GURL origin_;
670 fileapi::FileSystemType type_;
671 base::WeakPtrFactory<ObfuscatedFileUtilTest> weak_factory_;
672 SandboxFileSystemTestHelper sandbox_file_system_;
673 quota::QuotaStatusCode quota_status_;
674 int64 usage_;
675 MockFileChangeObserver change_observer_;
676 ChangeObserverList change_observers_;
677
678 DISALLOW_COPY_AND_ASSIGN(ObfuscatedFileUtilTest);
679 };
680
681 TEST_F(ObfuscatedFileUtilTest, TestCreateAndDeleteFile) {
682 base::PlatformFile file_handle = base::kInvalidPlatformFileValue;
683 bool created;
684 FileSystemURL url = CreateURLFromUTF8("fake/file");
685 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL));
686 int file_flags = base::PLATFORM_FILE_CREATE | base::PLATFORM_FILE_WRITE;
687
688 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND,
689 ofu()->CreateOrOpen(
690 context.get(), url, file_flags, &file_handle,
691 &created));
692
693 context.reset(NewContext(NULL));
694 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND,
695 ofu()->DeleteFile(context.get(), url));
696
697 url = CreateURLFromUTF8("test file");
698
699 EXPECT_TRUE(change_observer()->HasNoChange());
700
701 // Verify that file creation requires sufficient quota for the path.
702 context.reset(NewContext(NULL));
703 context->set_allowed_bytes_growth(
704 ObfuscatedFileUtil::ComputeFilePathCost(url.path()) - 1);
705 ASSERT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE,
706 ofu()->CreateOrOpen(
707 context.get(), url, file_flags, &file_handle, &created));
708
709 context.reset(NewContext(NULL));
710 context->set_allowed_bytes_growth(
711 ObfuscatedFileUtil::ComputeFilePathCost(url.path()));
712 ASSERT_EQ(base::PLATFORM_FILE_OK,
713 ofu()->CreateOrOpen(
714 context.get(), url, file_flags, &file_handle, &created));
715 ASSERT_TRUE(created);
716 EXPECT_EQ(1, change_observer()->get_and_reset_create_file_count());
717 EXPECT_NE(base::kInvalidPlatformFileValue, file_handle);
718
719 CheckFileAndCloseHandle(url, file_handle);
720
721 context.reset(NewContext(NULL));
722 base::FilePath local_path;
723 EXPECT_EQ(base::PLATFORM_FILE_OK, ofu()->GetLocalFilePath(
724 context.get(), url, &local_path));
725 EXPECT_TRUE(base::PathExists(local_path));
726
727 // Verify that deleting a file isn't stopped by zero quota, and that it frees
728 // up quote from its path.
729 context.reset(NewContext(NULL));
730 context->set_allowed_bytes_growth(0);
731 EXPECT_EQ(base::PLATFORM_FILE_OK,
732 ofu()->DeleteFile(context.get(), url));
733 EXPECT_EQ(1, change_observer()->get_and_reset_remove_file_count());
734 EXPECT_FALSE(base::PathExists(local_path));
735 EXPECT_EQ(ObfuscatedFileUtil::ComputeFilePathCost(url.path()),
736 context->allowed_bytes_growth());
737
738 context.reset(NewContext(NULL));
739 bool exclusive = true;
740 bool recursive = true;
741 FileSystemURL directory_url = CreateURLFromUTF8(
742 "series/of/directories");
743 url = FileSystemURLAppendUTF8(directory_url, "file name");
744 EXPECT_EQ(base::PLATFORM_FILE_OK, ofu()->CreateDirectory(
745 context.get(), directory_url, exclusive, recursive));
746 // The oepration created 3 directories recursively.
747 EXPECT_EQ(3, change_observer()->get_and_reset_create_directory_count());
748
749 context.reset(NewContext(NULL));
750 file_handle = base::kInvalidPlatformFileValue;
751 ASSERT_EQ(base::PLATFORM_FILE_OK,
752 ofu()->CreateOrOpen(
753 context.get(), url, file_flags, &file_handle, &created));
754 ASSERT_TRUE(created);
755 EXPECT_EQ(1, change_observer()->get_and_reset_create_file_count());
756 EXPECT_NE(base::kInvalidPlatformFileValue, file_handle);
757
758 CheckFileAndCloseHandle(url, file_handle);
759
760 context.reset(NewContext(NULL));
761 EXPECT_EQ(base::PLATFORM_FILE_OK, ofu()->GetLocalFilePath(
762 context.get(), url, &local_path));
763 EXPECT_TRUE(base::PathExists(local_path));
764
765 context.reset(NewContext(NULL));
766 EXPECT_EQ(base::PLATFORM_FILE_OK,
767 ofu()->DeleteFile(context.get(), url));
768 EXPECT_EQ(1, change_observer()->get_and_reset_remove_file_count());
769 EXPECT_FALSE(base::PathExists(local_path));
770
771 // Make sure we have no unexpected changes.
772 EXPECT_TRUE(change_observer()->HasNoChange());
773 }
774
775 TEST_F(ObfuscatedFileUtilTest, TestTruncate) {
776 bool created = false;
777 FileSystemURL url = CreateURLFromUTF8("file");
778 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL));
779
780 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND,
781 ofu()->Truncate(context.get(), url, 4));
782
783 context.reset(NewContext(NULL));
784 ASSERT_EQ(base::PLATFORM_FILE_OK,
785 ofu()->EnsureFileExists(context.get(), url, &created));
786 ASSERT_TRUE(created);
787 EXPECT_EQ(1, change_observer()->get_and_reset_create_file_count());
788
789 context.reset(NewContext(NULL));
790 base::FilePath local_path;
791 EXPECT_EQ(base::PLATFORM_FILE_OK, ofu()->GetLocalFilePath(
792 context.get(), url, &local_path));
793 EXPECT_EQ(0, GetSize(local_path));
794
795 context.reset(NewContext(NULL));
796 EXPECT_EQ(base::PLATFORM_FILE_OK, ofu()->Truncate(
797 context.get(), url, 10));
798 EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count());
799 EXPECT_EQ(10, GetSize(local_path));
800
801 context.reset(NewContext(NULL));
802 EXPECT_EQ(base::PLATFORM_FILE_OK, ofu()->Truncate(
803 context.get(), url, 1));
804 EXPECT_EQ(1, GetSize(local_path));
805 EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count());
806
807 EXPECT_FALSE(DirectoryExists(url));
808 EXPECT_TRUE(PathExists(url));
809
810 // Make sure we have no unexpected changes.
811 EXPECT_TRUE(change_observer()->HasNoChange());
812 }
813
814 TEST_F(ObfuscatedFileUtilTest, TestQuotaOnTruncation) {
815 bool created = false;
816 FileSystemURL url = CreateURLFromUTF8("file");
817
818 ASSERT_EQ(base::PLATFORM_FILE_OK,
819 ofu()->EnsureFileExists(
820 AllowUsageIncrease(PathCost(url))->context(),
821 url, &created));
822 ASSERT_TRUE(created);
823 ASSERT_EQ(0, ComputeTotalFileSize());
824
825 ASSERT_EQ(base::PLATFORM_FILE_OK,
826 ofu()->Truncate(
827 AllowUsageIncrease(1020)->context(),
828 url, 1020));
829 ASSERT_EQ(1020, ComputeTotalFileSize());
830
831 ASSERT_EQ(base::PLATFORM_FILE_OK,
832 ofu()->Truncate(
833 AllowUsageIncrease(-1020)->context(),
834 url, 0));
835 ASSERT_EQ(0, ComputeTotalFileSize());
836
837 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE,
838 ofu()->Truncate(
839 DisallowUsageIncrease(1021)->context(),
840 url, 1021));
841 ASSERT_EQ(0, ComputeTotalFileSize());
842
843 EXPECT_EQ(base::PLATFORM_FILE_OK,
844 ofu()->Truncate(
845 AllowUsageIncrease(1020)->context(),
846 url, 1020));
847 ASSERT_EQ(1020, ComputeTotalFileSize());
848
849 EXPECT_EQ(base::PLATFORM_FILE_OK,
850 ofu()->Truncate(
851 AllowUsageIncrease(0)->context(),
852 url, 1020));
853 ASSERT_EQ(1020, ComputeTotalFileSize());
854
855 // quota exceeded
856 {
857 scoped_ptr<UsageVerifyHelper> helper = AllowUsageIncrease(-1);
858 helper->context()->set_allowed_bytes_growth(
859 helper->context()->allowed_bytes_growth() - 1);
860 EXPECT_EQ(base::PLATFORM_FILE_OK,
861 ofu()->Truncate(helper->context(), url, 1019));
862 ASSERT_EQ(1019, ComputeTotalFileSize());
863 }
864
865 // Delete backing file to make following truncation fail.
866 base::FilePath local_path;
867 ASSERT_EQ(base::PLATFORM_FILE_OK,
868 ofu()->GetLocalFilePath(
869 UnlimitedContext().get(),
870 url, &local_path));
871 ASSERT_FALSE(local_path.empty());
872 ASSERT_TRUE(base::DeleteFile(local_path, false));
873
874 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND,
875 ofu()->Truncate(
876 LimitedContext(1234).get(),
877 url, 1234));
878 ASSERT_EQ(0, ComputeTotalFileSize());
879 }
880
881 TEST_F(ObfuscatedFileUtilTest, TestEnsureFileExists) {
882 FileSystemURL url = CreateURLFromUTF8("fake/file");
883 bool created = false;
884 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL));
885 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND,
886 ofu()->EnsureFileExists(
887 context.get(), url, &created));
888 EXPECT_TRUE(change_observer()->HasNoChange());
889
890 // Verify that file creation requires sufficient quota for the path.
891 context.reset(NewContext(NULL));
892 url = CreateURLFromUTF8("test file");
893 created = false;
894 context->set_allowed_bytes_growth(
895 ObfuscatedFileUtil::ComputeFilePathCost(url.path()) - 1);
896 ASSERT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE,
897 ofu()->EnsureFileExists(context.get(), url, &created));
898 ASSERT_FALSE(created);
899 EXPECT_TRUE(change_observer()->HasNoChange());
900
901 context.reset(NewContext(NULL));
902 context->set_allowed_bytes_growth(
903 ObfuscatedFileUtil::ComputeFilePathCost(url.path()));
904 ASSERT_EQ(base::PLATFORM_FILE_OK,
905 ofu()->EnsureFileExists(context.get(), url, &created));
906 ASSERT_TRUE(created);
907 EXPECT_EQ(1, change_observer()->get_and_reset_create_file_count());
908
909 CheckFileAndCloseHandle(url, base::kInvalidPlatformFileValue);
910
911 context.reset(NewContext(NULL));
912 ASSERT_EQ(base::PLATFORM_FILE_OK,
913 ofu()->EnsureFileExists(context.get(), url, &created));
914 ASSERT_FALSE(created);
915 EXPECT_TRUE(change_observer()->HasNoChange());
916
917 // Also test in a subdirectory.
918 url = CreateURLFromUTF8("path/to/file.txt");
919 context.reset(NewContext(NULL));
920 bool exclusive = true;
921 bool recursive = true;
922 EXPECT_EQ(base::PLATFORM_FILE_OK, ofu()->CreateDirectory(
923 context.get(),
924 FileSystemURLDirName(url),
925 exclusive, recursive));
926 // 2 directories: path/ and path/to.
927 EXPECT_EQ(2, change_observer()->get_and_reset_create_directory_count());
928
929 context.reset(NewContext(NULL));
930 ASSERT_EQ(base::PLATFORM_FILE_OK,
931 ofu()->EnsureFileExists(context.get(), url, &created));
932 ASSERT_TRUE(created);
933 EXPECT_FALSE(DirectoryExists(url));
934 EXPECT_TRUE(PathExists(url));
935 EXPECT_TRUE(change_observer()->HasNoChange());
936 }
937
938 TEST_F(ObfuscatedFileUtilTest, TestDirectoryOps) {
939 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL));
940
941 bool exclusive = false;
942 bool recursive = false;
943 FileSystemURL url = CreateURLFromUTF8("foo/bar");
944 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, ofu()->CreateDirectory(
945 context.get(), url, exclusive, recursive));
946
947 context.reset(NewContext(NULL));
948 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND,
949 ofu()->DeleteDirectory(context.get(), url));
950
951 FileSystemURL root = CreateURLFromUTF8(std::string());
952 EXPECT_FALSE(DirectoryExists(url));
953 EXPECT_FALSE(PathExists(url));
954 context.reset(NewContext(NULL));
955 EXPECT_TRUE(ofu()->IsDirectoryEmpty(context.get(), root));
956
957 context.reset(NewContext(NULL));
958 exclusive = false;
959 recursive = true;
960 EXPECT_EQ(base::PLATFORM_FILE_OK, ofu()->CreateDirectory(
961 context.get(), url, exclusive, recursive));
962 EXPECT_EQ(2, change_observer()->get_and_reset_create_directory_count());
963
964 EXPECT_TRUE(DirectoryExists(url));
965 EXPECT_TRUE(PathExists(url));
966
967 context.reset(NewContext(NULL));
968 EXPECT_FALSE(ofu()->IsDirectoryEmpty(context.get(), root));
969 EXPECT_TRUE(DirectoryExists(FileSystemURLDirName(url)));
970
971 context.reset(NewContext(NULL));
972 EXPECT_FALSE(ofu()->IsDirectoryEmpty(context.get(),
973 FileSystemURLDirName(url)));
974
975 // Can't remove a non-empty directory.
976 context.reset(NewContext(NULL));
977 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_EMPTY,
978 ofu()->DeleteDirectory(context.get(),
979 FileSystemURLDirName(url)));
980 EXPECT_TRUE(change_observer()->HasNoChange());
981
982 base::PlatformFileInfo file_info;
983 base::FilePath local_path;
984 EXPECT_EQ(base::PLATFORM_FILE_OK, ofu()->GetFileInfo(
985 context.get(), url, &file_info, &local_path));
986 EXPECT_TRUE(local_path.empty());
987 EXPECT_TRUE(file_info.is_directory);
988 EXPECT_FALSE(file_info.is_symbolic_link);
989
990 // Same create again should succeed, since exclusive is false.
991 context.reset(NewContext(NULL));
992 EXPECT_EQ(base::PLATFORM_FILE_OK, ofu()->CreateDirectory(
993 context.get(), url, exclusive, recursive));
994 EXPECT_TRUE(change_observer()->HasNoChange());
995
996 exclusive = true;
997 recursive = true;
998 context.reset(NewContext(NULL));
999 EXPECT_EQ(base::PLATFORM_FILE_ERROR_EXISTS, ofu()->CreateDirectory(
1000 context.get(), url, exclusive, recursive));
1001 EXPECT_TRUE(change_observer()->HasNoChange());
1002
1003 // Verify that deleting a directory isn't stopped by zero quota, and that it
1004 // frees up quota from its path.
1005 context.reset(NewContext(NULL));
1006 context->set_allowed_bytes_growth(0);
1007 EXPECT_EQ(base::PLATFORM_FILE_OK, ofu()->DeleteDirectory(context.get(), url));
1008 EXPECT_EQ(1, change_observer()->get_and_reset_remove_directory_count());
1009 EXPECT_EQ(ObfuscatedFileUtil::ComputeFilePathCost(url.path()),
1010 context->allowed_bytes_growth());
1011
1012 url = CreateURLFromUTF8("foo/bop");
1013
1014 EXPECT_FALSE(DirectoryExists(url));
1015 EXPECT_FALSE(PathExists(url));
1016
1017 context.reset(NewContext(NULL));
1018 EXPECT_TRUE(ofu()->IsDirectoryEmpty(context.get(), url));
1019 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, ofu()->GetFileInfo(
1020 context.get(), url, &file_info, &local_path));
1021
1022 // Verify that file creation requires sufficient quota for the path.
1023 exclusive = true;
1024 recursive = false;
1025 context.reset(NewContext(NULL));
1026 context->set_allowed_bytes_growth(
1027 ObfuscatedFileUtil::ComputeFilePathCost(url.path()) - 1);
1028 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE, ofu()->CreateDirectory(
1029 context.get(), url, exclusive, recursive));
1030 EXPECT_TRUE(change_observer()->HasNoChange());
1031
1032 context.reset(NewContext(NULL));
1033 context->set_allowed_bytes_growth(
1034 ObfuscatedFileUtil::ComputeFilePathCost(url.path()));
1035 EXPECT_EQ(base::PLATFORM_FILE_OK, ofu()->CreateDirectory(
1036 context.get(), url, exclusive, recursive));
1037 EXPECT_EQ(1, change_observer()->get_and_reset_create_directory_count());
1038
1039 EXPECT_TRUE(DirectoryExists(url));
1040 EXPECT_TRUE(PathExists(url));
1041
1042 exclusive = true;
1043 recursive = false;
1044 context.reset(NewContext(NULL));
1045 EXPECT_EQ(base::PLATFORM_FILE_ERROR_EXISTS, ofu()->CreateDirectory(
1046 context.get(), url, exclusive, recursive));
1047 EXPECT_TRUE(change_observer()->HasNoChange());
1048
1049 exclusive = true;
1050 recursive = false;
1051 url = CreateURLFromUTF8("foo");
1052 context.reset(NewContext(NULL));
1053 EXPECT_EQ(base::PLATFORM_FILE_ERROR_EXISTS, ofu()->CreateDirectory(
1054 context.get(), url, exclusive, recursive));
1055 EXPECT_TRUE(change_observer()->HasNoChange());
1056
1057 url = CreateURLFromUTF8("blah");
1058
1059 EXPECT_FALSE(DirectoryExists(url));
1060 EXPECT_FALSE(PathExists(url));
1061
1062 exclusive = true;
1063 recursive = false;
1064 context.reset(NewContext(NULL));
1065 EXPECT_EQ(base::PLATFORM_FILE_OK, ofu()->CreateDirectory(
1066 context.get(), url, exclusive, recursive));
1067 EXPECT_EQ(1, change_observer()->get_and_reset_create_directory_count());
1068
1069 EXPECT_TRUE(DirectoryExists(url));
1070 EXPECT_TRUE(PathExists(url));
1071
1072 exclusive = true;
1073 recursive = false;
1074 context.reset(NewContext(NULL));
1075 EXPECT_EQ(base::PLATFORM_FILE_ERROR_EXISTS, ofu()->CreateDirectory(
1076 context.get(), url, exclusive, recursive));
1077 EXPECT_TRUE(change_observer()->HasNoChange());
1078 }
1079
1080 TEST_F(ObfuscatedFileUtilTest, TestReadDirectory) {
1081 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL));
1082 bool exclusive = true;
1083 bool recursive = true;
1084 FileSystemURL url = CreateURLFromUTF8("directory/to/use");
1085 EXPECT_EQ(base::PLATFORM_FILE_OK, ofu()->CreateDirectory(
1086 context.get(), url, exclusive, recursive));
1087 TestReadDirectoryHelper(url);
1088 }
1089
1090 TEST_F(ObfuscatedFileUtilTest, TestReadRootWithSlash) {
1091 TestReadDirectoryHelper(CreateURLFromUTF8(std::string()));
1092 }
1093
1094 TEST_F(ObfuscatedFileUtilTest, TestReadRootWithEmptyString) {
1095 TestReadDirectoryHelper(CreateURLFromUTF8("/"));
1096 }
1097
1098 TEST_F(ObfuscatedFileUtilTest, TestReadDirectoryOnFile) {
1099 FileSystemURL url = CreateURLFromUTF8("file");
1100 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL));
1101
1102 bool created = false;
1103 ASSERT_EQ(base::PLATFORM_FILE_OK,
1104 ofu()->EnsureFileExists(context.get(), url, &created));
1105 ASSERT_TRUE(created);
1106
1107 std::vector<DirectoryEntry> entries;
1108 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY,
1109 AsyncFileTestHelper::ReadDirectory(
1110 file_system_context(), url, &entries));
1111
1112 EXPECT_TRUE(ofu()->IsDirectoryEmpty(context.get(), url));
1113 }
1114
1115 TEST_F(ObfuscatedFileUtilTest, TestTouch) {
1116 FileSystemURL url = CreateURLFromUTF8("file");
1117 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL));
1118
1119 base::Time last_access_time = base::Time::Now();
1120 base::Time last_modified_time = base::Time::Now();
1121
1122 // It's not there yet.
1123 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND,
1124 ofu()->Touch(
1125 context.get(), url, last_access_time, last_modified_time));
1126
1127 // OK, now create it.
1128 context.reset(NewContext(NULL));
1129 bool created = false;
1130 ASSERT_EQ(base::PLATFORM_FILE_OK,
1131 ofu()->EnsureFileExists(context.get(), url, &created));
1132 ASSERT_TRUE(created);
1133 TestTouchHelper(url, true);
1134
1135 // Now test a directory:
1136 context.reset(NewContext(NULL));
1137 bool exclusive = true;
1138 bool recursive = false;
1139 url = CreateURLFromUTF8("dir");
1140 ASSERT_EQ(base::PLATFORM_FILE_OK, ofu()->CreateDirectory(context.get(),
1141 url, exclusive, recursive));
1142 TestTouchHelper(url, false);
1143 }
1144
1145 TEST_F(ObfuscatedFileUtilTest, TestPathQuotas) {
1146 FileSystemURL url = CreateURLFromUTF8("fake/file");
1147 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL));
1148
1149 url = CreateURLFromUTF8("file name");
1150 context->set_allowed_bytes_growth(5);
1151 bool created = false;
1152 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE,
1153 ofu()->EnsureFileExists(context.get(), url, &created));
1154 EXPECT_FALSE(created);
1155 context->set_allowed_bytes_growth(1024);
1156 EXPECT_EQ(base::PLATFORM_FILE_OK,
1157 ofu()->EnsureFileExists(context.get(), url, &created));
1158 EXPECT_TRUE(created);
1159 int64 path_cost = ObfuscatedFileUtil::ComputeFilePathCost(url.path());
1160 EXPECT_EQ(1024 - path_cost, context->allowed_bytes_growth());
1161
1162 context->set_allowed_bytes_growth(1024);
1163 bool exclusive = true;
1164 bool recursive = true;
1165 url = CreateURLFromUTF8("directory/to/use");
1166 std::vector<base::FilePath::StringType> components;
1167 url.path().GetComponents(&components);
1168 path_cost = 0;
1169 typedef std::vector<base::FilePath::StringType>::iterator iterator;
1170 for (iterator iter = components.begin();
1171 iter != components.end(); ++iter) {
1172 path_cost += ObfuscatedFileUtil::ComputeFilePathCost(
1173 base::FilePath(*iter));
1174 }
1175 context.reset(NewContext(NULL));
1176 context->set_allowed_bytes_growth(1024);
1177 EXPECT_EQ(base::PLATFORM_FILE_OK, ofu()->CreateDirectory(
1178 context.get(), url, exclusive, recursive));
1179 EXPECT_EQ(1024 - path_cost, context->allowed_bytes_growth());
1180 }
1181
1182 TEST_F(ObfuscatedFileUtilTest, TestCopyOrMoveFileNotFound) {
1183 FileSystemURL source_url = CreateURLFromUTF8("path0.txt");
1184 FileSystemURL dest_url = CreateURLFromUTF8("path1.txt");
1185 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL));
1186
1187 bool is_copy_not_move = false;
1188 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND,
1189 ofu()->CopyOrMoveFile(context.get(), source_url, dest_url,
1190 FileSystemOperation::OPTION_NONE,
1191 is_copy_not_move));
1192 EXPECT_TRUE(change_observer()->HasNoChange());
1193 context.reset(NewContext(NULL));
1194 is_copy_not_move = true;
1195 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND,
1196 ofu()->CopyOrMoveFile(context.get(), source_url, dest_url,
1197 FileSystemOperation::OPTION_NONE,
1198 is_copy_not_move));
1199 EXPECT_TRUE(change_observer()->HasNoChange());
1200 source_url = CreateURLFromUTF8("dir/dir/file");
1201 bool exclusive = true;
1202 bool recursive = true;
1203 context.reset(NewContext(NULL));
1204 ASSERT_EQ(base::PLATFORM_FILE_OK, ofu()->CreateDirectory(
1205 context.get(),
1206 FileSystemURLDirName(source_url),
1207 exclusive, recursive));
1208 EXPECT_EQ(2, change_observer()->get_and_reset_create_directory_count());
1209 is_copy_not_move = false;
1210 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND,
1211 ofu()->CopyOrMoveFile(context.get(), source_url, dest_url,
1212 FileSystemOperation::OPTION_NONE,
1213 is_copy_not_move));
1214 EXPECT_TRUE(change_observer()->HasNoChange());
1215 context.reset(NewContext(NULL));
1216 is_copy_not_move = true;
1217 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND,
1218 ofu()->CopyOrMoveFile(context.get(), source_url, dest_url,
1219 FileSystemOperation::OPTION_NONE,
1220 is_copy_not_move));
1221 EXPECT_TRUE(change_observer()->HasNoChange());
1222 }
1223
1224 TEST_F(ObfuscatedFileUtilTest, TestCopyOrMoveFileSuccess) {
1225 const int64 kSourceLength = 5;
1226 const int64 kDestLength = 50;
1227
1228 for (size_t i = 0; i < arraysize(kCopyMoveTestCases); ++i) {
1229 SCOPED_TRACE(testing::Message() << "kCopyMoveTestCase " << i);
1230 const CopyMoveTestCaseRecord& test_case = kCopyMoveTestCases[i];
1231 SCOPED_TRACE(testing::Message() << "\t is_copy_not_move " <<
1232 test_case.is_copy_not_move);
1233 SCOPED_TRACE(testing::Message() << "\t source_path " <<
1234 test_case.source_path);
1235 SCOPED_TRACE(testing::Message() << "\t dest_path " <<
1236 test_case.dest_path);
1237 SCOPED_TRACE(testing::Message() << "\t cause_overwrite " <<
1238 test_case.cause_overwrite);
1239 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL));
1240
1241 bool exclusive = false;
1242 bool recursive = true;
1243 FileSystemURL source_url = CreateURLFromUTF8(test_case.source_path);
1244 FileSystemURL dest_url = CreateURLFromUTF8(test_case.dest_path);
1245
1246 context.reset(NewContext(NULL));
1247 ASSERT_EQ(base::PLATFORM_FILE_OK, ofu()->CreateDirectory(
1248 context.get(),
1249 FileSystemURLDirName(source_url),
1250 exclusive, recursive));
1251 context.reset(NewContext(NULL));
1252 ASSERT_EQ(base::PLATFORM_FILE_OK, ofu()->CreateDirectory(
1253 context.get(),
1254 FileSystemURLDirName(dest_url),
1255 exclusive, recursive));
1256
1257 bool created = false;
1258 context.reset(NewContext(NULL));
1259 ASSERT_EQ(base::PLATFORM_FILE_OK,
1260 ofu()->EnsureFileExists(context.get(), source_url, &created));
1261 ASSERT_TRUE(created);
1262 context.reset(NewContext(NULL));
1263 ASSERT_EQ(base::PLATFORM_FILE_OK,
1264 ofu()->Truncate(context.get(), source_url, kSourceLength));
1265
1266 if (test_case.cause_overwrite) {
1267 context.reset(NewContext(NULL));
1268 created = false;
1269 ASSERT_EQ(base::PLATFORM_FILE_OK,
1270 ofu()->EnsureFileExists(context.get(), dest_url, &created));
1271 ASSERT_TRUE(created);
1272 context.reset(NewContext(NULL));
1273 ASSERT_EQ(base::PLATFORM_FILE_OK,
1274 ofu()->Truncate(context.get(), dest_url, kDestLength));
1275 }
1276
1277 context.reset(NewContext(NULL));
1278 EXPECT_EQ(base::PLATFORM_FILE_OK, ofu()->CopyOrMoveFile(
1279 context.get(), source_url, dest_url, FileSystemOperation::OPTION_NONE,
1280 test_case.is_copy_not_move));
1281
1282 if (test_case.is_copy_not_move) {
1283 base::PlatformFileInfo file_info;
1284 base::FilePath local_path;
1285 context.reset(NewContext(NULL));
1286 EXPECT_EQ(base::PLATFORM_FILE_OK, ofu()->GetFileInfo(
1287 context.get(), source_url, &file_info, &local_path));
1288 EXPECT_EQ(kSourceLength, file_info.size);
1289 EXPECT_EQ(base::PLATFORM_FILE_OK,
1290 ofu()->DeleteFile(context.get(), source_url));
1291 } else {
1292 base::PlatformFileInfo file_info;
1293 base::FilePath local_path;
1294 context.reset(NewContext(NULL));
1295 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, ofu()->GetFileInfo(
1296 context.get(), source_url, &file_info, &local_path));
1297 }
1298 base::PlatformFileInfo file_info;
1299 base::FilePath local_path;
1300 EXPECT_EQ(base::PLATFORM_FILE_OK, ofu()->GetFileInfo(
1301 context.get(), dest_url, &file_info, &local_path));
1302 EXPECT_EQ(kSourceLength, file_info.size);
1303
1304 EXPECT_EQ(base::PLATFORM_FILE_OK,
1305 ofu()->DeleteFile(context.get(), dest_url));
1306 }
1307 }
1308
1309 TEST_F(ObfuscatedFileUtilTest, TestCopyPathQuotas) {
1310 FileSystemURL src_url = CreateURLFromUTF8("src path");
1311 FileSystemURL dest_url = CreateURLFromUTF8("destination path");
1312 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL));
1313 bool created = false;
1314 ASSERT_EQ(base::PLATFORM_FILE_OK, ofu()->EnsureFileExists(
1315 context.get(), src_url, &created));
1316
1317 bool is_copy = true;
1318 // Copy, no overwrite.
1319 context->set_allowed_bytes_growth(
1320 ObfuscatedFileUtil::ComputeFilePathCost(dest_url.path()) - 1);
1321 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE,
1322 ofu()->CopyOrMoveFile(
1323 context.get(),
1324 src_url, dest_url, FileSystemOperation::OPTION_NONE, is_copy));
1325 context.reset(NewContext(NULL));
1326 context->set_allowed_bytes_growth(
1327 ObfuscatedFileUtil::ComputeFilePathCost(dest_url.path()));
1328 EXPECT_EQ(base::PLATFORM_FILE_OK,
1329 ofu()->CopyOrMoveFile(
1330 context.get(),
1331 src_url, dest_url, FileSystemOperation::OPTION_NONE, is_copy));
1332
1333 // Copy, with overwrite.
1334 context.reset(NewContext(NULL));
1335 context->set_allowed_bytes_growth(0);
1336 EXPECT_EQ(base::PLATFORM_FILE_OK,
1337 ofu()->CopyOrMoveFile(
1338 context.get(),
1339 src_url, dest_url, FileSystemOperation::OPTION_NONE, is_copy));
1340 }
1341
1342 TEST_F(ObfuscatedFileUtilTest, TestMovePathQuotasWithRename) {
1343 FileSystemURL src_url = CreateURLFromUTF8("src path");
1344 FileSystemURL dest_url = CreateURLFromUTF8("destination path");
1345 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL));
1346 bool created = false;
1347 ASSERT_EQ(base::PLATFORM_FILE_OK, ofu()->EnsureFileExists(
1348 context.get(), src_url, &created));
1349
1350 bool is_copy = false;
1351 // Move, rename, no overwrite.
1352 context.reset(NewContext(NULL));
1353 context->set_allowed_bytes_growth(
1354 ObfuscatedFileUtil::ComputeFilePathCost(dest_url.path()) -
1355 ObfuscatedFileUtil::ComputeFilePathCost(src_url.path()) - 1);
1356 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE,
1357 ofu()->CopyOrMoveFile(
1358 context.get(),
1359 src_url, dest_url, FileSystemOperation::OPTION_NONE, is_copy));
1360 context.reset(NewContext(NULL));
1361 context->set_allowed_bytes_growth(
1362 ObfuscatedFileUtil::ComputeFilePathCost(dest_url.path()) -
1363 ObfuscatedFileUtil::ComputeFilePathCost(src_url.path()));
1364 EXPECT_EQ(base::PLATFORM_FILE_OK,
1365 ofu()->CopyOrMoveFile(
1366 context.get(),
1367 src_url, dest_url, FileSystemOperation::OPTION_NONE, is_copy));
1368
1369 context.reset(NewContext(NULL));
1370 ASSERT_EQ(base::PLATFORM_FILE_OK, ofu()->EnsureFileExists(
1371 context.get(), src_url, &created));
1372
1373 // Move, rename, with overwrite.
1374 context.reset(NewContext(NULL));
1375 context->set_allowed_bytes_growth(0);
1376 EXPECT_EQ(base::PLATFORM_FILE_OK,
1377 ofu()->CopyOrMoveFile(
1378 context.get(),
1379 src_url, dest_url, FileSystemOperation::OPTION_NONE, is_copy));
1380 }
1381
1382 TEST_F(ObfuscatedFileUtilTest, TestMovePathQuotasWithoutRename) {
1383 FileSystemURL src_url = CreateURLFromUTF8("src path");
1384 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL));
1385 bool created = false;
1386 ASSERT_EQ(base::PLATFORM_FILE_OK, ofu()->EnsureFileExists(
1387 context.get(), src_url, &created));
1388
1389 bool exclusive = true;
1390 bool recursive = false;
1391 FileSystemURL dir_url = CreateURLFromUTF8("directory path");
1392 context.reset(NewContext(NULL));
1393 ASSERT_EQ(base::PLATFORM_FILE_OK, ofu()->CreateDirectory(
1394 context.get(), dir_url, exclusive, recursive));
1395
1396 FileSystemURL dest_url = FileSystemURLAppend(
1397 dir_url, src_url.path().value());
1398
1399 bool is_copy = false;
1400 int64 allowed_bytes_growth = -1000; // Over quota, this should still work.
1401 // Move, no rename, no overwrite.
1402 context.reset(NewContext(NULL));
1403 context->set_allowed_bytes_growth(allowed_bytes_growth);
1404 EXPECT_EQ(base::PLATFORM_FILE_OK,
1405 ofu()->CopyOrMoveFile(
1406 context.get(),
1407 src_url, dest_url, FileSystemOperation::OPTION_NONE, is_copy));
1408 EXPECT_EQ(allowed_bytes_growth, context->allowed_bytes_growth());
1409
1410 // Move, no rename, with overwrite.
1411 context.reset(NewContext(NULL));
1412 ASSERT_EQ(base::PLATFORM_FILE_OK, ofu()->EnsureFileExists(
1413 context.get(), src_url, &created));
1414 context.reset(NewContext(NULL));
1415 context->set_allowed_bytes_growth(allowed_bytes_growth);
1416 EXPECT_EQ(base::PLATFORM_FILE_OK,
1417 ofu()->CopyOrMoveFile(
1418 context.get(),
1419 src_url, dest_url, FileSystemOperation::OPTION_NONE, is_copy));
1420 EXPECT_EQ(
1421 allowed_bytes_growth +
1422 ObfuscatedFileUtil::ComputeFilePathCost(src_url.path()),
1423 context->allowed_bytes_growth());
1424 }
1425
1426 TEST_F(ObfuscatedFileUtilTest, TestCopyInForeignFile) {
1427 TestCopyInForeignFileHelper(false /* overwrite */);
1428 TestCopyInForeignFileHelper(true /* overwrite */);
1429 }
1430
1431 TEST_F(ObfuscatedFileUtilTest, TestEnumerator) {
1432 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL));
1433 FileSystemURL src_url = CreateURLFromUTF8("source dir");
1434 bool exclusive = true;
1435 bool recursive = false;
1436 ASSERT_EQ(base::PLATFORM_FILE_OK, ofu()->CreateDirectory(
1437 context.get(), src_url, exclusive, recursive));
1438
1439 std::set<base::FilePath::StringType> files;
1440 std::set<base::FilePath::StringType> directories;
1441 FillTestDirectory(src_url, &files, &directories);
1442
1443 FileSystemURL dest_url = CreateURLFromUTF8("destination dir");
1444
1445 EXPECT_FALSE(DirectoryExists(dest_url));
1446 ASSERT_EQ(base::PLATFORM_FILE_OK,
1447 AsyncFileTestHelper::Copy(
1448 file_system_context(), src_url, dest_url));
1449
1450 ValidateTestDirectory(dest_url, files, directories);
1451 EXPECT_TRUE(DirectoryExists(src_url));
1452 EXPECT_TRUE(DirectoryExists(dest_url));
1453 recursive = true;
1454 ASSERT_EQ(base::PLATFORM_FILE_OK,
1455 AsyncFileTestHelper::Remove(
1456 file_system_context(), dest_url, recursive));
1457 EXPECT_FALSE(DirectoryExists(dest_url));
1458 }
1459
1460 TEST_F(ObfuscatedFileUtilTest, TestOriginEnumerator) {
1461 scoped_ptr<ObfuscatedFileUtil::AbstractOriginEnumerator>
1462 enumerator(ofu()->CreateOriginEnumerator());
1463 // The test helper starts out with a single filesystem.
1464 EXPECT_TRUE(enumerator.get());
1465 EXPECT_EQ(origin(), enumerator->Next());
1466 ASSERT_TRUE(type() == kFileSystemTypeTemporary);
1467 EXPECT_TRUE(enumerator->HasFileSystemType(kFileSystemTypeTemporary));
1468 EXPECT_FALSE(enumerator->HasFileSystemType(kFileSystemTypePersistent));
1469 EXPECT_EQ(GURL(), enumerator->Next());
1470 EXPECT_FALSE(enumerator->HasFileSystemType(kFileSystemTypeTemporary));
1471 EXPECT_FALSE(enumerator->HasFileSystemType(kFileSystemTypePersistent));
1472
1473 std::set<GURL> origins_expected;
1474 origins_expected.insert(origin());
1475
1476 for (size_t i = 0; i < arraysize(kOriginEnumerationTestRecords); ++i) {
1477 SCOPED_TRACE(testing::Message() <<
1478 "Validating kOriginEnumerationTestRecords " << i);
1479 const OriginEnumerationTestRecord& record =
1480 kOriginEnumerationTestRecords[i];
1481 GURL origin_url(record.origin_url);
1482 origins_expected.insert(origin_url);
1483 if (record.has_temporary) {
1484 scoped_ptr<SandboxFileSystemTestHelper> file_system(
1485 NewFileSystem(origin_url, kFileSystemTypeTemporary));
1486 scoped_ptr<FileSystemOperationContext> context(
1487 NewContext(file_system.get()));
1488 bool created = false;
1489 ASSERT_EQ(base::PLATFORM_FILE_OK,
1490 ofu()->EnsureFileExists(
1491 context.get(),
1492 file_system->CreateURLFromUTF8("file"),
1493 &created));
1494 EXPECT_TRUE(created);
1495 }
1496 if (record.has_persistent) {
1497 scoped_ptr<SandboxFileSystemTestHelper> file_system(
1498 NewFileSystem(origin_url, kFileSystemTypePersistent));
1499 scoped_ptr<FileSystemOperationContext> context(
1500 NewContext(file_system.get()));
1501 bool created = false;
1502 ASSERT_EQ(base::PLATFORM_FILE_OK,
1503 ofu()->EnsureFileExists(
1504 context.get(),
1505 file_system->CreateURLFromUTF8("file"),
1506 &created));
1507 EXPECT_TRUE(created);
1508 }
1509 }
1510 enumerator.reset(ofu()->CreateOriginEnumerator());
1511 EXPECT_TRUE(enumerator.get());
1512 std::set<GURL> origins_found;
1513 GURL origin_url;
1514 while (!(origin_url = enumerator->Next()).is_empty()) {
1515 origins_found.insert(origin_url);
1516 SCOPED_TRACE(testing::Message() << "Handling " << origin_url.spec());
1517 bool found = false;
1518 for (size_t i = 0; !found && i < arraysize(kOriginEnumerationTestRecords);
1519 ++i) {
1520 const OriginEnumerationTestRecord& record =
1521 kOriginEnumerationTestRecords[i];
1522 if (GURL(record.origin_url) != origin_url)
1523 continue;
1524 found = true;
1525 EXPECT_EQ(record.has_temporary,
1526 enumerator->HasFileSystemType(kFileSystemTypeTemporary));
1527 EXPECT_EQ(record.has_persistent,
1528 enumerator->HasFileSystemType(kFileSystemTypePersistent));
1529 }
1530 // Deal with the default filesystem created by the test helper.
1531 if (!found && origin_url == origin()) {
1532 ASSERT_TRUE(type() == kFileSystemTypeTemporary);
1533 EXPECT_EQ(true,
1534 enumerator->HasFileSystemType(kFileSystemTypeTemporary));
1535 EXPECT_FALSE(enumerator->HasFileSystemType(kFileSystemTypePersistent));
1536 found = true;
1537 }
1538 EXPECT_TRUE(found);
1539 }
1540
1541 std::set<GURL> diff;
1542 std::set_symmetric_difference(origins_expected.begin(),
1543 origins_expected.end(), origins_found.begin(), origins_found.end(),
1544 inserter(diff, diff.begin()));
1545 EXPECT_TRUE(diff.empty());
1546 }
1547
1548 TEST_F(ObfuscatedFileUtilTest, TestRevokeUsageCache) {
1549 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL));
1550
1551 int64 expected_quota = 0;
1552
1553 for (size_t i = 0; i < test::kRegularTestCaseSize; ++i) {
1554 SCOPED_TRACE(testing::Message() << "Creating kRegularTestCase " << i);
1555 const test::TestCaseRecord& test_case = test::kRegularTestCases[i];
1556 base::FilePath file_path(test_case.path);
1557 expected_quota += ObfuscatedFileUtil::ComputeFilePathCost(file_path);
1558 if (test_case.is_directory) {
1559 bool exclusive = true;
1560 bool recursive = false;
1561 ASSERT_EQ(base::PLATFORM_FILE_OK,
1562 ofu()->CreateDirectory(context.get(), CreateURL(file_path),
1563 exclusive, recursive));
1564 } else {
1565 bool created = false;
1566 ASSERT_EQ(base::PLATFORM_FILE_OK,
1567 ofu()->EnsureFileExists(context.get(), CreateURL(file_path),
1568 &created));
1569 ASSERT_TRUE(created);
1570 ASSERT_EQ(base::PLATFORM_FILE_OK,
1571 ofu()->Truncate(context.get(),
1572 CreateURL(file_path),
1573 test_case.data_file_size));
1574 expected_quota += test_case.data_file_size;
1575 }
1576 }
1577
1578 // Usually raw size in usage cache and the usage returned by QuotaUtil
1579 // should be same.
1580 EXPECT_EQ(expected_quota, SizeInUsageFile());
1581 EXPECT_EQ(expected_quota, SizeByQuotaUtil());
1582
1583 RevokeUsageCache();
1584 EXPECT_EQ(-1, SizeInUsageFile());
1585 EXPECT_EQ(expected_quota, SizeByQuotaUtil());
1586
1587 // This should reconstruct the cache.
1588 GetUsageFromQuotaManager();
1589 EXPECT_EQ(expected_quota, SizeInUsageFile());
1590 EXPECT_EQ(expected_quota, SizeByQuotaUtil());
1591 EXPECT_EQ(expected_quota, usage());
1592 }
1593
1594 TEST_F(ObfuscatedFileUtilTest, TestInconsistency) {
1595 const FileSystemURL kPath1 = CreateURLFromUTF8("hoge");
1596 const FileSystemURL kPath2 = CreateURLFromUTF8("fuga");
1597
1598 scoped_ptr<FileSystemOperationContext> context;
1599 base::PlatformFile file;
1600 base::PlatformFileInfo file_info;
1601 base::FilePath data_path;
1602 bool created = false;
1603
1604 // Create a non-empty file.
1605 context.reset(NewContext(NULL));
1606 EXPECT_EQ(base::PLATFORM_FILE_OK,
1607 ofu()->EnsureFileExists(context.get(), kPath1, &created));
1608 EXPECT_TRUE(created);
1609 context.reset(NewContext(NULL));
1610 EXPECT_EQ(base::PLATFORM_FILE_OK,
1611 ofu()->Truncate(context.get(), kPath1, 10));
1612 context.reset(NewContext(NULL));
1613 EXPECT_EQ(base::PLATFORM_FILE_OK,
1614 ofu()->GetFileInfo(
1615 context.get(), kPath1, &file_info, &data_path));
1616 EXPECT_EQ(10, file_info.size);
1617
1618 // Destroy database to make inconsistency between database and filesystem.
1619 ofu()->DestroyDirectoryDatabase(origin(), type());
1620
1621 // Try to get file info of broken file.
1622 EXPECT_FALSE(PathExists(kPath1));
1623 context.reset(NewContext(NULL));
1624 EXPECT_EQ(base::PLATFORM_FILE_OK,
1625 ofu()->EnsureFileExists(context.get(), kPath1, &created));
1626 EXPECT_TRUE(created);
1627 context.reset(NewContext(NULL));
1628 EXPECT_EQ(base::PLATFORM_FILE_OK,
1629 ofu()->GetFileInfo(
1630 context.get(), kPath1, &file_info, &data_path));
1631 EXPECT_EQ(0, file_info.size);
1632
1633 // Make another broken file to |kPath2|.
1634 context.reset(NewContext(NULL));
1635 EXPECT_EQ(base::PLATFORM_FILE_OK,
1636 ofu()->EnsureFileExists(context.get(), kPath2, &created));
1637 EXPECT_TRUE(created);
1638
1639 // Destroy again.
1640 ofu()->DestroyDirectoryDatabase(origin(), type());
1641
1642 // Repair broken |kPath1|.
1643 context.reset(NewContext(NULL));
1644 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND,
1645 ofu()->Touch(context.get(), kPath1, base::Time::Now(),
1646 base::Time::Now()));
1647 EXPECT_EQ(base::PLATFORM_FILE_OK,
1648 ofu()->EnsureFileExists(context.get(), kPath1, &created));
1649 EXPECT_TRUE(created);
1650
1651 // Copy from sound |kPath1| to broken |kPath2|.
1652 context.reset(NewContext(NULL));
1653 EXPECT_EQ(base::PLATFORM_FILE_OK,
1654 ofu()->CopyOrMoveFile(context.get(), kPath1, kPath2,
1655 FileSystemOperation::OPTION_NONE,
1656 true /* copy */));
1657
1658 ofu()->DestroyDirectoryDatabase(origin(), type());
1659 context.reset(NewContext(NULL));
1660 EXPECT_EQ(base::PLATFORM_FILE_OK,
1661 ofu()->CreateOrOpen(
1662 context.get(), kPath1,
1663 base::PLATFORM_FILE_READ | base::PLATFORM_FILE_CREATE,
1664 &file, &created));
1665 EXPECT_TRUE(created);
1666 EXPECT_TRUE(base::GetPlatformFileInfo(file, &file_info));
1667 EXPECT_EQ(0, file_info.size);
1668 EXPECT_TRUE(base::ClosePlatformFile(file));
1669 }
1670
1671 TEST_F(ObfuscatedFileUtilTest, TestIncompleteDirectoryReading) {
1672 const FileSystemURL kPath[] = {
1673 CreateURLFromUTF8("foo"),
1674 CreateURLFromUTF8("bar"),
1675 CreateURLFromUTF8("baz")
1676 };
1677 const FileSystemURL empty_path = CreateURL(base::FilePath());
1678 scoped_ptr<FileSystemOperationContext> context;
1679
1680 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kPath); ++i) {
1681 bool created = false;
1682 context.reset(NewContext(NULL));
1683 EXPECT_EQ(base::PLATFORM_FILE_OK,
1684 ofu()->EnsureFileExists(context.get(), kPath[i], &created));
1685 EXPECT_TRUE(created);
1686 }
1687
1688 std::vector<DirectoryEntry> entries;
1689 EXPECT_EQ(base::PLATFORM_FILE_OK,
1690 AsyncFileTestHelper::ReadDirectory(
1691 file_system_context(), empty_path, &entries));
1692 EXPECT_EQ(3u, entries.size());
1693
1694 base::FilePath local_path;
1695 EXPECT_EQ(base::PLATFORM_FILE_OK,
1696 ofu()->GetLocalFilePath(context.get(), kPath[0], &local_path));
1697 EXPECT_TRUE(base::DeleteFile(local_path, false));
1698
1699 entries.clear();
1700 EXPECT_EQ(base::PLATFORM_FILE_OK,
1701 AsyncFileTestHelper::ReadDirectory(
1702 file_system_context(), empty_path, &entries));
1703 EXPECT_EQ(ARRAYSIZE_UNSAFE(kPath) - 1, entries.size());
1704 }
1705
1706 TEST_F(ObfuscatedFileUtilTest, TestDirectoryTimestampForCreation) {
1707 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL));
1708 const FileSystemURL dir_url = CreateURLFromUTF8("foo_dir");
1709
1710 // Create working directory.
1711 EXPECT_EQ(base::PLATFORM_FILE_OK,
1712 ofu()->CreateDirectory(context.get(), dir_url, false, false));
1713
1714 // EnsureFileExists, create case.
1715 FileSystemURL url(FileSystemURLAppendUTF8(
1716 dir_url, "EnsureFileExists_file"));
1717 bool created = false;
1718 ClearTimestamp(dir_url);
1719 context.reset(NewContext(NULL));
1720 EXPECT_EQ(base::PLATFORM_FILE_OK,
1721 ofu()->EnsureFileExists(context.get(), url, &created));
1722 EXPECT_TRUE(created);
1723 EXPECT_NE(base::Time(), GetModifiedTime(dir_url));
1724
1725 // non create case.
1726 created = true;
1727 ClearTimestamp(dir_url);
1728 context.reset(NewContext(NULL));
1729 EXPECT_EQ(base::PLATFORM_FILE_OK,
1730 ofu()->EnsureFileExists(context.get(), url, &created));
1731 EXPECT_FALSE(created);
1732 EXPECT_EQ(base::Time(), GetModifiedTime(dir_url));
1733
1734 // fail case.
1735 url = FileSystemURLAppendUTF8(dir_url, "EnsureFileExists_dir");
1736 context.reset(NewContext(NULL));
1737 EXPECT_EQ(base::PLATFORM_FILE_OK,
1738 ofu()->CreateDirectory(context.get(), url, false, false));
1739
1740 ClearTimestamp(dir_url);
1741 context.reset(NewContext(NULL));
1742 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_A_FILE,
1743 ofu()->EnsureFileExists(context.get(), url, &created));
1744 EXPECT_EQ(base::Time(), GetModifiedTime(dir_url));
1745
1746 // CreateOrOpen, create case.
1747 url = FileSystemURLAppendUTF8(dir_url, "CreateOrOpen_file");
1748 base::PlatformFile file_handle = base::kInvalidPlatformFileValue;
1749 created = false;
1750 ClearTimestamp(dir_url);
1751 context.reset(NewContext(NULL));
1752 EXPECT_EQ(base::PLATFORM_FILE_OK,
1753 ofu()->CreateOrOpen(
1754 context.get(), url,
1755 base::PLATFORM_FILE_CREATE | base::PLATFORM_FILE_WRITE,
1756 &file_handle, &created));
1757 EXPECT_NE(base::kInvalidPlatformFileValue, file_handle);
1758 EXPECT_TRUE(created);
1759 EXPECT_TRUE(base::ClosePlatformFile(file_handle));
1760 EXPECT_NE(base::Time(), GetModifiedTime(dir_url));
1761
1762 // open case.
1763 file_handle = base::kInvalidPlatformFileValue;
1764 created = true;
1765 ClearTimestamp(dir_url);
1766 context.reset(NewContext(NULL));
1767 EXPECT_EQ(base::PLATFORM_FILE_OK,
1768 ofu()->CreateOrOpen(
1769 context.get(), url,
1770 base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_WRITE,
1771 &file_handle, &created));
1772 EXPECT_NE(base::kInvalidPlatformFileValue, file_handle);
1773 EXPECT_FALSE(created);
1774 EXPECT_TRUE(base::ClosePlatformFile(file_handle));
1775 EXPECT_EQ(base::Time(), GetModifiedTime(dir_url));
1776
1777 // fail case
1778 file_handle = base::kInvalidPlatformFileValue;
1779 ClearTimestamp(dir_url);
1780 context.reset(NewContext(NULL));
1781 EXPECT_EQ(base::PLATFORM_FILE_ERROR_EXISTS,
1782 ofu()->CreateOrOpen(
1783 context.get(), url,
1784 base::PLATFORM_FILE_CREATE | base::PLATFORM_FILE_WRITE,
1785 &file_handle, &created));
1786 EXPECT_EQ(base::kInvalidPlatformFileValue, file_handle);
1787 EXPECT_EQ(base::Time(), GetModifiedTime(dir_url));
1788
1789 // CreateDirectory, create case.
1790 // Creating CreateDirectory_dir and CreateDirectory_dir/subdir.
1791 url = FileSystemURLAppendUTF8(dir_url, "CreateDirectory_dir");
1792 FileSystemURL subdir_url(FileSystemURLAppendUTF8(url, "subdir"));
1793 ClearTimestamp(dir_url);
1794 context.reset(NewContext(NULL));
1795 EXPECT_EQ(base::PLATFORM_FILE_OK,
1796 ofu()->CreateDirectory(context.get(), subdir_url,
1797 true /* exclusive */, true /* recursive */));
1798 EXPECT_NE(base::Time(), GetModifiedTime(dir_url));
1799
1800 // create subdir case.
1801 // Creating CreateDirectory_dir/subdir2.
1802 subdir_url = FileSystemURLAppendUTF8(url, "subdir2");
1803 ClearTimestamp(dir_url);
1804 ClearTimestamp(url);
1805 context.reset(NewContext(NULL));
1806 EXPECT_EQ(base::PLATFORM_FILE_OK,
1807 ofu()->CreateDirectory(context.get(), subdir_url,
1808 true /* exclusive */, true /* recursive */));
1809 EXPECT_EQ(base::Time(), GetModifiedTime(dir_url));
1810 EXPECT_NE(base::Time(), GetModifiedTime(url));
1811
1812 // fail case.
1813 url = FileSystemURLAppendUTF8(dir_url, "CreateDirectory_dir");
1814 ClearTimestamp(dir_url);
1815 context.reset(NewContext(NULL));
1816 EXPECT_EQ(base::PLATFORM_FILE_ERROR_EXISTS,
1817 ofu()->CreateDirectory(context.get(), url,
1818 true /* exclusive */, true /* recursive */));
1819 EXPECT_EQ(base::Time(), GetModifiedTime(dir_url));
1820
1821 // CopyInForeignFile, create case.
1822 url = FileSystemURLAppendUTF8(dir_url, "CopyInForeignFile_file");
1823 FileSystemURL src_path = FileSystemURLAppendUTF8(
1824 dir_url, "CopyInForeignFile_src_file");
1825 context.reset(NewContext(NULL));
1826 EXPECT_EQ(base::PLATFORM_FILE_OK,
1827 ofu()->EnsureFileExists(context.get(), src_path, &created));
1828 EXPECT_TRUE(created);
1829 base::FilePath src_local_path;
1830 context.reset(NewContext(NULL));
1831 EXPECT_EQ(base::PLATFORM_FILE_OK,
1832 ofu()->GetLocalFilePath(context.get(), src_path, &src_local_path));
1833
1834 ClearTimestamp(dir_url);
1835 context.reset(NewContext(NULL));
1836 EXPECT_EQ(base::PLATFORM_FILE_OK,
1837 ofu()->CopyInForeignFile(context.get(),
1838 src_local_path,
1839 url));
1840 EXPECT_NE(base::Time(), GetModifiedTime(dir_url));
1841 }
1842
1843 TEST_F(ObfuscatedFileUtilTest, TestDirectoryTimestampForDeletion) {
1844 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL));
1845 const FileSystemURL dir_url = CreateURLFromUTF8("foo_dir");
1846
1847 // Create working directory.
1848 EXPECT_EQ(base::PLATFORM_FILE_OK,
1849 ofu()->CreateDirectory(context.get(), dir_url, false, false));
1850
1851 // DeleteFile, delete case.
1852 FileSystemURL url = FileSystemURLAppendUTF8(
1853 dir_url, "DeleteFile_file");
1854 bool created = false;
1855 context.reset(NewContext(NULL));
1856 EXPECT_EQ(base::PLATFORM_FILE_OK,
1857 ofu()->EnsureFileExists(context.get(), url, &created));
1858 EXPECT_TRUE(created);
1859
1860 ClearTimestamp(dir_url);
1861 context.reset(NewContext(NULL));
1862 EXPECT_EQ(base::PLATFORM_FILE_OK,
1863 ofu()->DeleteFile(context.get(), url));
1864 EXPECT_NE(base::Time(), GetModifiedTime(dir_url));
1865
1866 // fail case.
1867 ClearTimestamp(dir_url);
1868 context.reset(NewContext(NULL));
1869 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND,
1870 ofu()->DeleteFile(context.get(), url));
1871 EXPECT_EQ(base::Time(), GetModifiedTime(dir_url));
1872
1873 // DeleteDirectory, fail case.
1874 url = FileSystemURLAppendUTF8(dir_url, "DeleteDirectory_dir");
1875 FileSystemURL file_path(FileSystemURLAppendUTF8(url, "pakeratta"));
1876 context.reset(NewContext(NULL));
1877 EXPECT_EQ(base::PLATFORM_FILE_OK,
1878 ofu()->CreateDirectory(context.get(), url, true, true));
1879 created = false;
1880 context.reset(NewContext(NULL));
1881 EXPECT_EQ(base::PLATFORM_FILE_OK,
1882 ofu()->EnsureFileExists(context.get(), file_path, &created));
1883 EXPECT_TRUE(created);
1884
1885 ClearTimestamp(dir_url);
1886 context.reset(NewContext(NULL));
1887 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_EMPTY,
1888 ofu()->DeleteDirectory(context.get(), url));
1889 EXPECT_EQ(base::Time(), GetModifiedTime(dir_url));
1890
1891 // delete case.
1892 context.reset(NewContext(NULL));
1893 EXPECT_EQ(base::PLATFORM_FILE_OK,
1894 ofu()->DeleteFile(context.get(), file_path));
1895
1896 ClearTimestamp(dir_url);
1897 context.reset(NewContext(NULL));
1898 EXPECT_EQ(base::PLATFORM_FILE_OK, ofu()->DeleteDirectory(context.get(), url));
1899 EXPECT_NE(base::Time(), GetModifiedTime(dir_url));
1900 }
1901
1902 TEST_F(ObfuscatedFileUtilTest, TestDirectoryTimestampForCopyAndMove) {
1903 TestDirectoryTimestampHelper(
1904 CreateURLFromUTF8("copy overwrite"), true, true);
1905 TestDirectoryTimestampHelper(
1906 CreateURLFromUTF8("copy non-overwrite"), true, false);
1907 TestDirectoryTimestampHelper(
1908 CreateURLFromUTF8("move overwrite"), false, true);
1909 TestDirectoryTimestampHelper(
1910 CreateURLFromUTF8("move non-overwrite"), false, false);
1911 }
1912
1913 TEST_F(ObfuscatedFileUtilTest, TestFileEnumeratorTimestamp) {
1914 FileSystemURL dir = CreateURLFromUTF8("foo");
1915 FileSystemURL url1 = FileSystemURLAppendUTF8(dir, "bar");
1916 FileSystemURL url2 = FileSystemURLAppendUTF8(dir, "baz");
1917
1918 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL));
1919 EXPECT_EQ(base::PLATFORM_FILE_OK,
1920 ofu()->CreateDirectory(context.get(), dir, false, false));
1921
1922 bool created = false;
1923 context.reset(NewContext(NULL));
1924 EXPECT_EQ(base::PLATFORM_FILE_OK,
1925 ofu()->EnsureFileExists(context.get(), url1, &created));
1926 EXPECT_TRUE(created);
1927
1928 context.reset(NewContext(NULL));
1929 EXPECT_EQ(base::PLATFORM_FILE_OK,
1930 ofu()->CreateDirectory(context.get(), url2, false, false));
1931
1932 base::FilePath file_path;
1933 context.reset(NewContext(NULL));
1934 EXPECT_EQ(base::PLATFORM_FILE_OK,
1935 ofu()->GetLocalFilePath(context.get(), url1, &file_path));
1936 EXPECT_FALSE(file_path.empty());
1937
1938 context.reset(NewContext(NULL));
1939 EXPECT_EQ(base::PLATFORM_FILE_OK,
1940 ofu()->Touch(context.get(), url1,
1941 base::Time::Now() + base::TimeDelta::FromHours(1),
1942 base::Time()));
1943
1944 context.reset(NewContext(NULL));
1945 scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator> file_enum(
1946 ofu()->CreateFileEnumerator(context.get(), dir, false));
1947
1948 int count = 0;
1949 base::FilePath file_path_each;
1950 while (!(file_path_each = file_enum->Next()).empty()) {
1951 context.reset(NewContext(NULL));
1952 base::PlatformFileInfo file_info;
1953 base::FilePath file_path;
1954 EXPECT_EQ(base::PLATFORM_FILE_OK,
1955 ofu()->GetFileInfo(context.get(),
1956 FileSystemURL::CreateForTest(
1957 dir.origin(),
1958 dir.mount_type(),
1959 file_path_each),
1960 &file_info, &file_path));
1961 EXPECT_EQ(file_info.is_directory, file_enum->IsDirectory());
1962 EXPECT_EQ(file_info.last_modified, file_enum->LastModifiedTime());
1963 EXPECT_EQ(file_info.size, file_enum->Size());
1964 ++count;
1965 }
1966 EXPECT_EQ(2, count);
1967 }
1968
1969 // crbug.com/176470
1970 #if defined(OS_WIN) || defined(OS_ANDROID)
1971 #define MAYBE_TestQuotaOnCopyFile DISABLED_TestQuotaOnCopyFile
1972 #else
1973 #define MAYBE_TestQuotaOnCopyFile TestQuotaOnCopyFile
1974 #endif
1975 TEST_F(ObfuscatedFileUtilTest, MAYBE_TestQuotaOnCopyFile) {
1976 FileSystemURL from_file(CreateURLFromUTF8("fromfile"));
1977 FileSystemURL obstacle_file(CreateURLFromUTF8("obstaclefile"));
1978 FileSystemURL to_file1(CreateURLFromUTF8("tofile1"));
1979 FileSystemURL to_file2(CreateURLFromUTF8("tofile2"));
1980 bool created;
1981
1982 int64 expected_total_file_size = 0;
1983 ASSERT_EQ(base::PLATFORM_FILE_OK,
1984 ofu()->EnsureFileExists(
1985 AllowUsageIncrease(PathCost(from_file))->context(),
1986 from_file, &created));
1987 ASSERT_TRUE(created);
1988 ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize());
1989
1990 ASSERT_EQ(base::PLATFORM_FILE_OK,
1991 ofu()->EnsureFileExists(
1992 AllowUsageIncrease(PathCost(obstacle_file))->context(),
1993 obstacle_file, &created));
1994 ASSERT_TRUE(created);
1995 ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize());
1996
1997 int64 from_file_size = 1020;
1998 expected_total_file_size += from_file_size;
1999 ASSERT_EQ(base::PLATFORM_FILE_OK,
2000 ofu()->Truncate(
2001 AllowUsageIncrease(from_file_size)->context(),
2002 from_file, from_file_size));
2003 ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize());
2004
2005 int64 obstacle_file_size = 1;
2006 expected_total_file_size += obstacle_file_size;
2007 ASSERT_EQ(base::PLATFORM_FILE_OK,
2008 ofu()->Truncate(
2009 AllowUsageIncrease(obstacle_file_size)->context(),
2010 obstacle_file, obstacle_file_size));
2011 ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize());
2012
2013 int64 to_file1_size = from_file_size;
2014 expected_total_file_size += to_file1_size;
2015 ASSERT_EQ(base::PLATFORM_FILE_OK,
2016 ofu()->CopyOrMoveFile(
2017 AllowUsageIncrease(
2018 PathCost(to_file1) + to_file1_size)->context(),
2019 from_file, to_file1,
2020 FileSystemOperation::OPTION_NONE,
2021 true /* copy */));
2022 ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize());
2023
2024 ASSERT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE,
2025 ofu()->CopyOrMoveFile(
2026 DisallowUsageIncrease(
2027 PathCost(to_file2) + from_file_size)->context(),
2028 from_file, to_file2, FileSystemOperation::OPTION_NONE,
2029 true /* copy */));
2030 ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize());
2031
2032 int64 old_obstacle_file_size = obstacle_file_size;
2033 obstacle_file_size = from_file_size;
2034 expected_total_file_size += obstacle_file_size - old_obstacle_file_size;
2035 ASSERT_EQ(base::PLATFORM_FILE_OK,
2036 ofu()->CopyOrMoveFile(
2037 AllowUsageIncrease(
2038 obstacle_file_size - old_obstacle_file_size)->context(),
2039 from_file, obstacle_file,
2040 FileSystemOperation::OPTION_NONE,
2041 true /* copy */));
2042 ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize());
2043
2044 int64 old_from_file_size = from_file_size;
2045 from_file_size = old_from_file_size - 1;
2046 expected_total_file_size += from_file_size - old_from_file_size;
2047 ASSERT_EQ(base::PLATFORM_FILE_OK,
2048 ofu()->Truncate(
2049 AllowUsageIncrease(
2050 from_file_size - old_from_file_size)->context(),
2051 from_file, from_file_size));
2052 ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize());
2053
2054 // quota exceeded
2055 {
2056 old_obstacle_file_size = obstacle_file_size;
2057 obstacle_file_size = from_file_size;
2058 expected_total_file_size += obstacle_file_size - old_obstacle_file_size;
2059 scoped_ptr<UsageVerifyHelper> helper = AllowUsageIncrease(
2060 obstacle_file_size - old_obstacle_file_size);
2061 helper->context()->set_allowed_bytes_growth(
2062 helper->context()->allowed_bytes_growth() - 1);
2063 ASSERT_EQ(base::PLATFORM_FILE_OK,
2064 ofu()->CopyOrMoveFile(
2065 helper->context(),
2066 from_file, obstacle_file,
2067 FileSystemOperation::OPTION_NONE,
2068 true /* copy */));
2069 ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize());
2070 }
2071 }
2072
2073 TEST_F(ObfuscatedFileUtilTest, TestQuotaOnMoveFile) {
2074 FileSystemURL from_file(CreateURLFromUTF8("fromfile"));
2075 FileSystemURL obstacle_file(CreateURLFromUTF8("obstaclefile"));
2076 FileSystemURL to_file(CreateURLFromUTF8("tofile"));
2077 bool created;
2078
2079 int64 expected_total_file_size = 0;
2080 ASSERT_EQ(base::PLATFORM_FILE_OK,
2081 ofu()->EnsureFileExists(
2082 AllowUsageIncrease(PathCost(from_file))->context(),
2083 from_file, &created));
2084 ASSERT_TRUE(created);
2085 ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize());
2086
2087 int64 from_file_size = 1020;
2088 expected_total_file_size += from_file_size;
2089 ASSERT_EQ(base::PLATFORM_FILE_OK,
2090 ofu()->Truncate(
2091 AllowUsageIncrease(from_file_size)->context(),
2092 from_file, from_file_size));
2093 ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize());
2094
2095 int64 to_file_size ALLOW_UNUSED = from_file_size;
2096 from_file_size = 0;
2097 ASSERT_EQ(base::PLATFORM_FILE_OK,
2098 ofu()->CopyOrMoveFile(
2099 AllowUsageIncrease(-PathCost(from_file) +
2100 PathCost(to_file))->context(),
2101 from_file, to_file,
2102 FileSystemOperation::OPTION_NONE,
2103 false /* move */));
2104 ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize());
2105
2106 ASSERT_EQ(base::PLATFORM_FILE_OK,
2107 ofu()->EnsureFileExists(
2108 AllowUsageIncrease(PathCost(from_file))->context(),
2109 from_file, &created));
2110 ASSERT_TRUE(created);
2111 ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize());
2112
2113 ASSERT_EQ(base::PLATFORM_FILE_OK,
2114 ofu()->EnsureFileExists(
2115 AllowUsageIncrease(PathCost(obstacle_file))->context(),
2116 obstacle_file, &created));
2117 ASSERT_TRUE(created);
2118 ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize());
2119
2120 from_file_size = 1020;
2121 expected_total_file_size += from_file_size;
2122 ASSERT_EQ(base::PLATFORM_FILE_OK,
2123 ofu()->Truncate(
2124 AllowUsageIncrease(from_file_size)->context(),
2125 from_file, from_file_size));
2126 ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize());
2127
2128 int64 obstacle_file_size = 1;
2129 expected_total_file_size += obstacle_file_size;
2130 ASSERT_EQ(base::PLATFORM_FILE_OK,
2131 ofu()->Truncate(
2132 AllowUsageIncrease(1)->context(),
2133 obstacle_file, obstacle_file_size));
2134 ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize());
2135
2136 int64 old_obstacle_file_size = obstacle_file_size;
2137 obstacle_file_size = from_file_size;
2138 from_file_size = 0;
2139 expected_total_file_size -= old_obstacle_file_size;
2140 ASSERT_EQ(base::PLATFORM_FILE_OK,
2141 ofu()->CopyOrMoveFile(
2142 AllowUsageIncrease(
2143 -old_obstacle_file_size - PathCost(from_file))->context(),
2144 from_file, obstacle_file,
2145 FileSystemOperation::OPTION_NONE,
2146 false /* move */));
2147 ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize());
2148
2149 ASSERT_EQ(base::PLATFORM_FILE_OK,
2150 ofu()->EnsureFileExists(
2151 AllowUsageIncrease(PathCost(from_file))->context(),
2152 from_file, &created));
2153 ASSERT_TRUE(created);
2154 ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize());
2155
2156 from_file_size = 10;
2157 expected_total_file_size += from_file_size;
2158 ASSERT_EQ(base::PLATFORM_FILE_OK,
2159 ofu()->Truncate(
2160 AllowUsageIncrease(from_file_size)->context(),
2161 from_file, from_file_size));
2162 ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize());
2163
2164 // quota exceeded even after operation
2165 old_obstacle_file_size = obstacle_file_size;
2166 obstacle_file_size = from_file_size;
2167 from_file_size = 0;
2168 expected_total_file_size -= old_obstacle_file_size;
2169 scoped_ptr<FileSystemOperationContext> context =
2170 LimitedContext(-old_obstacle_file_size - PathCost(from_file) - 1);
2171 ASSERT_EQ(base::PLATFORM_FILE_OK,
2172 ofu()->CopyOrMoveFile(
2173 context.get(), from_file, obstacle_file,
2174 FileSystemOperation::OPTION_NONE,
2175 false /* move */));
2176 ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize());
2177 context.reset();
2178 }
2179
2180 TEST_F(ObfuscatedFileUtilTest, TestQuotaOnRemove) {
2181 FileSystemURL dir(CreateURLFromUTF8("dir"));
2182 FileSystemURL file(CreateURLFromUTF8("file"));
2183 FileSystemURL dfile1(CreateURLFromUTF8("dir/dfile1"));
2184 FileSystemURL dfile2(CreateURLFromUTF8("dir/dfile2"));
2185 bool created;
2186
2187 ASSERT_EQ(base::PLATFORM_FILE_OK,
2188 ofu()->EnsureFileExists(
2189 AllowUsageIncrease(PathCost(file))->context(),
2190 file, &created));
2191 ASSERT_TRUE(created);
2192 ASSERT_EQ(0, ComputeTotalFileSize());
2193
2194 ASSERT_EQ(base::PLATFORM_FILE_OK,
2195 ofu()->CreateDirectory(
2196 AllowUsageIncrease(PathCost(dir))->context(),
2197 dir, false, false));
2198 ASSERT_EQ(0, ComputeTotalFileSize());
2199
2200 ASSERT_EQ(base::PLATFORM_FILE_OK,
2201 ofu()->EnsureFileExists(
2202 AllowUsageIncrease(PathCost(dfile1))->context(),
2203 dfile1, &created));
2204 ASSERT_TRUE(created);
2205 ASSERT_EQ(0, ComputeTotalFileSize());
2206
2207 ASSERT_EQ(base::PLATFORM_FILE_OK,
2208 ofu()->EnsureFileExists(
2209 AllowUsageIncrease(PathCost(dfile2))->context(),
2210 dfile2, &created));
2211 ASSERT_TRUE(created);
2212 ASSERT_EQ(0, ComputeTotalFileSize());
2213
2214 ASSERT_EQ(base::PLATFORM_FILE_OK,
2215 ofu()->Truncate(
2216 AllowUsageIncrease(340)->context(),
2217 file, 340));
2218 ASSERT_EQ(340, ComputeTotalFileSize());
2219
2220 ASSERT_EQ(base::PLATFORM_FILE_OK,
2221 ofu()->Truncate(
2222 AllowUsageIncrease(1020)->context(),
2223 dfile1, 1020));
2224 ASSERT_EQ(1360, ComputeTotalFileSize());
2225
2226 ASSERT_EQ(base::PLATFORM_FILE_OK,
2227 ofu()->Truncate(
2228 AllowUsageIncrease(120)->context(),
2229 dfile2, 120));
2230 ASSERT_EQ(1480, ComputeTotalFileSize());
2231
2232 ASSERT_EQ(base::PLATFORM_FILE_OK,
2233 ofu()->DeleteFile(
2234 AllowUsageIncrease(-PathCost(file) - 340)->context(),
2235 file));
2236 ASSERT_EQ(1140, ComputeTotalFileSize());
2237
2238 ASSERT_EQ(base::PLATFORM_FILE_OK,
2239 AsyncFileTestHelper::Remove(
2240 file_system_context(), dir, true /* recursive */));
2241 ASSERT_EQ(0, ComputeTotalFileSize());
2242 }
2243
2244 TEST_F(ObfuscatedFileUtilTest, TestQuotaOnOpen) {
2245 FileSystemURL file(CreateURLFromUTF8("file"));
2246 base::PlatformFile file_handle;
2247 bool created;
2248
2249 // Creating a file.
2250 ASSERT_EQ(base::PLATFORM_FILE_OK,
2251 ofu()->EnsureFileExists(
2252 AllowUsageIncrease(PathCost(file))->context(),
2253 file, &created));
2254 ASSERT_TRUE(created);
2255 ASSERT_EQ(0, ComputeTotalFileSize());
2256
2257 // Opening it, which shouldn't change the usage.
2258 ASSERT_EQ(base::PLATFORM_FILE_OK,
2259 ofu()->CreateOrOpen(
2260 AllowUsageIncrease(0)->context(), file,
2261 base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_WRITE,
2262 &file_handle, &created));
2263 ASSERT_EQ(0, ComputeTotalFileSize());
2264 EXPECT_TRUE(base::ClosePlatformFile(file_handle));
2265
2266 const int length = 33;
2267 ASSERT_EQ(base::PLATFORM_FILE_OK,
2268 ofu()->Truncate(
2269 AllowUsageIncrease(length)->context(), file, length));
2270 ASSERT_EQ(length, ComputeTotalFileSize());
2271
2272 // Opening it with CREATE_ALWAYS flag, which should truncate the file size.
2273 ASSERT_EQ(base::PLATFORM_FILE_OK,
2274 ofu()->CreateOrOpen(
2275 AllowUsageIncrease(-length)->context(), file,
2276 base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_WRITE,
2277 &file_handle, &created));
2278 ASSERT_EQ(0, ComputeTotalFileSize());
2279 EXPECT_TRUE(base::ClosePlatformFile(file_handle));
2280
2281 // Extending the file again.
2282 ASSERT_EQ(base::PLATFORM_FILE_OK,
2283 ofu()->Truncate(
2284 AllowUsageIncrease(length)->context(), file, length));
2285 ASSERT_EQ(length, ComputeTotalFileSize());
2286
2287 // Opening it with TRUNCATED flag, which should truncate the file size.
2288 ASSERT_EQ(base::PLATFORM_FILE_OK,
2289 ofu()->CreateOrOpen(
2290 AllowUsageIncrease(-length)->context(), file,
2291 base::PLATFORM_FILE_OPEN_TRUNCATED | base::PLATFORM_FILE_WRITE,
2292 &file_handle, &created));
2293 ASSERT_EQ(0, ComputeTotalFileSize());
2294 EXPECT_TRUE(base::ClosePlatformFile(file_handle));
2295 }
2296
2297 TEST_F(ObfuscatedFileUtilTest, MaybeDropDatabasesAliveCase) {
2298 ObfuscatedFileUtil file_util(NULL,
2299 data_dir_path(),
2300 base::MessageLoopProxy::current().get());
2301 file_util.InitOriginDatabase(true /*create*/);
2302 ASSERT_TRUE(file_util.origin_database_ != NULL);
2303
2304 // Callback to Drop DB is called while ObfuscatedFileUtilTest is still alive.
2305 file_util.db_flush_delay_seconds_ = 0;
2306 file_util.MarkUsed();
2307 base::RunLoop().RunUntilIdle();
2308
2309 ASSERT_TRUE(file_util.origin_database_ == NULL);
2310 }
2311
2312 TEST_F(ObfuscatedFileUtilTest, MaybeDropDatabasesAlreadyDeletedCase) {
2313 // Run message loop after OFU is already deleted to make sure callback doesn't
2314 // cause a crash for use after free.
2315 {
2316 ObfuscatedFileUtil file_util(NULL,
2317 data_dir_path(),
2318 base::MessageLoopProxy::current().get());
2319 file_util.InitOriginDatabase(true /*create*/);
2320 file_util.db_flush_delay_seconds_ = 0;
2321 file_util.MarkUsed();
2322 }
2323
2324 // At this point the callback is still in the message queue but OFU is gone.
2325 base::RunLoop().RunUntilIdle();
2326 }
2327
2328 TEST_F(ObfuscatedFileUtilTest, DestroyDirectoryDatabase_Isolated) {
2329 storage_policy_->AddIsolated(origin_);
2330 ObfuscatedFileUtil file_util(
2331 storage_policy_.get(), data_dir_path(),
2332 base::MessageLoopProxy::current().get());
2333
2334 // Create DirectoryDatabase for isolated origin.
2335 SandboxDirectoryDatabase* db = file_util.GetDirectoryDatabase(
2336 origin_, kFileSystemTypePersistent, true /* create */);
2337 ASSERT_TRUE(db != NULL);
2338
2339 // Destory it.
2340 ASSERT_TRUE(
2341 file_util.DestroyDirectoryDatabase(origin_, kFileSystemTypePersistent));
2342 ASSERT_TRUE(file_util.directories_.empty());
2343 }
2344
2345 TEST_F(ObfuscatedFileUtilTest, GetDirectoryDatabase_Isolated) {
2346 storage_policy_->AddIsolated(origin_);
2347 ObfuscatedFileUtil file_util(
2348 storage_policy_.get(), data_dir_path(),
2349 base::MessageLoopProxy::current().get());
2350
2351 // Create DirectoryDatabase for isolated origin.
2352 SandboxDirectoryDatabase* db = file_util.GetDirectoryDatabase(
2353 origin_, kFileSystemTypePersistent, true /* create */);
2354 ASSERT_TRUE(db != NULL);
2355 ASSERT_EQ(1U, file_util.directories_.size());
2356
2357 // Remove isolated.
2358 storage_policy_->RemoveIsolated(origin_);
2359
2360 // This should still get the same database.
2361 SandboxDirectoryDatabase* db2 = file_util.GetDirectoryDatabase(
2362 origin_, kFileSystemTypePersistent, false /* create */);
2363 ASSERT_EQ(db, db2);
2364 }
2365
2366 TEST_F(ObfuscatedFileUtilTest, MigrationBackFromIsolated) {
2367 std::string kFakeDirectoryData("0123456789");
2368 base::FilePath old_directory_db_path;
2369
2370 // Initialize the directory with one origin using
2371 // SandboxIsolatedOriginDatabase.
2372 {
2373 std::string origin_string =
2374 webkit_database::GetIdentifierFromOrigin(origin_);
2375 SandboxIsolatedOriginDatabase database_old(origin_string, data_dir_path());
2376 base::FilePath path;
2377 EXPECT_TRUE(database_old.GetPathForOrigin(origin_string, &path));
2378 EXPECT_FALSE(path.empty());
2379
2380 // Populate the origin directory with some fake data.
2381 old_directory_db_path = data_dir_path().Append(path);
2382 ASSERT_TRUE(file_util::CreateDirectory(old_directory_db_path));
2383 EXPECT_EQ(static_cast<int>(kFakeDirectoryData.size()),
2384 file_util::WriteFile(old_directory_db_path.AppendASCII("dummy"),
2385 kFakeDirectoryData.data(),
2386 kFakeDirectoryData.size()));
2387 }
2388
2389 storage_policy_->AddIsolated(origin_);
2390 ObfuscatedFileUtil file_util(
2391 storage_policy_.get(), data_dir_path(),
2392 base::MessageLoopProxy::current().get());
2393 base::PlatformFileError error = base::PLATFORM_FILE_ERROR_FAILED;
2394 base::FilePath origin_directory = file_util.GetDirectoryForOrigin(
2395 origin_, true /* create */, &error);
2396 EXPECT_EQ(base::PLATFORM_FILE_OK, error);
2397
2398 // The database is migrated from the old one.
2399 EXPECT_TRUE(base::DirectoryExists(origin_directory));
2400 EXPECT_FALSE(base::DirectoryExists(old_directory_db_path));
2401
2402 // Check we see the same contents in the new origin directory.
2403 std::string origin_db_data;
2404 EXPECT_TRUE(base::PathExists(origin_directory.AppendASCII("dummy")));
2405 EXPECT_TRUE(base::ReadFileToString(
2406 origin_directory.AppendASCII("dummy"), &origin_db_data));
2407 EXPECT_EQ(kFakeDirectoryData, origin_db_data);
2408 }
2409
2410 TEST_F(ObfuscatedFileUtilTest, OpenPathInNonDirectory) {
2411 FileSystemURL file(CreateURLFromUTF8("file"));
2412 FileSystemURL path_in_file(CreateURLFromUTF8("file/file"));
2413 bool created;
2414
2415 ASSERT_EQ(base::PLATFORM_FILE_OK,
2416 ofu()->EnsureFileExists(UnlimitedContext().get(), file, &created));
2417 ASSERT_TRUE(created);
2418
2419 created = false;
2420 base::PlatformFile file_handle = base::kInvalidPlatformFileValue;
2421 int file_flags = base::PLATFORM_FILE_CREATE | base::PLATFORM_FILE_WRITE;
2422 ASSERT_EQ(base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY,
2423 ofu()->CreateOrOpen(UnlimitedContext().get(),
2424 path_in_file,
2425 file_flags,
2426 &file_handle,
2427 &created));
2428 ASSERT_FALSE(created);
2429 ASSERT_EQ(base::kInvalidPlatformFileValue, file_handle);
2430
2431 ASSERT_EQ(base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY,
2432 ofu()->CreateDirectory(UnlimitedContext().get(),
2433 path_in_file,
2434 false /* exclusive */,
2435 false /* recursive */));
2436 }
2437
2438 } // namespace fileapi
OLDNEW
« no previous file with comments | « webkit/browser/fileapi/mock_file_system_options.cc ('k') | webkit/browser/fileapi/recursive_operation_delegate_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698