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

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

Issue 7470037: [Refactor] to rename and re-layer the file_util stack layers. (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Rebased on the svn tree. Created 9 years, 3 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) 2011 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 <algorithm>
6 #include <set>
7 #include <string>
8
9 #include "base/file_path.h"
10 #include "base/file_util.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/memory/scoped_callback_factory.h"
13 #include "base/message_loop.h"
14 #include "base/platform_file.h"
15 #include "base/scoped_temp_dir.h"
16 #include "base/sys_string_conversions.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18 #include "webkit/fileapi/file_system_context.h"
19 #include "webkit/fileapi/file_system_operation_context.h"
20 #include "webkit/fileapi/file_system_path_manager.h"
21 #include "webkit/fileapi/file_system_test_helper.h"
22 #include "webkit/fileapi/file_system_usage_cache.h"
23 #include "webkit/fileapi/obfuscated_file_system_file_util.h"
24 #include "webkit/quota/mock_special_storage_policy.h"
25 #include "webkit/quota/quota_manager.h"
26 #include "webkit/quota/quota_types.h"
27
28 using namespace fileapi;
29
30 namespace {
31
32 FilePath UTF8ToFilePath(const std::string& str) {
33 FilePath::StringType result;
34 #if defined(OS_POSIX)
35 result = str;
36 #elif defined(OS_WIN)
37 result = base::SysUTF8ToWide(str);
38 #endif
39 return FilePath(result);
40 }
41
42 bool FileExists(const FilePath& path) {
43 return file_util::PathExists(path) && !file_util::DirectoryExists(path);
44 }
45
46 int64 GetSize(const FilePath& path) {
47 int64 size;
48 EXPECT_TRUE(file_util::GetFileSize(path, &size));
49 return size;
50 }
51
52 // After a move, the dest exists and the source doesn't.
53 // After a copy, both source and dest exist.
54 struct CopyMoveTestCaseRecord {
55 bool is_copy_not_move;
56 const char source_path[64];
57 const char dest_path[64];
58 bool cause_overwrite;
59 };
60
61 const CopyMoveTestCaseRecord kCopyMoveTestCases[] = {
62 // This is the combinatoric set of:
63 // rename vs. same-name
64 // different directory vs. same directory
65 // overwrite vs. no-overwrite
66 // copy vs. move
67 // We can never be called with source and destination paths identical, so
68 // those cases are omitted.
69 {true, "dir0/file0", "dir0/file1", false},
70 {false, "dir0/file0", "dir0/file1", false},
71 {true, "dir0/file0", "dir0/file1", true},
72 {false, "dir0/file0", "dir0/file1", true},
73
74 {true, "dir0/file0", "dir1/file0", false},
75 {false, "dir0/file0", "dir1/file0", false},
76 {true, "dir0/file0", "dir1/file0", true},
77 {false, "dir0/file0", "dir1/file0", true},
78 {true, "dir0/file0", "dir1/file1", false},
79 {false, "dir0/file0", "dir1/file1", false},
80 {true, "dir0/file0", "dir1/file1", true},
81 {false, "dir0/file0", "dir1/file1", true},
82 };
83
84 struct MigrationTestCaseRecord {
85 bool is_directory;
86 const FilePath::CharType path[64];
87 int64 data_file_size;
88 };
89
90 const MigrationTestCaseRecord kMigrationTestCases[] = {
91 {true, FILE_PATH_LITERAL("dir a"), 0},
92 {true, FILE_PATH_LITERAL("dir a/dir a"), 0},
93 {true, FILE_PATH_LITERAL("dir a/dir d"), 0},
94 {true, FILE_PATH_LITERAL("dir a/dir d/dir e"), 0},
95 {true, FILE_PATH_LITERAL("dir a/dir d/dir e/dir f"), 0},
96 {true, FILE_PATH_LITERAL("dir a/dir d/dir e/dir g"), 0},
97 {true, FILE_PATH_LITERAL("dir a/dir d/dir e/dir h"), 0},
98 {true, FILE_PATH_LITERAL("dir b"), 0},
99 {true, FILE_PATH_LITERAL("dir b/dir a"), 0},
100 {true, FILE_PATH_LITERAL("dir c"), 0},
101 {false, FILE_PATH_LITERAL("file 0"), 38},
102 {false, FILE_PATH_LITERAL("file 2"), 60},
103 {false, FILE_PATH_LITERAL("file 3"), 0},
104 {false, FILE_PATH_LITERAL("dir a/file 0"), 39},
105 {false, FILE_PATH_LITERAL("dir a/dir d/dir e/dir g/file 0"), 40},
106 {false, FILE_PATH_LITERAL("dir a/dir d/dir e/dir g/file 1"), 41},
107 {false, FILE_PATH_LITERAL("dir a/dir d/dir e/dir g/file 2"), 42},
108 {false, FILE_PATH_LITERAL("dir a/dir d/dir e/dir g/file 3"), 50},
109 };
110
111 struct OriginEnumerationTestRecord {
112 std::string origin_url;
113 bool has_temporary;
114 bool has_persistent;
115 };
116
117 const OriginEnumerationTestRecord kOriginEnumerationTestRecords[] = {
118 {"http://example.com", false, true},
119 {"http://example1.com", true, false},
120 {"https://example1.com", true, true},
121 {"file://", false, true},
122 {"http://example.com:8000", false, true},
123 };
124
125 } // namespace (anonymous)
126
127 // TODO(ericu): The vast majority of this and the other FSFU subclass tests
128 // could theoretically be shared. It would basically be a FSFU interface
129 // compliance test, and only the subclass-specific bits that look into the
130 // implementation would need to be written per-subclass.
131 class ObfuscatedFileSystemFileUtilTest : public testing::Test {
132 public:
133 ObfuscatedFileSystemFileUtilTest()
134 : origin_(GURL("http://www.example.com")),
135 type_(kFileSystemTypeTemporary),
136 callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
137 test_helper_(origin_, type_),
138 quota_status_(quota::kQuotaStatusUnknown),
139 usage_(-1) {
140 }
141
142 void SetUp() {
143 ASSERT_TRUE(data_dir_.CreateUniqueTempDir());
144
145 quota_manager_ = new quota::QuotaManager(
146 false /* is_incognito */,
147 data_dir_.path(),
148 base::MessageLoopProxy::current(),
149 base::MessageLoopProxy::current(),
150 NULL /* special storage policy */);
151
152 // Every time we create a new helper, it creates another context, which
153 // creates another path manager, another sandbox_mount_point_provider, and
154 // another OFSFU. We need to pass in the context to skip all that.
155 file_system_context_ = new FileSystemContext(
156 base::MessageLoopProxy::current(),
157 base::MessageLoopProxy::current(),
158 new quota::MockSpecialStoragePolicy(),
159 quota_manager_->proxy(),
160 data_dir_.path(),
161 false /* incognito */,
162 true /* allow_file_access_from_files */,
163 false /* unlimited_quota */,
164 NULL /* path_manager */);
165
166 obfuscated_file_system_file_util_ =
167 static_cast<ObfuscatedFileSystemFileUtil*>(
168 file_system_context_->path_manager()->GetFileSystemFileUtil(type_));
169
170
171 test_helper_.SetUp(file_system_context_.get(),
172 obfuscated_file_system_file_util_.get());
173 }
174
175 FileSystemOperationContext* NewContext(FileSystemTestOriginHelper* helper) {
176 FileSystemOperationContext* context;
177 if (helper)
178 context = helper->NewOperationContext();
179 else
180 context = test_helper_.NewOperationContext();
181 context->set_allowed_bytes_growth(1024 * 1024); // Big enough for all tests.
182 return context;
183 }
184
185 // This can only be used after SetUp has run and created file_system_context_
186 // and obfuscated_file_system_file_util_.
187 // Use this for tests which need to run in multiple origins; we need a test
188 // helper per origin.
189 FileSystemTestOriginHelper* NewHelper(
190 const GURL& origin, fileapi::FileSystemType type) {
191 FileSystemTestOriginHelper* helper =
192 new FileSystemTestOriginHelper(origin, type);
193
194 helper->SetUp(file_system_context_.get(),
195 obfuscated_file_system_file_util_.get());
196 return helper;
197 }
198
199 ObfuscatedFileSystemFileUtil* ofsfu() {
200 return obfuscated_file_system_file_util_.get();
201 }
202
203 const FilePath& test_directory() const {
204 return data_dir_.path();
205 }
206
207 const GURL& origin() const {
208 return origin_;
209 }
210
211 fileapi::FileSystemType type() const {
212 return type_;
213 }
214
215 void GetUsageFromQuotaManager() {
216 quota_manager_->GetUsageAndQuota(
217 origin(), test_helper_.storage_type(),
218 callback_factory_.NewCallback(
219 &ObfuscatedFileSystemFileUtilTest::OnGetUsage));
220 MessageLoop::current()->RunAllPending();
221 EXPECT_EQ(quota::kQuotaStatusOk, quota_status_);
222 }
223
224 void RevokeUsageCache() {
225 quota_manager_->ResetUsageTracker(test_helper_.storage_type());
226 ASSERT_TRUE(test_helper_.RevokeUsageCache());
227 }
228
229 int64 SizeInUsageFile() {
230 return test_helper_.GetCachedOriginUsage();
231 }
232
233 int64 usage() const { return usage_; }
234
235 void OnGetUsage(quota::QuotaStatusCode status, int64 usage, int64 unused) {
236 EXPECT_EQ(quota::kQuotaStatusOk, status);
237 quota_status_ = status;
238 usage_ = usage;
239 }
240
241 void CheckFileAndCloseHandle(
242 const FilePath& virtual_path, PlatformFile file_handle) {
243 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL));
244 FilePath local_path;
245 EXPECT_EQ(base::PLATFORM_FILE_OK, ofsfu()->GetLocalFilePath(
246 context.get(), virtual_path, &local_path));
247
248 base::PlatformFileInfo file_info0;
249 FilePath data_path;
250 EXPECT_EQ(base::PLATFORM_FILE_OK, ofsfu()->GetFileInfo(
251 context.get(), virtual_path, &file_info0, &data_path));
252 EXPECT_EQ(data_path, local_path);
253 EXPECT_TRUE(FileExists(data_path));
254 EXPECT_EQ(0, GetSize(data_path));
255
256 const char data[] = "test data";
257 const int length = arraysize(data) - 1;
258
259 if (base::kInvalidPlatformFileValue == file_handle) {
260 bool created = true;
261 PlatformFileError error;
262 file_handle = base::CreatePlatformFile(
263 data_path,
264 base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_WRITE,
265 &created,
266 &error);
267 ASSERT_NE(base::kInvalidPlatformFileValue, file_handle);
268 ASSERT_EQ(base::PLATFORM_FILE_OK, error);
269 EXPECT_FALSE(created);
270 }
271 ASSERT_EQ(length, base::WritePlatformFile(file_handle, 0, data, length));
272 EXPECT_TRUE(base::ClosePlatformFile(file_handle));
273
274 base::PlatformFileInfo file_info1;
275 EXPECT_EQ(length, GetSize(data_path));
276 context.reset(NewContext(NULL));
277 EXPECT_EQ(base::PLATFORM_FILE_OK, ofsfu()->GetFileInfo(
278 context.get(), virtual_path, &file_info1, &data_path));
279 EXPECT_EQ(data_path, local_path);
280
281 EXPECT_FALSE(file_info0.is_directory);
282 EXPECT_FALSE(file_info1.is_directory);
283 EXPECT_FALSE(file_info0.is_symbolic_link);
284 EXPECT_FALSE(file_info1.is_symbolic_link);
285 EXPECT_EQ(0, file_info0.size);
286 EXPECT_EQ(length, file_info1.size);
287 EXPECT_LE(file_info0.last_modified, file_info1.last_modified);
288
289 context.reset(NewContext(NULL));
290 EXPECT_EQ(base::PLATFORM_FILE_OK, ofsfu()->Truncate(
291 context.get(), virtual_path, length * 2));
292 EXPECT_EQ(length * 2, GetSize(data_path));
293
294 context.reset(NewContext(NULL));
295 EXPECT_EQ(base::PLATFORM_FILE_OK, ofsfu()->Truncate(
296 context.get(), virtual_path, 0));
297 EXPECT_EQ(0, GetSize(data_path));
298 }
299
300 void ValidateTestDirectory(
301 const FilePath& root_path,
302 const std::set<FilePath::StringType>& files,
303 const std::set<FilePath::StringType>& directories) {
304 scoped_ptr<FileSystemOperationContext> context;
305 std::set<FilePath::StringType>::const_iterator iter;
306 for (iter = files.begin(); iter != files.end(); ++iter) {
307 bool created = true;
308 context.reset(NewContext(NULL));
309 ASSERT_EQ(base::PLATFORM_FILE_OK,
310 ofsfu()->EnsureFileExists(
311 context.get(), root_path.Append(*iter),
312 &created));
313 ASSERT_FALSE(created);
314 }
315 for (iter = directories.begin(); iter != directories.end(); ++iter) {
316 context.reset(NewContext(NULL));
317 EXPECT_TRUE(ofsfu()->DirectoryExists(context.get(),
318 root_path.Append(*iter)));
319 }
320 }
321
322 void FillTestDirectory(
323 const FilePath& root_path,
324 std::set<FilePath::StringType>* files,
325 std::set<FilePath::StringType>* directories) {
326 scoped_ptr<FileSystemOperationContext> context;
327 context.reset(NewContext(NULL));
328 std::vector<base::FileUtilProxy::Entry> entries;
329 EXPECT_EQ(base::PLATFORM_FILE_OK,
330 ofsfu()->ReadDirectory(context.get(), root_path, &entries));
331 EXPECT_EQ(0UL, entries.size());
332
333 files->clear();
334 files->insert(FILE_PATH_LITERAL("first"));
335 files->insert(FILE_PATH_LITERAL("second"));
336 files->insert(FILE_PATH_LITERAL("third"));
337 directories->clear();
338 directories->insert(FILE_PATH_LITERAL("fourth"));
339 directories->insert(FILE_PATH_LITERAL("fifth"));
340 directories->insert(FILE_PATH_LITERAL("sixth"));
341 std::set<FilePath::StringType>::iterator iter;
342 for (iter = files->begin(); iter != files->end(); ++iter) {
343 bool created = false;
344 context.reset(NewContext(NULL));
345 ASSERT_EQ(base::PLATFORM_FILE_OK,
346 ofsfu()->EnsureFileExists(
347 context.get(), root_path.Append(*iter), &created));
348 ASSERT_TRUE(created);
349 }
350 for (iter = directories->begin(); iter != directories->end(); ++iter) {
351 bool exclusive = true;
352 bool recursive = false;
353 context.reset(NewContext(NULL));
354 EXPECT_EQ(base::PLATFORM_FILE_OK,
355 ofsfu()->CreateDirectory(
356 context.get(), root_path.Append(*iter), exclusive, recursive));
357 }
358 ValidateTestDirectory(root_path, *files, *directories);
359 }
360
361 void TestReadDirectoryHelper(const FilePath& root_path) {
362 std::set<FilePath::StringType> files;
363 std::set<FilePath::StringType> directories;
364 FillTestDirectory(root_path, &files, &directories);
365
366 scoped_ptr<FileSystemOperationContext> context;
367 std::vector<base::FileUtilProxy::Entry> entries;
368 context.reset(NewContext(NULL));
369 EXPECT_EQ(base::PLATFORM_FILE_OK,
370 ofsfu()->ReadDirectory(context.get(), root_path, &entries));
371 std::vector<base::FileUtilProxy::Entry>::iterator entry_iter;
372 EXPECT_EQ(files.size() + directories.size(), entries.size());
373 for (entry_iter = entries.begin(); entry_iter != entries.end();
374 ++entry_iter) {
375 const base::FileUtilProxy::Entry& entry = *entry_iter;
376 std::set<FilePath::StringType>::iterator iter = files.find(entry.name);
377 if (iter != files.end()) {
378 EXPECT_FALSE(entry.is_directory);
379 files.erase(iter);
380 continue;
381 }
382 iter = directories.find(entry.name);
383 EXPECT_FALSE(directories.end() == iter);
384 EXPECT_TRUE(entry.is_directory);
385 directories.erase(iter);
386 }
387 }
388
389 void TestTouchHelper(const FilePath& path, bool is_file) {
390 base::Time last_access_time = base::Time::Now();
391 base::Time last_modified_time = base::Time::Now();
392
393 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL));
394 EXPECT_EQ(base::PLATFORM_FILE_OK,
395 ofsfu()->Touch(
396 context.get(), path, last_access_time, last_modified_time));
397 FilePath local_path;
398 base::PlatformFileInfo file_info;
399 context.reset(NewContext(NULL));
400 EXPECT_EQ(base::PLATFORM_FILE_OK, ofsfu()->GetFileInfo(
401 context.get(), path, &file_info, &local_path));
402 // We compare as time_t here to lower our resolution, to avoid false
403 // negatives caused by conversion to the local filesystem's native
404 // representation and back.
405 EXPECT_EQ(file_info.last_modified.ToTimeT(), last_modified_time.ToTimeT());
406
407 context.reset(NewContext(NULL));
408 last_modified_time += base::TimeDelta::FromHours(1);
409 last_access_time += base::TimeDelta::FromHours(14);
410 EXPECT_EQ(base::PLATFORM_FILE_OK,
411 ofsfu()->Touch(
412 context.get(), path, last_access_time, last_modified_time));
413 context.reset(NewContext(NULL));
414 EXPECT_EQ(base::PLATFORM_FILE_OK, ofsfu()->GetFileInfo(
415 context.get(), path, &file_info, &local_path));
416 EXPECT_EQ(file_info.last_modified.ToTimeT(), last_modified_time.ToTimeT());
417 if (is_file) // Directories in OFSFU don't support atime.
418 EXPECT_EQ(file_info.last_accessed.ToTimeT(), last_access_time.ToTimeT());
419 }
420
421 void TestCopyInForeignFileHelper(bool overwrite) {
422 ScopedTempDir source_dir;
423 ASSERT_TRUE(source_dir.CreateUniqueTempDir());
424 FilePath root_path = source_dir.path();
425 FilePath src_path = root_path.AppendASCII("file_name");
426 FilePath dest_path(FILE_PATH_LITERAL("new file"));
427 int64 src_file_length = 87;
428
429 base::PlatformFileError error_code;
430 bool created = false;
431 int file_flags = base::PLATFORM_FILE_CREATE | base::PLATFORM_FILE_WRITE;
432 base::PlatformFile file_handle =
433 base::CreatePlatformFile(
434 src_path, file_flags, &created, &error_code);
435 EXPECT_TRUE(created);
436 ASSERT_EQ(base::PLATFORM_FILE_OK, error_code);
437 ASSERT_NE(base::kInvalidPlatformFileValue, file_handle);
438 ASSERT_TRUE(base::TruncatePlatformFile(file_handle, src_file_length));
439 EXPECT_TRUE(base::ClosePlatformFile(file_handle));
440
441 scoped_ptr<FileSystemOperationContext> context;
442
443 if (overwrite) {
444 context.reset(NewContext(NULL));
445 EXPECT_EQ(base::PLATFORM_FILE_OK,
446 ofsfu()->EnsureFileExists(context.get(), dest_path, &created));
447 EXPECT_TRUE(created);
448 }
449
450 const int64 path_cost =
451 ObfuscatedFileSystemFileUtil::ComputeFilePathCost(dest_path);
452 if (!overwrite) {
453 // Verify that file creation requires sufficient quota for the path.
454 context.reset(NewContext(NULL));
455 context->set_allowed_bytes_growth(path_cost + src_file_length - 1);
456 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE,
457 ofsfu()->CopyInForeignFile(context.get(), src_path, dest_path));
458 }
459
460 context.reset(NewContext(NULL));
461 context->set_allowed_bytes_growth(path_cost + src_file_length);
462 EXPECT_EQ(base::PLATFORM_FILE_OK,
463 ofsfu()->CopyInForeignFile(context.get(), src_path, dest_path));
464
465 context.reset(NewContext(NULL));
466 EXPECT_TRUE(ofsfu()->PathExists(context.get(), dest_path));
467 context.reset(NewContext(NULL));
468 EXPECT_FALSE(ofsfu()->DirectoryExists(context.get(), dest_path));
469 context.reset(NewContext(NULL));
470 base::PlatformFileInfo file_info;
471 FilePath data_path;
472 EXPECT_EQ(base::PLATFORM_FILE_OK, ofsfu()->GetFileInfo(
473 context.get(), dest_path, &file_info, &data_path));
474 EXPECT_NE(data_path, src_path);
475 EXPECT_TRUE(FileExists(data_path));
476 EXPECT_EQ(src_file_length, GetSize(data_path));
477
478 EXPECT_EQ(base::PLATFORM_FILE_OK,
479 ofsfu()->DeleteFile(context.get(), dest_path));
480 }
481
482 private:
483 ScopedTempDir data_dir_;
484 scoped_refptr<ObfuscatedFileSystemFileUtil> obfuscated_file_system_file_util_;
485 scoped_refptr<quota::QuotaManager> quota_manager_;
486 scoped_refptr<FileSystemContext> file_system_context_;
487 GURL origin_;
488 fileapi::FileSystemType type_;
489 base::ScopedCallbackFactory<ObfuscatedFileSystemFileUtilTest>
490 callback_factory_;
491 FileSystemTestOriginHelper test_helper_;
492 quota::QuotaStatusCode quota_status_;
493 int64 usage_;
494
495 DISALLOW_COPY_AND_ASSIGN(ObfuscatedFileSystemFileUtilTest);
496 };
497
498 TEST_F(ObfuscatedFileSystemFileUtilTest, TestCreateAndDeleteFile) {
499 base::PlatformFile file_handle = base::kInvalidPlatformFileValue;
500 bool created;
501 FilePath path = UTF8ToFilePath("fake/file");
502 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL));
503 int file_flags = base::PLATFORM_FILE_CREATE | base::PLATFORM_FILE_WRITE;
504
505 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND,
506 ofsfu()->CreateOrOpen(
507 context.get(), path, file_flags, &file_handle,
508 &created));
509
510 context.reset(NewContext(NULL));
511 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND,
512 ofsfu()->DeleteFile(context.get(), path));
513
514 path = UTF8ToFilePath("test file");
515
516 // Verify that file creation requires sufficient quota for the path.
517 context.reset(NewContext(NULL));
518 context->set_allowed_bytes_growth(
519 ObfuscatedFileSystemFileUtil::ComputeFilePathCost(path) - 1);
520 ASSERT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE,
521 ofsfu()->CreateOrOpen(
522 context.get(), path, file_flags, &file_handle, &created));
523
524 context.reset(NewContext(NULL));
525 context->set_allowed_bytes_growth(
526 ObfuscatedFileSystemFileUtil::ComputeFilePathCost(path));
527 ASSERT_EQ(base::PLATFORM_FILE_OK,
528 ofsfu()->CreateOrOpen(
529 context.get(), path, file_flags, &file_handle, &created));
530 ASSERT_TRUE(created);
531 EXPECT_NE(base::kInvalidPlatformFileValue, file_handle);
532
533 CheckFileAndCloseHandle(path, file_handle);
534
535 context.reset(NewContext(NULL));
536 FilePath local_path;
537 EXPECT_EQ(base::PLATFORM_FILE_OK, ofsfu()->GetLocalFilePath(
538 context.get(), path, &local_path));
539 EXPECT_TRUE(file_util::PathExists(local_path));
540
541 // Verify that deleting a file isn't stopped by zero quota, and that it frees
542 // up quote from its path.
543 context.reset(NewContext(NULL));
544 context->set_allowed_bytes_growth(0);
545 EXPECT_EQ(base::PLATFORM_FILE_OK,
546 ofsfu()->DeleteFile(context.get(), path));
547 EXPECT_FALSE(file_util::PathExists(local_path));
548 EXPECT_EQ(ObfuscatedFileSystemFileUtil::ComputeFilePathCost(path),
549 context->allowed_bytes_growth());
550
551 context.reset(NewContext(NULL));
552 bool exclusive = true;
553 bool recursive = true;
554 FilePath directory_path = UTF8ToFilePath("series/of/directories");
555 path = directory_path.AppendASCII("file name");
556 EXPECT_EQ(base::PLATFORM_FILE_OK, ofsfu()->CreateDirectory(
557 context.get(), directory_path, exclusive, recursive));
558
559 context.reset(NewContext(NULL));
560 file_handle = base::kInvalidPlatformFileValue;
561 ASSERT_EQ(base::PLATFORM_FILE_OK,
562 ofsfu()->CreateOrOpen(
563 context.get(), path, file_flags, &file_handle, &created));
564 ASSERT_TRUE(created);
565 EXPECT_NE(base::kInvalidPlatformFileValue, file_handle);
566
567 CheckFileAndCloseHandle(path, file_handle);
568
569 context.reset(NewContext(NULL));
570 EXPECT_EQ(base::PLATFORM_FILE_OK, ofsfu()->GetLocalFilePath(
571 context.get(), path, &local_path));
572 EXPECT_TRUE(file_util::PathExists(local_path));
573
574 context.reset(NewContext(NULL));
575 EXPECT_EQ(base::PLATFORM_FILE_OK,
576 ofsfu()->DeleteFile(context.get(), path));
577 EXPECT_FALSE(file_util::PathExists(local_path));
578 }
579
580 TEST_F(ObfuscatedFileSystemFileUtilTest, TestTruncate) {
581 bool created = false;
582 FilePath path = UTF8ToFilePath("file");
583 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL));
584
585 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND,
586 ofsfu()->Truncate(context.get(), path, 4));
587
588 context.reset(NewContext(NULL));
589 ASSERT_EQ(base::PLATFORM_FILE_OK,
590 ofsfu()->EnsureFileExists(context.get(), path, &created));
591 ASSERT_TRUE(created);
592
593 context.reset(NewContext(NULL));
594 FilePath local_path;
595 EXPECT_EQ(base::PLATFORM_FILE_OK, ofsfu()->GetLocalFilePath(
596 context.get(), path, &local_path));
597 EXPECT_EQ(0, GetSize(local_path));
598
599 context.reset(NewContext(NULL));
600 EXPECT_EQ(base::PLATFORM_FILE_OK, ofsfu()->Truncate(
601 context.get(), path, 10));
602 EXPECT_EQ(10, GetSize(local_path));
603
604 context.reset(NewContext(NULL));
605 EXPECT_EQ(base::PLATFORM_FILE_OK, ofsfu()->Truncate(
606 context.get(), path, 1));
607 EXPECT_EQ(1, GetSize(local_path));
608
609 context.reset(NewContext(NULL));
610 EXPECT_FALSE(ofsfu()->DirectoryExists(context.get(), path));
611 context.reset(NewContext(NULL));
612 EXPECT_TRUE(ofsfu()->PathExists(context.get(), path));
613 }
614
615 TEST_F(ObfuscatedFileSystemFileUtilTest, TestEnsureFileExists) {
616 FilePath path = UTF8ToFilePath("fake/file");
617 bool created = false;
618 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL));
619 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND,
620 ofsfu()->EnsureFileExists(
621 context.get(), path, &created));
622
623 // Verify that file creation requires sufficient quota for the path.
624 context.reset(NewContext(NULL));
625 path = UTF8ToFilePath("test file");
626 created = false;
627 context->set_allowed_bytes_growth(
628 ObfuscatedFileSystemFileUtil::ComputeFilePathCost(path) - 1);
629 ASSERT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE,
630 ofsfu()->EnsureFileExists(context.get(), path, &created));
631 ASSERT_FALSE(created);
632
633 context.reset(NewContext(NULL));
634 context->set_allowed_bytes_growth(
635 ObfuscatedFileSystemFileUtil::ComputeFilePathCost(path));
636 ASSERT_EQ(base::PLATFORM_FILE_OK,
637 ofsfu()->EnsureFileExists(context.get(), path, &created));
638 ASSERT_TRUE(created);
639
640 CheckFileAndCloseHandle(path, base::kInvalidPlatformFileValue);
641
642 context.reset(NewContext(NULL));
643 ASSERT_EQ(base::PLATFORM_FILE_OK,
644 ofsfu()->EnsureFileExists(context.get(), path, &created));
645 ASSERT_FALSE(created);
646
647 // Also test in a subdirectory.
648 path = UTF8ToFilePath("path/to/file.txt");
649 context.reset(NewContext(NULL));
650 bool exclusive = true;
651 bool recursive = true;
652 EXPECT_EQ(base::PLATFORM_FILE_OK, ofsfu()->CreateDirectory(
653 context.get(), path.DirName(), exclusive, recursive));
654
655 context.reset(NewContext(NULL));
656 ASSERT_EQ(base::PLATFORM_FILE_OK,
657 ofsfu()->EnsureFileExists(context.get(), path, &created));
658 ASSERT_TRUE(created);
659 context.reset(NewContext(NULL));
660 EXPECT_FALSE(ofsfu()->DirectoryExists(context.get(), path));
661 context.reset(NewContext(NULL));
662 EXPECT_TRUE(ofsfu()->PathExists(context.get(), path));
663 }
664
665 TEST_F(ObfuscatedFileSystemFileUtilTest, TestDirectoryOps) {
666 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL));
667
668 bool exclusive = false;
669 bool recursive = false;
670 FilePath path = UTF8ToFilePath("foo/bar");
671 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, ofsfu()->CreateDirectory(
672 context.get(), path, exclusive, recursive));
673
674 context.reset(NewContext(NULL));
675 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND,
676 ofsfu()->DeleteSingleDirectory(context.get(), path));
677
678 FilePath root = UTF8ToFilePath("");
679 context.reset(NewContext(NULL));
680 EXPECT_FALSE(ofsfu()->DirectoryExists(context.get(), path));
681 context.reset(NewContext(NULL));
682 EXPECT_FALSE(ofsfu()->PathExists(context.get(), path));
683 context.reset(NewContext(NULL));
684 EXPECT_TRUE(ofsfu()->IsDirectoryEmpty(context.get(), root));
685
686 context.reset(NewContext(NULL));
687 exclusive = false;
688 recursive = true;
689 EXPECT_EQ(base::PLATFORM_FILE_OK, ofsfu()->CreateDirectory(
690 context.get(), path, exclusive, recursive));
691
692 context.reset(NewContext(NULL));
693 EXPECT_TRUE(ofsfu()->DirectoryExists(context.get(), path));
694 context.reset(NewContext(NULL));
695 EXPECT_TRUE(ofsfu()->PathExists(context.get(), path));
696 context.reset(NewContext(NULL));
697 EXPECT_FALSE(ofsfu()->IsDirectoryEmpty(context.get(), root));
698 context.reset(NewContext(NULL));
699 EXPECT_TRUE(ofsfu()->DirectoryExists(context.get(), path.DirName()));
700 context.reset(NewContext(NULL));
701 EXPECT_FALSE(ofsfu()->IsDirectoryEmpty(context.get(), path.DirName()));
702
703 // Can't remove a non-empty directory.
704 context.reset(NewContext(NULL));
705 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_EMPTY,
706 ofsfu()->DeleteSingleDirectory(context.get(), path.DirName()));
707
708 base::PlatformFileInfo file_info;
709 FilePath local_path;
710 EXPECT_EQ(base::PLATFORM_FILE_OK, ofsfu()->GetFileInfo(
711 context.get(), path, &file_info, &local_path));
712 EXPECT_TRUE(local_path.empty());
713 EXPECT_TRUE(file_info.is_directory);
714 EXPECT_FALSE(file_info.is_symbolic_link);
715
716 // Same create again should succeed, since exclusive is false.
717 context.reset(NewContext(NULL));
718 EXPECT_EQ(base::PLATFORM_FILE_OK, ofsfu()->CreateDirectory(
719 context.get(), path, exclusive, recursive));
720
721 exclusive = true;
722 recursive = true;
723 context.reset(NewContext(NULL));
724 EXPECT_EQ(base::PLATFORM_FILE_ERROR_EXISTS, ofsfu()->CreateDirectory(
725 context.get(), path, exclusive, recursive));
726
727 // Verify that deleting a directory isn't stopped by zero quota, and that it
728 // frees up quota from its path.
729 context.reset(NewContext(NULL));
730 context->set_allowed_bytes_growth(0);
731 EXPECT_EQ(base::PLATFORM_FILE_OK,
732 ofsfu()->DeleteSingleDirectory(context.get(), path));
733 EXPECT_EQ(ObfuscatedFileSystemFileUtil::ComputeFilePathCost(path),
734 context->allowed_bytes_growth());
735
736 path = UTF8ToFilePath("foo/bop");
737
738 context.reset(NewContext(NULL));
739 EXPECT_FALSE(ofsfu()->DirectoryExists(context.get(), path));
740 context.reset(NewContext(NULL));
741 EXPECT_FALSE(ofsfu()->PathExists(context.get(), path));
742 context.reset(NewContext(NULL));
743 EXPECT_TRUE(ofsfu()->IsDirectoryEmpty(context.get(), path));
744 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, ofsfu()->GetFileInfo(
745 context.get(), path, &file_info, &local_path));
746
747 // Verify that file creation requires sufficient quota for the path.
748 exclusive = true;
749 recursive = false;
750 context.reset(NewContext(NULL));
751 context->set_allowed_bytes_growth(
752 ObfuscatedFileSystemFileUtil::ComputeFilePathCost(path) - 1);
753 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE, ofsfu()->CreateDirectory(
754 context.get(), path, exclusive, recursive));
755
756 context.reset(NewContext(NULL));
757 context->set_allowed_bytes_growth(
758 ObfuscatedFileSystemFileUtil::ComputeFilePathCost(path));
759 EXPECT_EQ(base::PLATFORM_FILE_OK, ofsfu()->CreateDirectory(
760 context.get(), path, exclusive, recursive));
761
762 context.reset(NewContext(NULL));
763 EXPECT_TRUE(ofsfu()->DirectoryExists(context.get(), path));
764 context.reset(NewContext(NULL));
765 EXPECT_TRUE(ofsfu()->PathExists(context.get(), path));
766
767 exclusive = true;
768 recursive = false;
769 EXPECT_EQ(base::PLATFORM_FILE_ERROR_EXISTS, ofsfu()->CreateDirectory(
770 context.get(), path, exclusive, recursive));
771
772 exclusive = true;
773 recursive = false;
774 path = UTF8ToFilePath("foo");
775 EXPECT_EQ(base::PLATFORM_FILE_ERROR_EXISTS, ofsfu()->CreateDirectory(
776 context.get(), path, exclusive, recursive));
777
778 path = UTF8ToFilePath("blah");
779
780 context.reset(NewContext(NULL));
781 EXPECT_FALSE(ofsfu()->DirectoryExists(context.get(), path));
782 context.reset(NewContext(NULL));
783 EXPECT_FALSE(ofsfu()->PathExists(context.get(), path));
784
785 exclusive = true;
786 recursive = false;
787 EXPECT_EQ(base::PLATFORM_FILE_OK, ofsfu()->CreateDirectory(
788 context.get(), path, exclusive, recursive));
789
790 context.reset(NewContext(NULL));
791 EXPECT_TRUE(ofsfu()->DirectoryExists(context.get(), path));
792 context.reset(NewContext(NULL));
793 EXPECT_TRUE(ofsfu()->PathExists(context.get(), path));
794
795 exclusive = true;
796 recursive = false;
797 EXPECT_EQ(base::PLATFORM_FILE_ERROR_EXISTS, ofsfu()->CreateDirectory(
798 context.get(), path, exclusive, recursive));
799 }
800
801 TEST_F(ObfuscatedFileSystemFileUtilTest, TestReadDirectory) {
802 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL));
803 bool exclusive = true;
804 bool recursive = true;
805 FilePath path = UTF8ToFilePath("directory/to/use");
806 EXPECT_EQ(base::PLATFORM_FILE_OK, ofsfu()->CreateDirectory(
807 context.get(), path, exclusive, recursive));
808 TestReadDirectoryHelper(path);
809 }
810
811 TEST_F(ObfuscatedFileSystemFileUtilTest, TestReadRootWithSlash) {
812 TestReadDirectoryHelper(UTF8ToFilePath(""));
813 }
814
815 TEST_F(ObfuscatedFileSystemFileUtilTest, TestReadRootWithEmptyString) {
816 TestReadDirectoryHelper(UTF8ToFilePath("/"));
817 }
818
819 TEST_F(ObfuscatedFileSystemFileUtilTest, TestReadDirectoryOnFile) {
820 FilePath path = UTF8ToFilePath("file");
821 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL));
822
823 bool created = false;
824 ASSERT_EQ(base::PLATFORM_FILE_OK,
825 ofsfu()->EnsureFileExists(context.get(), path, &created));
826 ASSERT_TRUE(created);
827
828 context.reset(NewContext(NULL));
829 std::vector<base::FileUtilProxy::Entry> entries;
830 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND,
831 ofsfu()->ReadDirectory(context.get(), path, &entries));
832
833 EXPECT_TRUE(ofsfu()->IsDirectoryEmpty(context.get(), path));
834 }
835
836 TEST_F(ObfuscatedFileSystemFileUtilTest, TestTouch) {
837 FilePath path = UTF8ToFilePath("file");
838 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL));
839
840 base::Time last_access_time = base::Time::Now();
841 base::Time last_modified_time = base::Time::Now();
842
843 // It's not there yet.
844 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND,
845 ofsfu()->Touch(
846 context.get(), path, last_access_time, last_modified_time));
847
848 // OK, now create it.
849 context.reset(NewContext(NULL));
850 bool created = false;
851 ASSERT_EQ(base::PLATFORM_FILE_OK,
852 ofsfu()->EnsureFileExists(context.get(), path, &created));
853 ASSERT_TRUE(created);
854 TestTouchHelper(path, true);
855
856 // Now test a directory:
857 context.reset(NewContext(NULL));
858 bool exclusive = true;
859 bool recursive = false;
860 path = UTF8ToFilePath("dir");
861 ASSERT_EQ(base::PLATFORM_FILE_OK, ofsfu()->CreateDirectory(context.get(),
862 path, exclusive, recursive));
863 TestTouchHelper(path, false);
864 }
865
866 TEST_F(ObfuscatedFileSystemFileUtilTest, TestPathQuotas) {
867 FilePath path = UTF8ToFilePath("fake/file");
868 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL));
869
870 path = UTF8ToFilePath("file name");
871 context->set_allowed_bytes_growth(5);
872 bool created = false;
873 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE,
874 ofsfu()->EnsureFileExists(
875 context.get(), path, &created));
876 EXPECT_FALSE(created);
877 context->set_allowed_bytes_growth(1024);
878 EXPECT_EQ(base::PLATFORM_FILE_OK,
879 ofsfu()->EnsureFileExists(
880 context.get(), path, &created));
881 EXPECT_TRUE(created);
882 int64 path_cost = ObfuscatedFileSystemFileUtil::ComputeFilePathCost(path);
883 EXPECT_EQ(1024 - path_cost, context->allowed_bytes_growth());
884
885 context->set_allowed_bytes_growth(1024);
886 bool exclusive = true;
887 bool recursive = true;
888 path = UTF8ToFilePath("directory/to/use");
889 std::vector<FilePath::StringType> components;
890 path.GetComponents(&components);
891 path_cost = 0;
892 for (std::vector<FilePath::StringType>::iterator iter = components.begin();
893 iter != components.end(); ++iter) {
894 path_cost += ObfuscatedFileSystemFileUtil::ComputeFilePathCost(
895 FilePath(*iter));
896 }
897 context.reset(NewContext(NULL));
898 context->set_allowed_bytes_growth(1024);
899 EXPECT_EQ(base::PLATFORM_FILE_OK, ofsfu()->CreateDirectory(
900 context.get(), path, exclusive, recursive));
901 EXPECT_EQ(1024 - path_cost, context->allowed_bytes_growth());
902 }
903
904 TEST_F(ObfuscatedFileSystemFileUtilTest, TestCopyOrMoveFileNotFound) {
905 FilePath source_path = UTF8ToFilePath("path0.txt");
906 FilePath dest_path = UTF8ToFilePath("path1.txt");
907 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL));
908
909 bool is_copy_not_move = false;
910 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND,
911 ofsfu()->CopyOrMoveFile(context.get(), source_path, dest_path,
912 is_copy_not_move));
913 context.reset(NewContext(NULL));
914 is_copy_not_move = true;
915 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND,
916 ofsfu()->CopyOrMoveFile(context.get(), source_path, dest_path,
917 is_copy_not_move));
918 source_path = UTF8ToFilePath("dir/dir/file");
919 bool exclusive = true;
920 bool recursive = true;
921 context.reset(NewContext(NULL));
922 ASSERT_EQ(base::PLATFORM_FILE_OK, ofsfu()->CreateDirectory(
923 context.get(), source_path.DirName(), exclusive, recursive));
924 is_copy_not_move = false;
925 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND,
926 ofsfu()->CopyOrMoveFile(context.get(), source_path, dest_path,
927 is_copy_not_move));
928 context.reset(NewContext(NULL));
929 is_copy_not_move = true;
930 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND,
931 ofsfu()->CopyOrMoveFile(context.get(), source_path, dest_path,
932 is_copy_not_move));
933 }
934
935 TEST_F(ObfuscatedFileSystemFileUtilTest, TestCopyOrMoveFileSuccess) {
936 const int64 kSourceLength = 5;
937 const int64 kDestLength = 50;
938
939 for (size_t i = 0; i < arraysize(kCopyMoveTestCases); ++i) {
940 SCOPED_TRACE(testing::Message() << "kCopyMoveTestCase " << i);
941 const CopyMoveTestCaseRecord& test_case = kCopyMoveTestCases[i];
942 SCOPED_TRACE(testing::Message() << "\t is_copy_not_move " <<
943 test_case.is_copy_not_move);
944 SCOPED_TRACE(testing::Message() << "\t source_path " <<
945 test_case.source_path);
946 SCOPED_TRACE(testing::Message() << "\t dest_path " <<
947 test_case.dest_path);
948 SCOPED_TRACE(testing::Message() << "\t cause_overwrite " <<
949 test_case.cause_overwrite);
950 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL));
951
952 bool exclusive = false;
953 bool recursive = true;
954 FilePath source_path = UTF8ToFilePath(test_case.source_path);
955 FilePath dest_path = UTF8ToFilePath(test_case.dest_path);
956
957 context.reset(NewContext(NULL));
958 ASSERT_EQ(base::PLATFORM_FILE_OK, ofsfu()->CreateDirectory(
959 context.get(), source_path.DirName(), exclusive, recursive));
960 context.reset(NewContext(NULL));
961 ASSERT_EQ(base::PLATFORM_FILE_OK, ofsfu()->CreateDirectory(
962 context.get(), dest_path.DirName(), exclusive, recursive));
963
964 bool created = false;
965 context.reset(NewContext(NULL));
966 ASSERT_EQ(base::PLATFORM_FILE_OK,
967 ofsfu()->EnsureFileExists(context.get(), source_path, &created));
968 ASSERT_TRUE(created);
969 context.reset(NewContext(NULL));
970 ASSERT_EQ(base::PLATFORM_FILE_OK,
971 ofsfu()->Truncate(context.get(), source_path, kSourceLength));
972
973 if (test_case.cause_overwrite) {
974 context.reset(NewContext(NULL));
975 created = false;
976 ASSERT_EQ(base::PLATFORM_FILE_OK,
977 ofsfu()->EnsureFileExists(context.get(), dest_path, &created));
978 ASSERT_TRUE(created);
979 context.reset(NewContext(NULL));
980 ASSERT_EQ(base::PLATFORM_FILE_OK,
981 ofsfu()->Truncate(context.get(), dest_path, kDestLength));
982 }
983
984 context.reset(NewContext(NULL));
985 EXPECT_EQ(base::PLATFORM_FILE_OK, ofsfu()->CopyOrMoveFile(context.get(),
986 source_path, dest_path, test_case.is_copy_not_move));
987 if (test_case.is_copy_not_move) {
988 base::PlatformFileInfo file_info;
989 FilePath local_path;
990 context.reset(NewContext(NULL));
991 EXPECT_EQ(base::PLATFORM_FILE_OK, ofsfu()->GetFileInfo(
992 context.get(), source_path, &file_info, &local_path));
993 EXPECT_EQ(kSourceLength, file_info.size);
994 EXPECT_EQ(base::PLATFORM_FILE_OK,
995 ofsfu()->DeleteFile(context.get(), source_path));
996 } else {
997 base::PlatformFileInfo file_info;
998 FilePath local_path;
999 context.reset(NewContext(NULL));
1000 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, ofsfu()->GetFileInfo(
1001 context.get(), source_path, &file_info, &local_path));
1002 }
1003 base::PlatformFileInfo file_info;
1004 FilePath local_path;
1005 EXPECT_EQ(base::PLATFORM_FILE_OK, ofsfu()->GetFileInfo(
1006 context.get(), dest_path, &file_info, &local_path));
1007 EXPECT_EQ(kSourceLength, file_info.size);
1008
1009 EXPECT_EQ(base::PLATFORM_FILE_OK,
1010 ofsfu()->DeleteFile(context.get(), dest_path));
1011 }
1012 }
1013
1014 TEST_F(ObfuscatedFileSystemFileUtilTest, TestCopyPathQuotas) {
1015 FilePath src_path = UTF8ToFilePath("src path");
1016 FilePath dest_path = UTF8ToFilePath("destination path");
1017 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL));
1018 bool created = false;
1019 ASSERT_EQ(base::PLATFORM_FILE_OK, ofsfu()->EnsureFileExists(
1020 context.get(), src_path, &created));
1021
1022 bool is_copy = true;
1023 // Copy, no overwrite.
1024 context->set_allowed_bytes_growth(
1025 ObfuscatedFileSystemFileUtil::ComputeFilePathCost(dest_path) - 1);
1026 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE,
1027 ofsfu()->CopyOrMoveFile(context.get(), src_path, dest_path, is_copy));
1028 context.reset(NewContext(NULL));
1029 context->set_allowed_bytes_growth(
1030 ObfuscatedFileSystemFileUtil::ComputeFilePathCost(dest_path));
1031 EXPECT_EQ(base::PLATFORM_FILE_OK,
1032 ofsfu()->CopyOrMoveFile(context.get(), src_path, dest_path, is_copy));
1033
1034 // Copy, with overwrite.
1035 context.reset(NewContext(NULL));
1036 context->set_allowed_bytes_growth(0);
1037 EXPECT_EQ(base::PLATFORM_FILE_OK,
1038 ofsfu()->CopyOrMoveFile(context.get(), src_path, dest_path, is_copy));
1039 }
1040
1041 TEST_F(ObfuscatedFileSystemFileUtilTest, TestMovePathQuotasWithRename) {
1042 FilePath src_path = UTF8ToFilePath("src path");
1043 FilePath dest_path = UTF8ToFilePath("destination path");
1044 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL));
1045 bool created = false;
1046 ASSERT_EQ(base::PLATFORM_FILE_OK, ofsfu()->EnsureFileExists(
1047 context.get(), src_path, &created));
1048
1049 bool is_copy = false;
1050 // Move, rename, no overwrite.
1051 context.reset(NewContext(NULL));
1052 context->set_allowed_bytes_growth(
1053 ObfuscatedFileSystemFileUtil::ComputeFilePathCost(dest_path) -
1054 ObfuscatedFileSystemFileUtil::ComputeFilePathCost(src_path) - 1);
1055 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE,
1056 ofsfu()->CopyOrMoveFile(context.get(), src_path, dest_path, is_copy));
1057 context.reset(NewContext(NULL));
1058 context->set_allowed_bytes_growth(
1059 ObfuscatedFileSystemFileUtil::ComputeFilePathCost(dest_path) -
1060 ObfuscatedFileSystemFileUtil::ComputeFilePathCost(src_path));
1061 EXPECT_EQ(base::PLATFORM_FILE_OK,
1062 ofsfu()->CopyOrMoveFile(context.get(), src_path, dest_path, is_copy));
1063
1064 context.reset(NewContext(NULL));
1065 ASSERT_EQ(base::PLATFORM_FILE_OK, ofsfu()->EnsureFileExists(
1066 context.get(), src_path, &created));
1067
1068 // Move, rename, with overwrite.
1069 context.reset(NewContext(NULL));
1070 context->set_allowed_bytes_growth(0);
1071 EXPECT_EQ(base::PLATFORM_FILE_OK,
1072 ofsfu()->CopyOrMoveFile(context.get(), src_path, dest_path, is_copy));
1073 }
1074
1075 TEST_F(ObfuscatedFileSystemFileUtilTest, TestMovePathQuotasWithoutRename) {
1076 FilePath src_path = UTF8ToFilePath("src path");
1077 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL));
1078 bool created = false;
1079 ASSERT_EQ(base::PLATFORM_FILE_OK, ofsfu()->EnsureFileExists(
1080 context.get(), src_path, &created));
1081
1082 bool exclusive = true;
1083 bool recursive = false;
1084 FilePath dir_path = UTF8ToFilePath("directory path");
1085 context.reset(NewContext(NULL));
1086 ASSERT_EQ(base::PLATFORM_FILE_OK, ofsfu()->CreateDirectory(
1087 context.get(), dir_path, exclusive, recursive));
1088
1089 FilePath dest_path = dir_path.Append(src_path);
1090
1091 bool is_copy = false;
1092 int64 allowed_bytes_growth = -1000; // Over quota, this should still work.
1093 // Move, no rename, no overwrite.
1094 context.reset(NewContext(NULL));
1095 context->set_allowed_bytes_growth(allowed_bytes_growth);
1096 EXPECT_EQ(base::PLATFORM_FILE_OK,
1097 ofsfu()->CopyOrMoveFile(context.get(), src_path, dest_path, is_copy));
1098 EXPECT_EQ(allowed_bytes_growth, context->allowed_bytes_growth());
1099
1100 // Move, no rename, with overwrite.
1101 context.reset(NewContext(NULL));
1102 ASSERT_EQ(base::PLATFORM_FILE_OK, ofsfu()->EnsureFileExists(
1103 context.get(), src_path, &created));
1104 context.reset(NewContext(NULL));
1105 context->set_allowed_bytes_growth(allowed_bytes_growth);
1106 EXPECT_EQ(base::PLATFORM_FILE_OK,
1107 ofsfu()->CopyOrMoveFile(context.get(), src_path, dest_path, is_copy));
1108 EXPECT_EQ(
1109 allowed_bytes_growth +
1110 ObfuscatedFileSystemFileUtil::ComputeFilePathCost(src_path),
1111 context->allowed_bytes_growth());
1112 }
1113
1114 TEST_F(ObfuscatedFileSystemFileUtilTest, TestCopyInForeignFile) {
1115 TestCopyInForeignFileHelper(false /* overwrite */);
1116 TestCopyInForeignFileHelper(true /* overwrite */);
1117 }
1118
1119 TEST_F(ObfuscatedFileSystemFileUtilTest, TestEnumerator) {
1120 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL));
1121 FilePath src_path = UTF8ToFilePath("source dir");
1122 bool exclusive = true;
1123 bool recursive = false;
1124 ASSERT_EQ(base::PLATFORM_FILE_OK, ofsfu()->CreateDirectory(
1125 context.get(), src_path, exclusive, recursive));
1126
1127 std::set<FilePath::StringType> files;
1128 std::set<FilePath::StringType> directories;
1129 FillTestDirectory(src_path, &files, &directories);
1130
1131 FilePath dest_path = UTF8ToFilePath("destination dir");
1132
1133 context.reset(NewContext(NULL));
1134 EXPECT_FALSE(ofsfu()->DirectoryExists(context.get(), dest_path));
1135 context.reset(NewContext(NULL));
1136 ASSERT_EQ(base::PLATFORM_FILE_OK,
1137 ofsfu()->Copy(context.get(), src_path, dest_path));
1138
1139 ValidateTestDirectory(dest_path, files, directories);
1140 context.reset(NewContext(NULL));
1141 EXPECT_TRUE(ofsfu()->DirectoryExists(context.get(), src_path));
1142 context.reset(NewContext(NULL));
1143 EXPECT_TRUE(ofsfu()->DirectoryExists(context.get(), dest_path));
1144 context.reset(NewContext(NULL));
1145 recursive = true;
1146 ASSERT_EQ(base::PLATFORM_FILE_OK,
1147 ofsfu()->Delete(context.get(), dest_path, recursive));
1148 context.reset(NewContext(NULL));
1149 EXPECT_FALSE(ofsfu()->DirectoryExists(context.get(), dest_path));
1150 }
1151
1152 TEST_F(ObfuscatedFileSystemFileUtilTest, TestMigration) {
1153 ScopedTempDir source_dir;
1154 ASSERT_TRUE(source_dir.CreateUniqueTempDir());
1155 FilePath root_path = source_dir.path().AppendASCII("chrome-pLmnMWXE7NzTFRsn");
1156 ASSERT_TRUE(file_util::CreateDirectory(root_path));
1157
1158 for (size_t i = 0; i < arraysize(kMigrationTestCases); ++i) {
1159 SCOPED_TRACE(testing::Message() << "Creating kMigrationTestPath " << i);
1160 const MigrationTestCaseRecord& test_case = kMigrationTestCases[i];
1161 FilePath local_src_path = root_path.Append(test_case.path);
1162 if (test_case.is_directory) {
1163 ASSERT_TRUE(
1164 file_util::CreateDirectory(local_src_path));
1165 } else {
1166 base::PlatformFileError error_code;
1167 bool created = false;
1168 int file_flags = base::PLATFORM_FILE_CREATE | base::PLATFORM_FILE_WRITE;
1169 base::PlatformFile file_handle =
1170 base::CreatePlatformFile(
1171 local_src_path, file_flags, &created, &error_code);
1172 EXPECT_TRUE(created);
1173 ASSERT_NE(base::kInvalidPlatformFileValue, file_handle);
1174 ASSERT_EQ(base::PLATFORM_FILE_OK, error_code);
1175 ASSERT_TRUE(
1176 base::TruncatePlatformFile(file_handle, test_case.data_file_size));
1177 EXPECT_TRUE(base::ClosePlatformFile(file_handle));
1178 }
1179 }
1180
1181 EXPECT_TRUE(ofsfu()->MigrateFromOldSandbox(origin(), type(), root_path));
1182
1183 FilePath new_root =
1184 test_directory().AppendASCII("File System").AppendASCII("000").Append(
1185 ofsfu()->GetDirectoryNameForType(type())).AppendASCII("Legacy");
1186 for (size_t i = 0; i < arraysize(kMigrationTestCases); ++i) {
1187 SCOPED_TRACE(testing::Message() << "Validating kMigrationTestPath " << i);
1188 const MigrationTestCaseRecord& test_case = kMigrationTestCases[i];
1189 FilePath local_data_path = new_root.Append(test_case.path);
1190 #if defined(OS_WIN)
1191 local_data_path = local_data_path.NormalizeWindowsPathSeparators();
1192 #endif
1193 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL));
1194 base::PlatformFileInfo ofsfu_file_info;
1195 FilePath data_path;
1196 SCOPED_TRACE(testing::Message() << "Path is " << test_case.path);
1197 EXPECT_EQ(base::PLATFORM_FILE_OK,
1198 ofsfu()->GetFileInfo(context.get(), FilePath(test_case.path),
1199 &ofsfu_file_info, &data_path));
1200 if (test_case.is_directory) {
1201 EXPECT_TRUE(ofsfu_file_info.is_directory);
1202 } else {
1203 base::PlatformFileInfo platform_file_info;
1204 SCOPED_TRACE(testing::Message() << "local_data_path is " <<
1205 local_data_path.value());
1206 SCOPED_TRACE(testing::Message() << "data_path is " << data_path.value());
1207 ASSERT_TRUE(file_util::GetFileInfo(local_data_path, &platform_file_info));
1208 EXPECT_EQ(test_case.data_file_size, platform_file_info.size);
1209 EXPECT_FALSE(platform_file_info.is_directory);
1210 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL));
1211 EXPECT_EQ(local_data_path, data_path);
1212 EXPECT_EQ(platform_file_info.size, ofsfu_file_info.size);
1213 EXPECT_FALSE(ofsfu_file_info.is_directory);
1214 }
1215 }
1216 }
1217
1218 TEST_F(ObfuscatedFileSystemFileUtilTest, TestOriginEnumerator) {
1219 scoped_ptr<ObfuscatedFileSystemFileUtil::AbstractOriginEnumerator>
1220 enumerator(ofsfu()->CreateOriginEnumerator());
1221 // The test helper starts out with a single filesystem.
1222 EXPECT_TRUE(enumerator.get());
1223 EXPECT_EQ(origin(), enumerator->Next());
1224 ASSERT_TRUE(type() == kFileSystemTypeTemporary);
1225 EXPECT_TRUE(enumerator->HasFileSystemType(kFileSystemTypeTemporary));
1226 EXPECT_FALSE(enumerator->HasFileSystemType(kFileSystemTypePersistent));
1227 EXPECT_EQ(GURL(), enumerator->Next());
1228 EXPECT_FALSE(enumerator->HasFileSystemType(kFileSystemTypeTemporary));
1229 EXPECT_FALSE(enumerator->HasFileSystemType(kFileSystemTypePersistent));
1230
1231 std::set<GURL> origins_expected;
1232 origins_expected.insert(origin());
1233
1234 for (size_t i = 0; i < arraysize(kOriginEnumerationTestRecords); ++i) {
1235 SCOPED_TRACE(testing::Message() <<
1236 "Validating kOriginEnumerationTestRecords " << i);
1237 const OriginEnumerationTestRecord& record =
1238 kOriginEnumerationTestRecords[i];
1239 GURL origin_url(record.origin_url);
1240 origins_expected.insert(origin_url);
1241 if (record.has_temporary) {
1242 scoped_ptr<FileSystemTestOriginHelper> helper(
1243 NewHelper(origin_url, kFileSystemTypeTemporary));
1244 scoped_ptr<FileSystemOperationContext> context(NewContext(helper.get()));
1245 context->set_src_origin_url(origin_url);
1246 context->set_src_type(kFileSystemTypeTemporary);
1247 bool created = false;
1248 ASSERT_EQ(base::PLATFORM_FILE_OK,
1249 ofsfu()->EnsureFileExists(context.get(),
1250 FilePath().AppendASCII("file"), &created));
1251 EXPECT_TRUE(created);
1252 }
1253 if (record.has_persistent) {
1254 scoped_ptr<FileSystemTestOriginHelper> helper(
1255 NewHelper(origin_url, kFileSystemTypePersistent));
1256 scoped_ptr<FileSystemOperationContext> context(NewContext(helper.get()));
1257 context->set_src_origin_url(origin_url);
1258 context->set_src_type(kFileSystemTypePersistent);
1259 bool created = false;
1260 ASSERT_EQ(base::PLATFORM_FILE_OK,
1261 ofsfu()->EnsureFileExists(context.get(),
1262 FilePath().AppendASCII("file"), &created));
1263 EXPECT_TRUE(created);
1264 }
1265 }
1266 enumerator.reset(ofsfu()->CreateOriginEnumerator());
1267 EXPECT_TRUE(enumerator.get());
1268 std::set<GURL> origins_found;
1269 GURL origin_url;
1270 while (!(origin_url = enumerator->Next()).is_empty()) {
1271 origins_found.insert(origin_url);
1272 SCOPED_TRACE(testing::Message() << "Handling " << origin_url.spec());
1273 bool found = false;
1274 for (size_t i = 0; !found && i < arraysize(kOriginEnumerationTestRecords);
1275 ++i) {
1276 const OriginEnumerationTestRecord& record =
1277 kOriginEnumerationTestRecords[i];
1278 if (GURL(record.origin_url) != origin_url)
1279 continue;
1280 found = true;
1281 EXPECT_EQ(record.has_temporary,
1282 enumerator->HasFileSystemType(kFileSystemTypeTemporary));
1283 EXPECT_EQ(record.has_persistent,
1284 enumerator->HasFileSystemType(kFileSystemTypePersistent));
1285 }
1286 // Deal with the default filesystem created by the test helper.
1287 if (!found && origin_url == origin()) {
1288 ASSERT_TRUE(type() == kFileSystemTypeTemporary);
1289 EXPECT_EQ(true,
1290 enumerator->HasFileSystemType(kFileSystemTypeTemporary));
1291 EXPECT_EQ(false,
1292 enumerator->HasFileSystemType(kFileSystemTypePersistent));
1293 found = true;
1294 }
1295 EXPECT_TRUE(found);
1296 }
1297
1298 std::set<GURL> diff;
1299 std::set_symmetric_difference(origins_expected.begin(),
1300 origins_expected.end(), origins_found.begin(), origins_found.end(),
1301 inserter(diff, diff.begin()));
1302 EXPECT_TRUE(diff.empty());
1303 }
1304
1305 TEST_F(ObfuscatedFileSystemFileUtilTest, TestRevokeUsageCache) {
1306 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL));
1307
1308 int64 expected_quota = 0;
1309
1310 for (size_t i = 0; i < arraysize(kMigrationTestCases); ++i) {
1311 SCOPED_TRACE(testing::Message() << "Creating kMigrationTestPath " << i);
1312 const MigrationTestCaseRecord& test_case = kMigrationTestCases[i];
1313 FilePath path(test_case.path);
1314 expected_quota += ObfuscatedFileSystemFileUtil::ComputeFilePathCost(path);
1315 if (test_case.is_directory) {
1316 bool exclusive = true;
1317 bool recursive = false;
1318 ASSERT_EQ(base::PLATFORM_FILE_OK,
1319 ofsfu()->CreateDirectory(context.get(), path, exclusive, recursive));
1320 } else {
1321 bool created = false;
1322 ASSERT_EQ(base::PLATFORM_FILE_OK,
1323 ofsfu()->EnsureFileExists(context.get(), path, &created));
1324 ASSERT_TRUE(created);
1325 ASSERT_EQ(base::PLATFORM_FILE_OK,
1326 ofsfu()->Truncate(context.get(), path,
1327 test_case.data_file_size));
1328 expected_quota += test_case.data_file_size;
1329 }
1330 }
1331 EXPECT_EQ(expected_quota, SizeInUsageFile());
1332 RevokeUsageCache();
1333 EXPECT_EQ(-1, SizeInUsageFile());
1334 GetUsageFromQuotaManager();
1335 EXPECT_EQ(expected_quota, SizeInUsageFile());
1336 EXPECT_EQ(expected_quota, usage());
1337 }
1338
1339 TEST_F(ObfuscatedFileSystemFileUtilTest, TestInconsistency) {
1340 const FilePath kPath1 = FilePath().AppendASCII("hoge");
1341 const FilePath kPath2 = FilePath().AppendASCII("fuga");
1342
1343 scoped_ptr<FileSystemOperationContext> context;
1344 base::PlatformFile file;
1345 base::PlatformFileInfo file_info;
1346 FilePath data_path;
1347 bool created = false;
1348
1349 // Create a non-empty file.
1350 context.reset(NewContext(NULL));
1351 EXPECT_EQ(base::PLATFORM_FILE_OK,
1352 ofsfu()->EnsureFileExists(context.get(), kPath1, &created));
1353 EXPECT_TRUE(created);
1354 context.reset(NewContext(NULL));
1355 EXPECT_EQ(base::PLATFORM_FILE_OK,
1356 ofsfu()->Truncate(context.get(), kPath1, 10));
1357 context.reset(NewContext(NULL));
1358 EXPECT_EQ(base::PLATFORM_FILE_OK,
1359 ofsfu()->GetFileInfo(
1360 context.get(), kPath1, &file_info, &data_path));
1361 EXPECT_EQ(10, file_info.size);
1362
1363 // Destroy database to make inconsistency between database and filesystem.
1364 ofsfu()->DestroyDirectoryDatabase(origin(), type());
1365
1366 // Try to get file info of broken file.
1367 context.reset(NewContext(NULL));
1368 EXPECT_FALSE(ofsfu()->PathExists(context.get(), kPath1));
1369 context.reset(NewContext(NULL));
1370 EXPECT_EQ(base::PLATFORM_FILE_OK,
1371 ofsfu()->EnsureFileExists(context.get(), kPath1, &created));
1372 EXPECT_TRUE(created);
1373 context.reset(NewContext(NULL));
1374 EXPECT_EQ(base::PLATFORM_FILE_OK,
1375 ofsfu()->GetFileInfo(
1376 context.get(), kPath1, &file_info, &data_path));
1377 EXPECT_EQ(0, file_info.size);
1378
1379 // Make another broken file to |kPath2|.
1380 context.reset(NewContext(NULL));
1381 EXPECT_EQ(base::PLATFORM_FILE_OK,
1382 ofsfu()->EnsureFileExists(context.get(), kPath2, &created));
1383 EXPECT_TRUE(created);
1384
1385 // Destroy again.
1386 ofsfu()->DestroyDirectoryDatabase(origin(), type());
1387
1388 // Repair broken |kPath1|.
1389 context.reset(NewContext(NULL));
1390 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND,
1391 ofsfu()->Touch(context.get(), kPath1, base::Time::Now(),
1392 base::Time::Now()));
1393 EXPECT_EQ(base::PLATFORM_FILE_OK,
1394 ofsfu()->EnsureFileExists(context.get(), kPath1, &created));
1395 EXPECT_TRUE(created);
1396
1397 // Copy from sound |kPath1| to broken |kPath2|.
1398 context.reset(NewContext(NULL));
1399 EXPECT_EQ(base::PLATFORM_FILE_OK,
1400 ofsfu()->CopyOrMoveFile(context.get(), kPath1, kPath2,
1401 true /* copy */));
1402
1403 ofsfu()->DestroyDirectoryDatabase(origin(), type());
1404 context.reset(NewContext(NULL));
1405 EXPECT_EQ(base::PLATFORM_FILE_OK,
1406 ofsfu()->CreateOrOpen(
1407 context.get(), kPath1,
1408 base::PLATFORM_FILE_READ | base::PLATFORM_FILE_CREATE,
1409 &file, &created));
1410 EXPECT_TRUE(created);
1411 EXPECT_TRUE(base::GetPlatformFileInfo(file, &file_info));
1412 EXPECT_EQ(0, file_info.size);
1413 EXPECT_TRUE(base::ClosePlatformFile(file));
1414 }
1415
1416 TEST_F(ObfuscatedFileSystemFileUtilTest, TestIncompleteDirectoryReading) {
1417 const FilePath kPath[] = {
1418 FilePath().AppendASCII("foo"),
1419 FilePath().AppendASCII("bar"),
1420 FilePath().AppendASCII("baz")
1421 };
1422 scoped_ptr<FileSystemOperationContext> context;
1423
1424 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kPath); ++i) {
1425 bool created = false;
1426 context.reset(NewContext(NULL));
1427 EXPECT_EQ(base::PLATFORM_FILE_OK,
1428 ofsfu()->EnsureFileExists(context.get(), kPath[i], &created));
1429 EXPECT_TRUE(created);
1430 }
1431
1432 context.reset(NewContext(NULL));
1433 std::vector<base::FileUtilProxy::Entry> entries;
1434 EXPECT_EQ(base::PLATFORM_FILE_OK,
1435 ofsfu()->ReadDirectory(context.get(), FilePath(), &entries));
1436 EXPECT_EQ(3u, entries.size());
1437
1438 context.reset(NewContext(NULL));
1439 FilePath local_path;
1440 EXPECT_EQ(base::PLATFORM_FILE_OK,
1441 ofsfu()->GetLocalFilePath(context.get(), kPath[0], &local_path));
1442 EXPECT_TRUE(file_util::Delete(local_path, false));
1443
1444 context.reset(NewContext(NULL));
1445 entries.clear();
1446 EXPECT_EQ(base::PLATFORM_FILE_OK,
1447 ofsfu()->ReadDirectory(context.get(), FilePath(), &entries));
1448 EXPECT_EQ(ARRAYSIZE_UNSAFE(kPath) - 1, entries.size());
1449 }
OLDNEW
« no previous file with comments | « webkit/fileapi/obfuscated_file_system_file_util.cc ('k') | webkit/fileapi/obfuscated_file_util.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698