| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/chromeos/drive/drive_file_system.h" | 5 #include "chrome/browser/chromeos/drive/drive_file_system.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 392 google_apis::test_util::RunBlockingPoolTask(); | 392 google_apis::test_util::RunBlockingPoolTask(); |
| 393 return error == DRIVE_FILE_OK; | 393 return error == DRIVE_FILE_OK; |
| 394 } | 394 } |
| 395 | 395 |
| 396 // Flag for specifying the timestamp of the test filesystem cache. | 396 // Flag for specifying the timestamp of the test filesystem cache. |
| 397 enum SaveTestFileSystemParam { | 397 enum SaveTestFileSystemParam { |
| 398 USE_OLD_TIMESTAMP, | 398 USE_OLD_TIMESTAMP, |
| 399 USE_SERVER_TIMESTAMP, | 399 USE_SERVER_TIMESTAMP, |
| 400 }; | 400 }; |
| 401 | 401 |
| 402 // Creates a proto file representing a filesystem with directories: | 402 // Saves a file representing a filesystem with directories: |
| 403 // drive, drive/Dir1, drive/Dir1/SubDir2 | 403 // drive, drive/Dir1, drive/Dir1/SubDir2 |
| 404 // and files | 404 // and files |
| 405 // drive/File1, drive/Dir1/File2, drive/Dir1/SubDir2/File3. | 405 // drive/File1, drive/Dir1/File2, drive/Dir1/SubDir2/File3. |
| 406 // If |use_up_to_date_timestamp| is true, sets the changestamp to 654321, | 406 // If |use_up_to_date_timestamp| is true, sets the changestamp to 654321, |
| 407 // equal to that of "account_metadata.json" test data, indicating the cache is | 407 // equal to that of "account_metadata.json" test data, indicating the cache is |
| 408 // holding the latest file system info. | 408 // holding the latest file system info. |
| 409 void SaveTestFileSystem(SaveTestFileSystemParam param) { | 409 bool SaveTestFileSystem(SaveTestFileSystemParam param) { |
| 410 DriveRootDirectoryProto root; | 410 const std::string root_resource_id = |
| 411 root.set_version(kProtoVersion); | 411 fake_drive_service_->GetRootResourceId(); |
| 412 root.set_largest_changestamp(param == USE_SERVER_TIMESTAMP ? 654321 : 1); | 412 DriveResourceMetadata resource_metadata(root_resource_id, |
| 413 DriveDirectoryProto* root_dir = root.mutable_drive_directory(); | 413 blocking_task_runner_); |
| 414 DriveEntryProto* dir_base = root_dir->mutable_drive_entry(); | 414 |
| 415 PlatformFileInfoProto* platform_info = dir_base->mutable_file_info(); | 415 DriveFileError error = DRIVE_FILE_ERROR_FAILED; |
| 416 dir_base->set_title("drive"); | 416 resource_metadata.SetLargestChangestamp( |
| 417 dir_base->set_resource_id(fake_drive_service_->GetRootResourceId()); | 417 param == USE_SERVER_TIMESTAMP ? 654321 : 1, |
| 418 dir_base->set_upload_url("http://resumable-create-media/1"); | 418 google_apis::test_util::CreateCopyResultCallback(&error)); |
| 419 platform_info->set_is_directory(true); | 419 google_apis::test_util::RunBlockingPoolTask(); |
| 420 if (error != DRIVE_FILE_OK) |
| 421 return false; |
| 420 | 422 |
| 421 // drive/File1 | 423 // drive/File1 |
| 422 DriveEntryProto* file = root_dir->add_child_files(); | 424 DriveEntryProto file1; |
| 423 file->set_title("File1"); | 425 file1.set_title("File1"); |
| 424 file->set_resource_id("resource_id:File1"); | 426 file1.set_resource_id("resource_id:File1"); |
| 425 file->set_parent_resource_id(root_dir->drive_entry().resource_id()); | 427 file1.set_parent_resource_id(root_resource_id); |
| 426 file->set_upload_url("http://resumable-edit-media/1"); | 428 file1.set_upload_url("http://resumable-edit-media/1"); |
| 427 file->mutable_file_specific_info()->set_file_md5("md5"); | 429 file1.mutable_file_specific_info()->set_file_md5("md5"); |
| 428 platform_info = file->mutable_file_info(); | 430 file1.mutable_file_info()->set_is_directory(false); |
| 429 platform_info->set_is_directory(false); | 431 file1.mutable_file_info()->set_size(1048576); |
| 430 platform_info->set_size(1048576); | 432 base::FilePath file_path; |
| 433 resource_metadata.AddEntry( |
| 434 file1, |
| 435 google_apis::test_util::CreateCopyResultCallback(&error, &file_path)); |
| 436 google_apis::test_util::RunBlockingPoolTask(); |
| 437 if (error != DRIVE_FILE_OK) |
| 438 return false; |
| 431 | 439 |
| 432 // drive/Dir1 | 440 // drive/Dir1 |
| 433 DriveDirectoryProto* dir1 = root_dir->add_child_directories(); | 441 DriveEntryProto dir1; |
| 434 dir_base = dir1->mutable_drive_entry(); | 442 dir1.set_title("Dir1"); |
| 435 dir_base->set_title("Dir1"); | 443 dir1.set_resource_id("resource_id:Dir1"); |
| 436 dir_base->set_resource_id("resource_id:Dir1"); | 444 dir1.set_parent_resource_id(root_resource_id); |
| 437 dir_base->set_parent_resource_id(root_dir->drive_entry().resource_id()); | 445 dir1.set_upload_url("http://resumable-create-media/2"); |
| 438 dir_base->set_upload_url("http://resumable-create-media/2"); | 446 dir1.mutable_file_info()->set_is_directory(true); |
| 439 platform_info = dir_base->mutable_file_info(); | 447 resource_metadata.AddEntry( |
| 440 platform_info->set_is_directory(true); | 448 dir1, |
| 449 google_apis::test_util::CreateCopyResultCallback(&error, &file_path)); |
| 450 google_apis::test_util::RunBlockingPoolTask(); |
| 451 if (error != DRIVE_FILE_OK) |
| 452 return false; |
| 441 | 453 |
| 442 // drive/Dir1/File2 | 454 // drive/Dir1/File2 |
| 443 file = dir1->add_child_files(); | 455 DriveEntryProto file2; |
| 444 file->set_title("File2"); | 456 file2.set_title("File2"); |
| 445 file->set_resource_id("resource_id:File2"); | 457 file2.set_resource_id("resource_id:File2"); |
| 446 file->set_parent_resource_id(dir1->drive_entry().resource_id()); | 458 file2.set_parent_resource_id(dir1.resource_id()); |
| 447 file->set_upload_url("http://resumable-edit-media/2"); | 459 file2.set_upload_url("http://resumable-edit-media/2"); |
| 448 file->mutable_file_specific_info()->set_file_md5("md5"); | 460 file2.mutable_file_specific_info()->set_file_md5("md5"); |
| 449 platform_info = file->mutable_file_info(); | 461 file2.mutable_file_info()->set_is_directory(false); |
| 450 platform_info->set_is_directory(false); | 462 file2.mutable_file_info()->set_size(555); |
| 451 platform_info->set_size(555); | 463 resource_metadata.AddEntry( |
| 464 file2, |
| 465 google_apis::test_util::CreateCopyResultCallback(&error, &file_path)); |
| 466 google_apis::test_util::RunBlockingPoolTask(); |
| 467 if (error != DRIVE_FILE_OK) |
| 468 return false; |
| 452 | 469 |
| 453 // drive/Dir1/SubDir2 | 470 // drive/Dir1/SubDir2 |
| 454 DriveDirectoryProto* dir2 = dir1->add_child_directories(); | 471 DriveEntryProto dir2; |
| 455 dir_base = dir2->mutable_drive_entry(); | 472 dir2.set_title("SubDir2"); |
| 456 dir_base->set_title("SubDir2"); | 473 dir2.set_resource_id("resource_id:SubDir2"); |
| 457 dir_base->set_resource_id("resource_id:SubDir2"); | 474 dir2.set_parent_resource_id(dir1.resource_id()); |
| 458 dir_base->set_parent_resource_id(dir1->drive_entry().resource_id()); | 475 dir2.set_upload_url("http://resumable-create-media/3"); |
| 459 dir_base->set_upload_url("http://resumable-create-media/3"); | 476 dir2.mutable_file_info()->set_is_directory(true); |
| 460 platform_info = dir_base->mutable_file_info(); | 477 resource_metadata.AddEntry( |
| 461 platform_info->set_is_directory(true); | 478 dir2, |
| 479 google_apis::test_util::CreateCopyResultCallback(&error, &file_path)); |
| 480 google_apis::test_util::RunBlockingPoolTask(); |
| 481 if (error != DRIVE_FILE_OK) |
| 482 return false; |
| 462 | 483 |
| 463 // drive/Dir1/SubDir2/File3 | 484 // drive/Dir1/SubDir2/File3 |
| 464 file = dir2->add_child_files(); | 485 DriveEntryProto file3; |
| 465 file->set_title("File3"); | 486 file3.set_title("File3"); |
| 466 file->set_resource_id("resource_id:File3"); | 487 file3.set_resource_id("resource_id:File3"); |
| 467 file->set_parent_resource_id(dir2->drive_entry().resource_id()); | 488 file3.set_parent_resource_id(dir2.resource_id()); |
| 468 file->set_upload_url("http://resumable-edit-media/3"); | 489 file3.set_upload_url("http://resumable-edit-media/3"); |
| 469 file->mutable_file_specific_info()->set_file_md5("md5"); | 490 file3.mutable_file_specific_info()->set_file_md5("md5"); |
| 470 platform_info = file->mutable_file_info(); | 491 file3.mutable_file_info()->set_is_directory(false); |
| 471 platform_info->set_is_directory(false); | 492 file3.mutable_file_info()->set_size(12345); |
| 472 platform_info->set_size(12345); | 493 resource_metadata.AddEntry( |
| 494 file3, |
| 495 google_apis::test_util::CreateCopyResultCallback(&error, &file_path)); |
| 496 google_apis::test_util::RunBlockingPoolTask(); |
| 497 if (error != DRIVE_FILE_OK) |
| 498 return false; |
| 473 | 499 |
| 474 // Write this proto out to GCache/vi/meta/file_system.pb | 500 // Write resource metadata. |
| 475 std::string serialized_proto; | 501 base::FilePath cache_dir_path = |
| 476 ASSERT_TRUE(root.SerializeToString(&serialized_proto)); | 502 cache_->GetCacheDirectoryPath(DriveCache::CACHE_TYPE_META); |
| 477 ASSERT_TRUE(!serialized_proto.empty()); | 503 if (!file_util::CreateDirectory(cache_dir_path)) |
| 504 return false; |
| 505 resource_metadata.MaybeSave(cache_dir_path); |
| 506 google_apis::test_util::RunBlockingPoolTask(); |
| 478 | 507 |
| 479 base::FilePath cache_dir_path = profile_->GetPath().Append( | 508 return true; |
| 480 FILE_PATH_LITERAL("GCache/v1/meta/")); | |
| 481 ASSERT_TRUE(file_util::CreateDirectory(cache_dir_path)); | |
| 482 const int file_size = static_cast<int>(serialized_proto.length()); | |
| 483 ASSERT_EQ(file_util::WriteFile(cache_dir_path.AppendASCII("file_system.pb"), | |
| 484 serialized_proto.data(), file_size), file_size); | |
| 485 } | 509 } |
| 486 | 510 |
| 487 // Verifies that |file_path| is a valid JSON file for the hosted document | 511 // Verifies that |file_path| is a valid JSON file for the hosted document |
| 488 // associated with |entry| (i.e. |url| and |resource_id| match). | 512 // associated with |entry| (i.e. |url| and |resource_id| match). |
| 489 void VerifyHostedDocumentJSONFile(const DriveEntryProto& entry_proto, | 513 void VerifyHostedDocumentJSONFile(const DriveEntryProto& entry_proto, |
| 490 const base::FilePath& file_path) { | 514 const base::FilePath& file_path) { |
| 491 std::string error; | 515 std::string error; |
| 492 JSONFileValueSerializer serializer(file_path); | 516 JSONFileValueSerializer serializer(file_path); |
| 493 scoped_ptr<Value> value(serializer.Deserialize(NULL, &error)); | 517 scoped_ptr<Value> value(serializer.Deserialize(NULL, &error)); |
| 494 ASSERT_TRUE(value.get()) << "Parse error " << file_path.value() | 518 ASSERT_TRUE(value.get()) << "Parse error " << file_path.value() |
| (...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 926 | 950 |
| 927 EXPECT_TRUE(EntryExists(base::FilePath(FILE_PATH_LITERAL( | 951 EXPECT_TRUE(EntryExists(base::FilePath(FILE_PATH_LITERAL( |
| 928 "drive/Directory 1")))); | 952 "drive/Directory 1")))); |
| 929 EXPECT_FALSE(EntryExists(base::FilePath(FILE_PATH_LITERAL( | 953 EXPECT_FALSE(EntryExists(base::FilePath(FILE_PATH_LITERAL( |
| 930 "drive/Directory 1/SubDirectory File 1.txt")))); | 954 "drive/Directory 1/SubDirectory File 1.txt")))); |
| 931 EXPECT_TRUE(EntryExists(base::FilePath(FILE_PATH_LITERAL( | 955 EXPECT_TRUE(EntryExists(base::FilePath(FILE_PATH_LITERAL( |
| 932 "drive/Directory 1/New SubDirectory File 1.txt")))); | 956 "drive/Directory 1/New SubDirectory File 1.txt")))); |
| 933 } | 957 } |
| 934 | 958 |
| 935 TEST_F(DriveFileSystemTest, CachedFeedLoading) { | 959 TEST_F(DriveFileSystemTest, CachedFeedLoading) { |
| 936 SaveTestFileSystem(USE_OLD_TIMESTAMP); | 960 ASSERT_TRUE(SaveTestFileSystem(USE_OLD_TIMESTAMP)); |
| 937 ASSERT_TRUE(TestLoadMetadataFromCache()); | 961 ASSERT_TRUE(TestLoadMetadataFromCache()); |
| 938 | 962 |
| 939 EXPECT_TRUE(EntryExists(base::FilePath(FILE_PATH_LITERAL("drive/File1")))); | 963 EXPECT_TRUE(EntryExists(base::FilePath(FILE_PATH_LITERAL("drive/File1")))); |
| 940 EXPECT_TRUE(EntryExists(base::FilePath(FILE_PATH_LITERAL("drive/Dir1")))); | 964 EXPECT_TRUE(EntryExists(base::FilePath(FILE_PATH_LITERAL("drive/Dir1")))); |
| 941 EXPECT_TRUE( | 965 EXPECT_TRUE( |
| 942 EntryExists(base::FilePath(FILE_PATH_LITERAL("drive/Dir1/File2")))); | 966 EntryExists(base::FilePath(FILE_PATH_LITERAL("drive/Dir1/File2")))); |
| 943 EXPECT_TRUE( | 967 EXPECT_TRUE( |
| 944 EntryExists(base::FilePath(FILE_PATH_LITERAL("drive/Dir1/SubDir2")))); | 968 EntryExists(base::FilePath(FILE_PATH_LITERAL("drive/Dir1/SubDir2")))); |
| 945 EXPECT_TRUE(EntryExists( | 969 EXPECT_TRUE(EntryExists( |
| 946 base::FilePath(FILE_PATH_LITERAL("drive/Dir1/SubDir2/File3")))); | 970 base::FilePath(FILE_PATH_LITERAL("drive/Dir1/SubDir2/File3")))); |
| 947 } | 971 } |
| 948 | 972 |
| 949 TEST_F(DriveFileSystemTest, CachedFeedLoadingThenServerFeedLoading) { | 973 TEST_F(DriveFileSystemTest, CachedFeedLoadingThenServerFeedLoading) { |
| 950 SaveTestFileSystem(USE_SERVER_TIMESTAMP); | 974 ASSERT_TRUE(SaveTestFileSystem(USE_SERVER_TIMESTAMP)); |
| 951 | 975 |
| 952 // Kicks loading of cached file system and query for server update. | 976 // Kicks loading of cached file system and query for server update. |
| 953 EXPECT_TRUE(EntryExists(base::FilePath(FILE_PATH_LITERAL("drive/File1")))); | 977 EXPECT_TRUE(EntryExists(base::FilePath(FILE_PATH_LITERAL("drive/File1")))); |
| 954 | 978 |
| 955 // SaveTestFileSystem and "account_metadata.json" have the same changestamp, | 979 // SaveTestFileSystem and "account_metadata.json" have the same changestamp, |
| 956 // so no request for new feeds (i.e., call to GetResourceList) should happen. | 980 // so no request for new feeds (i.e., call to GetResourceList) should happen. |
| 957 EXPECT_EQ(1, fake_drive_service_->about_resource_load_count()); | 981 EXPECT_EQ(1, fake_drive_service_->about_resource_load_count()); |
| 958 EXPECT_EQ(0, fake_drive_service_->resource_list_load_count()); | 982 EXPECT_EQ(0, fake_drive_service_->resource_list_load_count()); |
| 959 | 983 |
| 960 | 984 |
| 961 // Since the file system has verified that it holds the latest snapshot, | 985 // Since the file system has verified that it holds the latest snapshot, |
| 962 // it should change its state to INITIALIZED, which admits periodic refresh. | 986 // it should change its state to INITIALIZED, which admits periodic refresh. |
| 963 // To test it, call CheckForUpdates and verify it does try to check updates. | 987 // To test it, call CheckForUpdates and verify it does try to check updates. |
| 964 file_system_->CheckForUpdates(); | 988 file_system_->CheckForUpdates(); |
| 965 google_apis::test_util::RunBlockingPoolTask(); | 989 google_apis::test_util::RunBlockingPoolTask(); |
| 966 EXPECT_EQ(2, fake_drive_service_->about_resource_load_count()); | 990 EXPECT_EQ(2, fake_drive_service_->about_resource_load_count()); |
| 967 } | 991 } |
| 968 | 992 |
| 969 TEST_F(DriveFileSystemTest, OfflineCachedFeedLoading) { | 993 TEST_F(DriveFileSystemTest, OfflineCachedFeedLoading) { |
| 970 SaveTestFileSystem(USE_OLD_TIMESTAMP); | 994 ASSERT_TRUE(SaveTestFileSystem(USE_OLD_TIMESTAMP)); |
| 971 | 995 |
| 972 // Make GetResourceList fail for simulating offline situation. This will leave | 996 // Make GetResourceList fail for simulating offline situation. This will leave |
| 973 // the file system "loaded from cache, but not synced with server" state. | 997 // the file system "loaded from cache, but not synced with server" state. |
| 974 fake_drive_service_->set_offline(true); | 998 fake_drive_service_->set_offline(true); |
| 975 | 999 |
| 976 // Kicks loading of cached file system and query for server update. | 1000 // Kicks loading of cached file system and query for server update. |
| 977 EXPECT_TRUE(EntryExists(base::FilePath(FILE_PATH_LITERAL("drive/File1")))); | 1001 EXPECT_TRUE(EntryExists(base::FilePath(FILE_PATH_LITERAL("drive/File1")))); |
| 978 // Loading of account metadata should not happen as it's offline. | 1002 // Loading of account metadata should not happen as it's offline. |
| 979 EXPECT_EQ(0, fake_drive_service_->account_metadata_load_count()); | 1003 EXPECT_EQ(0, fake_drive_service_->account_metadata_load_count()); |
| 980 | 1004 |
| (...skipping 1173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2154 &error)); | 2178 &error)); |
| 2155 message_loop_.Run(); | 2179 message_loop_.Run(); |
| 2156 | 2180 |
| 2157 // It must fail. | 2181 // It must fail. |
| 2158 EXPECT_EQ(DRIVE_FILE_ERROR_NOT_FOUND, error); | 2182 EXPECT_EQ(DRIVE_FILE_ERROR_NOT_FOUND, error); |
| 2159 } | 2183 } |
| 2160 | 2184 |
| 2161 // TODO(satorux): Testing if WebAppsRegistry is loaded here is awkward. We | 2185 // TODO(satorux): Testing if WebAppsRegistry is loaded here is awkward. We |
| 2162 // should move this to change_list_loader_unittest.cc. crbug.com/161703 | 2186 // should move this to change_list_loader_unittest.cc. crbug.com/161703 |
| 2163 TEST_F(DriveFileSystemTest, WebAppsRegistryIsLoaded) { | 2187 TEST_F(DriveFileSystemTest, WebAppsRegistryIsLoaded) { |
| 2164 SaveTestFileSystem(USE_SERVER_TIMESTAMP); | 2188 ASSERT_TRUE(SaveTestFileSystem(USE_SERVER_TIMESTAMP)); |
| 2165 | 2189 |
| 2166 // No apps should be found as the webapps registry is empty. | 2190 // No apps should be found as the webapps registry is empty. |
| 2167 ScopedVector<DriveWebAppInfo> apps; | 2191 ScopedVector<DriveWebAppInfo> apps; |
| 2168 drive_webapps_registry_->GetWebAppsForFile( | 2192 drive_webapps_registry_->GetWebAppsForFile( |
| 2169 base::FilePath::FromUTF8Unsafe("foo.exe"), | 2193 base::FilePath::FromUTF8Unsafe("foo.exe"), |
| 2170 "" /* mime_type */, | 2194 "" /* mime_type */, |
| 2171 &apps); | 2195 &apps); |
| 2172 EXPECT_TRUE(apps.empty()); | 2196 EXPECT_TRUE(apps.empty()); |
| 2173 | 2197 |
| 2174 // Kicks loading of cached file system and query for server update. This | 2198 // Kicks loading of cached file system and query for server update. This |
| 2175 // will cause GetAccountMetadata() to be called, to check the server-side | 2199 // will cause GetAccountMetadata() to be called, to check the server-side |
| 2176 // changestamp, and the webapps registry will be loaded at the same time. | 2200 // changestamp, and the webapps registry will be loaded at the same time. |
| 2177 EXPECT_TRUE(EntryExists(base::FilePath(FILE_PATH_LITERAL("drive/File1")))); | 2201 EXPECT_TRUE(EntryExists(base::FilePath(FILE_PATH_LITERAL("drive/File1")))); |
| 2178 | 2202 |
| 2179 // An app for foo.exe should now be found, as the registry was loaded. | 2203 // An app for foo.exe should now be found, as the registry was loaded. |
| 2180 drive_webapps_registry_->GetWebAppsForFile( | 2204 drive_webapps_registry_->GetWebAppsForFile( |
| 2181 base::FilePath(FILE_PATH_LITERAL("foo.exe")), | 2205 base::FilePath(FILE_PATH_LITERAL("foo.exe")), |
| 2182 "" /* mime_type */, | 2206 "" /* mime_type */, |
| 2183 &apps); | 2207 &apps); |
| 2184 EXPECT_EQ(1U, apps.size()); | 2208 EXPECT_EQ(1U, apps.size()); |
| 2185 } | 2209 } |
| 2186 | 2210 |
| 2187 } // namespace drive | 2211 } // namespace drive |
| OLD | NEW |