15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/drive/file_system/download_operation.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/files/file_util.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/task_runner_util.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/drive/fake_free_disk_space_getter.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/drive/file_cache.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/drive/file_change.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/drive/file_system/operation_test_base.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/drive/file_system_util.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/drive/job_scheduler.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/drive/fake_drive_service.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/test/test_utils.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "google_apis/drive/test_util.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/cros_system_api/constants/cryptohome.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace drive { 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace file_system { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DownloadOperationTest : public OperationTestBase { 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void SetUp() OVERRIDE { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OperationTestBase::SetUp(); 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) operation_.reset(new DownloadOperation( 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocking_task_runner(), delegate(), scheduler(), metadata(), cache(), 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) temp_dir())); 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<DownloadOperation> operation_; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(DownloadOperationTest, 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnsureFileDownloadedByPath_FromServer_EnoughSpace) { 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::FilePath file_in_root(FILE_PATH_LITERAL("drive/root/File 1.txt")); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResourceEntry src_entry; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(file_in_root, &src_entry)); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int64 file_size = src_entry.file_info().size(); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Pretend we have enough space. 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fake_free_disk_space_getter()->set_default_value( 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_size + cryptohome::kMinFreeSpaceInBytes); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileError error = FILE_ERROR_FAILED; 49 base::FilePath file_path; 50 scoped_ptr<ResourceEntry> entry; 51 operation_->EnsureFileDownloadedByPath( 52 file_in_root, 53 ClientContext(USER_INITIATED), 54 GetFileContentInitializedCallback(), 55 google_apis::GetContentCallback(), 56 google_apis::test_util::CreateCopyResultCallback( 57 &error, &file_path, &entry)); 58 content::RunAllBlockingPoolTasksUntilIdle(); 59 60 EXPECT_EQ(FILE_ERROR_OK, error); 61 ASSERT_TRUE(entry); 62 EXPECT_FALSE(entry->file_specific_info().is_hosted_document()); 63 64 // The transfered file is cached and the change of "offline available" 65 // attribute is notified. 66 EXPECT_EQ(1U, delegate()->get_changed_files().size()); 67 EXPECT_EQ(1U, delegate()->get_changed_files().count(file_in_root)); 68} 69 70TEST_F(DownloadOperationTest, 71 EnsureFileDownloadedByPath_FromServer_NoSpaceAtAll) { 72 base::FilePath file_in_root(FILE_PATH_LITERAL("drive/root/File 1.txt")); 73 74 // Pretend we have no space at all. 75 fake_free_disk_space_getter()->set_default_value(0); 76 77 FileError error = FILE_ERROR_OK; 78 base::FilePath file_path; 79 scoped_ptr<ResourceEntry> entry; 80 operation_->EnsureFileDownloadedByPath( 81 file_in_root, 82 ClientContext(USER_INITIATED), 83 GetFileContentInitializedCallback(), 84 google_apis::GetContentCallback(), 85 google_apis::test_util::CreateCopyResultCallback( 86 &error, &file_path, &entry)); 87 content::RunAllBlockingPoolTasksUntilIdle(); 88 89 EXPECT_EQ(FILE_ERROR_NO_LOCAL_SPACE, error); 90} 91 92TEST_F(DownloadOperationTest, 93 EnsureFileDownloadedByPath_FromServer_NoEnoughSpaceButCanFreeUp) { 94 base::FilePath file_in_root(FILE_PATH_LITERAL("drive/root/File 1.txt")); 95 ResourceEntry src_entry; 96 ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(file_in_root, &src_entry)); 97 const int64 file_size = src_entry.file_info().size(); 98 99 // Make another file cached. 100 // This file's cache file will be removed to free up the disk space. 101 base::FilePath cached_file( 102 FILE_PATH_LITERAL("drive/root/Duplicate Name.txt")); 103 FileError error = FILE_ERROR_FAILED; 104 base::FilePath file_path; 105 scoped_ptr<ResourceEntry> entry; 106 operation_->EnsureFileDownloadedByPath( 107 cached_file, 108 ClientContext(USER_INITIATED), 109 GetFileContentInitializedCallback(), 110 google_apis::GetContentCallback(), 111 google_apis::test_util::CreateCopyResultCallback( 112 &error, &file_path, &entry)); 113 content::RunAllBlockingPoolTasksUntilIdle(); 114 EXPECT_EQ(FILE_ERROR_OK, error); 115 ASSERT_TRUE(entry); 116 EXPECT_TRUE(entry->file_specific_info().cache_state().is_present()); 117 118 // Pretend we have no space first (checked before downloading a file), 119 // but then start reporting we have space. This is to emulate that 120 // the disk space was freed up by removing temporary files. 121 fake_free_disk_space_getter()->set_default_value( 122 file_size + cryptohome::kMinFreeSpaceInBytes); 123 fake_free_disk_space_getter()->PushFakeValue(0); 124 125 operation_->EnsureFileDownloadedByPath( 126 file_in_root, 127 ClientContext(USER_INITIATED), 128 GetFileContentInitializedCallback(), 129 google_apis::GetContentCallback(), 130 google_apis::test_util::CreateCopyResultCallback( 131 &error, &file_path, &entry)); 132 content::RunAllBlockingPoolTasksUntilIdle(); 133 134 EXPECT_EQ(FILE_ERROR_OK, error); 135 ASSERT_TRUE(entry); 136 EXPECT_FALSE(entry->file_specific_info().is_hosted_document()); 137 138 // The transfered file is cached and the change of "offline available" 139 // attribute is notified. 140 EXPECT_EQ(2U, delegate()->get_changed_files().size()); 141 EXPECT_TRUE(delegate()->get_changed_files().count(file_in_root)); 142 EXPECT_TRUE(delegate()->get_changed_files().count(cached_file)); 143 144 // The cache for the other file should be removed in order to free up space. 145 ResourceEntry cached_file_entry; 146 EXPECT_EQ(FILE_ERROR_OK, 147 GetLocalResourceEntry(cached_file, &cached_file_entry)); 148 EXPECT_FALSE( 149 cached_file_entry.file_specific_info().cache_state().is_present()); 150} 151 152TEST_F(DownloadOperationTest, 153 EnsureFileDownloadedByPath_FromServer_EnoughSpaceButBecomeFull) { 154 base::FilePath file_in_root(FILE_PATH_LITERAL("drive/root/File 1.txt")); 155 ResourceEntry src_entry; 156 ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(file_in_root, &src_entry)); 157 const int64 file_size = src_entry.file_info().size(); 158 159 // Pretend we have enough space first (checked before downloading a file), 160 // but then start reporting we have not enough space. This is to emulate that 161 // the disk space becomes full after the file is downloaded for some reason 162 // (ex. the actual file was larger than the expected size). 163 fake_free_disk_space_getter()->PushFakeValue( 164 file_size + cryptohome::kMinFreeSpaceInBytes); 165 fake_free_disk_space_getter()->set_default_value( 166 cryptohome::kMinFreeSpaceInBytes - 1); 167 168 FileError error = FILE_ERROR_OK; 169 base::FilePath file_path; 170 scoped_ptr<ResourceEntry> entry; 171 operation_->EnsureFileDownloadedByPath( 172 file_in_root, 173 ClientContext(USER_INITIATED), 174 GetFileContentInitializedCallback(), 175 google_apis::GetContentCallback(), 176 google_apis::test_util::CreateCopyResultCallback( 177 &error, &file_path, &entry)); 178 content::RunAllBlockingPoolTasksUntilIdle(); 179 180 EXPECT_EQ(FILE_ERROR_NO_LOCAL_SPACE, error); 181} 182 183TEST_F(DownloadOperationTest, EnsureFileDownloadedByPath_FromCache) { 184 base::FilePath temp_file; 185 ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir(), &temp_file)); 186 187 base::FilePath file_in_root(FILE_PATH_LITERAL("drive/root/File 1.txt")); 188 ResourceEntry src_entry; 189 ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(file_in_root, &src_entry)); 190 191 // Store something as cached version of this file. 192 FileError error = FILE_ERROR_OK; 193 base::PostTaskAndReplyWithResult( 194 blocking_task_runner(), 195 FROM_HERE, 196 base::Bind(&internal::FileCache::Store, 197 base::Unretained(cache()), 198 GetLocalId(file_in_root), 199 src_entry.file_specific_info().md5(), 200 temp_file, 201 internal::FileCache::FILE_OPERATION_COPY), 202 google_apis::test_util::CreateCopyResultCallback(&error)); 203 content::RunAllBlockingPoolTasksUntilIdle(); 204 EXPECT_EQ(FILE_ERROR_OK, error); 205 206 base::FilePath file_path; 207 scoped_ptr<ResourceEntry> entry; 208 operation_->EnsureFileDownloadedByPath( 209 file_in_root, 210 ClientContext(USER_INITIATED), 211 GetFileContentInitializedCallback(), 212 google_apis::GetContentCallback(), 213 google_apis::test_util::CreateCopyResultCallback( 214 &error, &file_path, &entry)); 215 content::RunAllBlockingPoolTasksUntilIdle(); 216 217 EXPECT_EQ(FILE_ERROR_OK, error); 218 ASSERT_TRUE(entry); 219 EXPECT_FALSE(entry->file_specific_info().is_hosted_document()); 220} 221 222TEST_F(DownloadOperationTest, EnsureFileDownloadedByPath_HostedDocument) { 223 base::FilePath file_in_root(FILE_PATH_LITERAL( 224 "drive/root/Document 1 excludeDir-test.gdoc")); 225 226 FileError error = FILE_ERROR_FAILED; 227 base::FilePath file_path; 228 scoped_ptr<ResourceEntry> entry; 229 operation_->EnsureFileDownloadedByPath( 230 file_in_root, 231 ClientContext(USER_INITIATED), 232 GetFileContentInitializedCallback(), 233 google_apis::GetContentCallback(), 234 google_apis::test_util::CreateCopyResultCallback( 235 &error, &file_path, &entry)); 236 content::RunAllBlockingPoolTasksUntilIdle(); 237 238 EXPECT_EQ(FILE_ERROR_OK, error); 239 ASSERT_TRUE(entry); 240 EXPECT_TRUE(entry->file_specific_info().is_hosted_document()); 241 EXPECT_FALSE(file_path.empty()); 242 243 EXPECT_EQ(GURL(entry->file_specific_info().alternate_url()), 244 util::ReadUrlFromGDocFile(file_path)); 245 EXPECT_EQ(entry->resource_id(), util::ReadResourceIdFromGDocFile(file_path)); 246 EXPECT_EQ(FILE_PATH_LITERAL(".gdoc"), file_path.Extension()); 247} 248 249TEST_F(DownloadOperationTest, EnsureFileDownloadedByLocalId) { 250 base::FilePath file_in_root(FILE_PATH_LITERAL("drive/root/File 1.txt")); 251 ResourceEntry src_entry; 252 ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(file_in_root, &src_entry)); 253 254 FileError error = FILE_ERROR_OK; 255 base::FilePath file_path; 256 scoped_ptr<ResourceEntry> entry; 257 operation_->EnsureFileDownloadedByLocalId( 258 GetLocalId(file_in_root), 259 ClientContext(USER_INITIATED), 260 GetFileContentInitializedCallback(), 261 google_apis::GetContentCallback(), 262 google_apis::test_util::CreateCopyResultCallback( 263 &error, &file_path, &entry)); 264 content::RunAllBlockingPoolTasksUntilIdle(); 265 266 EXPECT_EQ(FILE_ERROR_OK, error); 267 ASSERT_TRUE(entry); 268 EXPECT_FALSE(entry->file_specific_info().is_hosted_document()); 269 270 // The transfered file is cached and the change of "offline available" 271 // attribute is notified. 272 EXPECT_EQ(1U, delegate()->get_changed_files().size()); 273 EXPECT_EQ(1U, delegate()->get_changed_files().count(file_in_root)); 274} 275 276TEST_F(DownloadOperationTest, 277 EnsureFileDownloadedByPath_WithGetContentCallback) { 278 base::FilePath file_in_root(FILE_PATH_LITERAL("drive/root/File 1.txt")); 279 280 { 281 FileError initialized_error = FILE_ERROR_FAILED; 282 scoped_ptr<ResourceEntry> entry, entry_dontcare; 283 base::FilePath local_path, local_path_dontcare; 284 google_apis::test_util::TestGetContentCallback get_content_callback; 285 FileError completion_error = FILE_ERROR_FAILED; 286 base::Closure cancel_download = operation_->EnsureFileDownloadedByPath( 287 file_in_root, 288 ClientContext(USER_INITIATED), 289 google_apis::test_util::CreateCopyResultCallback( 290 &initialized_error, &local_path, &entry), 291 get_content_callback.callback(), 292 google_apis::test_util::CreateCopyResultCallback( 293 &completion_error, &local_path_dontcare, &entry_dontcare)); 294 content::RunAllBlockingPoolTasksUntilIdle(); 295 296 // For the first time, file is downloaded from the remote server. 297 // In this case, |local_path| is empty. 298 EXPECT_EQ(FILE_ERROR_OK, initialized_error); 299 ASSERT_TRUE(entry); 300 ASSERT_TRUE(local_path.empty()); 301 EXPECT_FALSE(cancel_download.is_null()); 302 // Content is available through the second callback argument. 303 EXPECT_EQ(static_cast<size_t>(entry->file_info().size()), 304 get_content_callback.GetConcatenatedData().size()); 305 EXPECT_EQ(FILE_ERROR_OK, completion_error); 306 307 // The transfered file is cached and the change of "offline available" 308 // attribute is notified. 309 EXPECT_EQ(1U, delegate()->get_changed_files().size()); 310 EXPECT_EQ(1U, delegate()->get_changed_files().count(file_in_root)); 311 } 312 313 { 314 FileError initialized_error = FILE_ERROR_FAILED; 315 scoped_ptr<ResourceEntry> entry, entry_dontcare; 316 base::FilePath local_path, local_path_dontcare; 317 google_apis::test_util::TestGetContentCallback get_content_callback; 318 FileError completion_error = FILE_ERROR_FAILED; 319 base::Closure cancel_download = operation_->EnsureFileDownloadedByPath( 320 file_in_root, 321 ClientContext(USER_INITIATED), 322 google_apis::test_util::CreateCopyResultCallback( 323 &initialized_error, &local_path, &entry), 324 get_content_callback.callback(), 325 google_apis::test_util::CreateCopyResultCallback( 326 &completion_error, &local_path_dontcare, &entry_dontcare)); 327 content::RunAllBlockingPoolTasksUntilIdle(); 328 329 // Try second download. In this case, the file should be cached, so 330 // |local_path| should not be empty. 331 EXPECT_EQ(FILE_ERROR_OK, initialized_error); 332 ASSERT_TRUE(entry); 333 ASSERT_TRUE(!local_path.empty()); 334 EXPECT_FALSE(cancel_download.is_null()); 335 // The content is available from the cache file. 336 EXPECT_TRUE(get_content_callback.data().empty()); 337 int64 local_file_size = 0; 338 base::GetFileSize(local_path, &local_file_size); 339 EXPECT_EQ(entry->file_info().size(), local_file_size); 340 EXPECT_EQ(FILE_ERROR_OK, completion_error); 341 } 342} 343 344TEST_F(DownloadOperationTest, EnsureFileDownloadedByLocalId_FromCache) { 345 base::FilePath temp_file; 346 ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir(), &temp_file)); 347 348 base::FilePath file_in_root(FILE_PATH_LITERAL("drive/root/File 1.txt")); 349 ResourceEntry src_entry; 350 ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(file_in_root, &src_entry)); 351 352 // Store something as cached version of this file. 353 FileError error = FILE_ERROR_FAILED; 354 base::PostTaskAndReplyWithResult( 355 blocking_task_runner(), 356 FROM_HERE, 357 base::Bind(&internal::FileCache::Store, 358 base::Unretained(cache()), 359 GetLocalId(file_in_root), 360 src_entry.file_specific_info().md5(), 361 temp_file, 362 internal::FileCache::FILE_OPERATION_COPY), 363 google_apis::test_util::CreateCopyResultCallback(&error)); 364 content::RunAllBlockingPoolTasksUntilIdle(); 365 EXPECT_EQ(FILE_ERROR_OK, error); 366 367 // The file is obtained from the cache. 368 // Hence the downloading should work even if the drive service is offline. 369 fake_service()->set_offline(true); 370 371 base::FilePath file_path; 372 scoped_ptr<ResourceEntry> entry; 373 operation_->EnsureFileDownloadedByLocalId( 374 GetLocalId(file_in_root), 375 ClientContext(USER_INITIATED), 376 GetFileContentInitializedCallback(), 377 google_apis::GetContentCallback(), 378 google_apis::test_util::CreateCopyResultCallback( 379 &error, &file_path, &entry)); 380 content::RunAllBlockingPoolTasksUntilIdle(); 381 382 EXPECT_EQ(FILE_ERROR_OK, error); 383 ASSERT_TRUE(entry); 384 EXPECT_FALSE(entry->file_specific_info().is_hosted_document()); 385} 386 387TEST_F(DownloadOperationTest, EnsureFileDownloadedByPath_DirtyCache) { 388 base::FilePath file_in_root(FILE_PATH_LITERAL("drive/root/File 1.txt")); 389 ResourceEntry src_entry; 390 ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(file_in_root, &src_entry)); 391 392 // Prepare a dirty file to store to cache that has a different size than 393 // stored in resource metadata. 394 base::FilePath dirty_file = temp_dir().AppendASCII("dirty.txt"); 395 size_t dirty_size = src_entry.file_info().size() + 10; 396 google_apis::test_util::WriteStringToFile(dirty_file, 397 std::string(dirty_size, 'x')); 398 399 // Store the file as a cache, marking it to be dirty. 400 FileError error = FILE_ERROR_FAILED; 401 base::PostTaskAndReplyWithResult( 402 blocking_task_runner(), 403 FROM_HERE, 404 base::Bind(&internal::FileCache::Store, 405 base::Unretained(cache()), 406 GetLocalId(file_in_root), 407 std::string(), 408 dirty_file, 409 internal::FileCache::FILE_OPERATION_COPY), 410 google_apis::test_util::CreateCopyResultCallback(&error)); 411 content::RunAllBlockingPoolTasksUntilIdle(); 412 EXPECT_EQ(FILE_ERROR_OK, error); 413 414 // Record values passed to GetFileContentInitializedCallback(). 415 FileError init_error; 416 base::FilePath init_path; 417 scoped_ptr<ResourceEntry> init_entry; 418 base::FilePath file_path; 419 scoped_ptr<ResourceEntry> entry; 420 base::Closure cancel_callback = operation_->EnsureFileDownloadedByPath( 421 file_in_root, 422 ClientContext(USER_INITIATED), 423 google_apis::test_util::CreateCopyResultCallback( 424 &init_error, &init_path, &init_entry), 425 google_apis::GetContentCallback(), 426 google_apis::test_util::CreateCopyResultCallback( 427 &error, &file_path, &entry)); 428 content::RunAllBlockingPoolTasksUntilIdle(); 429 430 EXPECT_EQ(FILE_ERROR_OK, error); 431 // Check that the result of local modification is propagated. 432 EXPECT_EQ(static_cast<int64>(dirty_size), init_entry->file_info().size()); 433 EXPECT_EQ(static_cast<int64>(dirty_size), entry->file_info().size()); 434} 435 436TEST_F(DownloadOperationTest, EnsureFileDownloadedByPath_LocallyCreatedFile) { 437 // Add a new file with an empty resource ID. 438 base::FilePath file_path(FILE_PATH_LITERAL("drive/root/New File.txt")); 439 ResourceEntry parent; 440 ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(file_path.DirName(), &parent)); 441 442 ResourceEntry new_file; 443 new_file.set_title("New File.txt"); 444 new_file.set_parent_local_id(parent.local_id()); 445 446 FileError error = FILE_ERROR_FAILED; 447 std::string local_id; 448 base::PostTaskAndReplyWithResult( 449 blocking_task_runner(), 450 FROM_HERE, 451 base::Bind(&internal::ResourceMetadata::AddEntry, 452 base::Unretained(metadata()), 453 new_file, 454 &local_id), 455 google_apis::test_util::CreateCopyResultCallback(&error)); 456 content::RunAllBlockingPoolTasksUntilIdle(); 457 EXPECT_EQ(FILE_ERROR_OK, error); 458 459 // Empty cache file should be returned. 460 base::FilePath cache_file_path; 461 scoped_ptr<ResourceEntry> entry; 462 operation_->EnsureFileDownloadedByPath( 463 file_path, 464 ClientContext(USER_INITIATED), 465 GetFileContentInitializedCallback(), 466 google_apis::GetContentCallback(), 467 google_apis::test_util::CreateCopyResultCallback( 468 &error, &cache_file_path, &entry)); 469 content::RunAllBlockingPoolTasksUntilIdle(); 470 EXPECT_EQ(FILE_ERROR_OK, error); 471 472 int64 cache_file_size = 0; 473 EXPECT_TRUE(base::GetFileSize(cache_file_path, &cache_file_size)); 474 EXPECT_EQ(static_cast<int64>(0), cache_file_size); 475 ASSERT_TRUE(entry); 476 EXPECT_EQ(cache_file_size, entry->file_info().size()); 477} 478 479TEST_F(DownloadOperationTest, CancelBeforeDownloadStarts) { 480 base::FilePath file_in_root(FILE_PATH_LITERAL("drive/root/File 1.txt")); 481 ResourceEntry src_entry; 482 ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(file_in_root, &src_entry)); 483 484 // Start operation. 485 FileError error = FILE_ERROR_OK; 486 base::FilePath file_path; 487 scoped_ptr<ResourceEntry> entry; 488 base::Closure cancel_closure = operation_->EnsureFileDownloadedByLocalId( 489 GetLocalId(file_in_root), 490 ClientContext(USER_INITIATED), 491 GetFileContentInitializedCallback(), 492 google_apis::GetContentCallback(), 493 google_apis::test_util::CreateCopyResultCallback( 494 &error, &file_path, &entry)); 495 496 // Cancel immediately. 497 ASSERT_FALSE(cancel_closure.is_null()); 498 cancel_closure.Run(); 499 content::RunAllBlockingPoolTasksUntilIdle(); 500 501 EXPECT_EQ(FILE_ERROR_ABORT, error); 502} 503 504} // namespace file_system 505} // namespace drive 506