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