job_scheduler_unittest.cc revision eb525c5499e34cc9c4b825d6d9e75bb07cc06ace
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 "chrome/browser/chromeos/drive/job_scheduler.h" 6 7#include <set> 8 9#include "base/bind.h" 10#include "base/file_util.h" 11#include "base/prefs/pref_service.h" 12#include "base/run_loop.h" 13#include "base/stl_util.h" 14#include "chrome/browser/chromeos/drive/test_util.h" 15#include "chrome/browser/drive/fake_drive_service.h" 16#include "chrome/browser/google_apis/drive_api_parser.h" 17#include "chrome/browser/google_apis/gdata_wapi_parser.h" 18#include "chrome/browser/google_apis/test_util.h" 19#include "chrome/common/pref_names.h" 20#include "chrome/test/base/testing_profile.h" 21#include "content/public/test/test_browser_thread_bundle.h" 22#include "testing/gtest/include/gtest/gtest.h" 23 24namespace drive { 25 26namespace { 27 28void CopyResourceIdFromGetResourceEntryCallback( 29 std::vector<std::string>* id_list_out, 30 const std::string& requested_id, 31 google_apis::GDataErrorCode error_in, 32 scoped_ptr<google_apis::ResourceEntry> resource_entry_in) { 33 id_list_out->push_back(requested_id); 34} 35 36class JobListLogger : public JobListObserver { 37 public: 38 enum EventType { 39 ADDED, 40 UPDATED, 41 DONE, 42 }; 43 44 struct EventLog { 45 EventType type; 46 JobInfo info; 47 48 EventLog(EventType type, const JobInfo& info) : type(type), info(info) { 49 } 50 }; 51 52 // Checks whether the specified type of event has occurred. 53 bool Has(EventType type, JobType job_type) { 54 for (size_t i = 0; i < events.size(); ++i) { 55 if (events[i].type == type && events[i].info.job_type == job_type) 56 return true; 57 } 58 return false; 59 } 60 61 // Gets the progress event information of the specified type. 62 void GetProgressInfo(JobType job_type, std::vector<int64>* progress) { 63 for (size_t i = 0; i < events.size(); ++i) { 64 if (events[i].type == UPDATED && events[i].info.job_type == job_type) 65 progress->push_back(events[i].info.num_completed_bytes); 66 } 67 } 68 69 // JobListObserver overrides. 70 virtual void OnJobAdded(const JobInfo& info) OVERRIDE { 71 events.push_back(EventLog(ADDED, info)); 72 } 73 74 virtual void OnJobUpdated(const JobInfo& info) OVERRIDE { 75 events.push_back(EventLog(UPDATED, info)); 76 } 77 78 virtual void OnJobDone(const JobInfo& info, FileError error) OVERRIDE { 79 events.push_back(EventLog(DONE, info)); 80 } 81 82 private: 83 std::vector<EventLog> events; 84}; 85 86} // namespace 87 88class JobSchedulerTest : public testing::Test { 89 public: 90 JobSchedulerTest() 91 : profile_(new TestingProfile) { 92 } 93 94 virtual void SetUp() OVERRIDE { 95 fake_network_change_notifier_.reset( 96 new test_util::FakeNetworkChangeNotifier); 97 98 fake_drive_service_.reset(new FakeDriveService()); 99 fake_drive_service_->LoadResourceListForWapi( 100 "gdata/root_feed.json"); 101 fake_drive_service_->LoadAccountMetadataForWapi( 102 "gdata/account_metadata.json"); 103 fake_drive_service_->LoadAppListForDriveApi( 104 "drive/applist.json"); 105 106 scheduler_.reset(new JobScheduler(profile_.get(), 107 fake_drive_service_.get(), 108 base::MessageLoopProxy::current())); 109 scheduler_->SetDisableThrottling(true); 110 } 111 112 protected: 113 // Sets up FakeNetworkChangeNotifier as if it's connected to a network with 114 // the specified connection type. 115 void ChangeConnectionType(net::NetworkChangeNotifier::ConnectionType type) { 116 fake_network_change_notifier_->SetConnectionType(type); 117 } 118 119 // Sets up FakeNetworkChangeNotifier as if it's connected to wifi network. 120 void ConnectToWifi() { 121 ChangeConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI); 122 } 123 124 // Sets up FakeNetworkChangeNotifier as if it's connected to cellular network. 125 void ConnectToCellular() { 126 ChangeConnectionType(net::NetworkChangeNotifier::CONNECTION_2G); 127 } 128 129 // Sets up FakeNetworkChangeNotifier as if it's connected to wimax network. 130 void ConnectToWimax() { 131 ChangeConnectionType(net::NetworkChangeNotifier::CONNECTION_4G); 132 } 133 134 // Sets up FakeNetworkChangeNotifier as if it's disconnected. 135 void ConnectToNone() { 136 ChangeConnectionType(net::NetworkChangeNotifier::CONNECTION_NONE); 137 } 138 139 static int GetMetadataQueueMaxJobCount() { 140 return JobScheduler::kMaxJobCount[JobScheduler::METADATA_QUEUE]; 141 } 142 143 content::TestBrowserThreadBundle thread_bundle_; 144 scoped_ptr<TestingProfile> profile_; 145 scoped_ptr<test_util::FakeNetworkChangeNotifier> 146 fake_network_change_notifier_; 147 scoped_ptr<FakeDriveService> fake_drive_service_; 148 scoped_ptr<JobScheduler> scheduler_; 149}; 150 151TEST_F(JobSchedulerTest, GetAboutResource) { 152 ConnectToWifi(); 153 154 google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR; 155 scoped_ptr<google_apis::AboutResource> about_resource; 156 scheduler_->GetAboutResource( 157 google_apis::test_util::CreateCopyResultCallback( 158 &error, &about_resource)); 159 base::RunLoop().RunUntilIdle(); 160 ASSERT_EQ(google_apis::HTTP_SUCCESS, error); 161 ASSERT_TRUE(about_resource); 162} 163 164TEST_F(JobSchedulerTest, GetAppList) { 165 ConnectToWifi(); 166 167 google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR; 168 scoped_ptr<google_apis::AppList> app_list; 169 170 scheduler_->GetAppList( 171 google_apis::test_util::CreateCopyResultCallback(&error, &app_list)); 172 base::RunLoop().RunUntilIdle(); 173 174 ASSERT_EQ(google_apis::HTTP_SUCCESS, error); 175 ASSERT_TRUE(app_list); 176} 177 178TEST_F(JobSchedulerTest, GetAllResourceList) { 179 ConnectToWifi(); 180 181 google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR; 182 scoped_ptr<google_apis::ResourceList> resource_list; 183 184 scheduler_->GetAllResourceList( 185 google_apis::test_util::CreateCopyResultCallback( 186 &error, &resource_list)); 187 base::RunLoop().RunUntilIdle(); 188 189 ASSERT_EQ(google_apis::HTTP_SUCCESS, error); 190 ASSERT_TRUE(resource_list); 191} 192 193TEST_F(JobSchedulerTest, GetResourceListInDirectory) { 194 ConnectToWifi(); 195 196 google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR; 197 scoped_ptr<google_apis::ResourceList> resource_list; 198 199 scheduler_->GetResourceListInDirectory( 200 fake_drive_service_->GetRootResourceId(), 201 google_apis::test_util::CreateCopyResultCallback( 202 &error, &resource_list)); 203 base::RunLoop().RunUntilIdle(); 204 205 ASSERT_EQ(google_apis::HTTP_SUCCESS, error); 206 ASSERT_TRUE(resource_list); 207} 208 209TEST_F(JobSchedulerTest, Search) { 210 ConnectToWifi(); 211 212 google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR; 213 scoped_ptr<google_apis::ResourceList> resource_list; 214 215 scheduler_->Search( 216 "File", // search query 217 google_apis::test_util::CreateCopyResultCallback( 218 &error, &resource_list)); 219 base::RunLoop().RunUntilIdle(); 220 221 ASSERT_EQ(google_apis::HTTP_SUCCESS, error); 222 ASSERT_TRUE(resource_list); 223} 224 225TEST_F(JobSchedulerTest, GetChangeList) { 226 ConnectToWifi(); 227 228 google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR; 229 230 // Create a new directory. 231 // The loaded (initial) changestamp is 654321. Thus, by this operation, 232 // it should become 654322. 233 { 234 scoped_ptr<google_apis::ResourceEntry> resource_entry; 235 fake_drive_service_->AddNewDirectory( 236 fake_drive_service_->GetRootResourceId(), 237 "new directory", 238 google_apis::test_util::CreateCopyResultCallback( 239 &error, &resource_entry)); 240 base::RunLoop().RunUntilIdle(); 241 ASSERT_EQ(google_apis::HTTP_CREATED, error); 242 } 243 244 error = google_apis::GDATA_OTHER_ERROR; 245 scoped_ptr<google_apis::ResourceList> resource_list; 246 scheduler_->GetChangeList( 247 654321 + 1, // start_changestamp 248 google_apis::test_util::CreateCopyResultCallback( 249 &error, &resource_list)); 250 base::RunLoop().RunUntilIdle(); 251 252 ASSERT_EQ(google_apis::HTTP_SUCCESS, error); 253 ASSERT_TRUE(resource_list); 254} 255 256TEST_F(JobSchedulerTest, ContinueGetResourceList) { 257 ConnectToWifi(); 258 fake_drive_service_->set_default_max_results(2); 259 260 google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR; 261 scoped_ptr<google_apis::ResourceList> resource_list; 262 263 scheduler_->GetAllResourceList( 264 google_apis::test_util::CreateCopyResultCallback( 265 &error, &resource_list)); 266 base::RunLoop().RunUntilIdle(); 267 268 ASSERT_EQ(google_apis::HTTP_SUCCESS, error); 269 ASSERT_TRUE(resource_list); 270 271 const google_apis::Link* next_link = 272 resource_list->GetLinkByType(google_apis::Link::LINK_NEXT); 273 ASSERT_TRUE(next_link); 274 // Keep the next url before releasing the |resource_list|. 275 GURL next_url(next_link->href()); 276 277 error = google_apis::GDATA_OTHER_ERROR; 278 resource_list.reset(); 279 280 scheduler_->ContinueGetResourceList( 281 next_url, 282 google_apis::test_util::CreateCopyResultCallback( 283 &error, &resource_list)); 284 base::RunLoop().RunUntilIdle(); 285 286 ASSERT_EQ(google_apis::HTTP_SUCCESS, error); 287 ASSERT_TRUE(resource_list); 288} 289 290TEST_F(JobSchedulerTest, GetResourceEntry) { 291 ConnectToWifi(); 292 293 google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR; 294 scoped_ptr<google_apis::ResourceEntry> entry; 295 296 scheduler_->GetResourceEntry( 297 "file:2_file_resource_id", // resource ID 298 ClientContext(USER_INITIATED), 299 google_apis::test_util::CreateCopyResultCallback(&error, &entry)); 300 base::RunLoop().RunUntilIdle(); 301 302 ASSERT_EQ(google_apis::HTTP_SUCCESS, error); 303 ASSERT_TRUE(entry); 304} 305 306TEST_F(JobSchedulerTest, DeleteResource) { 307 ConnectToWifi(); 308 309 google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR; 310 311 scheduler_->DeleteResource( 312 "file:2_file_resource_id", 313 google_apis::test_util::CreateCopyResultCallback(&error)); 314 base::RunLoop().RunUntilIdle(); 315 316 ASSERT_EQ(google_apis::HTTP_SUCCESS, error); 317} 318 319TEST_F(JobSchedulerTest, CopyResource) { 320 ConnectToWifi(); 321 322 google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR; 323 scoped_ptr<google_apis::ResourceEntry> entry; 324 325 scheduler_->CopyResource( 326 "file:2_file_resource_id", // resource ID 327 "folder:1_folder_resource_id", // parent resource ID 328 "New Document", // new name 329 google_apis::test_util::CreateCopyResultCallback(&error, &entry)); 330 base::RunLoop().RunUntilIdle(); 331 332 ASSERT_EQ(google_apis::HTTP_SUCCESS, error); 333 ASSERT_TRUE(entry); 334} 335 336TEST_F(JobSchedulerTest, CopyHostedDocument) { 337 ConnectToWifi(); 338 339 google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR; 340 scoped_ptr<google_apis::ResourceEntry> entry; 341 342 scheduler_->CopyHostedDocument( 343 "document:5_document_resource_id", // resource ID 344 "New Document", // new name 345 google_apis::test_util::CreateCopyResultCallback(&error, &entry)); 346 base::RunLoop().RunUntilIdle(); 347 348 ASSERT_EQ(google_apis::HTTP_SUCCESS, error); 349 ASSERT_TRUE(entry); 350} 351 352TEST_F(JobSchedulerTest, RenameResource) { 353 ConnectToWifi(); 354 355 google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR; 356 357 scheduler_->RenameResource( 358 "file:2_file_resource_id", 359 "New Name", 360 google_apis::test_util::CreateCopyResultCallback(&error)); 361 base::RunLoop().RunUntilIdle(); 362 363 ASSERT_EQ(google_apis::HTTP_SUCCESS, error); 364} 365 366TEST_F(JobSchedulerTest, AddResourceToDirectory) { 367 ConnectToWifi(); 368 369 google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR; 370 371 scheduler_->AddResourceToDirectory( 372 "folder:1_folder_resource_id", 373 "file:2_file_resource_id", 374 google_apis::test_util::CreateCopyResultCallback(&error)); 375 base::RunLoop().RunUntilIdle(); 376 377 ASSERT_EQ(google_apis::HTTP_SUCCESS, error); 378} 379 380TEST_F(JobSchedulerTest, RemoveResourceFromDirectory) { 381 ConnectToWifi(); 382 383 google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR; 384 385 scheduler_->RemoveResourceFromDirectory( 386 "folder:1_folder_resource_id", 387 "file:subdirectory_file_1_id", // resource ID 388 google_apis::test_util::CreateCopyResultCallback(&error)); 389 base::RunLoop().RunUntilIdle(); 390 391 ASSERT_EQ(google_apis::HTTP_SUCCESS, error); 392} 393 394TEST_F(JobSchedulerTest, AddNewDirectory) { 395 ConnectToWifi(); 396 397 google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR; 398 scoped_ptr<google_apis::ResourceEntry> entry; 399 400 scheduler_->AddNewDirectory( 401 fake_drive_service_->GetRootResourceId(), // Root directory. 402 "New Directory", 403 google_apis::test_util::CreateCopyResultCallback(&error, &entry)); 404 base::RunLoop().RunUntilIdle(); 405 406 ASSERT_EQ(google_apis::HTTP_CREATED, error); 407 ASSERT_TRUE(entry); 408} 409 410TEST_F(JobSchedulerTest, GetResourceEntryPriority) { 411 // Saturate the metadata job queue with uninteresting jobs to prevent 412 // following jobs from starting. 413 google_apis::GDataErrorCode error_dontcare = google_apis::GDATA_OTHER_ERROR; 414 scoped_ptr<google_apis::ResourceEntry> entry_dontcare; 415 for (int i = 0; i < GetMetadataQueueMaxJobCount(); ++i) { 416 scheduler_->GetResourceEntry( 417 "uninteresting_resource_id", 418 ClientContext(USER_INITIATED), 419 google_apis::test_util::CreateCopyResultCallback(&error_dontcare, 420 &entry_dontcare)); 421 } 422 423 // Start jobs with different priorities. 424 std::string resource_1("file:1_file_resource_id"); 425 std::string resource_2("file:2_file_resource_id"); 426 std::string resource_3("file:3_file_resource_id"); 427 std::string resource_4("file:4_file_resource_id"); 428 std::vector<std::string> resource_ids; 429 430 scheduler_->GetResourceEntry( 431 resource_1, // resource ID 432 ClientContext(USER_INITIATED), 433 base::Bind(&CopyResourceIdFromGetResourceEntryCallback, 434 &resource_ids, 435 resource_1)); 436 scheduler_->GetResourceEntry( 437 resource_2, // resource ID 438 ClientContext(BACKGROUND), 439 base::Bind(&CopyResourceIdFromGetResourceEntryCallback, 440 &resource_ids, 441 resource_2)); 442 scheduler_->GetResourceEntry( 443 resource_3, // resource ID 444 ClientContext(BACKGROUND), 445 base::Bind(&CopyResourceIdFromGetResourceEntryCallback, 446 &resource_ids, 447 resource_3)); 448 scheduler_->GetResourceEntry( 449 resource_4, // resource ID 450 ClientContext(USER_INITIATED), 451 base::Bind(&CopyResourceIdFromGetResourceEntryCallback, 452 &resource_ids, 453 resource_4)); 454 455 base::RunLoop().RunUntilIdle(); 456 457 ASSERT_EQ(resource_ids.size(), 4ul); 458 EXPECT_EQ(resource_ids[0], resource_1); 459 EXPECT_EQ(resource_ids[1], resource_4); 460 EXPECT_EQ(resource_ids[2], resource_2); 461 EXPECT_EQ(resource_ids[3], resource_3); 462} 463 464TEST_F(JobSchedulerTest, GetResourceEntryNoConnectionUserInitiated) { 465 ConnectToNone(); 466 467 std::string resource_id("file:2_file_resource_id"); 468 469 google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR; 470 scoped_ptr<google_apis::ResourceEntry> entry; 471 scheduler_->GetResourceEntry( 472 resource_id, 473 ClientContext(USER_INITIATED), 474 google_apis::test_util::CreateCopyResultCallback(&error, &entry)); 475 base::RunLoop().RunUntilIdle(); 476 477 EXPECT_EQ(google_apis::GDATA_NO_CONNECTION, error); 478} 479 480TEST_F(JobSchedulerTest, GetResourceEntryNoConnectionBackground) { 481 ConnectToNone(); 482 483 std::string resource_id("file:2_file_resource_id"); 484 485 google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR; 486 scoped_ptr<google_apis::ResourceEntry> entry; 487 scheduler_->GetResourceEntry( 488 resource_id, 489 ClientContext(BACKGROUND), 490 google_apis::test_util::CreateCopyResultCallback(&error, &entry)); 491 base::RunLoop().RunUntilIdle(); 492 493 EXPECT_FALSE(entry); 494 495 // Reconnect to the net. 496 ConnectToWifi(); 497 498 base::RunLoop().RunUntilIdle(); 499 500 EXPECT_EQ(google_apis::HTTP_SUCCESS, error); 501 ASSERT_TRUE(entry); 502 EXPECT_EQ(resource_id, entry->resource_id()); 503} 504 505TEST_F(JobSchedulerTest, DownloadFileCellularDisabled) { 506 ConnectToCellular(); 507 508 // Disable fetching over cellular network. 509 profile_->GetPrefs()->SetBoolean(prefs::kDisableDriveOverCellular, true); 510 511 // Try to get a file in the background 512 base::ScopedTempDir temp_dir; 513 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 514 515 const base::FilePath kOutputFilePath = 516 temp_dir.path().AppendASCII("whatever.txt"); 517 google_apis::GDataErrorCode download_error = google_apis::GDATA_OTHER_ERROR; 518 base::FilePath output_file_path; 519 scheduler_->DownloadFile( 520 base::FilePath::FromUTF8Unsafe("drive/whatever.txt"), // virtual path 521 kOutputFilePath, 522 "file:2_file_resource_id", 523 ClientContext(BACKGROUND), 524 google_apis::test_util::CreateCopyResultCallback( 525 &download_error, &output_file_path), 526 google_apis::GetContentCallback()); 527 // Metadata should still work 528 google_apis::GDataErrorCode metadata_error = google_apis::GDATA_OTHER_ERROR; 529 scoped_ptr<google_apis::AboutResource> about_resource; 530 531 // Try to get the metadata 532 scheduler_->GetAboutResource( 533 google_apis::test_util::CreateCopyResultCallback( 534 &metadata_error, &about_resource)); 535 base::RunLoop().RunUntilIdle(); 536 537 // Check the metadata 538 ASSERT_EQ(google_apis::HTTP_SUCCESS, metadata_error); 539 ASSERT_TRUE(about_resource); 540 541 // Check the download 542 EXPECT_EQ(google_apis::GDATA_OTHER_ERROR, download_error); 543 544 // Switch to a Wifi connection 545 ConnectToWifi(); 546 547 base::RunLoop().RunUntilIdle(); 548 549 // Check the download again 550 EXPECT_EQ(google_apis::HTTP_SUCCESS, download_error); 551 std::string content; 552 EXPECT_EQ(output_file_path, kOutputFilePath); 553 ASSERT_TRUE(file_util::ReadFileToString(output_file_path, &content)); 554 EXPECT_EQ("This is some test content.", content); 555} 556 557TEST_F(JobSchedulerTest, DownloadFileWimaxDisabled) { 558 ConnectToWimax(); 559 560 // Disable fetching over cellular network. 561 profile_->GetPrefs()->SetBoolean(prefs::kDisableDriveOverCellular, true); 562 563 // Try to get a file in the background 564 base::ScopedTempDir temp_dir; 565 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 566 567 const base::FilePath kOutputFilePath = 568 temp_dir.path().AppendASCII("whatever.txt"); 569 google_apis::GDataErrorCode download_error = google_apis::GDATA_OTHER_ERROR; 570 base::FilePath output_file_path; 571 scheduler_->DownloadFile( 572 base::FilePath::FromUTF8Unsafe("drive/whatever.txt"), // virtual path 573 kOutputFilePath, 574 "file:2_file_resource_id", 575 ClientContext(BACKGROUND), 576 google_apis::test_util::CreateCopyResultCallback( 577 &download_error, &output_file_path), 578 google_apis::GetContentCallback()); 579 // Metadata should still work 580 google_apis::GDataErrorCode metadata_error = google_apis::GDATA_OTHER_ERROR; 581 scoped_ptr<google_apis::AboutResource> about_resource; 582 583 // Try to get the metadata 584 scheduler_->GetAboutResource( 585 google_apis::test_util::CreateCopyResultCallback( 586 &metadata_error, &about_resource)); 587 base::RunLoop().RunUntilIdle(); 588 589 // Check the metadata 590 ASSERT_EQ(google_apis::HTTP_SUCCESS, metadata_error); 591 ASSERT_TRUE(about_resource); 592 593 // Check the download 594 EXPECT_EQ(google_apis::GDATA_OTHER_ERROR, download_error); 595 596 // Switch to a Wifi connection 597 ConnectToWifi(); 598 599 base::RunLoop().RunUntilIdle(); 600 601 // Check the download again 602 EXPECT_EQ(google_apis::HTTP_SUCCESS, download_error); 603 std::string content; 604 EXPECT_EQ(output_file_path, kOutputFilePath); 605 ASSERT_TRUE(file_util::ReadFileToString(output_file_path, &content)); 606 EXPECT_EQ("This is some test content.", content); 607} 608 609TEST_F(JobSchedulerTest, DownloadFileCellularEnabled) { 610 ConnectToCellular(); 611 612 // Enable fetching over cellular network. 613 profile_->GetPrefs()->SetBoolean(prefs::kDisableDriveOverCellular, false); 614 615 // Try to get a file in the background 616 base::ScopedTempDir temp_dir; 617 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 618 619 const base::FilePath kOutputFilePath = 620 temp_dir.path().AppendASCII("whatever.txt"); 621 google_apis::GDataErrorCode download_error = google_apis::GDATA_OTHER_ERROR; 622 base::FilePath output_file_path; 623 scheduler_->DownloadFile( 624 base::FilePath::FromUTF8Unsafe("drive/whatever.txt"), // virtual path 625 kOutputFilePath, 626 "file:2_file_resource_id", 627 ClientContext(BACKGROUND), 628 google_apis::test_util::CreateCopyResultCallback( 629 &download_error, &output_file_path), 630 google_apis::GetContentCallback()); 631 // Metadata should still work 632 google_apis::GDataErrorCode metadata_error = google_apis::GDATA_OTHER_ERROR; 633 scoped_ptr<google_apis::AboutResource> about_resource; 634 635 // Try to get the metadata 636 scheduler_->GetAboutResource( 637 google_apis::test_util::CreateCopyResultCallback( 638 &metadata_error, &about_resource)); 639 base::RunLoop().RunUntilIdle(); 640 641 // Check the metadata 642 ASSERT_EQ(google_apis::HTTP_SUCCESS, metadata_error); 643 ASSERT_TRUE(about_resource); 644 645 // Check the download 646 EXPECT_EQ(google_apis::HTTP_SUCCESS, download_error); 647 std::string content; 648 EXPECT_EQ(output_file_path, kOutputFilePath); 649 ASSERT_TRUE(file_util::ReadFileToString(output_file_path, &content)); 650 EXPECT_EQ("This is some test content.", content); 651} 652 653TEST_F(JobSchedulerTest, DownloadFileWimaxEnabled) { 654 ConnectToWimax(); 655 656 // Enable fetching over cellular network. 657 profile_->GetPrefs()->SetBoolean(prefs::kDisableDriveOverCellular, false); 658 659 // Try to get a file in the background 660 base::ScopedTempDir temp_dir; 661 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 662 663 const base::FilePath kOutputFilePath = 664 temp_dir.path().AppendASCII("whatever.txt"); 665 google_apis::GDataErrorCode download_error = google_apis::GDATA_OTHER_ERROR; 666 base::FilePath output_file_path; 667 scheduler_->DownloadFile( 668 base::FilePath::FromUTF8Unsafe("drive/whatever.txt"), // virtual path 669 kOutputFilePath, 670 "file:2_file_resource_id", 671 ClientContext(BACKGROUND), 672 google_apis::test_util::CreateCopyResultCallback( 673 &download_error, &output_file_path), 674 google_apis::GetContentCallback()); 675 // Metadata should still work 676 google_apis::GDataErrorCode metadata_error = google_apis::GDATA_OTHER_ERROR; 677 scoped_ptr<google_apis::AboutResource> about_resource; 678 679 // Try to get the metadata 680 scheduler_->GetAboutResource( 681 google_apis::test_util::CreateCopyResultCallback( 682 &metadata_error, &about_resource)); 683 base::RunLoop().RunUntilIdle(); 684 685 // Check the metadata 686 ASSERT_EQ(google_apis::HTTP_SUCCESS, metadata_error); 687 ASSERT_TRUE(about_resource); 688 689 // Check the download 690 EXPECT_EQ(google_apis::HTTP_SUCCESS, download_error); 691 std::string content; 692 EXPECT_EQ(output_file_path, kOutputFilePath); 693 ASSERT_TRUE(file_util::ReadFileToString(output_file_path, &content)); 694 EXPECT_EQ("This is some test content.", content); 695} 696 697TEST_F(JobSchedulerTest, JobInfo) { 698 JobListLogger logger; 699 scheduler_->AddObserver(&logger); 700 701 // Disable background upload/download. 702 ConnectToWimax(); 703 profile_->GetPrefs()->SetBoolean(prefs::kDisableDriveOverCellular, true); 704 705 base::ScopedTempDir temp_dir; 706 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 707 708 google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR; 709 scoped_ptr<google_apis::ResourceEntry> entry; 710 scoped_ptr<google_apis::AboutResource> about_resource; 711 base::FilePath path; 712 713 std::set<JobType> expected_types; 714 715 // Add many jobs. 716 expected_types.insert(TYPE_ADD_NEW_DIRECTORY); 717 scheduler_->AddNewDirectory( 718 fake_drive_service_->GetRootResourceId(), 719 "New Directory", 720 google_apis::test_util::CreateCopyResultCallback(&error, &entry)); 721 expected_types.insert(TYPE_GET_ABOUT_RESOURCE); 722 scheduler_->GetAboutResource( 723 google_apis::test_util::CreateCopyResultCallback( 724 &error, &about_resource)); 725 expected_types.insert(TYPE_RENAME_RESOURCE); 726 scheduler_->RenameResource( 727 "file:2_file_resource_id", 728 "New Name", 729 google_apis::test_util::CreateCopyResultCallback(&error)); 730 expected_types.insert(TYPE_DOWNLOAD_FILE); 731 scheduler_->DownloadFile( 732 base::FilePath::FromUTF8Unsafe("drive/whatever.txt"), // virtual path 733 temp_dir.path().AppendASCII("whatever.txt"), 734 "file:2_file_resource_id", 735 ClientContext(BACKGROUND), 736 google_apis::test_util::CreateCopyResultCallback(&error, &path), 737 google_apis::GetContentCallback()); 738 739 // The number of jobs queued so far. 740 EXPECT_EQ(4U, scheduler_->GetJobInfoList().size()); 741 EXPECT_TRUE(logger.Has(JobListLogger::ADDED, TYPE_ADD_NEW_DIRECTORY)); 742 EXPECT_TRUE(logger.Has(JobListLogger::ADDED, TYPE_GET_ABOUT_RESOURCE)); 743 EXPECT_TRUE(logger.Has(JobListLogger::ADDED, TYPE_RENAME_RESOURCE)); 744 EXPECT_TRUE(logger.Has(JobListLogger::ADDED, TYPE_DOWNLOAD_FILE)); 745 EXPECT_FALSE(logger.Has(JobListLogger::DONE, TYPE_ADD_NEW_DIRECTORY)); 746 EXPECT_FALSE(logger.Has(JobListLogger::DONE, TYPE_GET_ABOUT_RESOURCE)); 747 EXPECT_FALSE(logger.Has(JobListLogger::DONE, TYPE_RENAME_RESOURCE)); 748 EXPECT_FALSE(logger.Has(JobListLogger::DONE, TYPE_DOWNLOAD_FILE)); 749 750 // Add more jobs. 751 expected_types.insert(TYPE_ADD_RESOURCE_TO_DIRECTORY); 752 scheduler_->AddResourceToDirectory( 753 "folder:1_folder_resource_id", 754 "file:2_file_resource_id", 755 google_apis::test_util::CreateCopyResultCallback(&error)); 756 expected_types.insert(TYPE_COPY_HOSTED_DOCUMENT); 757 scheduler_->CopyHostedDocument( 758 "document:5_document_resource_id", 759 "New Document", 760 google_apis::test_util::CreateCopyResultCallback(&error, &entry)); 761 762 // 6 jobs in total were queued. 763 std::vector<JobInfo> jobs = scheduler_->GetJobInfoList(); 764 EXPECT_EQ(6U, jobs.size()); 765 std::set<JobType> actual_types; 766 std::set<JobID> job_ids; 767 for (size_t i = 0; i < jobs.size(); ++i) { 768 actual_types.insert(jobs[i].job_type); 769 job_ids.insert(jobs[i].job_id); 770 } 771 EXPECT_EQ(expected_types, actual_types); 772 EXPECT_EQ(6U, job_ids.size()) << "All job IDs must be unique"; 773 EXPECT_TRUE(logger.Has(JobListLogger::ADDED, TYPE_ADD_RESOURCE_TO_DIRECTORY)); 774 EXPECT_TRUE(logger.Has(JobListLogger::ADDED, TYPE_COPY_HOSTED_DOCUMENT)); 775 EXPECT_FALSE(logger.Has(JobListLogger::DONE, TYPE_ADD_RESOURCE_TO_DIRECTORY)); 776 EXPECT_FALSE(logger.Has(JobListLogger::DONE, TYPE_COPY_HOSTED_DOCUMENT)); 777 778 // Run the jobs. 779 base::RunLoop().RunUntilIdle(); 780 781 // All jobs except the BACKGROUND job should have started running (UPDATED) 782 // and then finished (DONE). 783 jobs = scheduler_->GetJobInfoList(); 784 ASSERT_EQ(1U, jobs.size()); 785 EXPECT_EQ(TYPE_DOWNLOAD_FILE, jobs[0].job_type); 786 787 EXPECT_TRUE(logger.Has(JobListLogger::UPDATED, TYPE_ADD_NEW_DIRECTORY)); 788 EXPECT_TRUE(logger.Has(JobListLogger::UPDATED, TYPE_GET_ABOUT_RESOURCE)); 789 EXPECT_TRUE(logger.Has(JobListLogger::UPDATED, TYPE_RENAME_RESOURCE)); 790 EXPECT_TRUE(logger.Has(JobListLogger::UPDATED, 791 TYPE_ADD_RESOURCE_TO_DIRECTORY)); 792 EXPECT_TRUE(logger.Has(JobListLogger::UPDATED, TYPE_COPY_HOSTED_DOCUMENT)); 793 EXPECT_FALSE(logger.Has(JobListLogger::UPDATED, TYPE_DOWNLOAD_FILE)); 794 795 EXPECT_TRUE(logger.Has(JobListLogger::DONE, TYPE_ADD_NEW_DIRECTORY)); 796 EXPECT_TRUE(logger.Has(JobListLogger::DONE, TYPE_GET_ABOUT_RESOURCE)); 797 EXPECT_TRUE(logger.Has(JobListLogger::DONE, TYPE_RENAME_RESOURCE)); 798 EXPECT_TRUE(logger.Has(JobListLogger::DONE, TYPE_ADD_RESOURCE_TO_DIRECTORY)); 799 EXPECT_TRUE(logger.Has(JobListLogger::DONE, TYPE_COPY_HOSTED_DOCUMENT)); 800 EXPECT_FALSE(logger.Has(JobListLogger::DONE, TYPE_DOWNLOAD_FILE)); 801 802 // Run the background downloading job as well. 803 ConnectToWifi(); 804 base::RunLoop().RunUntilIdle(); 805 806 // All jobs should have finished. 807 EXPECT_EQ(0U, scheduler_->GetJobInfoList().size()); 808 EXPECT_TRUE(logger.Has(JobListLogger::UPDATED, TYPE_DOWNLOAD_FILE)); 809 EXPECT_TRUE(logger.Has(JobListLogger::DONE, TYPE_DOWNLOAD_FILE)); 810} 811 812 813TEST_F(JobSchedulerTest, JobInfoProgress) { 814 JobListLogger logger; 815 scheduler_->AddObserver(&logger); 816 817 ConnectToWifi(); 818 819 base::ScopedTempDir temp_dir; 820 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 821 822 google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR; 823 base::FilePath path; 824 825 // Download job. 826 scheduler_->DownloadFile( 827 base::FilePath::FromUTF8Unsafe("drive/whatever.txt"), // virtual path 828 temp_dir.path().AppendASCII("whatever.txt"), 829 "file:2_file_resource_id", 830 ClientContext(BACKGROUND), 831 google_apis::test_util::CreateCopyResultCallback(&error, &path), 832 google_apis::GetContentCallback()); 833 base::RunLoop().RunUntilIdle(); 834 835 std::vector<int64> download_progress; 836 logger.GetProgressInfo(TYPE_DOWNLOAD_FILE, &download_progress); 837 ASSERT_TRUE(!download_progress.empty()); 838 EXPECT_TRUE(base::STLIsSorted(download_progress)); 839 EXPECT_GE(download_progress.front(), 0); 840 EXPECT_LE(download_progress.back(), 26); 841 842 // Upload job. 843 path = temp_dir.path().AppendASCII("new_file.txt"); 844 ASSERT_TRUE(google_apis::test_util::WriteStringToFile(path, "Hello")); 845 google_apis::GDataErrorCode upload_error = 846 google_apis::GDATA_OTHER_ERROR; 847 scoped_ptr<google_apis::ResourceEntry> entry; 848 849 scheduler_->UploadNewFile( 850 fake_drive_service_->GetRootResourceId(), 851 base::FilePath::FromUTF8Unsafe("drive/new_file.txt"), 852 path, 853 "dummy title", 854 "plain/plain", 855 ClientContext(BACKGROUND), 856 google_apis::test_util::CreateCopyResultCallback(&upload_error, &entry)); 857 base::RunLoop().RunUntilIdle(); 858 859 std::vector<int64> upload_progress; 860 logger.GetProgressInfo(TYPE_UPLOAD_NEW_FILE, &upload_progress); 861 ASSERT_TRUE(!upload_progress.empty()); 862 EXPECT_TRUE(base::STLIsSorted(upload_progress)); 863 EXPECT_GE(upload_progress.front(), 0); 864 EXPECT_LE(upload_progress.back(), 13); 865} 866 867} // namespace drive 868