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.
5 #include "components/drive/job_scheduler.h"
10 #include "base/files/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/single_thread_task_runner.h"
15 #include "base/stl_util.h"
16 #include "base/strings/stringprintf.h"
17 #include "base/thread_task_runner_handle.h"
18 #include "components/drive/drive_pref_names.h"
19 #include "components/drive/drive_test_util.h"
20 #include "components/drive/event_logger.h"
21 #include "components/drive/service/fake_drive_service.h"
22 #include "components/drive/service/test_util.h"
23 #include "content/public/test/test_browser_thread_bundle.h"
24 #include "google_apis/drive/drive_api_parser.h"
25 #include "google_apis/drive/test_util.h"
26 #include "testing/gtest/include/gtest/gtest.h"
32 // Dummy value passed for the |expected_file_size| parameter of DownloadFile().
33 const int64 kDummyDownloadFileSize
= 0;
35 void CopyTitleFromFileResourceCallback(
36 std::vector
<std::string
>* title_list_out
,
37 google_apis::DriveApiErrorCode error_in
,
38 scoped_ptr
<google_apis::FileResource
> entry_in
) {
39 title_list_out
->push_back(entry_in
->title());
42 class JobListLogger
: public JobListObserver
{
54 EventLog(EventType type
, const JobInfo
& info
) : type(type
), info(info
) {
58 // Checks whether the specified type of event has occurred.
59 bool Has(EventType type
, JobType job_type
) {
60 for (size_t i
= 0; i
< events
.size(); ++i
) {
61 if (events
[i
].type
== type
&& events
[i
].info
.job_type
== job_type
)
67 // Gets the progress event information of the specified type.
68 void GetProgressInfo(JobType job_type
, std::vector
<int64
>* progress
) {
69 for (size_t i
= 0; i
< events
.size(); ++i
) {
70 if (events
[i
].type
== UPDATED
&& events
[i
].info
.job_type
== job_type
)
71 progress
->push_back(events
[i
].info
.num_completed_bytes
);
75 // JobListObserver overrides.
76 void OnJobAdded(const JobInfo
& info
) override
{
77 events
.push_back(EventLog(ADDED
, info
));
80 void OnJobUpdated(const JobInfo
& info
) override
{
81 events
.push_back(EventLog(UPDATED
, info
));
84 void OnJobDone(const JobInfo
& info
, FileError error
) override
{
85 events
.push_back(EventLog(DONE
, info
));
89 std::vector
<EventLog
> events
;
92 // Fake drive service extended for testing cancellation.
93 // When upload_new_file_cancelable is set, this Drive service starts
94 // returning a closure to cancel from InitiateUploadNewFile(). The task will
95 // finish only when the cancel closure is called.
96 class CancelTestableFakeDriveService
: public FakeDriveService
{
98 CancelTestableFakeDriveService()
99 : upload_new_file_cancelable_(false) {
102 void set_upload_new_file_cancelable(bool cancelable
) {
103 upload_new_file_cancelable_
= cancelable
;
106 google_apis::CancelCallback
InitiateUploadNewFile(
107 const std::string
& content_type
,
108 int64 content_length
,
109 const std::string
& parent_resource_id
,
110 const std::string
& title
,
111 const UploadNewFileOptions
& options
,
112 const google_apis::InitiateUploadCallback
& callback
) override
{
113 if (upload_new_file_cancelable_
)
114 return base::Bind(callback
, google_apis::DRIVE_CANCELLED
, GURL());
116 return FakeDriveService::InitiateUploadNewFile(content_type
,
125 bool upload_new_file_cancelable_
;
130 class JobSchedulerTest
: public testing::Test
{
133 : pref_service_(new TestingPrefServiceSimple
) {
134 test_util::RegisterDrivePrefs(pref_service_
->registry());
137 void SetUp() override
{
138 fake_network_change_notifier_
.reset(
139 new test_util::FakeNetworkChangeNotifier
);
141 logger_
.reset(new EventLogger
);
143 fake_drive_service_
.reset(new CancelTestableFakeDriveService
);
144 test_util::SetUpTestEntries(fake_drive_service_
.get());
145 fake_drive_service_
->LoadAppListForDriveApi("drive/applist.json");
147 scheduler_
.reset(new JobScheduler(
150 fake_drive_service_
.get(),
151 base::ThreadTaskRunnerHandle::Get().get()));
152 scheduler_
->SetDisableThrottling(true);
156 // Sets up FakeNetworkChangeNotifier as if it's connected to a network with
157 // the specified connection type.
158 void ChangeConnectionType(net::NetworkChangeNotifier::ConnectionType type
) {
159 fake_network_change_notifier_
->SetConnectionType(type
);
162 // Sets up FakeNetworkChangeNotifier as if it's connected to wifi network.
163 void ConnectToWifi() {
164 ChangeConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI
);
167 // Sets up FakeNetworkChangeNotifier as if it's connected to cellular network.
168 void ConnectToCellular() {
169 ChangeConnectionType(net::NetworkChangeNotifier::CONNECTION_2G
);
172 // Sets up FakeNetworkChangeNotifier as if it's connected to wimax network.
173 void ConnectToWimax() {
174 ChangeConnectionType(net::NetworkChangeNotifier::CONNECTION_4G
);
177 // Sets up FakeNetworkChangeNotifier as if it's disconnected.
178 void ConnectToNone() {
179 ChangeConnectionType(net::NetworkChangeNotifier::CONNECTION_NONE
);
182 static int GetMetadataQueueMaxJobCount() {
183 return JobScheduler::kMaxJobCount
[JobScheduler::METADATA_QUEUE
];
186 content::TestBrowserThreadBundle thread_bundle_
;
187 scoped_ptr
<TestingPrefServiceSimple
> pref_service_
;
188 scoped_ptr
<test_util::FakeNetworkChangeNotifier
>
189 fake_network_change_notifier_
;
190 scoped_ptr
<EventLogger
> logger_
;
191 scoped_ptr
<CancelTestableFakeDriveService
> fake_drive_service_
;
192 scoped_ptr
<JobScheduler
> scheduler_
;
195 TEST_F(JobSchedulerTest
, GetAboutResource
) {
198 google_apis::DriveApiErrorCode error
= google_apis::DRIVE_OTHER_ERROR
;
199 scoped_ptr
<google_apis::AboutResource
> about_resource
;
200 scheduler_
->GetAboutResource(
201 google_apis::test_util::CreateCopyResultCallback(
202 &error
, &about_resource
));
203 base::RunLoop().RunUntilIdle();
204 ASSERT_EQ(google_apis::HTTP_SUCCESS
, error
);
205 ASSERT_TRUE(about_resource
);
208 TEST_F(JobSchedulerTest
, GetAppList
) {
211 google_apis::DriveApiErrorCode error
= google_apis::DRIVE_OTHER_ERROR
;
212 scoped_ptr
<google_apis::AppList
> app_list
;
214 scheduler_
->GetAppList(
215 google_apis::test_util::CreateCopyResultCallback(&error
, &app_list
));
216 base::RunLoop().RunUntilIdle();
218 ASSERT_EQ(google_apis::HTTP_SUCCESS
, error
);
219 ASSERT_TRUE(app_list
);
222 TEST_F(JobSchedulerTest
, GetAllFileList
) {
225 google_apis::DriveApiErrorCode error
= google_apis::DRIVE_OTHER_ERROR
;
226 scoped_ptr
<google_apis::FileList
> file_list
;
228 scheduler_
->GetAllFileList(
229 google_apis::test_util::CreateCopyResultCallback(&error
, &file_list
));
230 base::RunLoop().RunUntilIdle();
232 ASSERT_EQ(google_apis::HTTP_SUCCESS
, error
);
233 ASSERT_TRUE(file_list
);
236 TEST_F(JobSchedulerTest
, GetFileListInDirectory
) {
239 google_apis::DriveApiErrorCode error
= google_apis::DRIVE_OTHER_ERROR
;
240 scoped_ptr
<google_apis::FileList
> file_list
;
242 scheduler_
->GetFileListInDirectory(
243 fake_drive_service_
->GetRootResourceId(),
244 google_apis::test_util::CreateCopyResultCallback(&error
, &file_list
));
245 base::RunLoop().RunUntilIdle();
247 ASSERT_EQ(google_apis::HTTP_SUCCESS
, error
);
248 ASSERT_TRUE(file_list
);
251 TEST_F(JobSchedulerTest
, Search
) {
254 google_apis::DriveApiErrorCode error
= google_apis::DRIVE_OTHER_ERROR
;
255 scoped_ptr
<google_apis::FileList
> file_list
;
258 "File", // search query
259 google_apis::test_util::CreateCopyResultCallback(&error
, &file_list
));
260 base::RunLoop().RunUntilIdle();
262 ASSERT_EQ(google_apis::HTTP_SUCCESS
, error
);
263 ASSERT_TRUE(file_list
);
266 TEST_F(JobSchedulerTest
, GetChangeList
) {
269 int64 old_largest_change_id
=
270 fake_drive_service_
->about_resource().largest_change_id();
272 google_apis::DriveApiErrorCode error
= google_apis::DRIVE_OTHER_ERROR
;
274 // Create a new directory.
276 scoped_ptr
<google_apis::FileResource
> entry
;
277 fake_drive_service_
->AddNewDirectory(
278 fake_drive_service_
->GetRootResourceId(), "new directory",
279 AddNewDirectoryOptions(),
280 google_apis::test_util::CreateCopyResultCallback(&error
, &entry
));
281 base::RunLoop().RunUntilIdle();
282 ASSERT_EQ(google_apis::HTTP_CREATED
, error
);
285 error
= google_apis::DRIVE_OTHER_ERROR
;
286 scoped_ptr
<google_apis::ChangeList
> change_list
;
287 scheduler_
->GetChangeList(
288 old_largest_change_id
+ 1,
289 google_apis::test_util::CreateCopyResultCallback(&error
, &change_list
));
290 base::RunLoop().RunUntilIdle();
292 ASSERT_EQ(google_apis::HTTP_SUCCESS
, error
);
293 ASSERT_TRUE(change_list
);
296 TEST_F(JobSchedulerTest
, GetRemainingChangeList
) {
298 fake_drive_service_
->set_default_max_results(2);
300 google_apis::DriveApiErrorCode error
= google_apis::DRIVE_OTHER_ERROR
;
301 scoped_ptr
<google_apis::ChangeList
> change_list
;
303 scheduler_
->GetChangeList(
305 google_apis::test_util::CreateCopyResultCallback(&error
, &change_list
));
306 base::RunLoop().RunUntilIdle();
308 ASSERT_EQ(google_apis::HTTP_SUCCESS
, error
);
309 ASSERT_TRUE(change_list
);
311 // Keep the next url before releasing the |change_list|.
312 GURL
next_url(change_list
->next_link());
314 error
= google_apis::DRIVE_OTHER_ERROR
;
317 scheduler_
->GetRemainingChangeList(
319 google_apis::test_util::CreateCopyResultCallback(&error
, &change_list
));
320 base::RunLoop().RunUntilIdle();
322 ASSERT_EQ(google_apis::HTTP_SUCCESS
, error
);
323 ASSERT_TRUE(change_list
);
326 TEST_F(JobSchedulerTest
, GetRemainingFileList
) {
328 fake_drive_service_
->set_default_max_results(2);
330 google_apis::DriveApiErrorCode error
= google_apis::DRIVE_OTHER_ERROR
;
331 scoped_ptr
<google_apis::FileList
> file_list
;
333 scheduler_
->GetFileListInDirectory(
334 fake_drive_service_
->GetRootResourceId(),
335 google_apis::test_util::CreateCopyResultCallback(&error
, &file_list
));
336 base::RunLoop().RunUntilIdle();
338 ASSERT_EQ(google_apis::HTTP_SUCCESS
, error
);
339 ASSERT_TRUE(file_list
);
341 // Keep the next url before releasing the |file_list|.
342 GURL
next_url(file_list
->next_link());
344 error
= google_apis::DRIVE_OTHER_ERROR
;
347 scheduler_
->GetRemainingFileList(
349 google_apis::test_util::CreateCopyResultCallback(&error
, &file_list
));
350 base::RunLoop().RunUntilIdle();
352 ASSERT_EQ(google_apis::HTTP_SUCCESS
, error
);
353 ASSERT_TRUE(file_list
);
356 TEST_F(JobSchedulerTest
, GetFileResource
) {
359 google_apis::DriveApiErrorCode error
= google_apis::DRIVE_OTHER_ERROR
;
360 scoped_ptr
<google_apis::FileResource
> entry
;
362 scheduler_
->GetFileResource(
363 "2_file_resource_id", // resource ID
364 ClientContext(USER_INITIATED
),
365 google_apis::test_util::CreateCopyResultCallback(&error
, &entry
));
366 base::RunLoop().RunUntilIdle();
368 ASSERT_EQ(google_apis::HTTP_SUCCESS
, error
);
372 TEST_F(JobSchedulerTest
, GetShareUrl
) {
375 google_apis::DriveApiErrorCode error
= google_apis::DRIVE_OTHER_ERROR
;
378 scheduler_
->GetShareUrl(
379 "2_file_resource_id", // resource ID
380 GURL("chrome-extension://test-id/"), // embed origin
381 ClientContext(USER_INITIATED
),
382 google_apis::test_util::CreateCopyResultCallback(&error
, &share_url
));
383 base::RunLoop().RunUntilIdle();
385 ASSERT_EQ(google_apis::HTTP_SUCCESS
, error
);
386 ASSERT_FALSE(share_url
.is_empty());
389 TEST_F(JobSchedulerTest
, TrashResource
) {
392 google_apis::DriveApiErrorCode error
= google_apis::DRIVE_OTHER_ERROR
;
394 scheduler_
->TrashResource(
395 "2_file_resource_id",
396 ClientContext(USER_INITIATED
),
397 google_apis::test_util::CreateCopyResultCallback(&error
));
398 base::RunLoop().RunUntilIdle();
400 ASSERT_EQ(google_apis::HTTP_SUCCESS
, error
);
403 TEST_F(JobSchedulerTest
, CopyResource
) {
406 google_apis::DriveApiErrorCode error
= google_apis::DRIVE_OTHER_ERROR
;
407 scoped_ptr
<google_apis::FileResource
> entry
;
409 scheduler_
->CopyResource(
410 "2_file_resource_id", // resource ID
411 "1_folder_resource_id", // parent resource ID
412 "New Document", // new title
414 google_apis::test_util::CreateCopyResultCallback(&error
, &entry
));
415 base::RunLoop().RunUntilIdle();
417 ASSERT_EQ(google_apis::HTTP_SUCCESS
, error
);
421 TEST_F(JobSchedulerTest
, UpdateResource
) {
424 google_apis::DriveApiErrorCode error
= google_apis::DRIVE_OTHER_ERROR
;
425 scoped_ptr
<google_apis::FileResource
> entry
;
427 scheduler_
->UpdateResource(
428 "2_file_resource_id", // resource ID
429 "1_folder_resource_id", // parent resource ID
430 "New Document", // new title
431 base::Time(), base::Time(), google_apis::drive::Properties(),
432 ClientContext(USER_INITIATED
),
433 google_apis::test_util::CreateCopyResultCallback(&error
, &entry
));
434 base::RunLoop().RunUntilIdle();
436 ASSERT_EQ(google_apis::HTTP_SUCCESS
, error
);
440 TEST_F(JobSchedulerTest
, AddResourceToDirectory
) {
443 google_apis::DriveApiErrorCode error
= google_apis::DRIVE_OTHER_ERROR
;
445 scheduler_
->AddResourceToDirectory(
446 "1_folder_resource_id",
447 "2_file_resource_id",
448 google_apis::test_util::CreateCopyResultCallback(&error
));
449 base::RunLoop().RunUntilIdle();
451 ASSERT_EQ(google_apis::HTTP_SUCCESS
, error
);
454 TEST_F(JobSchedulerTest
, RemoveResourceFromDirectory
) {
457 google_apis::DriveApiErrorCode error
= google_apis::DRIVE_OTHER_ERROR
;
459 scheduler_
->RemoveResourceFromDirectory(
460 "1_folder_resource_id",
461 "subdirectory_file_1_id", // resource ID
462 ClientContext(USER_INITIATED
),
463 google_apis::test_util::CreateCopyResultCallback(&error
));
464 base::RunLoop().RunUntilIdle();
466 ASSERT_EQ(google_apis::HTTP_NO_CONTENT
, error
);
469 TEST_F(JobSchedulerTest
, AddNewDirectory
) {
472 google_apis::DriveApiErrorCode error
= google_apis::DRIVE_OTHER_ERROR
;
473 scoped_ptr
<google_apis::FileResource
> entry
;
475 scheduler_
->AddNewDirectory(
476 fake_drive_service_
->GetRootResourceId(), // Root directory.
477 "New Directory", AddNewDirectoryOptions(), ClientContext(USER_INITIATED
),
478 google_apis::test_util::CreateCopyResultCallback(&error
, &entry
));
479 base::RunLoop().RunUntilIdle();
481 ASSERT_EQ(google_apis::HTTP_CREATED
, error
);
485 TEST_F(JobSchedulerTest
, PriorityHandling
) {
486 // Saturate the metadata job queue with uninteresting jobs to prevent
487 // following jobs from starting.
488 google_apis::DriveApiErrorCode error_dontcare
=
489 google_apis::DRIVE_OTHER_ERROR
;
490 scoped_ptr
<google_apis::FileResource
> entry_dontcare
;
491 for (int i
= 0; i
< GetMetadataQueueMaxJobCount(); ++i
) {
492 std::string
resource_id("2_file_resource_id");
493 scheduler_
->GetFileResource(
495 ClientContext(USER_INITIATED
),
496 google_apis::test_util::CreateCopyResultCallback(&error_dontcare
,
500 // Start jobs with different priorities.
501 std::string
title_1("new file 1");
502 std::string
title_2("new file 2");
503 std::string
title_3("new file 3");
504 std::string
title_4("new file 4");
505 std::vector
<std::string
> titles
;
507 scheduler_
->AddNewDirectory(
508 fake_drive_service_
->GetRootResourceId(), title_1
,
509 AddNewDirectoryOptions(), ClientContext(USER_INITIATED
),
510 base::Bind(&CopyTitleFromFileResourceCallback
, &titles
));
511 scheduler_
->AddNewDirectory(
512 fake_drive_service_
->GetRootResourceId(), title_2
,
513 AddNewDirectoryOptions(), ClientContext(BACKGROUND
),
514 base::Bind(&CopyTitleFromFileResourceCallback
, &titles
));
515 scheduler_
->AddNewDirectory(
516 fake_drive_service_
->GetRootResourceId(), title_3
,
517 AddNewDirectoryOptions(), ClientContext(BACKGROUND
),
518 base::Bind(&CopyTitleFromFileResourceCallback
, &titles
));
519 scheduler_
->AddNewDirectory(
520 fake_drive_service_
->GetRootResourceId(), title_4
,
521 AddNewDirectoryOptions(), ClientContext(USER_INITIATED
),
522 base::Bind(&CopyTitleFromFileResourceCallback
, &titles
));
524 base::RunLoop().RunUntilIdle();
526 ASSERT_EQ(4ul, titles
.size());
527 EXPECT_EQ(title_1
, titles
[0]);
528 EXPECT_EQ(title_4
, titles
[1]);
529 EXPECT_EQ(title_2
, titles
[2]);
530 EXPECT_EQ(title_3
, titles
[3]);
533 TEST_F(JobSchedulerTest
, NoConnectionUserInitiated
) {
536 std::string
resource_id("2_file_resource_id");
538 google_apis::DriveApiErrorCode error
= google_apis::DRIVE_OTHER_ERROR
;
539 scoped_ptr
<google_apis::FileResource
> entry
;
540 scheduler_
->GetFileResource(
542 ClientContext(USER_INITIATED
),
543 google_apis::test_util::CreateCopyResultCallback(&error
, &entry
));
544 base::RunLoop().RunUntilIdle();
546 EXPECT_EQ(google_apis::DRIVE_NO_CONNECTION
, error
);
549 TEST_F(JobSchedulerTest
, NoConnectionBackground
) {
552 std::string
resource_id("2_file_resource_id");
554 google_apis::DriveApiErrorCode error
= google_apis::DRIVE_OTHER_ERROR
;
555 scoped_ptr
<google_apis::FileResource
> entry
;
556 scheduler_
->GetFileResource(
558 ClientContext(BACKGROUND
),
559 google_apis::test_util::CreateCopyResultCallback(&error
, &entry
));
560 base::RunLoop().RunUntilIdle();
564 // Reconnect to the net.
567 base::RunLoop().RunUntilIdle();
569 EXPECT_EQ(google_apis::HTTP_SUCCESS
, error
);
573 TEST_F(JobSchedulerTest
, DownloadFileCellularDisabled
) {
576 // Disable fetching over cellular network.
577 pref_service_
->SetBoolean(prefs::kDisableDriveOverCellular
, true);
579 // Try to get a file in the background
580 base::ScopedTempDir temp_dir
;
581 ASSERT_TRUE(temp_dir
.CreateUniqueTempDir());
583 const base::FilePath kOutputFilePath
=
584 temp_dir
.path().AppendASCII("whatever.txt");
585 google_apis::DriveApiErrorCode download_error
=
586 google_apis::DRIVE_OTHER_ERROR
;
587 base::FilePath output_file_path
;
588 scheduler_
->DownloadFile(
589 base::FilePath::FromUTF8Unsafe("drive/whatever.txt"), // virtual path
590 kDummyDownloadFileSize
,
592 "2_file_resource_id",
593 ClientContext(BACKGROUND
),
594 google_apis::test_util::CreateCopyResultCallback(
595 &download_error
, &output_file_path
),
596 google_apis::GetContentCallback());
597 // Metadata should still work
598 google_apis::DriveApiErrorCode metadata_error
=
599 google_apis::DRIVE_OTHER_ERROR
;
600 scoped_ptr
<google_apis::AboutResource
> about_resource
;
602 // Try to get the metadata
603 scheduler_
->GetAboutResource(
604 google_apis::test_util::CreateCopyResultCallback(
605 &metadata_error
, &about_resource
));
606 base::RunLoop().RunUntilIdle();
608 // Check the metadata
609 ASSERT_EQ(google_apis::HTTP_SUCCESS
, metadata_error
);
610 ASSERT_TRUE(about_resource
);
612 // Check the download
613 EXPECT_EQ(google_apis::DRIVE_OTHER_ERROR
, download_error
);
615 // Switch to a Wifi connection
618 base::RunLoop().RunUntilIdle();
620 // Check the download again
621 EXPECT_EQ(google_apis::HTTP_SUCCESS
, download_error
);
623 EXPECT_EQ(output_file_path
, kOutputFilePath
);
624 ASSERT_TRUE(base::ReadFileToString(output_file_path
, &content
));
625 EXPECT_EQ("This is some test content.", content
);
628 TEST_F(JobSchedulerTest
, DownloadFileWimaxDisabled
) {
631 // Disable fetching over cellular network.
632 pref_service_
->SetBoolean(prefs::kDisableDriveOverCellular
, true);
634 // Try to get a file in the background
635 base::ScopedTempDir temp_dir
;
636 ASSERT_TRUE(temp_dir
.CreateUniqueTempDir());
638 const base::FilePath kOutputFilePath
=
639 temp_dir
.path().AppendASCII("whatever.txt");
640 google_apis::DriveApiErrorCode download_error
=
641 google_apis::DRIVE_OTHER_ERROR
;
642 base::FilePath output_file_path
;
643 scheduler_
->DownloadFile(
644 base::FilePath::FromUTF8Unsafe("drive/whatever.txt"), // virtual path
645 kDummyDownloadFileSize
,
647 "2_file_resource_id",
648 ClientContext(BACKGROUND
),
649 google_apis::test_util::CreateCopyResultCallback(
650 &download_error
, &output_file_path
),
651 google_apis::GetContentCallback());
652 // Metadata should still work
653 google_apis::DriveApiErrorCode metadata_error
=
654 google_apis::DRIVE_OTHER_ERROR
;
655 scoped_ptr
<google_apis::AboutResource
> about_resource
;
657 // Try to get the metadata
658 scheduler_
->GetAboutResource(
659 google_apis::test_util::CreateCopyResultCallback(
660 &metadata_error
, &about_resource
));
661 base::RunLoop().RunUntilIdle();
663 // Check the metadata
664 ASSERT_EQ(google_apis::HTTP_SUCCESS
, metadata_error
);
665 ASSERT_TRUE(about_resource
);
667 // Check the download
668 EXPECT_EQ(google_apis::DRIVE_OTHER_ERROR
, download_error
);
670 // Switch to a Wifi connection
673 base::RunLoop().RunUntilIdle();
675 // Check the download again
676 EXPECT_EQ(google_apis::HTTP_SUCCESS
, download_error
);
678 EXPECT_EQ(output_file_path
, kOutputFilePath
);
679 ASSERT_TRUE(base::ReadFileToString(output_file_path
, &content
));
680 EXPECT_EQ("This is some test content.", content
);
683 TEST_F(JobSchedulerTest
, DownloadFileCellularEnabled
) {
686 // Enable fetching over cellular network.
687 pref_service_
->SetBoolean(prefs::kDisableDriveOverCellular
, false);
689 // Try to get a file in the background
690 base::ScopedTempDir temp_dir
;
691 ASSERT_TRUE(temp_dir
.CreateUniqueTempDir());
693 const base::FilePath kOutputFilePath
=
694 temp_dir
.path().AppendASCII("whatever.txt");
695 google_apis::DriveApiErrorCode download_error
=
696 google_apis::DRIVE_OTHER_ERROR
;
697 base::FilePath output_file_path
;
698 scheduler_
->DownloadFile(
699 base::FilePath::FromUTF8Unsafe("drive/whatever.txt"), // virtual path
700 kDummyDownloadFileSize
,
702 "2_file_resource_id",
703 ClientContext(BACKGROUND
),
704 google_apis::test_util::CreateCopyResultCallback(
705 &download_error
, &output_file_path
),
706 google_apis::GetContentCallback());
707 // Metadata should still work
708 google_apis::DriveApiErrorCode metadata_error
=
709 google_apis::DRIVE_OTHER_ERROR
;
710 scoped_ptr
<google_apis::AboutResource
> about_resource
;
712 // Try to get the metadata
713 scheduler_
->GetAboutResource(
714 google_apis::test_util::CreateCopyResultCallback(
715 &metadata_error
, &about_resource
));
716 base::RunLoop().RunUntilIdle();
718 // Check the metadata
719 ASSERT_EQ(google_apis::HTTP_SUCCESS
, metadata_error
);
720 ASSERT_TRUE(about_resource
);
722 // Check the download
723 EXPECT_EQ(google_apis::HTTP_SUCCESS
, download_error
);
725 EXPECT_EQ(output_file_path
, kOutputFilePath
);
726 ASSERT_TRUE(base::ReadFileToString(output_file_path
, &content
));
727 EXPECT_EQ("This is some test content.", content
);
730 TEST_F(JobSchedulerTest
, DownloadFileWimaxEnabled
) {
733 // Enable fetching over cellular network.
734 pref_service_
->SetBoolean(prefs::kDisableDriveOverCellular
, false);
736 // Try to get a file in the background
737 base::ScopedTempDir temp_dir
;
738 ASSERT_TRUE(temp_dir
.CreateUniqueTempDir());
740 const base::FilePath kOutputFilePath
=
741 temp_dir
.path().AppendASCII("whatever.txt");
742 google_apis::DriveApiErrorCode download_error
=
743 google_apis::DRIVE_OTHER_ERROR
;
744 base::FilePath output_file_path
;
745 scheduler_
->DownloadFile(
746 base::FilePath::FromUTF8Unsafe("drive/whatever.txt"), // virtual path
747 kDummyDownloadFileSize
,
749 "2_file_resource_id",
750 ClientContext(BACKGROUND
),
751 google_apis::test_util::CreateCopyResultCallback(
752 &download_error
, &output_file_path
),
753 google_apis::GetContentCallback());
754 // Metadata should still work
755 google_apis::DriveApiErrorCode metadata_error
=
756 google_apis::DRIVE_OTHER_ERROR
;
757 scoped_ptr
<google_apis::AboutResource
> about_resource
;
759 // Try to get the metadata
760 scheduler_
->GetAboutResource(
761 google_apis::test_util::CreateCopyResultCallback(
762 &metadata_error
, &about_resource
));
763 base::RunLoop().RunUntilIdle();
765 // Check the metadata
766 ASSERT_EQ(google_apis::HTTP_SUCCESS
, metadata_error
);
767 ASSERT_TRUE(about_resource
);
769 // Check the download
770 EXPECT_EQ(google_apis::HTTP_SUCCESS
, download_error
);
772 EXPECT_EQ(output_file_path
, kOutputFilePath
);
773 ASSERT_TRUE(base::ReadFileToString(output_file_path
, &content
));
774 EXPECT_EQ("This is some test content.", content
);
777 TEST_F(JobSchedulerTest
, JobInfo
) {
778 JobListLogger logger
;
779 scheduler_
->AddObserver(&logger
);
781 // Disable background upload/download.
783 pref_service_
->SetBoolean(prefs::kDisableDriveOverCellular
, true);
785 base::ScopedTempDir temp_dir
;
786 ASSERT_TRUE(temp_dir
.CreateUniqueTempDir());
788 google_apis::DriveApiErrorCode error
= google_apis::DRIVE_OTHER_ERROR
;
789 scoped_ptr
<google_apis::FileResource
> entry
;
790 scoped_ptr
<google_apis::AboutResource
> about_resource
;
793 std::set
<JobType
> expected_types
;
796 expected_types
.insert(TYPE_ADD_NEW_DIRECTORY
);
797 scheduler_
->AddNewDirectory(
798 fake_drive_service_
->GetRootResourceId(), "New Directory",
799 AddNewDirectoryOptions(), ClientContext(USER_INITIATED
),
800 google_apis::test_util::CreateCopyResultCallback(&error
, &entry
));
801 expected_types
.insert(TYPE_GET_ABOUT_RESOURCE
);
802 scheduler_
->GetAboutResource(
803 google_apis::test_util::CreateCopyResultCallback(
804 &error
, &about_resource
));
805 expected_types
.insert(TYPE_UPDATE_RESOURCE
);
806 scheduler_
->UpdateResource(
807 "2_file_resource_id", std::string(), "New Title", base::Time(),
808 base::Time(), google_apis::drive::Properties(),
809 ClientContext(USER_INITIATED
),
810 google_apis::test_util::CreateCopyResultCallback(&error
, &entry
));
811 expected_types
.insert(TYPE_DOWNLOAD_FILE
);
812 scheduler_
->DownloadFile(
813 base::FilePath::FromUTF8Unsafe("drive/whatever.txt"), // virtual path
814 kDummyDownloadFileSize
,
815 temp_dir
.path().AppendASCII("whatever.txt"),
816 "2_file_resource_id",
817 ClientContext(BACKGROUND
),
818 google_apis::test_util::CreateCopyResultCallback(&error
, &path
),
819 google_apis::GetContentCallback());
821 // The number of jobs queued so far.
822 EXPECT_EQ(4U, scheduler_
->GetJobInfoList().size());
823 EXPECT_TRUE(logger
.Has(JobListLogger::ADDED
, TYPE_ADD_NEW_DIRECTORY
));
824 EXPECT_TRUE(logger
.Has(JobListLogger::ADDED
, TYPE_GET_ABOUT_RESOURCE
));
825 EXPECT_TRUE(logger
.Has(JobListLogger::ADDED
, TYPE_UPDATE_RESOURCE
));
826 EXPECT_TRUE(logger
.Has(JobListLogger::ADDED
, TYPE_DOWNLOAD_FILE
));
827 EXPECT_FALSE(logger
.Has(JobListLogger::DONE
, TYPE_ADD_NEW_DIRECTORY
));
828 EXPECT_FALSE(logger
.Has(JobListLogger::DONE
, TYPE_GET_ABOUT_RESOURCE
));
829 EXPECT_FALSE(logger
.Has(JobListLogger::DONE
, TYPE_UPDATE_RESOURCE
));
830 EXPECT_FALSE(logger
.Has(JobListLogger::DONE
, TYPE_DOWNLOAD_FILE
));
833 expected_types
.insert(TYPE_ADD_RESOURCE_TO_DIRECTORY
);
834 scheduler_
->AddResourceToDirectory(
835 "1_folder_resource_id",
836 "2_file_resource_id",
837 google_apis::test_util::CreateCopyResultCallback(&error
));
838 expected_types
.insert(TYPE_COPY_RESOURCE
);
839 scheduler_
->CopyResource(
840 "5_document_resource_id",
841 fake_drive_service_
->GetRootResourceId(),
843 base::Time(), // last_modified
844 google_apis::test_util::CreateCopyResultCallback(&error
, &entry
));
846 // 6 jobs in total were queued.
847 std::vector
<JobInfo
> jobs
= scheduler_
->GetJobInfoList();
848 EXPECT_EQ(6U, jobs
.size());
849 std::set
<JobType
> actual_types
;
850 std::set
<JobID
> job_ids
;
851 for (size_t i
= 0; i
< jobs
.size(); ++i
) {
852 actual_types
.insert(jobs
[i
].job_type
);
853 job_ids
.insert(jobs
[i
].job_id
);
855 EXPECT_EQ(expected_types
, actual_types
);
856 EXPECT_EQ(6U, job_ids
.size()) << "All job IDs must be unique";
857 EXPECT_TRUE(logger
.Has(JobListLogger::ADDED
, TYPE_ADD_RESOURCE_TO_DIRECTORY
));
858 EXPECT_TRUE(logger
.Has(JobListLogger::ADDED
, TYPE_COPY_RESOURCE
));
859 EXPECT_FALSE(logger
.Has(JobListLogger::DONE
, TYPE_ADD_RESOURCE_TO_DIRECTORY
));
860 EXPECT_FALSE(logger
.Has(JobListLogger::DONE
, TYPE_COPY_RESOURCE
));
863 base::RunLoop().RunUntilIdle();
865 // All jobs except the BACKGROUND job should have started running (UPDATED)
866 // and then finished (DONE).
867 jobs
= scheduler_
->GetJobInfoList();
868 ASSERT_EQ(1U, jobs
.size());
869 EXPECT_EQ(TYPE_DOWNLOAD_FILE
, jobs
[0].job_type
);
871 EXPECT_TRUE(logger
.Has(JobListLogger::UPDATED
, TYPE_ADD_NEW_DIRECTORY
));
872 EXPECT_TRUE(logger
.Has(JobListLogger::UPDATED
, TYPE_GET_ABOUT_RESOURCE
));
873 EXPECT_TRUE(logger
.Has(JobListLogger::UPDATED
, TYPE_UPDATE_RESOURCE
));
874 EXPECT_TRUE(logger
.Has(JobListLogger::UPDATED
,
875 TYPE_ADD_RESOURCE_TO_DIRECTORY
));
876 EXPECT_TRUE(logger
.Has(JobListLogger::UPDATED
, TYPE_COPY_RESOURCE
));
877 EXPECT_FALSE(logger
.Has(JobListLogger::UPDATED
, TYPE_DOWNLOAD_FILE
));
879 EXPECT_TRUE(logger
.Has(JobListLogger::DONE
, TYPE_ADD_NEW_DIRECTORY
));
880 EXPECT_TRUE(logger
.Has(JobListLogger::DONE
, TYPE_GET_ABOUT_RESOURCE
));
881 EXPECT_TRUE(logger
.Has(JobListLogger::DONE
, TYPE_UPDATE_RESOURCE
));
882 EXPECT_TRUE(logger
.Has(JobListLogger::DONE
, TYPE_ADD_RESOURCE_TO_DIRECTORY
));
883 EXPECT_TRUE(logger
.Has(JobListLogger::DONE
, TYPE_COPY_RESOURCE
));
884 EXPECT_FALSE(logger
.Has(JobListLogger::DONE
, TYPE_DOWNLOAD_FILE
));
886 // Run the background downloading job as well.
888 base::RunLoop().RunUntilIdle();
890 // All jobs should have finished.
891 EXPECT_EQ(0U, scheduler_
->GetJobInfoList().size());
892 EXPECT_TRUE(logger
.Has(JobListLogger::UPDATED
, TYPE_DOWNLOAD_FILE
));
893 EXPECT_TRUE(logger
.Has(JobListLogger::DONE
, TYPE_DOWNLOAD_FILE
));
896 TEST_F(JobSchedulerTest
, JobInfoProgress
) {
897 JobListLogger logger
;
898 scheduler_
->AddObserver(&logger
);
902 base::ScopedTempDir temp_dir
;
903 ASSERT_TRUE(temp_dir
.CreateUniqueTempDir());
905 google_apis::DriveApiErrorCode error
= google_apis::DRIVE_OTHER_ERROR
;
909 scheduler_
->DownloadFile(
910 base::FilePath::FromUTF8Unsafe("drive/whatever.txt"), // virtual path
911 kDummyDownloadFileSize
,
912 temp_dir
.path().AppendASCII("whatever.txt"),
913 "2_file_resource_id",
914 ClientContext(BACKGROUND
),
915 google_apis::test_util::CreateCopyResultCallback(&error
, &path
),
916 google_apis::GetContentCallback());
917 base::RunLoop().RunUntilIdle();
919 std::vector
<int64
> download_progress
;
920 logger
.GetProgressInfo(TYPE_DOWNLOAD_FILE
, &download_progress
);
921 ASSERT_TRUE(!download_progress
.empty());
922 EXPECT_TRUE(base::STLIsSorted(download_progress
));
923 EXPECT_GE(download_progress
.front(), 0);
924 EXPECT_LE(download_progress
.back(), 26);
927 path
= temp_dir
.path().AppendASCII("new_file.txt");
928 ASSERT_TRUE(google_apis::test_util::WriteStringToFile(path
, "Hello"));
929 google_apis::DriveApiErrorCode upload_error
=
930 google_apis::DRIVE_OTHER_ERROR
;
931 scoped_ptr
<google_apis::FileResource
> entry
;
933 scheduler_
->UploadNewFile(
934 fake_drive_service_
->GetRootResourceId(), std::string("Hello").size(),
935 base::FilePath::FromUTF8Unsafe("drive/new_file.txt"), path
, "dummy title",
936 "plain/plain", UploadNewFileOptions(), ClientContext(BACKGROUND
),
937 google_apis::test_util::CreateCopyResultCallback(&upload_error
, &entry
));
938 base::RunLoop().RunUntilIdle();
940 std::vector
<int64
> upload_progress
;
941 logger
.GetProgressInfo(TYPE_UPLOAD_NEW_FILE
, &upload_progress
);
942 ASSERT_TRUE(!upload_progress
.empty());
943 EXPECT_TRUE(base::STLIsSorted(upload_progress
));
944 EXPECT_GE(upload_progress
.front(), 0);
945 EXPECT_LE(upload_progress
.back(), 13);
948 TEST_F(JobSchedulerTest
, CancelPendingJob
) {
949 base::ScopedTempDir temp_dir
;
950 ASSERT_TRUE(temp_dir
.CreateUniqueTempDir());
951 base::FilePath upload_path
= temp_dir
.path().AppendASCII("new_file.txt");
952 ASSERT_TRUE(google_apis::test_util::WriteStringToFile(upload_path
, "Hello"));
954 // To create a pending job for testing, set the mode to cellular connection
955 // and issue BACKGROUND jobs.
957 pref_service_
->SetBoolean(prefs::kDisableDriveOverCellular
, true);
959 // Start the first job and record its job ID.
960 google_apis::DriveApiErrorCode error1
= google_apis::DRIVE_OTHER_ERROR
;
961 scoped_ptr
<google_apis::FileResource
> entry
;
962 scheduler_
->UploadNewFile(
963 fake_drive_service_
->GetRootResourceId(), std::string("Hello").size(),
964 base::FilePath::FromUTF8Unsafe("dummy/path"), upload_path
,
965 "dummy title 1", "text/plain", UploadNewFileOptions(),
966 ClientContext(BACKGROUND
),
967 google_apis::test_util::CreateCopyResultCallback(&error1
, &entry
));
969 const std::vector
<JobInfo
>& jobs
= scheduler_
->GetJobInfoList();
970 ASSERT_EQ(1u, jobs
.size());
971 ASSERT_EQ(STATE_NONE
, jobs
[0].state
); // Not started yet.
972 JobID first_job_id
= jobs
[0].job_id
;
974 // Start the second job.
975 google_apis::DriveApiErrorCode error2
= google_apis::DRIVE_OTHER_ERROR
;
976 scheduler_
->UploadNewFile(
977 fake_drive_service_
->GetRootResourceId(), std::string("Hello").size(),
978 base::FilePath::FromUTF8Unsafe("dummy/path"), upload_path
,
979 "dummy title 2", "text/plain", UploadNewFileOptions(),
980 ClientContext(BACKGROUND
),
981 google_apis::test_util::CreateCopyResultCallback(&error2
, &entry
));
983 // Cancel the first one.
984 scheduler_
->CancelJob(first_job_id
);
986 // Only the first job should be cancelled.
988 base::RunLoop().RunUntilIdle();
989 EXPECT_EQ(google_apis::DRIVE_CANCELLED
, error1
);
990 EXPECT_EQ(google_apis::HTTP_SUCCESS
, error2
);
991 EXPECT_TRUE(scheduler_
->GetJobInfoList().empty());
994 TEST_F(JobSchedulerTest
, CancelRunningJob
) {
997 base::ScopedTempDir temp_dir
;
998 ASSERT_TRUE(temp_dir
.CreateUniqueTempDir());
999 base::FilePath upload_path
= temp_dir
.path().AppendASCII("new_file.txt");
1000 ASSERT_TRUE(google_apis::test_util::WriteStringToFile(upload_path
, "Hello"));
1002 // Run as a cancelable task.
1003 fake_drive_service_
->set_upload_new_file_cancelable(true);
1004 google_apis::DriveApiErrorCode error1
= google_apis::DRIVE_OTHER_ERROR
;
1005 scoped_ptr
<google_apis::FileResource
> entry
;
1006 scheduler_
->UploadNewFile(
1007 fake_drive_service_
->GetRootResourceId(), std::string("Hello").size(),
1008 base::FilePath::FromUTF8Unsafe("dummy/path"), upload_path
,
1009 "dummy title 1", "text/plain", UploadNewFileOptions(),
1010 ClientContext(USER_INITIATED
),
1011 google_apis::test_util::CreateCopyResultCallback(&error1
, &entry
));
1013 const std::vector
<JobInfo
>& jobs
= scheduler_
->GetJobInfoList();
1014 ASSERT_EQ(1u, jobs
.size());
1015 ASSERT_EQ(STATE_RUNNING
, jobs
[0].state
); // It's running.
1016 JobID first_job_id
= jobs
[0].job_id
;
1018 // Start the second job normally.
1019 fake_drive_service_
->set_upload_new_file_cancelable(false);
1020 google_apis::DriveApiErrorCode error2
= google_apis::DRIVE_OTHER_ERROR
;
1021 scheduler_
->UploadNewFile(
1022 fake_drive_service_
->GetRootResourceId(), std::string("Hello").size(),
1023 base::FilePath::FromUTF8Unsafe("dummy/path"), upload_path
,
1024 "dummy title 2", "text/plain", UploadNewFileOptions(),
1025 ClientContext(USER_INITIATED
),
1026 google_apis::test_util::CreateCopyResultCallback(&error2
, &entry
));
1028 // Cancel the first one.
1029 scheduler_
->CancelJob(first_job_id
);
1031 // Only the first job should be cancelled.
1032 base::RunLoop().RunUntilIdle();
1033 EXPECT_EQ(google_apis::DRIVE_CANCELLED
, error1
);
1034 EXPECT_EQ(google_apis::HTTP_SUCCESS
, error2
);
1035 EXPECT_TRUE(scheduler_
->GetJobInfoList().empty());
1038 } // namespace drive