| 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 "webkit/fileapi/local_file_system_operation.h" | |
| 6 | |
| 7 #include "base/bind.h" | |
| 8 #include "base/files/scoped_temp_dir.h" | |
| 9 #include "base/logging.h" | |
| 10 #include "base/memory/scoped_ptr.h" | |
| 11 #include "base/memory/weak_ptr.h" | |
| 12 #include "base/message_loop.h" | |
| 13 #include "base/strings/string_number_conversions.h" | |
| 14 #include "googleurl/src/gurl.h" | |
| 15 #include "testing/gtest/include/gtest/gtest.h" | |
| 16 #include "webkit/blob/shareable_file_reference.h" | |
| 17 #include "webkit/fileapi/async_file_test_helper.h" | |
| 18 #include "webkit/fileapi/file_system_context.h" | |
| 19 #include "webkit/fileapi/file_system_file_util.h" | |
| 20 #include "webkit/fileapi/file_system_mount_point_provider.h" | |
| 21 #include "webkit/fileapi/file_system_operation_context.h" | |
| 22 #include "webkit/fileapi/file_system_quota_util.h" | |
| 23 #include "webkit/fileapi/file_system_util.h" | |
| 24 #include "webkit/fileapi/local_file_system_test_helper.h" | |
| 25 #include "webkit/fileapi/mock_file_change_observer.h" | |
| 26 #include "webkit/quota/mock_quota_manager.h" | |
| 27 #include "webkit/quota/quota_manager.h" | |
| 28 | |
| 29 using quota::QuotaManager; | |
| 30 using quota::QuotaManagerProxy; | |
| 31 using webkit_blob::ShareableFileReference; | |
| 32 | |
| 33 namespace fileapi { | |
| 34 | |
| 35 namespace { | |
| 36 | |
| 37 const int kFileOperationStatusNotSet = 1; | |
| 38 | |
| 39 void AssertFileErrorEq(base::PlatformFileError expected, | |
| 40 base::PlatformFileError actual) { | |
| 41 ASSERT_EQ(expected, actual); | |
| 42 } | |
| 43 | |
| 44 } // namespace (anonymous) | |
| 45 | |
| 46 // Test class for LocalFileSystemOperation. | |
| 47 class LocalFileSystemOperationTest | |
| 48 : public testing::Test, | |
| 49 public base::SupportsWeakPtr<LocalFileSystemOperationTest> { | |
| 50 public: | |
| 51 LocalFileSystemOperationTest() | |
| 52 : status_(kFileOperationStatusNotSet), | |
| 53 next_unique_path_suffix_(0) { | |
| 54 EXPECT_TRUE(base_.CreateUniqueTempDir()); | |
| 55 change_observers_ = MockFileChangeObserver::CreateList(&change_observer_); | |
| 56 } | |
| 57 | |
| 58 virtual void SetUp() OVERRIDE { | |
| 59 base::FilePath base_dir = base_.path().AppendASCII("filesystem"); | |
| 60 quota_manager_ = new quota::MockQuotaManager( | |
| 61 false /* is_incognito */, base_dir, | |
| 62 base::MessageLoopProxy::current(), | |
| 63 base::MessageLoopProxy::current(), | |
| 64 NULL /* special storage policy */); | |
| 65 quota_manager_proxy_ = new quota::MockQuotaManagerProxy( | |
| 66 quota_manager(), | |
| 67 base::MessageLoopProxy::current()); | |
| 68 test_helper_.SetUp(base_dir, quota_manager_proxy_.get()); | |
| 69 } | |
| 70 | |
| 71 virtual void TearDown() OVERRIDE { | |
| 72 // Let the client go away before dropping a ref of the quota manager proxy. | |
| 73 quota_manager_proxy()->SimulateQuotaManagerDestroyed(); | |
| 74 quota_manager_ = NULL; | |
| 75 quota_manager_proxy_ = NULL; | |
| 76 test_helper_.TearDown(); | |
| 77 } | |
| 78 | |
| 79 LocalFileSystemOperation* NewOperation() { | |
| 80 LocalFileSystemOperation* operation = test_helper_.NewOperation(); | |
| 81 operation->operation_context()->set_change_observers(change_observers()); | |
| 82 return operation; | |
| 83 } | |
| 84 | |
| 85 int status() const { return status_; } | |
| 86 const base::PlatformFileInfo& info() const { return info_; } | |
| 87 const base::FilePath& path() const { return path_; } | |
| 88 const std::vector<base::FileUtilProxy::Entry>& entries() const { | |
| 89 return entries_; | |
| 90 } | |
| 91 const ShareableFileReference* shareable_file_ref() const { | |
| 92 return shareable_file_ref_; | |
| 93 } | |
| 94 | |
| 95 protected: | |
| 96 // Common temp base for nondestructive uses. | |
| 97 base::ScopedTempDir base_; | |
| 98 | |
| 99 quota::MockQuotaManager* quota_manager() { | |
| 100 return static_cast<quota::MockQuotaManager*>(quota_manager_.get()); | |
| 101 } | |
| 102 | |
| 103 quota::MockQuotaManagerProxy* quota_manager_proxy() { | |
| 104 return static_cast<quota::MockQuotaManagerProxy*>( | |
| 105 quota_manager_proxy_.get()); | |
| 106 } | |
| 107 | |
| 108 FileSystemFileUtil* file_util() { | |
| 109 return test_helper_.file_util(); | |
| 110 } | |
| 111 | |
| 112 const ChangeObserverList& change_observers() const { | |
| 113 return change_observers_; | |
| 114 } | |
| 115 | |
| 116 MockFileChangeObserver* change_observer() { | |
| 117 return &change_observer_; | |
| 118 } | |
| 119 | |
| 120 FileSystemOperationContext* NewContext() { | |
| 121 FileSystemOperationContext* context = test_helper_.NewOperationContext(); | |
| 122 // Grant enough quota for all test cases. | |
| 123 context->set_allowed_bytes_growth(1000000); | |
| 124 return context; | |
| 125 } | |
| 126 | |
| 127 FileSystemURL URLForPath(const base::FilePath& path) const { | |
| 128 return test_helper_.CreateURL(path); | |
| 129 } | |
| 130 | |
| 131 base::FilePath PlatformPath(const base::FilePath& virtual_path) { | |
| 132 return test_helper_.GetLocalPath(virtual_path); | |
| 133 } | |
| 134 | |
| 135 bool FileExists(const base::FilePath& virtual_path) { | |
| 136 FileSystemURL url = test_helper_.CreateURL(virtual_path); | |
| 137 return AsyncFileTestHelper::FileExists( | |
| 138 test_helper_.file_system_context(), url, | |
| 139 AsyncFileTestHelper::kDontCheckSize); | |
| 140 } | |
| 141 | |
| 142 bool DirectoryExists(const base::FilePath& virtual_path) { | |
| 143 FileSystemURL url = test_helper_.CreateURL(virtual_path); | |
| 144 return AsyncFileTestHelper::DirectoryExists( | |
| 145 test_helper_.file_system_context(), url); | |
| 146 } | |
| 147 | |
| 148 base::FilePath CreateUniqueFileInDir(const base::FilePath& virtual_dir_path) { | |
| 149 base::FilePath file_name = base::FilePath::FromUTF8Unsafe( | |
| 150 "tmpfile-" + base::IntToString(next_unique_path_suffix_++)); | |
| 151 FileSystemURL url = test_helper_.CreateURL( | |
| 152 virtual_dir_path.Append(file_name)); | |
| 153 | |
| 154 scoped_ptr<FileSystemOperationContext> context(NewContext()); | |
| 155 bool created; | |
| 156 EXPECT_EQ(base::PLATFORM_FILE_OK, | |
| 157 file_util()->EnsureFileExists(context.get(), url, &created)); | |
| 158 EXPECT_TRUE(created); | |
| 159 return url.path(); | |
| 160 } | |
| 161 | |
| 162 base::FilePath CreateUniqueDirInDir(const base::FilePath& virtual_dir_path) { | |
| 163 base::FilePath dir_name = base::FilePath::FromUTF8Unsafe( | |
| 164 "tmpdir-" + base::IntToString(next_unique_path_suffix_++)); | |
| 165 FileSystemURL url = test_helper_.CreateURL( | |
| 166 virtual_dir_path.Append(dir_name)); | |
| 167 | |
| 168 scoped_ptr<FileSystemOperationContext> context(NewContext()); | |
| 169 EXPECT_EQ(base::PLATFORM_FILE_OK, | |
| 170 file_util()->CreateDirectory(context.get(), url, false, true)); | |
| 171 return url.path(); | |
| 172 } | |
| 173 | |
| 174 base::FilePath CreateUniqueDir() { | |
| 175 return CreateUniqueDirInDir(base::FilePath()); | |
| 176 } | |
| 177 | |
| 178 LocalFileSystemTestOriginHelper test_helper_; | |
| 179 | |
| 180 // Callbacks for recording test results. | |
| 181 FileSystemOperation::StatusCallback RecordStatusCallback() { | |
| 182 return base::Bind(&LocalFileSystemOperationTest::DidFinish, AsWeakPtr()); | |
| 183 } | |
| 184 | |
| 185 FileSystemOperation::ReadDirectoryCallback | |
| 186 RecordReadDirectoryCallback() { | |
| 187 return base::Bind(&LocalFileSystemOperationTest::DidReadDirectory, | |
| 188 AsWeakPtr()); | |
| 189 } | |
| 190 | |
| 191 FileSystemOperation::GetMetadataCallback RecordMetadataCallback() { | |
| 192 return base::Bind(&LocalFileSystemOperationTest::DidGetMetadata, | |
| 193 AsWeakPtr()); | |
| 194 } | |
| 195 | |
| 196 FileSystemOperation::SnapshotFileCallback RecordSnapshotFileCallback() { | |
| 197 return base::Bind(&LocalFileSystemOperationTest::DidCreateSnapshotFile, | |
| 198 AsWeakPtr()); | |
| 199 } | |
| 200 | |
| 201 void DidFinish(base::PlatformFileError status) { | |
| 202 status_ = status; | |
| 203 } | |
| 204 | |
| 205 void DidReadDirectory( | |
| 206 base::PlatformFileError status, | |
| 207 const std::vector<base::FileUtilProxy::Entry>& entries, | |
| 208 bool /* has_more */) { | |
| 209 entries_ = entries; | |
| 210 status_ = status; | |
| 211 } | |
| 212 | |
| 213 void DidGetMetadata(base::PlatformFileError status, | |
| 214 const base::PlatformFileInfo& info, | |
| 215 const base::FilePath& platform_path) { | |
| 216 info_ = info; | |
| 217 path_ = platform_path; | |
| 218 status_ = status; | |
| 219 } | |
| 220 | |
| 221 void DidCreateSnapshotFile( | |
| 222 base::PlatformFileError status, | |
| 223 const base::PlatformFileInfo& info, | |
| 224 const base::FilePath& platform_path, | |
| 225 const scoped_refptr<ShareableFileReference>& shareable_file_ref) { | |
| 226 info_ = info; | |
| 227 path_ = platform_path; | |
| 228 status_ = status; | |
| 229 shareable_file_ref_ = shareable_file_ref; | |
| 230 } | |
| 231 | |
| 232 void GetUsageAndQuota(int64* usage, int64* quota) { | |
| 233 quota::QuotaStatusCode status = | |
| 234 AsyncFileTestHelper::GetUsageAndQuota( | |
| 235 quota_manager_, test_helper_.origin(), test_helper_.type(), | |
| 236 usage, quota); | |
| 237 base::MessageLoop::current()->RunUntilIdle(); | |
| 238 ASSERT_EQ(quota::kQuotaStatusOk, status); | |
| 239 } | |
| 240 | |
| 241 void GenerateUniquePathInDir(const base::FilePath& dir, | |
| 242 base::FilePath* file_path, | |
| 243 int64* path_cost) { | |
| 244 int64 base_usage; | |
| 245 GetUsageAndQuota(&base_usage, NULL); | |
| 246 *file_path = CreateUniqueFileInDir(dir); | |
| 247 NewOperation()->Remove(URLForPath(*file_path), | |
| 248 false /* recursive */, | |
| 249 base::Bind(&AssertFileErrorEq, | |
| 250 base::PLATFORM_FILE_OK)); | |
| 251 base::MessageLoop::current()->RunUntilIdle(); | |
| 252 | |
| 253 int64 total_usage; | |
| 254 GetUsageAndQuota(&total_usage, NULL); | |
| 255 *path_cost = total_usage - base_usage; | |
| 256 } | |
| 257 | |
| 258 void GrantQuotaForCurrentUsage() { | |
| 259 int64 usage; | |
| 260 GetUsageAndQuota(&usage, NULL); | |
| 261 quota_manager()->SetQuota(test_helper_.origin(), | |
| 262 test_helper_.storage_type(), | |
| 263 usage); | |
| 264 } | |
| 265 | |
| 266 void AddQuota(int64 quota_delta) { | |
| 267 int64 quota; | |
| 268 GetUsageAndQuota(NULL, "a); | |
| 269 quota_manager()->SetQuota(test_helper_.origin(), | |
| 270 test_helper_.storage_type(), | |
| 271 quota + quota_delta); | |
| 272 } | |
| 273 | |
| 274 // For post-operation status. | |
| 275 int status_; | |
| 276 base::PlatformFileInfo info_; | |
| 277 base::FilePath path_; | |
| 278 std::vector<base::FileUtilProxy::Entry> entries_; | |
| 279 scoped_refptr<ShareableFileReference> shareable_file_ref_; | |
| 280 | |
| 281 private: | |
| 282 base::MessageLoop message_loop_; | |
| 283 scoped_refptr<QuotaManager> quota_manager_; | |
| 284 scoped_refptr<QuotaManagerProxy> quota_manager_proxy_; | |
| 285 | |
| 286 MockFileChangeObserver change_observer_; | |
| 287 ChangeObserverList change_observers_; | |
| 288 | |
| 289 int next_unique_path_suffix_; | |
| 290 | |
| 291 DISALLOW_COPY_AND_ASSIGN(LocalFileSystemOperationTest); | |
| 292 }; | |
| 293 | |
| 294 TEST_F(LocalFileSystemOperationTest, TestMoveFailureSrcDoesntExist) { | |
| 295 FileSystemURL src(URLForPath(base::FilePath(FILE_PATH_LITERAL("a")))); | |
| 296 FileSystemURL dest(URLForPath(base::FilePath(FILE_PATH_LITERAL("b")))); | |
| 297 change_observer()->ResetCount(); | |
| 298 NewOperation()->Move(src, dest, RecordStatusCallback()); | |
| 299 base::MessageLoop::current()->RunUntilIdle(); | |
| 300 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, status()); | |
| 301 EXPECT_TRUE(change_observer()->HasNoChange()); | |
| 302 } | |
| 303 | |
| 304 TEST_F(LocalFileSystemOperationTest, TestMoveFailureContainsPath) { | |
| 305 base::FilePath src_dir_path(CreateUniqueDir()); | |
| 306 base::FilePath dest_dir_path(CreateUniqueDirInDir(src_dir_path)); | |
| 307 NewOperation()->Move( | |
| 308 URLForPath(src_dir_path), URLForPath(dest_dir_path), | |
| 309 RecordStatusCallback()); | |
| 310 base::MessageLoop::current()->RunUntilIdle(); | |
| 311 EXPECT_EQ(base::PLATFORM_FILE_ERROR_INVALID_OPERATION, status()); | |
| 312 EXPECT_TRUE(change_observer()->HasNoChange()); | |
| 313 } | |
| 314 | |
| 315 TEST_F(LocalFileSystemOperationTest, TestMoveFailureSrcDirExistsDestFile) { | |
| 316 // Src exists and is dir. Dest is a file. | |
| 317 base::FilePath src_dir_path(CreateUniqueDir()); | |
| 318 base::FilePath dest_dir_path(CreateUniqueDir()); | |
| 319 base::FilePath dest_file_path(CreateUniqueFileInDir(dest_dir_path)); | |
| 320 | |
| 321 NewOperation()->Move( | |
| 322 URLForPath(src_dir_path), URLForPath(dest_file_path), | |
| 323 RecordStatusCallback()); | |
| 324 base::MessageLoop::current()->RunUntilIdle(); | |
| 325 EXPECT_EQ(base::PLATFORM_FILE_ERROR_INVALID_OPERATION, status()); | |
| 326 EXPECT_TRUE(change_observer()->HasNoChange()); | |
| 327 } | |
| 328 | |
| 329 TEST_F(LocalFileSystemOperationTest, | |
| 330 TestMoveFailureSrcFileExistsDestNonEmptyDir) { | |
| 331 // Src exists and is a directory. Dest is a non-empty directory. | |
| 332 base::FilePath src_dir_path(CreateUniqueDir()); | |
| 333 base::FilePath dest_dir_path(CreateUniqueDir()); | |
| 334 base::FilePath child_file_path(CreateUniqueFileInDir(dest_dir_path)); | |
| 335 | |
| 336 NewOperation()->Move( | |
| 337 URLForPath(src_dir_path), URLForPath(dest_dir_path), | |
| 338 RecordStatusCallback()); | |
| 339 base::MessageLoop::current()->RunUntilIdle(); | |
| 340 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_EMPTY, status()); | |
| 341 EXPECT_TRUE(change_observer()->HasNoChange()); | |
| 342 } | |
| 343 | |
| 344 TEST_F(LocalFileSystemOperationTest, TestMoveFailureSrcFileExistsDestDir) { | |
| 345 // Src exists and is a file. Dest is a directory. | |
| 346 base::FilePath src_dir_path(CreateUniqueDir()); | |
| 347 base::FilePath src_file_path(CreateUniqueFileInDir(src_dir_path)); | |
| 348 base::FilePath dest_dir_path(CreateUniqueDir()); | |
| 349 | |
| 350 NewOperation()->Move( | |
| 351 URLForPath(src_file_path), URLForPath(dest_dir_path), | |
| 352 RecordStatusCallback()); | |
| 353 base::MessageLoop::current()->RunUntilIdle(); | |
| 354 EXPECT_EQ(base::PLATFORM_FILE_ERROR_INVALID_OPERATION, status()); | |
| 355 EXPECT_TRUE(change_observer()->HasNoChange()); | |
| 356 } | |
| 357 | |
| 358 TEST_F(LocalFileSystemOperationTest, TestMoveFailureDestParentDoesntExist) { | |
| 359 // Dest. parent path does not exist. | |
| 360 base::FilePath src_dir_path(CreateUniqueDir()); | |
| 361 base::FilePath nonexisting_file = base::FilePath( | |
| 362 FILE_PATH_LITERAL("NonexistingDir")). | |
| 363 Append(FILE_PATH_LITERAL("NonexistingFile")); | |
| 364 | |
| 365 NewOperation()->Move( | |
| 366 URLForPath(src_dir_path), URLForPath(nonexisting_file), | |
| 367 RecordStatusCallback()); | |
| 368 base::MessageLoop::current()->RunUntilIdle(); | |
| 369 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, status()); | |
| 370 EXPECT_TRUE(change_observer()->HasNoChange()); | |
| 371 } | |
| 372 | |
| 373 TEST_F(LocalFileSystemOperationTest, TestMoveSuccessSrcFileAndOverwrite) { | |
| 374 base::FilePath src_dir_path(CreateUniqueDir()); | |
| 375 base::FilePath src_file_path(CreateUniqueFileInDir(src_dir_path)); | |
| 376 base::FilePath dest_dir_path(CreateUniqueDir()); | |
| 377 base::FilePath dest_file_path(CreateUniqueFileInDir(dest_dir_path)); | |
| 378 | |
| 379 NewOperation()->Move( | |
| 380 URLForPath(src_file_path), URLForPath(dest_file_path), | |
| 381 RecordStatusCallback()); | |
| 382 base::MessageLoop::current()->RunUntilIdle(); | |
| 383 EXPECT_EQ(base::PLATFORM_FILE_OK, status()); | |
| 384 EXPECT_TRUE(FileExists(dest_file_path)); | |
| 385 | |
| 386 EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count()); | |
| 387 EXPECT_EQ(1, change_observer()->get_and_reset_remove_file_count()); | |
| 388 EXPECT_TRUE(change_observer()->HasNoChange()); | |
| 389 | |
| 390 EXPECT_EQ(1, quota_manager_proxy()->notify_storage_accessed_count()); | |
| 391 } | |
| 392 | |
| 393 TEST_F(LocalFileSystemOperationTest, TestMoveSuccessSrcFileAndNew) { | |
| 394 base::FilePath src_dir_path(CreateUniqueDir()); | |
| 395 base::FilePath src_file_path(CreateUniqueFileInDir(src_dir_path)); | |
| 396 base::FilePath dest_dir_path(CreateUniqueDir()); | |
| 397 base::FilePath dest_file_path( | |
| 398 dest_dir_path.Append(FILE_PATH_LITERAL("NewFile"))); | |
| 399 | |
| 400 NewOperation()->Move( | |
| 401 URLForPath(src_file_path), URLForPath(dest_file_path), | |
| 402 RecordStatusCallback()); | |
| 403 base::MessageLoop::current()->RunUntilIdle(); | |
| 404 EXPECT_EQ(base::PLATFORM_FILE_OK, status()); | |
| 405 EXPECT_TRUE(FileExists(dest_file_path)); | |
| 406 | |
| 407 EXPECT_EQ(1, change_observer()->get_and_reset_create_file_from_count()); | |
| 408 EXPECT_EQ(1, change_observer()->get_and_reset_remove_file_count()); | |
| 409 EXPECT_TRUE(change_observer()->HasNoChange()); | |
| 410 } | |
| 411 | |
| 412 TEST_F(LocalFileSystemOperationTest, TestMoveSuccessSrcDirAndOverwrite) { | |
| 413 base::FilePath src_dir_path(CreateUniqueDir()); | |
| 414 base::FilePath dest_dir_path(CreateUniqueDir()); | |
| 415 | |
| 416 NewOperation()->Move( | |
| 417 URLForPath(src_dir_path), URLForPath(dest_dir_path), | |
| 418 RecordStatusCallback()); | |
| 419 base::MessageLoop::current()->RunUntilIdle(); | |
| 420 EXPECT_EQ(base::PLATFORM_FILE_OK, status()); | |
| 421 EXPECT_FALSE(DirectoryExists(src_dir_path)); | |
| 422 | |
| 423 EXPECT_EQ(1, change_observer()->get_and_reset_create_directory_count()); | |
| 424 EXPECT_EQ(2, change_observer()->get_and_reset_remove_directory_count()); | |
| 425 EXPECT_TRUE(change_observer()->HasNoChange()); | |
| 426 | |
| 427 // Make sure we've overwritten but not moved the source under the |dest_dir|. | |
| 428 EXPECT_TRUE(DirectoryExists(dest_dir_path)); | |
| 429 EXPECT_FALSE(DirectoryExists( | |
| 430 dest_dir_path.Append(VirtualPath::BaseName(src_dir_path)))); | |
| 431 } | |
| 432 | |
| 433 TEST_F(LocalFileSystemOperationTest, TestMoveSuccessSrcDirAndNew) { | |
| 434 base::FilePath src_dir_path(CreateUniqueDir()); | |
| 435 base::FilePath dest_parent_dir_path(CreateUniqueDir()); | |
| 436 base::FilePath dest_child_dir_path(dest_parent_dir_path. | |
| 437 Append(FILE_PATH_LITERAL("NewDirectory"))); | |
| 438 | |
| 439 NewOperation()->Move( | |
| 440 URLForPath(src_dir_path), URLForPath(dest_child_dir_path), | |
| 441 RecordStatusCallback()); | |
| 442 base::MessageLoop::current()->RunUntilIdle(); | |
| 443 EXPECT_EQ(base::PLATFORM_FILE_OK, status()); | |
| 444 EXPECT_FALSE(DirectoryExists(src_dir_path)); | |
| 445 EXPECT_TRUE(DirectoryExists(dest_child_dir_path)); | |
| 446 | |
| 447 EXPECT_EQ(1, change_observer()->get_and_reset_remove_directory_count()); | |
| 448 EXPECT_EQ(1, change_observer()->get_and_reset_create_directory_count()); | |
| 449 EXPECT_TRUE(change_observer()->HasNoChange()); | |
| 450 } | |
| 451 | |
| 452 TEST_F(LocalFileSystemOperationTest, TestMoveSuccessSrcDirRecursive) { | |
| 453 base::FilePath src_dir_path(CreateUniqueDir()); | |
| 454 base::FilePath child_dir_path(CreateUniqueDirInDir(src_dir_path)); | |
| 455 base::FilePath grandchild_file_path( | |
| 456 CreateUniqueFileInDir(child_dir_path)); | |
| 457 | |
| 458 base::FilePath dest_dir_path(CreateUniqueDir()); | |
| 459 | |
| 460 NewOperation()->Move( | |
| 461 URLForPath(src_dir_path), URLForPath(dest_dir_path), | |
| 462 RecordStatusCallback()); | |
| 463 base::MessageLoop::current()->RunUntilIdle(); | |
| 464 EXPECT_EQ(base::PLATFORM_FILE_OK, status()); | |
| 465 EXPECT_TRUE(DirectoryExists(dest_dir_path.Append( | |
| 466 VirtualPath::BaseName(child_dir_path)))); | |
| 467 EXPECT_TRUE(FileExists(dest_dir_path.Append( | |
| 468 VirtualPath::BaseName(child_dir_path)).Append( | |
| 469 VirtualPath::BaseName(grandchild_file_path)))); | |
| 470 | |
| 471 EXPECT_EQ(3, change_observer()->get_and_reset_remove_directory_count()); | |
| 472 EXPECT_EQ(2, change_observer()->get_and_reset_create_directory_count()); | |
| 473 EXPECT_EQ(1, change_observer()->get_and_reset_remove_file_count()); | |
| 474 EXPECT_EQ(1, change_observer()->get_and_reset_create_file_from_count()); | |
| 475 EXPECT_TRUE(change_observer()->HasNoChange()); | |
| 476 } | |
| 477 | |
| 478 TEST_F(LocalFileSystemOperationTest, TestCopyFailureSrcDoesntExist) { | |
| 479 NewOperation()->Copy( | |
| 480 URLForPath(base::FilePath(FILE_PATH_LITERAL("a"))), | |
| 481 URLForPath(base::FilePath(FILE_PATH_LITERAL("b"))), | |
| 482 RecordStatusCallback()); | |
| 483 base::MessageLoop::current()->RunUntilIdle(); | |
| 484 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, status()); | |
| 485 EXPECT_TRUE(change_observer()->HasNoChange()); | |
| 486 } | |
| 487 | |
| 488 TEST_F(LocalFileSystemOperationTest, TestCopyFailureContainsPath) { | |
| 489 base::FilePath src_dir_path(CreateUniqueDir()); | |
| 490 base::FilePath dest_dir_path(CreateUniqueDirInDir(src_dir_path)); | |
| 491 NewOperation()->Copy( | |
| 492 URLForPath(src_dir_path), URLForPath(dest_dir_path), | |
| 493 RecordStatusCallback()); | |
| 494 base::MessageLoop::current()->RunUntilIdle(); | |
| 495 EXPECT_EQ(base::PLATFORM_FILE_ERROR_INVALID_OPERATION, status()); | |
| 496 EXPECT_TRUE(change_observer()->HasNoChange()); | |
| 497 } | |
| 498 | |
| 499 TEST_F(LocalFileSystemOperationTest, TestCopyFailureSrcDirExistsDestFile) { | |
| 500 // Src exists and is dir. Dest is a file. | |
| 501 base::FilePath src_dir_path(CreateUniqueDir()); | |
| 502 base::FilePath dest_dir_path(CreateUniqueDir()); | |
| 503 base::FilePath dest_file_path(CreateUniqueFileInDir(dest_dir_path)); | |
| 504 | |
| 505 NewOperation()->Copy( | |
| 506 URLForPath(src_dir_path), URLForPath(dest_file_path), | |
| 507 RecordStatusCallback()); | |
| 508 base::MessageLoop::current()->RunUntilIdle(); | |
| 509 EXPECT_EQ(base::PLATFORM_FILE_ERROR_INVALID_OPERATION, status()); | |
| 510 EXPECT_TRUE(change_observer()->HasNoChange()); | |
| 511 } | |
| 512 | |
| 513 TEST_F(LocalFileSystemOperationTest, | |
| 514 TestCopyFailureSrcFileExistsDestNonEmptyDir) { | |
| 515 // Src exists and is a directory. Dest is a non-empty directory. | |
| 516 base::FilePath src_dir_path(CreateUniqueDir()); | |
| 517 base::FilePath dest_dir_path(CreateUniqueDir()); | |
| 518 base::FilePath child_file_path(CreateUniqueFileInDir(dest_dir_path)); | |
| 519 | |
| 520 NewOperation()->Copy( | |
| 521 URLForPath(src_dir_path), URLForPath(dest_dir_path), | |
| 522 RecordStatusCallback()); | |
| 523 base::MessageLoop::current()->RunUntilIdle(); | |
| 524 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_EMPTY, status()); | |
| 525 EXPECT_TRUE(change_observer()->HasNoChange()); | |
| 526 } | |
| 527 | |
| 528 TEST_F(LocalFileSystemOperationTest, TestCopyFailureSrcFileExistsDestDir) { | |
| 529 // Src exists and is a file. Dest is a directory. | |
| 530 base::FilePath src_dir_path(CreateUniqueDir()); | |
| 531 base::FilePath src_file_path(CreateUniqueFileInDir(src_dir_path)); | |
| 532 base::FilePath dest_dir_path(CreateUniqueDir()); | |
| 533 | |
| 534 NewOperation()->Copy( | |
| 535 URLForPath(src_file_path), URLForPath(dest_dir_path), | |
| 536 RecordStatusCallback()); | |
| 537 base::MessageLoop::current()->RunUntilIdle(); | |
| 538 EXPECT_EQ(base::PLATFORM_FILE_ERROR_INVALID_OPERATION, status()); | |
| 539 EXPECT_TRUE(change_observer()->HasNoChange()); | |
| 540 } | |
| 541 | |
| 542 TEST_F(LocalFileSystemOperationTest, TestCopyFailureDestParentDoesntExist) { | |
| 543 // Dest. parent path does not exist. | |
| 544 base::FilePath src_dir_path(CreateUniqueDir()); | |
| 545 base::FilePath nonexisting_path = base::FilePath( | |
| 546 FILE_PATH_LITERAL("DontExistDir")); | |
| 547 base::FilePath nonexisting_file_path(nonexisting_path.Append( | |
| 548 FILE_PATH_LITERAL("DontExistFile"))); | |
| 549 | |
| 550 NewOperation()->Copy( | |
| 551 URLForPath(src_dir_path), | |
| 552 URLForPath(nonexisting_file_path), | |
| 553 RecordStatusCallback()); | |
| 554 base::MessageLoop::current()->RunUntilIdle(); | |
| 555 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, status()); | |
| 556 EXPECT_TRUE(change_observer()->HasNoChange()); | |
| 557 } | |
| 558 | |
| 559 TEST_F(LocalFileSystemOperationTest, TestCopyFailureByQuota) { | |
| 560 base::PlatformFileInfo info; | |
| 561 | |
| 562 base::FilePath src_dir_path(CreateUniqueDir()); | |
| 563 base::FilePath src_file_path(CreateUniqueFileInDir(src_dir_path)); | |
| 564 base::FilePath dest_dir_path(CreateUniqueDir()); | |
| 565 | |
| 566 base::FilePath dest_file_path; | |
| 567 int64 dest_path_cost; | |
| 568 GenerateUniquePathInDir(dest_dir_path, &dest_file_path, &dest_path_cost); | |
| 569 | |
| 570 GrantQuotaForCurrentUsage(); | |
| 571 AddQuota(6); | |
| 572 | |
| 573 NewOperation()->Truncate(URLForPath(src_file_path), 6, | |
| 574 RecordStatusCallback()); | |
| 575 base::MessageLoop::current()->RunUntilIdle(); | |
| 576 EXPECT_EQ(base::PLATFORM_FILE_OK, status()); | |
| 577 | |
| 578 AddQuota(6 + dest_path_cost - 1); | |
| 579 | |
| 580 EXPECT_TRUE(file_util::GetFileInfo(PlatformPath(src_file_path), &info)); | |
| 581 EXPECT_EQ(6, info.size); | |
| 582 | |
| 583 NewOperation()->Copy( | |
| 584 URLForPath(src_file_path), URLForPath(dest_file_path), | |
| 585 RecordStatusCallback()); | |
| 586 base::MessageLoop::current()->RunUntilIdle(); | |
| 587 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE, status()); | |
| 588 EXPECT_FALSE(FileExists(dest_file_path)); | |
| 589 } | |
| 590 | |
| 591 TEST_F(LocalFileSystemOperationTest, TestCopySuccessSrcFileAndOverwrite) { | |
| 592 base::FilePath src_dir_path(CreateUniqueDir()); | |
| 593 base::FilePath src_file_path(CreateUniqueFileInDir(src_dir_path)); | |
| 594 base::FilePath dest_dir_path(CreateUniqueDir()); | |
| 595 base::FilePath dest_file_path(CreateUniqueFileInDir(dest_dir_path)); | |
| 596 | |
| 597 NewOperation()->Copy( | |
| 598 URLForPath(src_file_path), URLForPath(dest_file_path), | |
| 599 RecordStatusCallback()); | |
| 600 base::MessageLoop::current()->RunUntilIdle(); | |
| 601 EXPECT_EQ(base::PLATFORM_FILE_OK, status()); | |
| 602 EXPECT_TRUE(FileExists(dest_file_path)); | |
| 603 EXPECT_EQ(2, quota_manager_proxy()->notify_storage_accessed_count()); | |
| 604 | |
| 605 EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count()); | |
| 606 EXPECT_TRUE(change_observer()->HasNoChange()); | |
| 607 } | |
| 608 | |
| 609 TEST_F(LocalFileSystemOperationTest, TestCopySuccessSrcFileAndNew) { | |
| 610 base::FilePath src_dir_path(CreateUniqueDir()); | |
| 611 base::FilePath src_file_path(CreateUniqueFileInDir(src_dir_path)); | |
| 612 base::FilePath dest_dir_path(CreateUniqueDir()); | |
| 613 base::FilePath dest_file_path(dest_dir_path.Append( | |
| 614 FILE_PATH_LITERAL("NewFile"))); | |
| 615 | |
| 616 NewOperation()->Copy( | |
| 617 URLForPath(src_file_path), URLForPath(dest_file_path), | |
| 618 RecordStatusCallback()); | |
| 619 base::MessageLoop::current()->RunUntilIdle(); | |
| 620 EXPECT_EQ(base::PLATFORM_FILE_OK, status()); | |
| 621 EXPECT_TRUE(FileExists(dest_file_path)); | |
| 622 EXPECT_EQ(2, quota_manager_proxy()->notify_storage_accessed_count()); | |
| 623 | |
| 624 EXPECT_EQ(1, change_observer()->get_and_reset_create_file_from_count()); | |
| 625 EXPECT_TRUE(change_observer()->HasNoChange()); | |
| 626 } | |
| 627 | |
| 628 TEST_F(LocalFileSystemOperationTest, TestCopySuccessSrcDirAndOverwrite) { | |
| 629 base::FilePath src_dir_path(CreateUniqueDir()); | |
| 630 base::FilePath dest_dir_path(CreateUniqueDir()); | |
| 631 | |
| 632 NewOperation()->Copy( | |
| 633 URLForPath(src_dir_path), URLForPath(dest_dir_path), | |
| 634 RecordStatusCallback()); | |
| 635 base::MessageLoop::current()->RunUntilIdle(); | |
| 636 EXPECT_EQ(base::PLATFORM_FILE_OK, status()); | |
| 637 | |
| 638 // Make sure we've overwritten but not copied the source under the |dest_dir|. | |
| 639 EXPECT_TRUE(DirectoryExists(dest_dir_path)); | |
| 640 EXPECT_FALSE(DirectoryExists( | |
| 641 dest_dir_path.Append(VirtualPath::BaseName(src_dir_path)))); | |
| 642 EXPECT_EQ(3, quota_manager_proxy()->notify_storage_accessed_count()); | |
| 643 | |
| 644 EXPECT_EQ(1, change_observer()->get_and_reset_remove_directory_count()); | |
| 645 EXPECT_EQ(1, change_observer()->get_and_reset_create_directory_count()); | |
| 646 EXPECT_TRUE(change_observer()->HasNoChange()); | |
| 647 } | |
| 648 | |
| 649 TEST_F(LocalFileSystemOperationTest, TestCopySuccessSrcDirAndNew) { | |
| 650 base::FilePath src_dir_path(CreateUniqueDir()); | |
| 651 base::FilePath dest_parent_dir_path(CreateUniqueDir()); | |
| 652 base::FilePath dest_child_dir_path(dest_parent_dir_path. | |
| 653 Append(FILE_PATH_LITERAL("NewDirectory"))); | |
| 654 | |
| 655 NewOperation()->Copy( | |
| 656 URLForPath(src_dir_path), URLForPath(dest_child_dir_path), | |
| 657 RecordStatusCallback()); | |
| 658 base::MessageLoop::current()->RunUntilIdle(); | |
| 659 EXPECT_EQ(base::PLATFORM_FILE_OK, status()); | |
| 660 EXPECT_TRUE(DirectoryExists(dest_child_dir_path)); | |
| 661 EXPECT_EQ(2, quota_manager_proxy()->notify_storage_accessed_count()); | |
| 662 | |
| 663 EXPECT_EQ(1, change_observer()->get_and_reset_create_directory_count()); | |
| 664 EXPECT_TRUE(change_observer()->HasNoChange()); | |
| 665 } | |
| 666 | |
| 667 TEST_F(LocalFileSystemOperationTest, TestCopySuccessSrcDirRecursive) { | |
| 668 base::FilePath src_dir_path(CreateUniqueDir()); | |
| 669 base::FilePath child_dir_path(CreateUniqueDirInDir(src_dir_path)); | |
| 670 base::FilePath grandchild_file_path( | |
| 671 CreateUniqueFileInDir(child_dir_path)); | |
| 672 | |
| 673 base::FilePath dest_dir_path(CreateUniqueDir()); | |
| 674 NewOperation()->Copy( | |
| 675 URLForPath(src_dir_path), URLForPath(dest_dir_path), | |
| 676 RecordStatusCallback()); | |
| 677 base::MessageLoop::current()->RunUntilIdle(); | |
| 678 EXPECT_EQ(base::PLATFORM_FILE_OK, status()); | |
| 679 EXPECT_TRUE(DirectoryExists(dest_dir_path.Append( | |
| 680 VirtualPath::BaseName(child_dir_path)))); | |
| 681 EXPECT_TRUE(FileExists(dest_dir_path.Append( | |
| 682 VirtualPath::BaseName(child_dir_path)).Append( | |
| 683 VirtualPath::BaseName(grandchild_file_path)))); | |
| 684 | |
| 685 // For recursive copy we may record multiple read access. | |
| 686 EXPECT_GE(quota_manager_proxy()->notify_storage_accessed_count(), 1); | |
| 687 | |
| 688 EXPECT_EQ(2, change_observer()->get_and_reset_create_directory_count()); | |
| 689 EXPECT_EQ(1, change_observer()->get_and_reset_remove_directory_count()); | |
| 690 EXPECT_EQ(1, change_observer()->get_and_reset_create_file_from_count()); | |
| 691 EXPECT_TRUE(change_observer()->HasNoChange()); | |
| 692 } | |
| 693 | |
| 694 TEST_F(LocalFileSystemOperationTest, TestCopyInForeignFileSuccess) { | |
| 695 base::FilePath src_local_disk_file_path; | |
| 696 file_util::CreateTemporaryFile(&src_local_disk_file_path); | |
| 697 const char test_data[] = "foo"; | |
| 698 int data_size = ARRAYSIZE_UNSAFE(test_data); | |
| 699 file_util::WriteFile(src_local_disk_file_path, test_data, data_size); | |
| 700 base::FilePath dest_dir_path(CreateUniqueDir()); | |
| 701 base::FilePath dest_file_path(dest_dir_path.Append( | |
| 702 src_local_disk_file_path.BaseName())); | |
| 703 FileSystemURL dest_file_url = URLForPath(dest_file_path); | |
| 704 int64 before_usage; | |
| 705 GetUsageAndQuota(&before_usage, NULL); | |
| 706 | |
| 707 // Check that the file copied and corresponding usage increased. | |
| 708 NewOperation()->CopyInForeignFile(src_local_disk_file_path, | |
| 709 dest_file_url, | |
| 710 RecordStatusCallback()); | |
| 711 base::MessageLoop::current()->RunUntilIdle(); | |
| 712 EXPECT_EQ(1, change_observer()->create_file_count()); | |
| 713 EXPECT_EQ(base::PLATFORM_FILE_OK, status()); | |
| 714 EXPECT_TRUE(FileExists(dest_file_path)); | |
| 715 int64 after_usage; | |
| 716 GetUsageAndQuota(&after_usage, NULL); | |
| 717 EXPECT_GT(after_usage, before_usage); | |
| 718 | |
| 719 // Compare contents of src and copied file. | |
| 720 char buffer[100]; | |
| 721 EXPECT_EQ(data_size, file_util::ReadFile(PlatformPath(dest_file_path), | |
| 722 buffer, data_size)); | |
| 723 for (int i = 0; i < data_size; ++i) | |
| 724 EXPECT_EQ(test_data[i], buffer[i]); | |
| 725 } | |
| 726 | |
| 727 TEST_F(LocalFileSystemOperationTest, TestCopyInForeignFileFailureByQuota) { | |
| 728 base::FilePath src_local_disk_file_path; | |
| 729 file_util::CreateTemporaryFile(&src_local_disk_file_path); | |
| 730 const char test_data[] = "foo"; | |
| 731 file_util::WriteFile(src_local_disk_file_path, test_data, | |
| 732 ARRAYSIZE_UNSAFE(test_data)); | |
| 733 | |
| 734 base::FilePath dest_dir_path(CreateUniqueDir()); | |
| 735 base::FilePath dest_file_path(dest_dir_path.Append( | |
| 736 src_local_disk_file_path.BaseName())); | |
| 737 FileSystemURL dest_file_url = URLForPath(dest_file_path); | |
| 738 | |
| 739 // Set quota of 0 which should force copy to fail by quota. | |
| 740 quota_manager()->SetQuota(dest_file_url.origin(), | |
| 741 test_helper_.storage_type(), | |
| 742 static_cast<int64>(0)); | |
| 743 NewOperation()->CopyInForeignFile(src_local_disk_file_path, | |
| 744 dest_file_url, | |
| 745 RecordStatusCallback()); | |
| 746 base::MessageLoop::current()->RunUntilIdle(); | |
| 747 | |
| 748 EXPECT_TRUE(!FileExists(dest_file_path)); | |
| 749 EXPECT_EQ(0, change_observer()->create_file_count()); | |
| 750 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE, status()); | |
| 751 } | |
| 752 | |
| 753 TEST_F(LocalFileSystemOperationTest, TestCreateFileFailure) { | |
| 754 // Already existing file and exclusive true. | |
| 755 base::FilePath dir_path(CreateUniqueDir()); | |
| 756 base::FilePath file_path(CreateUniqueFileInDir(dir_path)); | |
| 757 NewOperation()->CreateFile(URLForPath(file_path), true, | |
| 758 RecordStatusCallback()); | |
| 759 base::MessageLoop::current()->RunUntilIdle(); | |
| 760 EXPECT_EQ(base::PLATFORM_FILE_ERROR_EXISTS, status()); | |
| 761 EXPECT_TRUE(change_observer()->HasNoChange()); | |
| 762 } | |
| 763 | |
| 764 TEST_F(LocalFileSystemOperationTest, TestCreateFileSuccessFileExists) { | |
| 765 // Already existing file and exclusive false. | |
| 766 base::FilePath dir_path(CreateUniqueDir()); | |
| 767 base::FilePath file_path(CreateUniqueFileInDir(dir_path)); | |
| 768 NewOperation()->CreateFile(URLForPath(file_path), false, | |
| 769 RecordStatusCallback()); | |
| 770 base::MessageLoop::current()->RunUntilIdle(); | |
| 771 EXPECT_EQ(base::PLATFORM_FILE_OK, status()); | |
| 772 EXPECT_TRUE(FileExists(file_path)); | |
| 773 | |
| 774 // The file was already there; did nothing. | |
| 775 EXPECT_TRUE(change_observer()->HasNoChange()); | |
| 776 } | |
| 777 | |
| 778 TEST_F(LocalFileSystemOperationTest, TestCreateFileSuccessExclusive) { | |
| 779 // File doesn't exist but exclusive is true. | |
| 780 base::FilePath dir_path(CreateUniqueDir()); | |
| 781 base::FilePath file_path( | |
| 782 dir_path.Append(FILE_PATH_LITERAL("FileDoesntExist"))); | |
| 783 NewOperation()->CreateFile(URLForPath(file_path), true, | |
| 784 RecordStatusCallback()); | |
| 785 base::MessageLoop::current()->RunUntilIdle(); | |
| 786 EXPECT_EQ(base::PLATFORM_FILE_OK, status()); | |
| 787 EXPECT_TRUE(FileExists(file_path)); | |
| 788 EXPECT_EQ(1, change_observer()->get_and_reset_create_file_count()); | |
| 789 } | |
| 790 | |
| 791 TEST_F(LocalFileSystemOperationTest, TestCreateFileSuccessFileDoesntExist) { | |
| 792 // Non existing file. | |
| 793 base::FilePath dir_path(CreateUniqueDir()); | |
| 794 base::FilePath file_path( | |
| 795 dir_path.Append(FILE_PATH_LITERAL("FileDoesntExist"))); | |
| 796 NewOperation()->CreateFile(URLForPath(file_path), false, | |
| 797 RecordStatusCallback()); | |
| 798 base::MessageLoop::current()->RunUntilIdle(); | |
| 799 EXPECT_EQ(base::PLATFORM_FILE_OK, status()); | |
| 800 EXPECT_EQ(1, change_observer()->get_and_reset_create_file_count()); | |
| 801 } | |
| 802 | |
| 803 TEST_F(LocalFileSystemOperationTest, | |
| 804 TestCreateDirFailureDestParentDoesntExist) { | |
| 805 // Dest. parent path does not exist. | |
| 806 base::FilePath nonexisting_path(base::FilePath( | |
| 807 FILE_PATH_LITERAL("DirDoesntExist"))); | |
| 808 base::FilePath nonexisting_file_path(nonexisting_path.Append( | |
| 809 FILE_PATH_LITERAL("FileDoesntExist"))); | |
| 810 NewOperation()->CreateDirectory( | |
| 811 URLForPath(nonexisting_file_path), false, false, | |
| 812 RecordStatusCallback()); | |
| 813 base::MessageLoop::current()->RunUntilIdle(); | |
| 814 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, status()); | |
| 815 EXPECT_TRUE(change_observer()->HasNoChange()); | |
| 816 } | |
| 817 | |
| 818 TEST_F(LocalFileSystemOperationTest, TestCreateDirFailureDirExists) { | |
| 819 // Exclusive and dir existing at path. | |
| 820 base::FilePath src_dir_path(CreateUniqueDir()); | |
| 821 NewOperation()->CreateDirectory(URLForPath(src_dir_path), true, false, | |
| 822 RecordStatusCallback()); | |
| 823 base::MessageLoop::current()->RunUntilIdle(); | |
| 824 EXPECT_EQ(base::PLATFORM_FILE_ERROR_EXISTS, status()); | |
| 825 EXPECT_TRUE(change_observer()->HasNoChange()); | |
| 826 } | |
| 827 | |
| 828 TEST_F(LocalFileSystemOperationTest, TestCreateDirFailureFileExists) { | |
| 829 // Exclusive true and file existing at path. | |
| 830 base::FilePath dir_path(CreateUniqueDir()); | |
| 831 base::FilePath file_path(CreateUniqueFileInDir(dir_path)); | |
| 832 NewOperation()->CreateDirectory(URLForPath(file_path), true, false, | |
| 833 RecordStatusCallback()); | |
| 834 base::MessageLoop::current()->RunUntilIdle(); | |
| 835 EXPECT_EQ(base::PLATFORM_FILE_ERROR_EXISTS, status()); | |
| 836 EXPECT_TRUE(change_observer()->HasNoChange()); | |
| 837 } | |
| 838 | |
| 839 TEST_F(LocalFileSystemOperationTest, TestCreateDirSuccess) { | |
| 840 // Dir exists and exclusive is false. | |
| 841 base::FilePath dir_path(CreateUniqueDir()); | |
| 842 NewOperation()->CreateDirectory(URLForPath(dir_path), false, false, | |
| 843 RecordStatusCallback()); | |
| 844 base::MessageLoop::current()->RunUntilIdle(); | |
| 845 EXPECT_EQ(base::PLATFORM_FILE_OK, status()); | |
| 846 EXPECT_TRUE(change_observer()->HasNoChange()); | |
| 847 | |
| 848 // Dir doesn't exist. | |
| 849 base::FilePath nonexisting_dir_path(base::FilePath( | |
| 850 FILE_PATH_LITERAL("nonexistingdir"))); | |
| 851 NewOperation()->CreateDirectory( | |
| 852 URLForPath(nonexisting_dir_path), false, false, | |
| 853 RecordStatusCallback()); | |
| 854 base::MessageLoop::current()->RunUntilIdle(); | |
| 855 EXPECT_EQ(base::PLATFORM_FILE_OK, status()); | |
| 856 EXPECT_TRUE(DirectoryExists(nonexisting_dir_path)); | |
| 857 EXPECT_EQ(1, change_observer()->get_and_reset_create_directory_count()); | |
| 858 } | |
| 859 | |
| 860 TEST_F(LocalFileSystemOperationTest, TestCreateDirSuccessExclusive) { | |
| 861 // Dir doesn't exist. | |
| 862 base::FilePath nonexisting_dir_path(base::FilePath( | |
| 863 FILE_PATH_LITERAL("nonexistingdir"))); | |
| 864 | |
| 865 NewOperation()->CreateDirectory( | |
| 866 URLForPath(nonexisting_dir_path), true, false, | |
| 867 RecordStatusCallback()); | |
| 868 base::MessageLoop::current()->RunUntilIdle(); | |
| 869 EXPECT_EQ(base::PLATFORM_FILE_OK, status()); | |
| 870 EXPECT_TRUE(DirectoryExists(nonexisting_dir_path)); | |
| 871 EXPECT_EQ(1, change_observer()->get_and_reset_create_directory_count()); | |
| 872 EXPECT_TRUE(change_observer()->HasNoChange()); | |
| 873 } | |
| 874 | |
| 875 TEST_F(LocalFileSystemOperationTest, TestExistsAndMetadataFailure) { | |
| 876 base::FilePath nonexisting_dir_path(base::FilePath( | |
| 877 FILE_PATH_LITERAL("nonexistingdir"))); | |
| 878 NewOperation()->GetMetadata( | |
| 879 URLForPath(nonexisting_dir_path), | |
| 880 RecordMetadataCallback()); | |
| 881 base::MessageLoop::current()->RunUntilIdle(); | |
| 882 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, status()); | |
| 883 | |
| 884 NewOperation()->FileExists(URLForPath(nonexisting_dir_path), | |
| 885 RecordStatusCallback()); | |
| 886 base::MessageLoop::current()->RunUntilIdle(); | |
| 887 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, status()); | |
| 888 | |
| 889 nonexisting_dir_path = nonexisting_dir_path.AsEndingWithSeparator(); | |
| 890 NewOperation()->DirectoryExists(URLForPath(nonexisting_dir_path), | |
| 891 RecordStatusCallback()); | |
| 892 base::MessageLoop::current()->RunUntilIdle(); | |
| 893 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, status()); | |
| 894 EXPECT_TRUE(change_observer()->HasNoChange()); | |
| 895 } | |
| 896 | |
| 897 TEST_F(LocalFileSystemOperationTest, TestExistsAndMetadataSuccess) { | |
| 898 base::FilePath dir_path(CreateUniqueDir()); | |
| 899 int read_access = 0; | |
| 900 | |
| 901 NewOperation()->DirectoryExists(URLForPath(dir_path), | |
| 902 RecordStatusCallback()); | |
| 903 base::MessageLoop::current()->RunUntilIdle(); | |
| 904 EXPECT_EQ(base::PLATFORM_FILE_OK, status()); | |
| 905 ++read_access; | |
| 906 | |
| 907 NewOperation()->GetMetadata(URLForPath(dir_path), RecordMetadataCallback()); | |
| 908 base::MessageLoop::current()->RunUntilIdle(); | |
| 909 EXPECT_EQ(base::PLATFORM_FILE_OK, status()); | |
| 910 EXPECT_TRUE(info().is_directory); | |
| 911 EXPECT_EQ(base::FilePath(), path()); | |
| 912 ++read_access; | |
| 913 | |
| 914 base::FilePath file_path(CreateUniqueFileInDir(dir_path)); | |
| 915 NewOperation()->FileExists(URLForPath(file_path), RecordStatusCallback()); | |
| 916 base::MessageLoop::current()->RunUntilIdle(); | |
| 917 EXPECT_EQ(base::PLATFORM_FILE_OK, status()); | |
| 918 ++read_access; | |
| 919 | |
| 920 NewOperation()->GetMetadata(URLForPath(file_path), RecordMetadataCallback()); | |
| 921 base::MessageLoop::current()->RunUntilIdle(); | |
| 922 EXPECT_EQ(base::PLATFORM_FILE_OK, status()); | |
| 923 EXPECT_FALSE(info().is_directory); | |
| 924 EXPECT_EQ(PlatformPath(file_path), path()); | |
| 925 ++read_access; | |
| 926 | |
| 927 EXPECT_EQ(read_access, | |
| 928 quota_manager_proxy()->notify_storage_accessed_count()); | |
| 929 EXPECT_TRUE(change_observer()->HasNoChange()); | |
| 930 } | |
| 931 | |
| 932 TEST_F(LocalFileSystemOperationTest, TestTypeMismatchErrors) { | |
| 933 base::FilePath dir_path(CreateUniqueDir()); | |
| 934 NewOperation()->FileExists(URLForPath(dir_path), RecordStatusCallback()); | |
| 935 base::MessageLoop::current()->RunUntilIdle(); | |
| 936 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_A_FILE, status()); | |
| 937 | |
| 938 base::FilePath file_path(CreateUniqueFileInDir(dir_path)); | |
| 939 ASSERT_FALSE(file_path.empty()); | |
| 940 NewOperation()->DirectoryExists(URLForPath(file_path), | |
| 941 RecordStatusCallback()); | |
| 942 base::MessageLoop::current()->RunUntilIdle(); | |
| 943 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY, status()); | |
| 944 } | |
| 945 | |
| 946 TEST_F(LocalFileSystemOperationTest, TestReadDirFailure) { | |
| 947 // Path doesn't exist | |
| 948 base::FilePath nonexisting_dir_path(base::FilePath( | |
| 949 FILE_PATH_LITERAL("NonExistingDir")).AsEndingWithSeparator()); | |
| 950 NewOperation()->ReadDirectory(URLForPath(nonexisting_dir_path), | |
| 951 RecordReadDirectoryCallback()); | |
| 952 base::MessageLoop::current()->RunUntilIdle(); | |
| 953 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, status()); | |
| 954 | |
| 955 // File exists. | |
| 956 base::FilePath dir_path(CreateUniqueDir()); | |
| 957 base::FilePath file_path(CreateUniqueFileInDir(dir_path)); | |
| 958 NewOperation()->ReadDirectory(URLForPath(file_path), | |
| 959 RecordReadDirectoryCallback()); | |
| 960 base::MessageLoop::current()->RunUntilIdle(); | |
| 961 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY, status()); | |
| 962 EXPECT_TRUE(change_observer()->HasNoChange()); | |
| 963 } | |
| 964 | |
| 965 TEST_F(LocalFileSystemOperationTest, TestReadDirSuccess) { | |
| 966 // parent_dir | |
| 967 // | | | |
| 968 // child_dir child_file | |
| 969 // Verify reading parent_dir. | |
| 970 base::FilePath parent_dir_path(CreateUniqueDir()); | |
| 971 base::FilePath child_file_path(CreateUniqueFileInDir(parent_dir_path)); | |
| 972 base::FilePath child_dir_path(CreateUniqueDirInDir(parent_dir_path)); | |
| 973 ASSERT_FALSE(child_dir_path.empty()); | |
| 974 | |
| 975 NewOperation()->ReadDirectory(URLForPath(parent_dir_path), | |
| 976 RecordReadDirectoryCallback()); | |
| 977 base::MessageLoop::current()->RunUntilIdle(); | |
| 978 EXPECT_EQ(base::PLATFORM_FILE_OK, status()); | |
| 979 EXPECT_EQ(2u, entries().size()); | |
| 980 | |
| 981 for (size_t i = 0; i < entries().size(); ++i) { | |
| 982 if (entries()[i].is_directory) { | |
| 983 EXPECT_EQ(VirtualPath::BaseName(child_dir_path).value(), | |
| 984 entries()[i].name); | |
| 985 } else { | |
| 986 EXPECT_EQ(VirtualPath::BaseName(child_file_path).value(), | |
| 987 entries()[i].name); | |
| 988 } | |
| 989 } | |
| 990 EXPECT_EQ(1, quota_manager_proxy()->notify_storage_accessed_count()); | |
| 991 EXPECT_TRUE(change_observer()->HasNoChange()); | |
| 992 } | |
| 993 | |
| 994 TEST_F(LocalFileSystemOperationTest, TestRemoveFailure) { | |
| 995 // Path doesn't exist. | |
| 996 base::FilePath nonexisting_path(base::FilePath( | |
| 997 FILE_PATH_LITERAL("NonExistingDir")).AsEndingWithSeparator()); | |
| 998 | |
| 999 NewOperation()->Remove(URLForPath(nonexisting_path), false /* recursive */, | |
| 1000 RecordStatusCallback()); | |
| 1001 base::MessageLoop::current()->RunUntilIdle(); | |
| 1002 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, status()); | |
| 1003 | |
| 1004 // It's an error to try to remove a non-empty directory if recursive flag | |
| 1005 // is false. | |
| 1006 // parent_dir | |
| 1007 // | | | |
| 1008 // child_dir child_file | |
| 1009 // Verify deleting parent_dir. | |
| 1010 base::FilePath parent_dir_path(CreateUniqueDir()); | |
| 1011 base::FilePath child_file_path(CreateUniqueFileInDir(parent_dir_path)); | |
| 1012 base::FilePath child_dir_path(CreateUniqueDirInDir(parent_dir_path)); | |
| 1013 ASSERT_FALSE(child_dir_path.empty()); | |
| 1014 | |
| 1015 NewOperation()->Remove(URLForPath(parent_dir_path), false /* recursive */, | |
| 1016 RecordStatusCallback()); | |
| 1017 base::MessageLoop::current()->RunUntilIdle(); | |
| 1018 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_EMPTY, status()); | |
| 1019 EXPECT_TRUE(change_observer()->HasNoChange()); | |
| 1020 } | |
| 1021 | |
| 1022 TEST_F(LocalFileSystemOperationTest, TestRemoveSuccess) { | |
| 1023 base::FilePath empty_dir_path(CreateUniqueDir()); | |
| 1024 EXPECT_TRUE(DirectoryExists(empty_dir_path)); | |
| 1025 | |
| 1026 NewOperation()->Remove(URLForPath(empty_dir_path), false /* recursive */, | |
| 1027 RecordStatusCallback()); | |
| 1028 base::MessageLoop::current()->RunUntilIdle(); | |
| 1029 EXPECT_EQ(base::PLATFORM_FILE_OK, status()); | |
| 1030 EXPECT_FALSE(DirectoryExists(empty_dir_path)); | |
| 1031 | |
| 1032 EXPECT_EQ(1, change_observer()->get_and_reset_remove_directory_count()); | |
| 1033 EXPECT_TRUE(change_observer()->HasNoChange()); | |
| 1034 } | |
| 1035 | |
| 1036 TEST_F(LocalFileSystemOperationTest, TestRemoveSuccessRecursive) { | |
| 1037 // Removing a non-empty directory with recursive flag == true should be ok. | |
| 1038 // parent_dir | |
| 1039 // | | | |
| 1040 // child_dir child_files | |
| 1041 // | | |
| 1042 // child_files | |
| 1043 // | |
| 1044 // Verify deleting parent_dir. | |
| 1045 base::FilePath parent_dir_path(CreateUniqueDir()); | |
| 1046 for (int i = 0; i < 8; ++i) | |
| 1047 CreateUniqueFileInDir(parent_dir_path); | |
| 1048 base::FilePath child_dir_path(CreateUniqueDirInDir(parent_dir_path)); | |
| 1049 ASSERT_FALSE(child_dir_path.empty()); | |
| 1050 for (int i = 0; i < 8; ++i) | |
| 1051 CreateUniqueFileInDir(child_dir_path); | |
| 1052 | |
| 1053 NewOperation()->Remove(URLForPath(parent_dir_path), true /* recursive */, | |
| 1054 RecordStatusCallback()); | |
| 1055 base::MessageLoop::current()->RunUntilIdle(); | |
| 1056 EXPECT_EQ(base::PLATFORM_FILE_OK, status()); | |
| 1057 EXPECT_FALSE(DirectoryExists(parent_dir_path)); | |
| 1058 | |
| 1059 EXPECT_EQ(2, change_observer()->get_and_reset_remove_directory_count()); | |
| 1060 EXPECT_EQ(16, change_observer()->get_and_reset_remove_file_count()); | |
| 1061 EXPECT_TRUE(change_observer()->HasNoChange()); | |
| 1062 } | |
| 1063 | |
| 1064 TEST_F(LocalFileSystemOperationTest, TestTruncate) { | |
| 1065 base::FilePath dir_path(CreateUniqueDir()); | |
| 1066 base::FilePath file_path(CreateUniqueFileInDir(dir_path)); | |
| 1067 | |
| 1068 char test_data[] = "test data"; | |
| 1069 int data_size = static_cast<int>(sizeof(test_data)); | |
| 1070 EXPECT_EQ(data_size, | |
| 1071 file_util::WriteFile(PlatformPath(file_path), | |
| 1072 test_data, data_size)); | |
| 1073 | |
| 1074 // Check that its length is the size of the data written. | |
| 1075 NewOperation()->GetMetadata(URLForPath(file_path), RecordMetadataCallback()); | |
| 1076 base::MessageLoop::current()->RunUntilIdle(); | |
| 1077 EXPECT_EQ(base::PLATFORM_FILE_OK, status()); | |
| 1078 EXPECT_FALSE(info().is_directory); | |
| 1079 EXPECT_EQ(data_size, info().size); | |
| 1080 | |
| 1081 // Extend the file by truncating it. | |
| 1082 int length = 17; | |
| 1083 NewOperation()->Truncate( | |
| 1084 URLForPath(file_path), length, RecordStatusCallback()); | |
| 1085 base::MessageLoop::current()->RunUntilIdle(); | |
| 1086 EXPECT_EQ(base::PLATFORM_FILE_OK, status()); | |
| 1087 | |
| 1088 EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count()); | |
| 1089 EXPECT_TRUE(change_observer()->HasNoChange()); | |
| 1090 | |
| 1091 // Check that its length is now 17 and that it's all zeroes after the test | |
| 1092 // data. | |
| 1093 base::PlatformFileInfo info; | |
| 1094 | |
| 1095 EXPECT_TRUE(file_util::GetFileInfo(PlatformPath(file_path), &info)); | |
| 1096 EXPECT_EQ(length, info.size); | |
| 1097 char data[100]; | |
| 1098 EXPECT_EQ(length, file_util::ReadFile(PlatformPath(file_path), data, length)); | |
| 1099 for (int i = 0; i < length; ++i) { | |
| 1100 if (i < static_cast<int>(sizeof(test_data))) | |
| 1101 EXPECT_EQ(test_data[i], data[i]); | |
| 1102 else | |
| 1103 EXPECT_EQ(0, data[i]); | |
| 1104 } | |
| 1105 | |
| 1106 // Shorten the file by truncating it. | |
| 1107 length = 3; | |
| 1108 NewOperation()->Truncate( | |
| 1109 URLForPath(file_path), length, RecordStatusCallback()); | |
| 1110 base::MessageLoop::current()->RunUntilIdle(); | |
| 1111 EXPECT_EQ(base::PLATFORM_FILE_OK, status()); | |
| 1112 | |
| 1113 EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count()); | |
| 1114 EXPECT_TRUE(change_observer()->HasNoChange()); | |
| 1115 | |
| 1116 // Check that its length is now 3 and that it contains only bits of test data. | |
| 1117 EXPECT_TRUE(file_util::GetFileInfo(PlatformPath(file_path), &info)); | |
| 1118 EXPECT_EQ(length, info.size); | |
| 1119 EXPECT_EQ(length, file_util::ReadFile(PlatformPath(file_path), data, length)); | |
| 1120 for (int i = 0; i < length; ++i) | |
| 1121 EXPECT_EQ(test_data[i], data[i]); | |
| 1122 | |
| 1123 // Truncate is not a 'read' access. (Here expected access count is 1 | |
| 1124 // since we made 1 read access for GetMetadata.) | |
| 1125 EXPECT_EQ(1, quota_manager_proxy()->notify_storage_accessed_count()); | |
| 1126 } | |
| 1127 | |
| 1128 TEST_F(LocalFileSystemOperationTest, TestTruncateFailureByQuota) { | |
| 1129 base::PlatformFileInfo info; | |
| 1130 | |
| 1131 base::FilePath dir_path(CreateUniqueDir()); | |
| 1132 base::FilePath file_path(CreateUniqueFileInDir(dir_path)); | |
| 1133 | |
| 1134 GrantQuotaForCurrentUsage(); | |
| 1135 AddQuota(10); | |
| 1136 | |
| 1137 NewOperation()->Truncate(URLForPath(file_path), 10, RecordStatusCallback()); | |
| 1138 base::MessageLoop::current()->RunUntilIdle(); | |
| 1139 EXPECT_EQ(base::PLATFORM_FILE_OK, status()); | |
| 1140 EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count()); | |
| 1141 EXPECT_TRUE(change_observer()->HasNoChange()); | |
| 1142 | |
| 1143 EXPECT_TRUE(file_util::GetFileInfo(PlatformPath(file_path), &info)); | |
| 1144 EXPECT_EQ(10, info.size); | |
| 1145 | |
| 1146 NewOperation()->Truncate(URLForPath(file_path), 11, RecordStatusCallback()); | |
| 1147 base::MessageLoop::current()->RunUntilIdle(); | |
| 1148 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE, status()); | |
| 1149 EXPECT_TRUE(change_observer()->HasNoChange()); | |
| 1150 | |
| 1151 EXPECT_TRUE(file_util::GetFileInfo(PlatformPath(file_path), &info)); | |
| 1152 EXPECT_EQ(10, info.size); | |
| 1153 } | |
| 1154 | |
| 1155 TEST_F(LocalFileSystemOperationTest, TestTouchFile) { | |
| 1156 base::FilePath file_path(CreateUniqueFileInDir(base::FilePath())); | |
| 1157 base::FilePath platform_path = PlatformPath(file_path); | |
| 1158 | |
| 1159 base::PlatformFileInfo info; | |
| 1160 | |
| 1161 EXPECT_TRUE(file_util::GetFileInfo(platform_path, &info)); | |
| 1162 EXPECT_FALSE(info.is_directory); | |
| 1163 EXPECT_EQ(0, info.size); | |
| 1164 const base::Time last_modified = info.last_modified; | |
| 1165 const base::Time last_accessed = info.last_accessed; | |
| 1166 | |
| 1167 const base::Time new_modified_time = base::Time::UnixEpoch(); | |
| 1168 const base::Time new_accessed_time = new_modified_time + | |
| 1169 base::TimeDelta::FromHours(77); | |
| 1170 ASSERT_NE(last_modified, new_modified_time); | |
| 1171 ASSERT_NE(last_accessed, new_accessed_time); | |
| 1172 | |
| 1173 NewOperation()->TouchFile( | |
| 1174 URLForPath(file_path), new_accessed_time, new_modified_time, | |
| 1175 RecordStatusCallback()); | |
| 1176 base::MessageLoop::current()->RunUntilIdle(); | |
| 1177 EXPECT_EQ(base::PLATFORM_FILE_OK, status()); | |
| 1178 EXPECT_TRUE(change_observer()->HasNoChange()); | |
| 1179 | |
| 1180 EXPECT_TRUE(file_util::GetFileInfo(platform_path, &info)); | |
| 1181 // We compare as time_t here to lower our resolution, to avoid false | |
| 1182 // negatives caused by conversion to the local filesystem's native | |
| 1183 // representation and back. | |
| 1184 EXPECT_EQ(new_modified_time.ToTimeT(), info.last_modified.ToTimeT()); | |
| 1185 EXPECT_EQ(new_accessed_time.ToTimeT(), info.last_accessed.ToTimeT()); | |
| 1186 } | |
| 1187 | |
| 1188 TEST_F(LocalFileSystemOperationTest, TestCreateSnapshotFile) { | |
| 1189 base::FilePath dir_path(CreateUniqueDir()); | |
| 1190 | |
| 1191 // Create a file for the testing. | |
| 1192 NewOperation()->DirectoryExists(URLForPath(dir_path), | |
| 1193 RecordStatusCallback()); | |
| 1194 base::FilePath file_path(CreateUniqueFileInDir(dir_path)); | |
| 1195 NewOperation()->FileExists(URLForPath(file_path), RecordStatusCallback()); | |
| 1196 base::MessageLoop::current()->RunUntilIdle(); | |
| 1197 EXPECT_EQ(base::PLATFORM_FILE_OK, status()); | |
| 1198 | |
| 1199 // See if we can get a 'snapshot' file info for the file. | |
| 1200 // Since LocalFileSystemOperation assumes the file exists in the local | |
| 1201 // directory it should just returns the same metadata and platform_path | |
| 1202 // as the file itself. | |
| 1203 NewOperation()->CreateSnapshotFile(URLForPath(file_path), | |
| 1204 RecordSnapshotFileCallback()); | |
| 1205 base::MessageLoop::current()->RunUntilIdle(); | |
| 1206 EXPECT_EQ(base::PLATFORM_FILE_OK, status()); | |
| 1207 EXPECT_FALSE(info().is_directory); | |
| 1208 EXPECT_EQ(PlatformPath(file_path), path()); | |
| 1209 EXPECT_TRUE(change_observer()->HasNoChange()); | |
| 1210 | |
| 1211 // The FileSystemOpration implementation does not create a | |
| 1212 // shareable file reference. | |
| 1213 EXPECT_EQ(NULL, shareable_file_ref()); | |
| 1214 } | |
| 1215 | |
| 1216 } // namespace fileapi | |
| OLD | NEW |