1 // Copyright 2013 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 "chrome/browser/chromeos/drive/file_system/copy_operation.h" 6 7 #include "base/files/file_util.h" 8 #include "base/task_runner_util.h" 9 #include "chrome/browser/chromeos/drive/file_cache.h" 10 #include "chrome/browser/chromeos/drive/file_change.h" 11 #include "chrome/browser/chromeos/drive/file_system/operation_test_base.h" 12 #include "chrome/browser/chromeos/drive/file_system_util.h" 13 #include "chrome/browser/chromeos/drive/resource_metadata.h" 14 #include "chrome/browser/drive/drive_api_util.h" 15 #include "chrome/browser/drive/fake_drive_service.h" 16 #include "content/public/test/test_utils.h" 17 #include "google_apis/drive/drive_api_parser.h" 18 #include "google_apis/drive/test_util.h" 19 #include "testing/gtest/include/gtest/gtest.h" 20 21 namespace drive { 22 namespace file_system { 23 24 namespace { 25 26 // Used to handle WaitForSyncComplete() calls. 27 bool CopyWaitForSyncCompleteArguments(std::string* out_local_id, 28 FileOperationCallback* out_callback, 29 const std::string& local_id, 30 const FileOperationCallback& callback) { 31 *out_local_id = local_id; 32 *out_callback = callback; 33 return true; 34 } 35 36 } // namespace 37 38 class CopyOperationTest : public OperationTestBase { 39 protected: 40 virtual void SetUp() OVERRIDE { 41 OperationTestBase::SetUp(); 42 operation_.reset(new CopyOperation( 43 blocking_task_runner(), delegate(), scheduler(), metadata(), cache())); 44 } 45 46 scoped_ptr<CopyOperation> operation_; 47 }; 48 49 TEST_F(CopyOperationTest, TransferFileFromLocalToRemote_RegularFile) { 50 const base::FilePath local_src_path = temp_dir().AppendASCII("local.txt"); 51 const base::FilePath remote_dest_path( 52 FILE_PATH_LITERAL("drive/root/remote.txt")); 53 54 // Prepare a local file. 55 ASSERT_TRUE( 56 google_apis::test_util::WriteStringToFile(local_src_path, "hello")); 57 // Confirm that the remote file does not exist. 58 ResourceEntry entry; 59 ASSERT_EQ(FILE_ERROR_NOT_FOUND, 60 GetLocalResourceEntry(remote_dest_path, &entry)); 61 62 // Transfer the local file to Drive. 63 FileError error = FILE_ERROR_FAILED; 64 operation_->TransferFileFromLocalToRemote( 65 local_src_path, 66 remote_dest_path, 67 google_apis::test_util::CreateCopyResultCallback(&error)); 68 content::RunAllBlockingPoolTasksUntilIdle(); 69 EXPECT_EQ(FILE_ERROR_OK, error); 70 71 // TransferFileFromLocalToRemote stores a copy of the local file in the cache, 72 // marks it dirty and requests the observer to upload the file. 73 EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(remote_dest_path, &entry)); 74 EXPECT_EQ(1U, delegate()->updated_local_ids().count(entry.local_id())); 75 EXPECT_TRUE(entry.file_specific_info().cache_state().is_present()); 76 EXPECT_TRUE(entry.file_specific_info().cache_state().is_dirty()); 77 78 EXPECT_EQ(1U, delegate()->get_changed_files().size()); 79 EXPECT_TRUE(delegate()->get_changed_files().count(remote_dest_path)); 80 } 81 82 TEST_F(CopyOperationTest, TransferFileFromLocalToRemote_Overwrite) { 83 const base::FilePath local_src_path = temp_dir().AppendASCII("local.txt"); 84 const base::FilePath remote_dest_path( 85 FILE_PATH_LITERAL("drive/root/File 1.txt")); 86 87 // Prepare a local file. 88 EXPECT_TRUE( 89 google_apis::test_util::WriteStringToFile(local_src_path, "hello")); 90 // Confirm that the remote file exists. 91 ResourceEntry entry; 92 EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(remote_dest_path, &entry)); 93 94 // Transfer the local file to Drive. 95 FileError error = FILE_ERROR_FAILED; 96 operation_->TransferFileFromLocalToRemote( 97 local_src_path, 98 remote_dest_path, 99 google_apis::test_util::CreateCopyResultCallback(&error)); 100 content::RunAllBlockingPoolTasksUntilIdle(); 101 EXPECT_EQ(FILE_ERROR_OK, error); 102 103 // TransferFileFromLocalToRemote stores a copy of the local file in the cache, 104 // marks it dirty and requests the observer to upload the file. 105 EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(remote_dest_path, &entry)); 106 EXPECT_EQ(1U, delegate()->updated_local_ids().count(entry.local_id())); 107 EXPECT_TRUE(entry.file_specific_info().cache_state().is_present()); 108 EXPECT_TRUE(entry.file_specific_info().cache_state().is_dirty()); 109 110 EXPECT_EQ(1U, delegate()->get_changed_files().size()); 111 EXPECT_TRUE(delegate()->get_changed_files().count(remote_dest_path)); 112 } 113 114 TEST_F(CopyOperationTest, 115 TransferFileFromLocalToRemote_ExistingHostedDocument) { 116 const base::FilePath local_src_path = temp_dir().AppendASCII("local.gdoc"); 117 const base::FilePath remote_dest_path(FILE_PATH_LITERAL( 118 "drive/root/Directory 1/copied.gdoc")); 119 120 // Prepare a local file, which is a json file of a hosted document, which 121 // matches "drive/root/Document 1 excludeDir-test". 122 ASSERT_TRUE(util::CreateGDocFile( 123 local_src_path, 124 GURL("https://3_document_self_link/5_document_resource_id"), 125 "5_document_resource_id")); 126 127 ResourceEntry entry; 128 ASSERT_EQ(FILE_ERROR_NOT_FOUND, 129 GetLocalResourceEntry(remote_dest_path, &entry)); 130 131 // Transfer the local file to Drive. 132 FileError error = FILE_ERROR_FAILED; 133 operation_->TransferFileFromLocalToRemote( 134 local_src_path, 135 remote_dest_path, 136 google_apis::test_util::CreateCopyResultCallback(&error)); 137 content::RunAllBlockingPoolTasksUntilIdle(); 138 EXPECT_EQ(FILE_ERROR_OK, error); 139 140 EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(remote_dest_path, &entry)); 141 142 EXPECT_EQ(1U, delegate()->get_changed_files().size()); 143 EXPECT_TRUE(delegate()->get_changed_files().count(remote_dest_path)); 144 // New copy is created. 145 EXPECT_NE("5_document_resource_id", entry.resource_id()); 146 } 147 148 TEST_F(CopyOperationTest, TransferFileFromLocalToRemote_OrphanHostedDocument) { 149 const base::FilePath local_src_path = temp_dir().AppendASCII("local.gdoc"); 150 const base::FilePath remote_dest_path(FILE_PATH_LITERAL( 151 "drive/root/Directory 1/moved.gdoc")); 152 153 // Prepare a local file, which is a json file of a hosted document, which 154 // matches "drive/other/Orphan Document". 155 ASSERT_TRUE(util::CreateGDocFile( 156 local_src_path, 157 GURL("https://3_document_self_link/orphan_doc_1"), 158 "orphan_doc_1")); 159 160 ResourceEntry entry; 161 ASSERT_EQ(FILE_ERROR_NOT_FOUND, 162 GetLocalResourceEntry(remote_dest_path, &entry)); 163 164 // Transfer the local file to Drive. 165 FileError error = FILE_ERROR_FAILED; 166 operation_->TransferFileFromLocalToRemote( 167 local_src_path, 168 remote_dest_path, 169 google_apis::test_util::CreateCopyResultCallback(&error)); 170 content::RunAllBlockingPoolTasksUntilIdle(); 171 EXPECT_EQ(FILE_ERROR_OK, error); 172 173 EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(remote_dest_path, &entry)); 174 EXPECT_EQ(ResourceEntry::DIRTY, entry.metadata_edit_state()); 175 EXPECT_TRUE(delegate()->updated_local_ids().count(entry.local_id())); 176 177 EXPECT_EQ(1U, delegate()->get_changed_files().size()); 178 EXPECT_TRUE(delegate()->get_changed_files().count(remote_dest_path)); 179 // The original document got new parent. 180 EXPECT_EQ("orphan_doc_1", entry.resource_id()); 181 } 182 183 TEST_F(CopyOperationTest, TransferFileFromLocalToRemote_NewHostedDocument) { 184 const base::FilePath local_src_path = temp_dir().AppendASCII("local.gdoc"); 185 const base::FilePath remote_dest_path(FILE_PATH_LITERAL( 186 "drive/root/Directory 1/moved.gdoc")); 187 188 // Create a hosted document on the server that is not synced to local yet. 189 google_apis::GDataErrorCode gdata_error = google_apis::GDATA_OTHER_ERROR; 190 scoped_ptr<google_apis::FileResource> new_gdoc_entry; 191 fake_service()->AddNewFile( 192 "application/vnd.google-apps.document", "", "", "title", true, 193 google_apis::test_util::CreateCopyResultCallback(&gdata_error, 194 &new_gdoc_entry)); 195 content::RunAllBlockingPoolTasksUntilIdle(); 196 ASSERT_EQ(google_apis::HTTP_CREATED, gdata_error); 197 198 // Prepare a local file, which is a json file of the added hosted document. 199 ASSERT_TRUE(util::CreateGDocFile( 200 local_src_path, 201 GURL("https://3_document_self_link/" + new_gdoc_entry->file_id()), 202 new_gdoc_entry->file_id())); 203 204 ResourceEntry entry; 205 ASSERT_EQ(FILE_ERROR_NOT_FOUND, 206 GetLocalResourceEntry(remote_dest_path, &entry)); 207 208 // Transfer the local file to Drive. 209 FileError error = FILE_ERROR_FAILED; 210 operation_->TransferFileFromLocalToRemote( 211 local_src_path, 212 remote_dest_path, 213 google_apis::test_util::CreateCopyResultCallback(&error)); 214 content::RunAllBlockingPoolTasksUntilIdle(); 215 EXPECT_EQ(FILE_ERROR_OK, error); 216 217 EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(remote_dest_path, &entry)); 218 219 EXPECT_EQ(1U, delegate()->get_changed_files().size()); 220 EXPECT_TRUE(delegate()->get_changed_files().count(remote_dest_path)); 221 // The original document got new parent. 222 EXPECT_EQ(new_gdoc_entry->file_id(), entry.resource_id()); 223 } 224 225 TEST_F(CopyOperationTest, CopyNotExistingFile) { 226 base::FilePath src_path(FILE_PATH_LITERAL("drive/root/Dummy file.txt")); 227 base::FilePath dest_path(FILE_PATH_LITERAL("drive/root/Test.log")); 228 229 ResourceEntry entry; 230 ASSERT_EQ(FILE_ERROR_NOT_FOUND, GetLocalResourceEntry(src_path, &entry)); 231 232 FileError error = FILE_ERROR_OK; 233 operation_->Copy(src_path, 234 dest_path, 235 false, 236 google_apis::test_util::CreateCopyResultCallback(&error)); 237 content::RunAllBlockingPoolTasksUntilIdle(); 238 EXPECT_EQ(FILE_ERROR_NOT_FOUND, error); 239 240 EXPECT_EQ(FILE_ERROR_NOT_FOUND, GetLocalResourceEntry(src_path, &entry)); 241 EXPECT_EQ(FILE_ERROR_NOT_FOUND, GetLocalResourceEntry(dest_path, &entry)); 242 EXPECT_TRUE(delegate()->get_changed_files().empty()); 243 } 244 245 TEST_F(CopyOperationTest, CopyFileToNonExistingDirectory) { 246 base::FilePath src_path(FILE_PATH_LITERAL("drive/root/File 1.txt")); 247 base::FilePath dest_path(FILE_PATH_LITERAL("drive/root/Dummy/Test.log")); 248 249 ResourceEntry entry; 250 ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(src_path, &entry)); 251 ASSERT_EQ(FILE_ERROR_NOT_FOUND, 252 GetLocalResourceEntry(dest_path.DirName(), &entry)); 253 254 FileError error = FILE_ERROR_OK; 255 operation_->Copy(src_path, 256 dest_path, 257 false, 258 google_apis::test_util::CreateCopyResultCallback(&error)); 259 content::RunAllBlockingPoolTasksUntilIdle(); 260 EXPECT_EQ(FILE_ERROR_NOT_FOUND, error); 261 262 EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(src_path, &entry)); 263 EXPECT_EQ(FILE_ERROR_NOT_FOUND, GetLocalResourceEntry(dest_path, &entry)); 264 EXPECT_TRUE(delegate()->get_changed_files().empty()); 265 } 266 267 // Test the case where the parent of the destination path is an existing file, 268 // not a directory. 269 TEST_F(CopyOperationTest, CopyFileToInvalidPath) { 270 base::FilePath src_path(FILE_PATH_LITERAL( 271 "drive/root/Document 1 excludeDir-test.gdoc")); 272 base::FilePath dest_path(FILE_PATH_LITERAL( 273 "drive/root/Duplicate Name.txt/Document 1 excludeDir-test.gdoc")); 274 275 ResourceEntry entry; 276 ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(src_path, &entry)); 277 ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(dest_path.DirName(), &entry)); 278 ASSERT_FALSE(entry.file_info().is_directory()); 279 280 FileError error = FILE_ERROR_OK; 281 operation_->Copy(src_path, 282 dest_path, 283 false, 284 google_apis::test_util::CreateCopyResultCallback(&error)); 285 content::RunAllBlockingPoolTasksUntilIdle(); 286 EXPECT_EQ(FILE_ERROR_NOT_A_DIRECTORY, error); 287 288 EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(src_path, &entry)); 289 EXPECT_EQ(FILE_ERROR_NOT_FOUND, GetLocalResourceEntry(dest_path, &entry)); 290 EXPECT_TRUE(delegate()->get_changed_files().empty()); 291 } 292 293 TEST_F(CopyOperationTest, CopyDirtyFile) { 294 base::FilePath src_path(FILE_PATH_LITERAL("drive/root/File 1.txt")); 295 base::FilePath dest_path(FILE_PATH_LITERAL( 296 "drive/root/Directory 1/New File.txt")); 297 298 ResourceEntry src_entry; 299 EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(src_path, &src_entry)); 300 301 // Store a dirty cache file. 302 base::FilePath temp_file; 303 EXPECT_TRUE(base::CreateTemporaryFileInDir(temp_dir(), &temp_file)); 304 std::string contents = "test content"; 305 EXPECT_TRUE(google_apis::test_util::WriteStringToFile(temp_file, contents)); 306 FileError error = FILE_ERROR_FAILED; 307 base::PostTaskAndReplyWithResult( 308 blocking_task_runner(), 309 FROM_HERE, 310 base::Bind(&internal::FileCache::Store, 311 base::Unretained(cache()), 312 src_entry.local_id(), 313 std::string(), 314 temp_file, 315 internal::FileCache::FILE_OPERATION_MOVE), 316 google_apis::test_util::CreateCopyResultCallback(&error)); 317 content::RunAllBlockingPoolTasksUntilIdle(); 318 EXPECT_EQ(FILE_ERROR_OK, error); 319 320 // Copy. 321 operation_->Copy(src_path, 322 dest_path, 323 false, 324 google_apis::test_util::CreateCopyResultCallback(&error)); 325 content::RunAllBlockingPoolTasksUntilIdle(); 326 EXPECT_EQ(FILE_ERROR_OK, error); 327 328 ResourceEntry dest_entry; 329 EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(dest_path, &dest_entry)); 330 EXPECT_EQ(ResourceEntry::DIRTY, dest_entry.metadata_edit_state()); 331 332 EXPECT_EQ(1u, delegate()->updated_local_ids().size()); 333 EXPECT_TRUE(delegate()->updated_local_ids().count(dest_entry.local_id())); 334 EXPECT_EQ(1u, delegate()->get_changed_files().size()); 335 EXPECT_TRUE(delegate()->get_changed_files().count(dest_path)); 336 337 // Copied cache file should be dirty. 338 EXPECT_TRUE(dest_entry.file_specific_info().cache_state().is_dirty()); 339 340 // File contents should match. 341 base::FilePath cache_file_path; 342 base::PostTaskAndReplyWithResult( 343 blocking_task_runner(), 344 FROM_HERE, 345 base::Bind(&internal::FileCache::GetFile, 346 base::Unretained(cache()), 347 dest_entry.local_id(), 348 &cache_file_path), 349 google_apis::test_util::CreateCopyResultCallback(&error)); 350 content::RunAllBlockingPoolTasksUntilIdle(); 351 EXPECT_EQ(FILE_ERROR_OK, error); 352 353 std::string copied_contents; 354 EXPECT_TRUE(base::ReadFileToString(cache_file_path, &copied_contents)); 355 EXPECT_EQ(contents, copied_contents); 356 } 357 358 TEST_F(CopyOperationTest, CopyFileOverwriteFile) { 359 base::FilePath src_path(FILE_PATH_LITERAL("drive/root/File 1.txt")); 360 base::FilePath dest_path(FILE_PATH_LITERAL( 361 "drive/root/Directory 1/SubDirectory File 1.txt")); 362 363 ResourceEntry old_dest_entry; 364 EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(dest_path, &old_dest_entry)); 365 366 FileError error = FILE_ERROR_OK; 367 operation_->Copy(src_path, 368 dest_path, 369 false, 370 google_apis::test_util::CreateCopyResultCallback(&error)); 371 content::RunAllBlockingPoolTasksUntilIdle(); 372 EXPECT_EQ(FILE_ERROR_OK, error); 373 374 ResourceEntry new_dest_entry; 375 EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(dest_path, &new_dest_entry)); 376 377 EXPECT_EQ(1u, delegate()->updated_local_ids().size()); 378 EXPECT_TRUE(delegate()->updated_local_ids().count(old_dest_entry.local_id())); 379 EXPECT_EQ(1u, delegate()->get_changed_files().size()); 380 EXPECT_TRUE(delegate()->get_changed_files().count(dest_path)); 381 } 382 383 TEST_F(CopyOperationTest, CopyFileOverwriteDirectory) { 384 base::FilePath src_path(FILE_PATH_LITERAL("drive/root/File 1.txt")); 385 base::FilePath dest_path(FILE_PATH_LITERAL("drive/root/Directory 1")); 386 387 FileError error = FILE_ERROR_OK; 388 operation_->Copy(src_path, 389 dest_path, 390 false, 391 google_apis::test_util::CreateCopyResultCallback(&error)); 392 content::RunAllBlockingPoolTasksUntilIdle(); 393 EXPECT_EQ(FILE_ERROR_INVALID_OPERATION, error); 394 } 395 396 TEST_F(CopyOperationTest, CopyDirectory) { 397 base::FilePath src_path(FILE_PATH_LITERAL("drive/root/Directory 1")); 398 base::FilePath dest_path(FILE_PATH_LITERAL("drive/root/New Directory")); 399 400 ResourceEntry entry; 401 ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(src_path, &entry)); 402 ASSERT_TRUE(entry.file_info().is_directory()); 403 ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(dest_path.DirName(), &entry)); 404 ASSERT_TRUE(entry.file_info().is_directory()); 405 406 FileError error = FILE_ERROR_OK; 407 operation_->Copy(src_path, 408 dest_path, 409 false, 410 google_apis::test_util::CreateCopyResultCallback(&error)); 411 content::RunAllBlockingPoolTasksUntilIdle(); 412 EXPECT_EQ(FILE_ERROR_NOT_A_FILE, error); 413 } 414 415 TEST_F(CopyOperationTest, PreserveLastModified) { 416 base::FilePath src_path(FILE_PATH_LITERAL("drive/root/File 1.txt")); 417 base::FilePath dest_path(FILE_PATH_LITERAL("drive/root/File 2.txt")); 418 419 ResourceEntry entry; 420 ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(src_path, &entry)); 421 ASSERT_EQ(FILE_ERROR_OK, 422 GetLocalResourceEntry(dest_path.DirName(), &entry)); 423 424 FileError error = FILE_ERROR_OK; 425 operation_->Copy(src_path, 426 dest_path, 427 true, // Preserve last modified. 428 google_apis::test_util::CreateCopyResultCallback(&error)); 429 content::RunAllBlockingPoolTasksUntilIdle(); 430 EXPECT_EQ(FILE_ERROR_OK, error); 431 432 ResourceEntry entry2; 433 EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(src_path, &entry)); 434 EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(dest_path, &entry2)); 435 EXPECT_EQ(entry.file_info().last_modified(), 436 entry2.file_info().last_modified()); 437 } 438 439 TEST_F(CopyOperationTest, WaitForSyncComplete) { 440 // Create a directory locally. 441 base::FilePath src_path(FILE_PATH_LITERAL("drive/root/File 1.txt")); 442 base::FilePath directory_path(FILE_PATH_LITERAL("drive/root/New Directory")); 443 base::FilePath dest_path = directory_path.AppendASCII("File 1.txt"); 444 445 ResourceEntry directory_parent; 446 EXPECT_EQ(FILE_ERROR_OK, 447 GetLocalResourceEntry(directory_path.DirName(), &directory_parent)); 448 449 ResourceEntry directory; 450 directory.set_parent_local_id(directory_parent.local_id()); 451 directory.set_title(directory_path.BaseName().AsUTF8Unsafe()); 452 directory.mutable_file_info()->set_is_directory(true); 453 directory.set_metadata_edit_state(ResourceEntry::DIRTY); 454 455 std::string directory_local_id; 456 FileError error = FILE_ERROR_FAILED; 457 base::PostTaskAndReplyWithResult( 458 blocking_task_runner(), 459 FROM_HERE, 460 base::Bind(&internal::ResourceMetadata::AddEntry, 461 base::Unretained(metadata()), directory, &directory_local_id), 462 google_apis::test_util::CreateCopyResultCallback(&error)); 463 content::RunAllBlockingPoolTasksUntilIdle(); 464 EXPECT_EQ(FILE_ERROR_OK, error); 465 466 // Try to copy a file to the new directory which lacks resource ID. 467 // This should result in waiting for the directory to sync. 468 std::string waited_local_id; 469 FileOperationCallback pending_callback; 470 delegate()->set_wait_for_sync_complete_handler( 471 base::Bind(&CopyWaitForSyncCompleteArguments, 472 &waited_local_id, &pending_callback)); 473 474 FileError copy_error = FILE_ERROR_FAILED; 475 operation_->Copy(src_path, 476 dest_path, 477 true, // Preserve last modified. 478 google_apis::test_util::CreateCopyResultCallback( 479 ©_error)); 480 content::RunAllBlockingPoolTasksUntilIdle(); 481 EXPECT_EQ(directory_local_id, waited_local_id); 482 ASSERT_FALSE(pending_callback.is_null()); 483 484 // Add a new directory to the server and store the resource ID locally. 485 google_apis::GDataErrorCode status = google_apis::GDATA_OTHER_ERROR; 486 scoped_ptr<google_apis::FileResource> file_resource; 487 fake_service()->AddNewDirectory( 488 directory_parent.resource_id(), 489 directory.title(), 490 DriveServiceInterface::AddNewDirectoryOptions(), 491 google_apis::test_util::CreateCopyResultCallback( 492 &status, &file_resource)); 493 content::RunAllBlockingPoolTasksUntilIdle(); 494 EXPECT_EQ(google_apis::HTTP_CREATED, status); 495 ASSERT_TRUE(file_resource); 496 497 directory.set_local_id(directory_local_id); 498 directory.set_resource_id(file_resource->file_id()); 499 base::PostTaskAndReplyWithResult( 500 blocking_task_runner(), 501 FROM_HERE, 502 base::Bind(&internal::ResourceMetadata::RefreshEntry, 503 base::Unretained(metadata()), directory), 504 google_apis::test_util::CreateCopyResultCallback(&error)); 505 content::RunAllBlockingPoolTasksUntilIdle(); 506 EXPECT_EQ(FILE_ERROR_OK, error); 507 508 // Resume the copy operation. 509 pending_callback.Run(FILE_ERROR_OK); 510 content::RunAllBlockingPoolTasksUntilIdle(); 511 512 EXPECT_EQ(FILE_ERROR_OK, copy_error); 513 ResourceEntry entry; 514 EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(dest_path, &entry)); 515 } 516 517 } // namespace file_system 518 } // namespace drive 519