job_scheduler_unittest.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
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/files/scoped_temp_dir.h" 12#include "base/prefs/testing_pref_service.h" 13#include "base/run_loop.h" 14#include "base/stl_util.h" 15#include "base/strings/stringprintf.h" 16#include "chrome/browser/chromeos/drive/test_util.h" 17#include "chrome/browser/drive/event_logger.h" 18#include "chrome/browser/drive/fake_drive_service.h" 19#include "chrome/common/pref_names.h" 20#include "content/public/test/test_browser_thread_bundle.h" 21#include "google_apis/drive/drive_api_parser.h" 22#include "google_apis/drive/gdata_wapi_parser.h" 23#include "google_apis/drive/test_util.h" 24#include "testing/gtest/include/gtest/gtest.h" 25 26namespace drive { 27 28namespace { 29 30// Dummy value passed for the |expected_file_size| parameter of DownloadFile(). 31const int64 kDummyDownloadFileSize = 0; 32 33void CopyTitleFromGetResourceEntryCallback( 34 std::vector<std::string>* title_list_out, 35 google_apis::GDataErrorCode error_in, 36 scoped_ptr<google_apis::ResourceEntry> resource_entry_in) { 37 title_list_out->push_back(resource_entry_in->title()); 38} 39 40class JobListLogger : public JobListObserver { 41 public: 42 enum EventType { 43 ADDED, 44 UPDATED, 45 DONE, 46 }; 47 48 struct EventLog { 49 EventType type; 50 JobInfo info; 51 52 EventLog(EventType type, const JobInfo& info) : type(type), info(info) { 53 } 54 }; 55 56 // Checks whether the specified type of event has occurred. 57 bool Has(EventType type, JobType job_type) { 58 for (size_t i = 0; i < events.size(); ++i) { 59 if (events[i].type == type && events[i].info.job_type == job_type) 60 return true; 61 } 62 return false; 63 } 64 65 // Gets the progress event information of the specified type. 66 void GetProgressInfo(JobType job_type, std::vector<int64>* progress) { 67 for (size_t i = 0; i < events.size(); ++i) { 68 if (events[i].type == UPDATED && events[i].info.job_type == job_type) 69 progress->push_back(events[i].info.num_completed_bytes); 70 } 71 } 72 73 // JobListObserver overrides. 74 virtual void OnJobAdded(const JobInfo& info) OVERRIDE { 75 events.push_back(EventLog(ADDED, info)); 76 } 77 78 virtual void OnJobUpdated(const JobInfo& info) OVERRIDE { 79 events.push_back(EventLog(UPDATED, info)); 80 } 81 82 virtual void OnJobDone(const JobInfo& info, FileError error) OVERRIDE { 83 events.push_back(EventLog(DONE, info)); 84 } 85 86 private: 87 std::vector<EventLog> events; 88}; 89 90// Fake drive service extended for testing cancellation. 91// When upload_new_file_cancelable is set, this Drive service starts 92// returning a closure to cancel from InitiateUploadNewFile(). The task will 93// finish only when the cancel closure is called. 94class CancelTestableFakeDriveService : public FakeDriveService { 95 public: 96 CancelTestableFakeDriveService() 97 : upload_new_file_cancelable_(false) { 98 } 99 100 void set_upload_new_file_cancelable(bool cancelable) { 101 upload_new_file_cancelable_ = cancelable; 102 } 103 104 virtual google_apis::CancelCallback InitiateUploadNewFile( 105 const std::string& content_type, 106 int64 content_length, 107 const std::string& parent_resource_id, 108 const std::string& title, 109 const InitiateUploadNewFileOptions& options, 110 const google_apis::InitiateUploadCallback& callback) OVERRIDE { 111 if (upload_new_file_cancelable_) 112 return base::Bind(callback, google_apis::GDATA_CANCELLED, GURL()); 113 114 return FakeDriveService::InitiateUploadNewFile(content_type, 115 content_length, 116 parent_resource_id, 117 title, 118 options, 119 callback); 120 } 121 122 private: 123 bool upload_new_file_cancelable_; 124}; 125 126} // namespace 127 128class JobSchedulerTest : public testing::Test { 129 public: 130 JobSchedulerTest() 131 : pref_service_(new TestingPrefServiceSimple) { 132 test_util::RegisterDrivePrefs(pref_service_->registry()); 133 } 134 135 virtual void SetUp() OVERRIDE { 136 fake_network_change_notifier_.reset( 137 new test_util::FakeNetworkChangeNotifier); 138 139 logger_.reset(new EventLogger); 140 141 fake_drive_service_.reset(new CancelTestableFakeDriveService); 142 fake_drive_service_->LoadResourceListForWapi( 143 "gdata/root_feed.json"); 144 fake_drive_service_->LoadAccountMetadataForWapi( 145 "gdata/account_metadata.json"); 146 fake_drive_service_->LoadAppListForDriveApi( 147 "drive/applist.json"); 148 149 scheduler_.reset(new JobScheduler(pref_service_.get(), 150 logger_.get(), 151 fake_drive_service_.get(), 152 base::MessageLoopProxy::current().get())); 153 scheduler_->SetDisableThrottling(true); 154 } 155 156 protected: 157 // Sets up FakeNetworkChangeNotifier as if it's connected to a network with 158 // the specified connection type. 159 void ChangeConnectionType(net::NetworkChangeNotifier::ConnectionType type) { 160 fake_network_change_notifier_->SetConnectionType(type); 161 } 162 163 // Sets up FakeNetworkChangeNotifier as if it's connected to wifi network. 164 void ConnectToWifi() { 165 ChangeConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI); 166 } 167 168 // Sets up FakeNetworkChangeNotifier as if it's connected to cellular network. 169 void ConnectToCellular() { 170 ChangeConnectionType(net::NetworkChangeNotifier::CONNECTION_2G); 171 } 172 173 // Sets up FakeNetworkChangeNotifier as if it's connected to wimax network. 174 void ConnectToWimax() { 175 ChangeConnectionType(net::NetworkChangeNotifier::CONNECTION_4G); 176 } 177 178 // Sets up FakeNetworkChangeNotifier as if it's disconnected. 179 void ConnectToNone() { 180 ChangeConnectionType(net::NetworkChangeNotifier::CONNECTION_NONE); 181 } 182 183 static int GetMetadataQueueMaxJobCount() { 184 return JobScheduler::kMaxJobCount[JobScheduler::METADATA_QUEUE]; 185 } 186 187 content::TestBrowserThreadBundle thread_bundle_; 188 scoped_ptr<TestingPrefServiceSimple> pref_service_; 189 scoped_ptr<test_util::FakeNetworkChangeNotifier> 190 fake_network_change_notifier_; 191 scoped_ptr<EventLogger> logger_; 192 scoped_ptr<CancelTestableFakeDriveService> fake_drive_service_; 193 scoped_ptr<JobScheduler> scheduler_; 194}; 195 196TEST_F(JobSchedulerTest, GetAboutResource) { 197 ConnectToWifi(); 198 199 google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR; 200 scoped_ptr<google_apis::AboutResource> about_resource; 201 scheduler_->GetAboutResource( 202 google_apis::test_util::CreateCopyResultCallback( 203 &error, &about_resource)); 204 base::RunLoop().RunUntilIdle(); 205 ASSERT_EQ(google_apis::HTTP_SUCCESS, error); 206 ASSERT_TRUE(about_resource); 207} 208 209TEST_F(JobSchedulerTest, GetAppList) { 210 ConnectToWifi(); 211 212 google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR; 213 scoped_ptr<google_apis::AppList> app_list; 214 215 scheduler_->GetAppList( 216 google_apis::test_util::CreateCopyResultCallback(&error, &app_list)); 217 base::RunLoop().RunUntilIdle(); 218 219 ASSERT_EQ(google_apis::HTTP_SUCCESS, error); 220 ASSERT_TRUE(app_list); 221} 222 223TEST_F(JobSchedulerTest, GetAllResourceList) { 224 ConnectToWifi(); 225 226 google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR; 227 scoped_ptr<google_apis::ResourceList> resource_list; 228 229 scheduler_->GetAllResourceList( 230 google_apis::test_util::CreateCopyResultCallback( 231 &error, &resource_list)); 232 base::RunLoop().RunUntilIdle(); 233 234 ASSERT_EQ(google_apis::HTTP_SUCCESS, error); 235 ASSERT_TRUE(resource_list); 236} 237 238TEST_F(JobSchedulerTest, GetResourceListInDirectory) { 239 ConnectToWifi(); 240 241 google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR; 242 scoped_ptr<google_apis::ResourceList> resource_list; 243 244 scheduler_->GetResourceListInDirectory( 245 fake_drive_service_->GetRootResourceId(), 246 google_apis::test_util::CreateCopyResultCallback( 247 &error, &resource_list)); 248 base::RunLoop().RunUntilIdle(); 249 250 ASSERT_EQ(google_apis::HTTP_SUCCESS, error); 251 ASSERT_TRUE(resource_list); 252} 253 254TEST_F(JobSchedulerTest, Search) { 255 ConnectToWifi(); 256 257 google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR; 258 scoped_ptr<google_apis::ResourceList> resource_list; 259 260 scheduler_->Search( 261 "File", // search query 262 google_apis::test_util::CreateCopyResultCallback( 263 &error, &resource_list)); 264 base::RunLoop().RunUntilIdle(); 265 266 ASSERT_EQ(google_apis::HTTP_SUCCESS, error); 267 ASSERT_TRUE(resource_list); 268} 269 270TEST_F(JobSchedulerTest, GetChangeList) { 271 ConnectToWifi(); 272 273 google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR; 274 275 // Create a new directory. 276 // The loaded (initial) changestamp is 654321. Thus, by this operation, 277 // it should become 654322. 278 { 279 scoped_ptr<google_apis::ResourceEntry> resource_entry; 280 fake_drive_service_->AddNewDirectory( 281 fake_drive_service_->GetRootResourceId(), 282 "new directory", 283 DriveServiceInterface::AddNewDirectoryOptions(), 284 google_apis::test_util::CreateCopyResultCallback( 285 &error, &resource_entry)); 286 base::RunLoop().RunUntilIdle(); 287 ASSERT_EQ(google_apis::HTTP_CREATED, error); 288 } 289 290 error = google_apis::GDATA_OTHER_ERROR; 291 scoped_ptr<google_apis::ResourceList> resource_list; 292 scheduler_->GetChangeList( 293 654321 + 1, // start_changestamp 294 google_apis::test_util::CreateCopyResultCallback( 295 &error, &resource_list)); 296 base::RunLoop().RunUntilIdle(); 297 298 ASSERT_EQ(google_apis::HTTP_SUCCESS, error); 299 ASSERT_TRUE(resource_list); 300} 301 302TEST_F(JobSchedulerTest, GetRemainingChangeList) { 303 ConnectToWifi(); 304 fake_drive_service_->set_default_max_results(2); 305 306 google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR; 307 scoped_ptr<google_apis::ResourceList> resource_list; 308 309 scheduler_->GetAllResourceList( 310 google_apis::test_util::CreateCopyResultCallback( 311 &error, &resource_list)); 312 base::RunLoop().RunUntilIdle(); 313 314 ASSERT_EQ(google_apis::HTTP_SUCCESS, error); 315 ASSERT_TRUE(resource_list); 316 317 const google_apis::Link* next_link = 318 resource_list->GetLinkByType(google_apis::Link::LINK_NEXT); 319 ASSERT_TRUE(next_link); 320 // Keep the next url before releasing the |resource_list|. 321 GURL next_url(next_link->href()); 322 323 error = google_apis::GDATA_OTHER_ERROR; 324 resource_list.reset(); 325 326 scheduler_->GetRemainingChangeList( 327 next_url, 328 google_apis::test_util::CreateCopyResultCallback( 329 &error, &resource_list)); 330 base::RunLoop().RunUntilIdle(); 331 332 ASSERT_EQ(google_apis::HTTP_SUCCESS, error); 333 ASSERT_TRUE(resource_list); 334} 335 336TEST_F(JobSchedulerTest, GetRemainingFileList) { 337 ConnectToWifi(); 338 fake_drive_service_->set_default_max_results(2); 339 340 google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR; 341 scoped_ptr<google_apis::ResourceList> resource_list; 342 343 scheduler_->GetResourceListInDirectory( 344 fake_drive_service_->GetRootResourceId(), 345 google_apis::test_util::CreateCopyResultCallback( 346 &error, &resource_list)); 347 base::RunLoop().RunUntilIdle(); 348 349 ASSERT_EQ(google_apis::HTTP_SUCCESS, error); 350 ASSERT_TRUE(resource_list); 351 352 const google_apis::Link* next_link = 353 resource_list->GetLinkByType(google_apis::Link::LINK_NEXT); 354 ASSERT_TRUE(next_link); 355 // Keep the next url before releasing the |resource_list|. 356 GURL next_url(next_link->href()); 357 358 error = google_apis::GDATA_OTHER_ERROR; 359 resource_list.reset(); 360 361 scheduler_->GetRemainingFileList( 362 next_url, 363 google_apis::test_util::CreateCopyResultCallback( 364 &error, &resource_list)); 365 base::RunLoop().RunUntilIdle(); 366 367 ASSERT_EQ(google_apis::HTTP_SUCCESS, error); 368 ASSERT_TRUE(resource_list); 369} 370 371TEST_F(JobSchedulerTest, GetResourceEntry) { 372 ConnectToWifi(); 373 374 google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR; 375 scoped_ptr<google_apis::ResourceEntry> entry; 376 377 scheduler_->GetResourceEntry( 378 "file:2_file_resource_id", // resource ID 379 ClientContext(USER_INITIATED), 380 google_apis::test_util::CreateCopyResultCallback(&error, &entry)); 381 base::RunLoop().RunUntilIdle(); 382 383 ASSERT_EQ(google_apis::HTTP_SUCCESS, error); 384 ASSERT_TRUE(entry); 385} 386 387TEST_F(JobSchedulerTest, GetShareUrl) { 388 ConnectToWifi(); 389 390 google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR; 391 GURL share_url; 392 393 scheduler_->GetShareUrl( 394 "file:2_file_resource_id", // resource ID 395 GURL("chrome-extension://test-id/"), // embed origin 396 ClientContext(USER_INITIATED), 397 google_apis::test_util::CreateCopyResultCallback(&error, &share_url)); 398 base::RunLoop().RunUntilIdle(); 399 400 ASSERT_EQ(google_apis::HTTP_SUCCESS, error); 401 ASSERT_FALSE(share_url.is_empty()); 402} 403 404TEST_F(JobSchedulerTest, TrashResource) { 405 ConnectToWifi(); 406 407 google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR; 408 409 scheduler_->TrashResource( 410 "file:2_file_resource_id", 411 ClientContext(USER_INITIATED), 412 google_apis::test_util::CreateCopyResultCallback(&error)); 413 base::RunLoop().RunUntilIdle(); 414 415 ASSERT_EQ(google_apis::HTTP_SUCCESS, error); 416} 417 418TEST_F(JobSchedulerTest, CopyResource) { 419 ConnectToWifi(); 420 421 google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR; 422 scoped_ptr<google_apis::ResourceEntry> entry; 423 424 scheduler_->CopyResource( 425 "file:2_file_resource_id", // resource ID 426 "folder:1_folder_resource_id", // parent resource ID 427 "New Document", // new title 428 base::Time(), 429 google_apis::test_util::CreateCopyResultCallback(&error, &entry)); 430 base::RunLoop().RunUntilIdle(); 431 432 ASSERT_EQ(google_apis::HTTP_SUCCESS, error); 433 ASSERT_TRUE(entry); 434} 435 436TEST_F(JobSchedulerTest, UpdateResource) { 437 ConnectToWifi(); 438 439 google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR; 440 scoped_ptr<google_apis::ResourceEntry> entry; 441 442 scheduler_->UpdateResource( 443 "file:2_file_resource_id", // resource ID 444 "folder:1_folder_resource_id", // parent resource ID 445 "New Document", // new title 446 base::Time(), 447 base::Time(), 448 ClientContext(USER_INITIATED), 449 google_apis::test_util::CreateCopyResultCallback(&error, &entry)); 450 base::RunLoop().RunUntilIdle(); 451 452 ASSERT_EQ(google_apis::HTTP_SUCCESS, error); 453 ASSERT_TRUE(entry); 454} 455 456TEST_F(JobSchedulerTest, RenameResource) { 457 ConnectToWifi(); 458 459 google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR; 460 461 scheduler_->RenameResource( 462 "file:2_file_resource_id", 463 "New Title", 464 google_apis::test_util::CreateCopyResultCallback(&error)); 465 base::RunLoop().RunUntilIdle(); 466 467 ASSERT_EQ(google_apis::HTTP_SUCCESS, error); 468} 469 470TEST_F(JobSchedulerTest, AddResourceToDirectory) { 471 ConnectToWifi(); 472 473 google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR; 474 475 scheduler_->AddResourceToDirectory( 476 "folder:1_folder_resource_id", 477 "file:2_file_resource_id", 478 google_apis::test_util::CreateCopyResultCallback(&error)); 479 base::RunLoop().RunUntilIdle(); 480 481 ASSERT_EQ(google_apis::HTTP_SUCCESS, error); 482} 483 484TEST_F(JobSchedulerTest, RemoveResourceFromDirectory) { 485 ConnectToWifi(); 486 487 google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR; 488 489 scheduler_->RemoveResourceFromDirectory( 490 "folder:1_folder_resource_id", 491 "file:subdirectory_file_1_id", // resource ID 492 ClientContext(USER_INITIATED), 493 google_apis::test_util::CreateCopyResultCallback(&error)); 494 base::RunLoop().RunUntilIdle(); 495 496 ASSERT_EQ(google_apis::HTTP_NO_CONTENT, error); 497} 498 499TEST_F(JobSchedulerTest, AddNewDirectory) { 500 ConnectToWifi(); 501 502 google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR; 503 scoped_ptr<google_apis::ResourceEntry> entry; 504 505 scheduler_->AddNewDirectory( 506 fake_drive_service_->GetRootResourceId(), // Root directory. 507 "New Directory", 508 DriveServiceInterface::AddNewDirectoryOptions(), 509 ClientContext(USER_INITIATED), 510 google_apis::test_util::CreateCopyResultCallback(&error, &entry)); 511 base::RunLoop().RunUntilIdle(); 512 513 ASSERT_EQ(google_apis::HTTP_CREATED, error); 514 ASSERT_TRUE(entry); 515} 516 517TEST_F(JobSchedulerTest, PriorityHandling) { 518 // Saturate the metadata job queue with uninteresting jobs to prevent 519 // following jobs from starting. 520 google_apis::GDataErrorCode error_dontcare = google_apis::GDATA_OTHER_ERROR; 521 scoped_ptr<google_apis::ResourceEntry> entry_dontcare; 522 for (int i = 0; i < GetMetadataQueueMaxJobCount(); ++i) { 523 std::string resource_id("file:2_file_resource_id"); 524 scheduler_->GetResourceEntry( 525 resource_id, 526 ClientContext(USER_INITIATED), 527 google_apis::test_util::CreateCopyResultCallback(&error_dontcare, 528 &entry_dontcare)); 529 } 530 531 // Start jobs with different priorities. 532 std::string title_1("new file 1"); 533 std::string title_2("new file 2"); 534 std::string title_3("new file 3"); 535 std::string title_4("new file 4"); 536 std::vector<std::string> titles; 537 538 scheduler_->AddNewDirectory( 539 fake_drive_service_->GetRootResourceId(), 540 title_1, 541 DriveServiceInterface::AddNewDirectoryOptions(), 542 ClientContext(USER_INITIATED), 543 base::Bind(&CopyTitleFromGetResourceEntryCallback, &titles)); 544 scheduler_->AddNewDirectory( 545 fake_drive_service_->GetRootResourceId(), 546 title_2, 547 DriveServiceInterface::AddNewDirectoryOptions(), 548 ClientContext(BACKGROUND), 549 base::Bind(&CopyTitleFromGetResourceEntryCallback, &titles)); 550 scheduler_->AddNewDirectory( 551 fake_drive_service_->GetRootResourceId(), 552 title_3, 553 DriveServiceInterface::AddNewDirectoryOptions(), 554 ClientContext(BACKGROUND), 555 base::Bind(&CopyTitleFromGetResourceEntryCallback, &titles)); 556 scheduler_->AddNewDirectory( 557 fake_drive_service_->GetRootResourceId(), 558 title_4, 559 DriveServiceInterface::AddNewDirectoryOptions(), 560 ClientContext(USER_INITIATED), 561 base::Bind(&CopyTitleFromGetResourceEntryCallback, &titles)); 562 563 base::RunLoop().RunUntilIdle(); 564 565 ASSERT_EQ(4ul, titles.size()); 566 EXPECT_EQ(title_1, titles[0]); 567 EXPECT_EQ(title_4, titles[1]); 568 EXPECT_EQ(title_2, titles[2]); 569 EXPECT_EQ(title_3, titles[3]); 570} 571 572TEST_F(JobSchedulerTest, NoConnectionUserInitiated) { 573 ConnectToNone(); 574 575 std::string resource_id("file:2_file_resource_id"); 576 577 google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR; 578 scoped_ptr<google_apis::ResourceEntry> entry; 579 scheduler_->GetResourceEntry( 580 resource_id, 581 ClientContext(USER_INITIATED), 582 google_apis::test_util::CreateCopyResultCallback(&error, &entry)); 583 base::RunLoop().RunUntilIdle(); 584 585 EXPECT_EQ(google_apis::GDATA_NO_CONNECTION, error); 586} 587 588TEST_F(JobSchedulerTest, NoConnectionBackground) { 589 ConnectToNone(); 590 591 std::string resource_id("file:2_file_resource_id"); 592 593 google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR; 594 scoped_ptr<google_apis::ResourceEntry> entry; 595 scheduler_->GetResourceEntry( 596 resource_id, 597 ClientContext(BACKGROUND), 598 google_apis::test_util::CreateCopyResultCallback(&error, &entry)); 599 base::RunLoop().RunUntilIdle(); 600 601 EXPECT_FALSE(entry); 602 603 // Reconnect to the net. 604 ConnectToWifi(); 605 606 base::RunLoop().RunUntilIdle(); 607 608 EXPECT_EQ(google_apis::HTTP_SUCCESS, error); 609 ASSERT_TRUE(entry); 610} 611 612TEST_F(JobSchedulerTest, DownloadFileCellularDisabled) { 613 ConnectToCellular(); 614 615 // Disable fetching over cellular network. 616 pref_service_->SetBoolean(prefs::kDisableDriveOverCellular, true); 617 618 // Try to get a file in the background 619 base::ScopedTempDir temp_dir; 620 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 621 622 const base::FilePath kOutputFilePath = 623 temp_dir.path().AppendASCII("whatever.txt"); 624 google_apis::GDataErrorCode download_error = google_apis::GDATA_OTHER_ERROR; 625 base::FilePath output_file_path; 626 scheduler_->DownloadFile( 627 base::FilePath::FromUTF8Unsafe("drive/whatever.txt"), // virtual path 628 kDummyDownloadFileSize, 629 kOutputFilePath, 630 "file:2_file_resource_id", 631 ClientContext(BACKGROUND), 632 google_apis::test_util::CreateCopyResultCallback( 633 &download_error, &output_file_path), 634 google_apis::GetContentCallback()); 635 // Metadata should still work 636 google_apis::GDataErrorCode metadata_error = google_apis::GDATA_OTHER_ERROR; 637 scoped_ptr<google_apis::AboutResource> about_resource; 638 639 // Try to get the metadata 640 scheduler_->GetAboutResource( 641 google_apis::test_util::CreateCopyResultCallback( 642 &metadata_error, &about_resource)); 643 base::RunLoop().RunUntilIdle(); 644 645 // Check the metadata 646 ASSERT_EQ(google_apis::HTTP_SUCCESS, metadata_error); 647 ASSERT_TRUE(about_resource); 648 649 // Check the download 650 EXPECT_EQ(google_apis::GDATA_OTHER_ERROR, download_error); 651 652 // Switch to a Wifi connection 653 ConnectToWifi(); 654 655 base::RunLoop().RunUntilIdle(); 656 657 // Check the download again 658 EXPECT_EQ(google_apis::HTTP_SUCCESS, download_error); 659 std::string content; 660 EXPECT_EQ(output_file_path, kOutputFilePath); 661 ASSERT_TRUE(base::ReadFileToString(output_file_path, &content)); 662 EXPECT_EQ("This is some test content.", content); 663} 664 665TEST_F(JobSchedulerTest, DownloadFileWimaxDisabled) { 666 ConnectToWimax(); 667 668 // Disable fetching over cellular network. 669 pref_service_->SetBoolean(prefs::kDisableDriveOverCellular, true); 670 671 // Try to get a file in the background 672 base::ScopedTempDir temp_dir; 673 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 674 675 const base::FilePath kOutputFilePath = 676 temp_dir.path().AppendASCII("whatever.txt"); 677 google_apis::GDataErrorCode download_error = google_apis::GDATA_OTHER_ERROR; 678 base::FilePath output_file_path; 679 scheduler_->DownloadFile( 680 base::FilePath::FromUTF8Unsafe("drive/whatever.txt"), // virtual path 681 kDummyDownloadFileSize, 682 kOutputFilePath, 683 "file:2_file_resource_id", 684 ClientContext(BACKGROUND), 685 google_apis::test_util::CreateCopyResultCallback( 686 &download_error, &output_file_path), 687 google_apis::GetContentCallback()); 688 // Metadata should still work 689 google_apis::GDataErrorCode metadata_error = google_apis::GDATA_OTHER_ERROR; 690 scoped_ptr<google_apis::AboutResource> about_resource; 691 692 // Try to get the metadata 693 scheduler_->GetAboutResource( 694 google_apis::test_util::CreateCopyResultCallback( 695 &metadata_error, &about_resource)); 696 base::RunLoop().RunUntilIdle(); 697 698 // Check the metadata 699 ASSERT_EQ(google_apis::HTTP_SUCCESS, metadata_error); 700 ASSERT_TRUE(about_resource); 701 702 // Check the download 703 EXPECT_EQ(google_apis::GDATA_OTHER_ERROR, download_error); 704 705 // Switch to a Wifi connection 706 ConnectToWifi(); 707 708 base::RunLoop().RunUntilIdle(); 709 710 // Check the download again 711 EXPECT_EQ(google_apis::HTTP_SUCCESS, download_error); 712 std::string content; 713 EXPECT_EQ(output_file_path, kOutputFilePath); 714 ASSERT_TRUE(base::ReadFileToString(output_file_path, &content)); 715 EXPECT_EQ("This is some test content.", content); 716} 717 718TEST_F(JobSchedulerTest, DownloadFileCellularEnabled) { 719 ConnectToCellular(); 720 721 // Enable fetching over cellular network. 722 pref_service_->SetBoolean(prefs::kDisableDriveOverCellular, false); 723 724 // Try to get a file in the background 725 base::ScopedTempDir temp_dir; 726 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 727 728 const base::FilePath kOutputFilePath = 729 temp_dir.path().AppendASCII("whatever.txt"); 730 google_apis::GDataErrorCode download_error = google_apis::GDATA_OTHER_ERROR; 731 base::FilePath output_file_path; 732 scheduler_->DownloadFile( 733 base::FilePath::FromUTF8Unsafe("drive/whatever.txt"), // virtual path 734 kDummyDownloadFileSize, 735 kOutputFilePath, 736 "file:2_file_resource_id", 737 ClientContext(BACKGROUND), 738 google_apis::test_util::CreateCopyResultCallback( 739 &download_error, &output_file_path), 740 google_apis::GetContentCallback()); 741 // Metadata should still work 742 google_apis::GDataErrorCode metadata_error = google_apis::GDATA_OTHER_ERROR; 743 scoped_ptr<google_apis::AboutResource> about_resource; 744 745 // Try to get the metadata 746 scheduler_->GetAboutResource( 747 google_apis::test_util::CreateCopyResultCallback( 748 &metadata_error, &about_resource)); 749 base::RunLoop().RunUntilIdle(); 750 751 // Check the metadata 752 ASSERT_EQ(google_apis::HTTP_SUCCESS, metadata_error); 753 ASSERT_TRUE(about_resource); 754 755 // Check the download 756 EXPECT_EQ(google_apis::HTTP_SUCCESS, download_error); 757 std::string content; 758 EXPECT_EQ(output_file_path, kOutputFilePath); 759 ASSERT_TRUE(base::ReadFileToString(output_file_path, &content)); 760 EXPECT_EQ("This is some test content.", content); 761} 762 763TEST_F(JobSchedulerTest, DownloadFileWimaxEnabled) { 764 ConnectToWimax(); 765 766 // Enable fetching over cellular network. 767 pref_service_->SetBoolean(prefs::kDisableDriveOverCellular, false); 768 769 // Try to get a file in the background 770 base::ScopedTempDir temp_dir; 771 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 772 773 const base::FilePath kOutputFilePath = 774 temp_dir.path().AppendASCII("whatever.txt"); 775 google_apis::GDataErrorCode download_error = google_apis::GDATA_OTHER_ERROR; 776 base::FilePath output_file_path; 777 scheduler_->DownloadFile( 778 base::FilePath::FromUTF8Unsafe("drive/whatever.txt"), // virtual path 779 kDummyDownloadFileSize, 780 kOutputFilePath, 781 "file:2_file_resource_id", 782 ClientContext(BACKGROUND), 783 google_apis::test_util::CreateCopyResultCallback( 784 &download_error, &output_file_path), 785 google_apis::GetContentCallback()); 786 // Metadata should still work 787 google_apis::GDataErrorCode metadata_error = google_apis::GDATA_OTHER_ERROR; 788 scoped_ptr<google_apis::AboutResource> about_resource; 789 790 // Try to get the metadata 791 scheduler_->GetAboutResource( 792 google_apis::test_util::CreateCopyResultCallback( 793 &metadata_error, &about_resource)); 794 base::RunLoop().RunUntilIdle(); 795 796 // Check the metadata 797 ASSERT_EQ(google_apis::HTTP_SUCCESS, metadata_error); 798 ASSERT_TRUE(about_resource); 799 800 // Check the download 801 EXPECT_EQ(google_apis::HTTP_SUCCESS, download_error); 802 std::string content; 803 EXPECT_EQ(output_file_path, kOutputFilePath); 804 ASSERT_TRUE(base::ReadFileToString(output_file_path, &content)); 805 EXPECT_EQ("This is some test content.", content); 806} 807 808TEST_F(JobSchedulerTest, JobInfo) { 809 JobListLogger logger; 810 scheduler_->AddObserver(&logger); 811 812 // Disable background upload/download. 813 ConnectToWimax(); 814 pref_service_->SetBoolean(prefs::kDisableDriveOverCellular, true); 815 816 base::ScopedTempDir temp_dir; 817 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 818 819 google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR; 820 scoped_ptr<google_apis::ResourceEntry> entry; 821 scoped_ptr<google_apis::AboutResource> about_resource; 822 base::FilePath path; 823 824 std::set<JobType> expected_types; 825 826 // Add many jobs. 827 expected_types.insert(TYPE_ADD_NEW_DIRECTORY); 828 scheduler_->AddNewDirectory( 829 fake_drive_service_->GetRootResourceId(), 830 "New Directory", 831 DriveServiceInterface::AddNewDirectoryOptions(), 832 ClientContext(USER_INITIATED), 833 google_apis::test_util::CreateCopyResultCallback(&error, &entry)); 834 expected_types.insert(TYPE_GET_ABOUT_RESOURCE); 835 scheduler_->GetAboutResource( 836 google_apis::test_util::CreateCopyResultCallback( 837 &error, &about_resource)); 838 expected_types.insert(TYPE_RENAME_RESOURCE); 839 scheduler_->RenameResource( 840 "file:2_file_resource_id", 841 "New Title", 842 google_apis::test_util::CreateCopyResultCallback(&error)); 843 expected_types.insert(TYPE_DOWNLOAD_FILE); 844 scheduler_->DownloadFile( 845 base::FilePath::FromUTF8Unsafe("drive/whatever.txt"), // virtual path 846 kDummyDownloadFileSize, 847 temp_dir.path().AppendASCII("whatever.txt"), 848 "file:2_file_resource_id", 849 ClientContext(BACKGROUND), 850 google_apis::test_util::CreateCopyResultCallback(&error, &path), 851 google_apis::GetContentCallback()); 852 853 // The number of jobs queued so far. 854 EXPECT_EQ(4U, scheduler_->GetJobInfoList().size()); 855 EXPECT_TRUE(logger.Has(JobListLogger::ADDED, TYPE_ADD_NEW_DIRECTORY)); 856 EXPECT_TRUE(logger.Has(JobListLogger::ADDED, TYPE_GET_ABOUT_RESOURCE)); 857 EXPECT_TRUE(logger.Has(JobListLogger::ADDED, TYPE_RENAME_RESOURCE)); 858 EXPECT_TRUE(logger.Has(JobListLogger::ADDED, TYPE_DOWNLOAD_FILE)); 859 EXPECT_FALSE(logger.Has(JobListLogger::DONE, TYPE_ADD_NEW_DIRECTORY)); 860 EXPECT_FALSE(logger.Has(JobListLogger::DONE, TYPE_GET_ABOUT_RESOURCE)); 861 EXPECT_FALSE(logger.Has(JobListLogger::DONE, TYPE_RENAME_RESOURCE)); 862 EXPECT_FALSE(logger.Has(JobListLogger::DONE, TYPE_DOWNLOAD_FILE)); 863 864 // Add more jobs. 865 expected_types.insert(TYPE_ADD_RESOURCE_TO_DIRECTORY); 866 scheduler_->AddResourceToDirectory( 867 "folder:1_folder_resource_id", 868 "file:2_file_resource_id", 869 google_apis::test_util::CreateCopyResultCallback(&error)); 870 expected_types.insert(TYPE_COPY_RESOURCE); 871 scheduler_->CopyResource( 872 "document:5_document_resource_id", 873 fake_drive_service_->GetRootResourceId(), 874 "New Document", 875 base::Time(), // last_modified 876 google_apis::test_util::CreateCopyResultCallback(&error, &entry)); 877 878 // 6 jobs in total were queued. 879 std::vector<JobInfo> jobs = scheduler_->GetJobInfoList(); 880 EXPECT_EQ(6U, jobs.size()); 881 std::set<JobType> actual_types; 882 std::set<JobID> job_ids; 883 for (size_t i = 0; i < jobs.size(); ++i) { 884 actual_types.insert(jobs[i].job_type); 885 job_ids.insert(jobs[i].job_id); 886 } 887 EXPECT_EQ(expected_types, actual_types); 888 EXPECT_EQ(6U, job_ids.size()) << "All job IDs must be unique"; 889 EXPECT_TRUE(logger.Has(JobListLogger::ADDED, TYPE_ADD_RESOURCE_TO_DIRECTORY)); 890 EXPECT_TRUE(logger.Has(JobListLogger::ADDED, TYPE_COPY_RESOURCE)); 891 EXPECT_FALSE(logger.Has(JobListLogger::DONE, TYPE_ADD_RESOURCE_TO_DIRECTORY)); 892 EXPECT_FALSE(logger.Has(JobListLogger::DONE, TYPE_COPY_RESOURCE)); 893 894 // Run the jobs. 895 base::RunLoop().RunUntilIdle(); 896 897 // All jobs except the BACKGROUND job should have started running (UPDATED) 898 // and then finished (DONE). 899 jobs = scheduler_->GetJobInfoList(); 900 ASSERT_EQ(1U, jobs.size()); 901 EXPECT_EQ(TYPE_DOWNLOAD_FILE, jobs[0].job_type); 902 903 EXPECT_TRUE(logger.Has(JobListLogger::UPDATED, TYPE_ADD_NEW_DIRECTORY)); 904 EXPECT_TRUE(logger.Has(JobListLogger::UPDATED, TYPE_GET_ABOUT_RESOURCE)); 905 EXPECT_TRUE(logger.Has(JobListLogger::UPDATED, TYPE_RENAME_RESOURCE)); 906 EXPECT_TRUE(logger.Has(JobListLogger::UPDATED, 907 TYPE_ADD_RESOURCE_TO_DIRECTORY)); 908 EXPECT_TRUE(logger.Has(JobListLogger::UPDATED, TYPE_COPY_RESOURCE)); 909 EXPECT_FALSE(logger.Has(JobListLogger::UPDATED, TYPE_DOWNLOAD_FILE)); 910 911 EXPECT_TRUE(logger.Has(JobListLogger::DONE, TYPE_ADD_NEW_DIRECTORY)); 912 EXPECT_TRUE(logger.Has(JobListLogger::DONE, TYPE_GET_ABOUT_RESOURCE)); 913 EXPECT_TRUE(logger.Has(JobListLogger::DONE, TYPE_RENAME_RESOURCE)); 914 EXPECT_TRUE(logger.Has(JobListLogger::DONE, TYPE_ADD_RESOURCE_TO_DIRECTORY)); 915 EXPECT_TRUE(logger.Has(JobListLogger::DONE, TYPE_COPY_RESOURCE)); 916 EXPECT_FALSE(logger.Has(JobListLogger::DONE, TYPE_DOWNLOAD_FILE)); 917 918 // Run the background downloading job as well. 919 ConnectToWifi(); 920 base::RunLoop().RunUntilIdle(); 921 922 // All jobs should have finished. 923 EXPECT_EQ(0U, scheduler_->GetJobInfoList().size()); 924 EXPECT_TRUE(logger.Has(JobListLogger::UPDATED, TYPE_DOWNLOAD_FILE)); 925 EXPECT_TRUE(logger.Has(JobListLogger::DONE, TYPE_DOWNLOAD_FILE)); 926} 927 928TEST_F(JobSchedulerTest, JobInfoProgress) { 929 JobListLogger logger; 930 scheduler_->AddObserver(&logger); 931 932 ConnectToWifi(); 933 934 base::ScopedTempDir temp_dir; 935 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 936 937 google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR; 938 base::FilePath path; 939 940 // Download job. 941 scheduler_->DownloadFile( 942 base::FilePath::FromUTF8Unsafe("drive/whatever.txt"), // virtual path 943 kDummyDownloadFileSize, 944 temp_dir.path().AppendASCII("whatever.txt"), 945 "file:2_file_resource_id", 946 ClientContext(BACKGROUND), 947 google_apis::test_util::CreateCopyResultCallback(&error, &path), 948 google_apis::GetContentCallback()); 949 base::RunLoop().RunUntilIdle(); 950 951 std::vector<int64> download_progress; 952 logger.GetProgressInfo(TYPE_DOWNLOAD_FILE, &download_progress); 953 ASSERT_TRUE(!download_progress.empty()); 954 EXPECT_TRUE(base::STLIsSorted(download_progress)); 955 EXPECT_GE(download_progress.front(), 0); 956 EXPECT_LE(download_progress.back(), 26); 957 958 // Upload job. 959 path = temp_dir.path().AppendASCII("new_file.txt"); 960 ASSERT_TRUE(google_apis::test_util::WriteStringToFile(path, "Hello")); 961 google_apis::GDataErrorCode upload_error = 962 google_apis::GDATA_OTHER_ERROR; 963 scoped_ptr<google_apis::ResourceEntry> entry; 964 965 scheduler_->UploadNewFile( 966 fake_drive_service_->GetRootResourceId(), 967 base::FilePath::FromUTF8Unsafe("drive/new_file.txt"), 968 path, 969 "dummy title", 970 "plain/plain", 971 DriveUploader::UploadNewFileOptions(), 972 ClientContext(BACKGROUND), 973 google_apis::test_util::CreateCopyResultCallback(&upload_error, &entry)); 974 base::RunLoop().RunUntilIdle(); 975 976 std::vector<int64> upload_progress; 977 logger.GetProgressInfo(TYPE_UPLOAD_NEW_FILE, &upload_progress); 978 ASSERT_TRUE(!upload_progress.empty()); 979 EXPECT_TRUE(base::STLIsSorted(upload_progress)); 980 EXPECT_GE(upload_progress.front(), 0); 981 EXPECT_LE(upload_progress.back(), 13); 982} 983 984TEST_F(JobSchedulerTest, CancelPendingJob) { 985 base::ScopedTempDir temp_dir; 986 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 987 base::FilePath upload_path = temp_dir.path().AppendASCII("new_file.txt"); 988 ASSERT_TRUE(google_apis::test_util::WriteStringToFile(upload_path, "Hello")); 989 990 // To create a pending job for testing, set the mode to cellular connection 991 // and issue BACKGROUND jobs. 992 ConnectToCellular(); 993 pref_service_->SetBoolean(prefs::kDisableDriveOverCellular, true); 994 995 // Start the first job and record its job ID. 996 google_apis::GDataErrorCode error1 = google_apis::GDATA_OTHER_ERROR; 997 scoped_ptr<google_apis::ResourceEntry> entry; 998 scheduler_->UploadNewFile( 999 fake_drive_service_->GetRootResourceId(), 1000 base::FilePath::FromUTF8Unsafe("dummy/path"), 1001 upload_path, 1002 "dummy title 1", 1003 "text/plain", 1004 DriveUploader::UploadNewFileOptions(), 1005 ClientContext(BACKGROUND), 1006 google_apis::test_util::CreateCopyResultCallback(&error1, &entry)); 1007 1008 const std::vector<JobInfo>& jobs = scheduler_->GetJobInfoList(); 1009 ASSERT_EQ(1u, jobs.size()); 1010 ASSERT_EQ(STATE_NONE, jobs[0].state); // Not started yet. 1011 JobID first_job_id = jobs[0].job_id; 1012 1013 // Start the second job. 1014 google_apis::GDataErrorCode error2 = google_apis::GDATA_OTHER_ERROR; 1015 scheduler_->UploadNewFile( 1016 fake_drive_service_->GetRootResourceId(), 1017 base::FilePath::FromUTF8Unsafe("dummy/path"), 1018 upload_path, 1019 "dummy title 2", 1020 "text/plain", 1021 DriveUploader::UploadNewFileOptions(), 1022 ClientContext(BACKGROUND), 1023 google_apis::test_util::CreateCopyResultCallback(&error2, &entry)); 1024 1025 // Cancel the first one. 1026 scheduler_->CancelJob(first_job_id); 1027 1028 // Only the first job should be cancelled. 1029 ConnectToWifi(); 1030 base::RunLoop().RunUntilIdle(); 1031 EXPECT_EQ(google_apis::GDATA_CANCELLED, error1); 1032 EXPECT_EQ(google_apis::HTTP_SUCCESS, error2); 1033 EXPECT_TRUE(scheduler_->GetJobInfoList().empty()); 1034} 1035 1036TEST_F(JobSchedulerTest, CancelRunningJob) { 1037 ConnectToWifi(); 1038 1039 base::ScopedTempDir temp_dir; 1040 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 1041 base::FilePath upload_path = temp_dir.path().AppendASCII("new_file.txt"); 1042 ASSERT_TRUE(google_apis::test_util::WriteStringToFile(upload_path, "Hello")); 1043 1044 // Run as a cancelable task. 1045 fake_drive_service_->set_upload_new_file_cancelable(true); 1046 google_apis::GDataErrorCode error1 = google_apis::GDATA_OTHER_ERROR; 1047 scoped_ptr<google_apis::ResourceEntry> entry; 1048 scheduler_->UploadNewFile( 1049 fake_drive_service_->GetRootResourceId(), 1050 base::FilePath::FromUTF8Unsafe("dummy/path"), 1051 upload_path, 1052 "dummy title 1", 1053 "text/plain", 1054 DriveUploader::UploadNewFileOptions(), 1055 ClientContext(USER_INITIATED), 1056 google_apis::test_util::CreateCopyResultCallback(&error1, &entry)); 1057 1058 const std::vector<JobInfo>& jobs = scheduler_->GetJobInfoList(); 1059 ASSERT_EQ(1u, jobs.size()); 1060 ASSERT_EQ(STATE_RUNNING, jobs[0].state); // It's running. 1061 JobID first_job_id = jobs[0].job_id; 1062 1063 // Start the second job normally. 1064 fake_drive_service_->set_upload_new_file_cancelable(false); 1065 google_apis::GDataErrorCode error2 = google_apis::GDATA_OTHER_ERROR; 1066 scheduler_->UploadNewFile( 1067 fake_drive_service_->GetRootResourceId(), 1068 base::FilePath::FromUTF8Unsafe("dummy/path"), 1069 upload_path, 1070 "dummy title 2", 1071 "text/plain", 1072 DriveUploader::UploadNewFileOptions(), 1073 ClientContext(USER_INITIATED), 1074 google_apis::test_util::CreateCopyResultCallback(&error2, &entry)); 1075 1076 // Cancel the first one. 1077 scheduler_->CancelJob(first_job_id); 1078 1079 // Only the first job should be cancelled. 1080 base::RunLoop().RunUntilIdle(); 1081 EXPECT_EQ(google_apis::GDATA_CANCELLED, error1); 1082 EXPECT_EQ(google_apis::HTTP_SUCCESS, error2); 1083 EXPECT_TRUE(scheduler_->GetJobInfoList().empty()); 1084} 1085 1086} // namespace drive 1087