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

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

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

Powered by Google App Engine
This is Rietveld 408576698