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