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 "chrome/browser/chromeos/drive/job_scheduler.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"
30 // Dummy value passed for the |expected_file_size| parameter of DownloadFile().
31 const int64 kDummyDownloadFileSize
= 0;
33 void 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());
40 class JobListLogger
: public JobListObserver
{
52 EventLog(EventType type
, const JobInfo
& info
) : type(type
), info(info
) {
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
)
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
);
73 // JobListObserver overrides.
74 virtual void OnJobAdded(const JobInfo
& info
) OVERRIDE
{
75 events
.push_back(EventLog(ADDED
, info
));
78 virtual void OnJobUpdated(const JobInfo
& info
) OVERRIDE
{
79 events
.push_back(EventLog(UPDATED
, info
));
82 virtual void OnJobDone(const JobInfo
& info
, FileError error
) OVERRIDE
{
83 events
.push_back(EventLog(DONE
, info
));
87 std::vector
<EventLog
> events
;
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.
94 class CancelTestableFakeDriveService
: public FakeDriveService
{
96 CancelTestableFakeDriveService()
97 : upload_new_file_cancelable_(false) {
100 void set_upload_new_file_cancelable(bool cancelable
) {
101 upload_new_file_cancelable_
= cancelable
;
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());
114 return FakeDriveService::InitiateUploadNewFile(content_type
,
123 bool upload_new_file_cancelable_
;
128 class JobSchedulerTest
: public testing::Test
{
131 : pref_service_(new TestingPrefServiceSimple
) {
132 test_util::RegisterDrivePrefs(pref_service_
->registry());
135 virtual void SetUp() OVERRIDE
{
136 fake_network_change_notifier_
.reset(
137 new test_util::FakeNetworkChangeNotifier
);
139 logger_
.reset(new EventLogger
);
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");
149 scheduler_
.reset(new JobScheduler(pref_service_
.get(),
151 fake_drive_service_
.get(),
152 base::MessageLoopProxy::current().get()));
153 scheduler_
->SetDisableThrottling(true);
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
);
163 // Sets up FakeNetworkChangeNotifier as if it's connected to wifi network.
164 void ConnectToWifi() {
165 ChangeConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI
);
168 // Sets up FakeNetworkChangeNotifier as if it's connected to cellular network.
169 void ConnectToCellular() {
170 ChangeConnectionType(net::NetworkChangeNotifier::CONNECTION_2G
);
173 // Sets up FakeNetworkChangeNotifier as if it's connected to wimax network.
174 void ConnectToWimax() {
175 ChangeConnectionType(net::NetworkChangeNotifier::CONNECTION_4G
);
178 // Sets up FakeNetworkChangeNotifier as if it's disconnected.
179 void ConnectToNone() {
180 ChangeConnectionType(net::NetworkChangeNotifier::CONNECTION_NONE
);
183 static int GetMetadataQueueMaxJobCount() {
184 return JobScheduler::kMaxJobCount
[JobScheduler::METADATA_QUEUE
];
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_
;
196 TEST_F(JobSchedulerTest
, GetAboutResource
) {
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
);
209 TEST_F(JobSchedulerTest
, GetAppList
) {
212 google_apis::GDataErrorCode error
= google_apis::GDATA_OTHER_ERROR
;
213 scoped_ptr
<google_apis::AppList
> app_list
;
215 scheduler_
->GetAppList(
216 google_apis::test_util::CreateCopyResultCallback(&error
, &app_list
));
217 base::RunLoop().RunUntilIdle();
219 ASSERT_EQ(google_apis::HTTP_SUCCESS
, error
);
220 ASSERT_TRUE(app_list
);
223 TEST_F(JobSchedulerTest
, GetAllResourceList
) {
226 google_apis::GDataErrorCode error
= google_apis::GDATA_OTHER_ERROR
;
227 scoped_ptr
<google_apis::ResourceList
> resource_list
;
229 scheduler_
->GetAllResourceList(
230 google_apis::test_util::CreateCopyResultCallback(
231 &error
, &resource_list
));
232 base::RunLoop().RunUntilIdle();
234 ASSERT_EQ(google_apis::HTTP_SUCCESS
, error
);
235 ASSERT_TRUE(resource_list
);
238 TEST_F(JobSchedulerTest
, GetResourceListInDirectory
) {
241 google_apis::GDataErrorCode error
= google_apis::GDATA_OTHER_ERROR
;
242 scoped_ptr
<google_apis::ResourceList
> resource_list
;
244 scheduler_
->GetResourceListInDirectory(
245 fake_drive_service_
->GetRootResourceId(),
246 google_apis::test_util::CreateCopyResultCallback(
247 &error
, &resource_list
));
248 base::RunLoop().RunUntilIdle();
250 ASSERT_EQ(google_apis::HTTP_SUCCESS
, error
);
251 ASSERT_TRUE(resource_list
);
254 TEST_F(JobSchedulerTest
, Search
) {
257 google_apis::GDataErrorCode error
= google_apis::GDATA_OTHER_ERROR
;
258 scoped_ptr
<google_apis::ResourceList
> resource_list
;
261 "File", // search query
262 google_apis::test_util::CreateCopyResultCallback(
263 &error
, &resource_list
));
264 base::RunLoop().RunUntilIdle();
266 ASSERT_EQ(google_apis::HTTP_SUCCESS
, error
);
267 ASSERT_TRUE(resource_list
);
270 TEST_F(JobSchedulerTest
, GetChangeList
) {
273 google_apis::GDataErrorCode error
= google_apis::GDATA_OTHER_ERROR
;
275 // Create a new directory.
276 // The loaded (initial) changestamp is 654321. Thus, by this operation,
277 // it should become 654322.
279 scoped_ptr
<google_apis::ResourceEntry
> resource_entry
;
280 fake_drive_service_
->AddNewDirectory(
281 fake_drive_service_
->GetRootResourceId(),
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
);
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();
298 ASSERT_EQ(google_apis::HTTP_SUCCESS
, error
);
299 ASSERT_TRUE(resource_list
);
302 TEST_F(JobSchedulerTest
, GetRemainingChangeList
) {
304 fake_drive_service_
->set_default_max_results(2);
306 google_apis::GDataErrorCode error
= google_apis::GDATA_OTHER_ERROR
;
307 scoped_ptr
<google_apis::ResourceList
> resource_list
;
309 scheduler_
->GetAllResourceList(
310 google_apis::test_util::CreateCopyResultCallback(
311 &error
, &resource_list
));
312 base::RunLoop().RunUntilIdle();
314 ASSERT_EQ(google_apis::HTTP_SUCCESS
, error
);
315 ASSERT_TRUE(resource_list
);
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());
323 error
= google_apis::GDATA_OTHER_ERROR
;
324 resource_list
.reset();
326 scheduler_
->GetRemainingChangeList(
328 google_apis::test_util::CreateCopyResultCallback(
329 &error
, &resource_list
));
330 base::RunLoop().RunUntilIdle();
332 ASSERT_EQ(google_apis::HTTP_SUCCESS
, error
);
333 ASSERT_TRUE(resource_list
);
336 TEST_F(JobSchedulerTest
, GetRemainingFileList
) {
338 fake_drive_service_
->set_default_max_results(2);
340 google_apis::GDataErrorCode error
= google_apis::GDATA_OTHER_ERROR
;
341 scoped_ptr
<google_apis::ResourceList
> resource_list
;
343 scheduler_
->GetResourceListInDirectory(
344 fake_drive_service_
->GetRootResourceId(),
345 google_apis::test_util::CreateCopyResultCallback(
346 &error
, &resource_list
));
347 base::RunLoop().RunUntilIdle();
349 ASSERT_EQ(google_apis::HTTP_SUCCESS
, error
);
350 ASSERT_TRUE(resource_list
);
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());
358 error
= google_apis::GDATA_OTHER_ERROR
;
359 resource_list
.reset();
361 scheduler_
->GetRemainingFileList(
363 google_apis::test_util::CreateCopyResultCallback(
364 &error
, &resource_list
));
365 base::RunLoop().RunUntilIdle();
367 ASSERT_EQ(google_apis::HTTP_SUCCESS
, error
);
368 ASSERT_TRUE(resource_list
);
371 TEST_F(JobSchedulerTest
, GetResourceEntry
) {
374 google_apis::GDataErrorCode error
= google_apis::GDATA_OTHER_ERROR
;
375 scoped_ptr
<google_apis::ResourceEntry
> entry
;
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();
383 ASSERT_EQ(google_apis::HTTP_SUCCESS
, error
);
387 TEST_F(JobSchedulerTest
, GetShareUrl
) {
390 google_apis::GDataErrorCode error
= google_apis::GDATA_OTHER_ERROR
;
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();
400 ASSERT_EQ(google_apis::HTTP_SUCCESS
, error
);
401 ASSERT_FALSE(share_url
.is_empty());
404 TEST_F(JobSchedulerTest
, TrashResource
) {
407 google_apis::GDataErrorCode error
= google_apis::GDATA_OTHER_ERROR
;
409 scheduler_
->TrashResource(
410 "file:2_file_resource_id",
411 ClientContext(USER_INITIATED
),
412 google_apis::test_util::CreateCopyResultCallback(&error
));
413 base::RunLoop().RunUntilIdle();
415 ASSERT_EQ(google_apis::HTTP_SUCCESS
, error
);
418 TEST_F(JobSchedulerTest
, CopyResource
) {
421 google_apis::GDataErrorCode error
= google_apis::GDATA_OTHER_ERROR
;
422 scoped_ptr
<google_apis::ResourceEntry
> entry
;
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
429 google_apis::test_util::CreateCopyResultCallback(&error
, &entry
));
430 base::RunLoop().RunUntilIdle();
432 ASSERT_EQ(google_apis::HTTP_SUCCESS
, error
);
436 TEST_F(JobSchedulerTest
, UpdateResource
) {
439 google_apis::GDataErrorCode error
= google_apis::GDATA_OTHER_ERROR
;
440 scoped_ptr
<google_apis::ResourceEntry
> entry
;
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
448 ClientContext(USER_INITIATED
),
449 google_apis::test_util::CreateCopyResultCallback(&error
, &entry
));
450 base::RunLoop().RunUntilIdle();
452 ASSERT_EQ(google_apis::HTTP_SUCCESS
, error
);
456 TEST_F(JobSchedulerTest
, RenameResource
) {
459 google_apis::GDataErrorCode error
= google_apis::GDATA_OTHER_ERROR
;
461 scheduler_
->RenameResource(
462 "file:2_file_resource_id",
464 google_apis::test_util::CreateCopyResultCallback(&error
));
465 base::RunLoop().RunUntilIdle();
467 ASSERT_EQ(google_apis::HTTP_SUCCESS
, error
);
470 TEST_F(JobSchedulerTest
, AddResourceToDirectory
) {
473 google_apis::GDataErrorCode error
= google_apis::GDATA_OTHER_ERROR
;
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();
481 ASSERT_EQ(google_apis::HTTP_SUCCESS
, error
);
484 TEST_F(JobSchedulerTest
, RemoveResourceFromDirectory
) {
487 google_apis::GDataErrorCode error
= google_apis::GDATA_OTHER_ERROR
;
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();
496 ASSERT_EQ(google_apis::HTTP_NO_CONTENT
, error
);
499 TEST_F(JobSchedulerTest
, AddNewDirectory
) {
502 google_apis::GDataErrorCode error
= google_apis::GDATA_OTHER_ERROR
;
503 scoped_ptr
<google_apis::ResourceEntry
> entry
;
505 scheduler_
->AddNewDirectory(
506 fake_drive_service_
->GetRootResourceId(), // Root directory.
508 DriveServiceInterface::AddNewDirectoryOptions(),
509 ClientContext(USER_INITIATED
),
510 google_apis::test_util::CreateCopyResultCallback(&error
, &entry
));
511 base::RunLoop().RunUntilIdle();
513 ASSERT_EQ(google_apis::HTTP_CREATED
, error
);
517 TEST_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(
526 ClientContext(USER_INITIATED
),
527 google_apis::test_util::CreateCopyResultCallback(&error_dontcare
,
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
;
538 scheduler_
->AddNewDirectory(
539 fake_drive_service_
->GetRootResourceId(),
541 DriveServiceInterface::AddNewDirectoryOptions(),
542 ClientContext(USER_INITIATED
),
543 base::Bind(&CopyTitleFromGetResourceEntryCallback
, &titles
));
544 scheduler_
->AddNewDirectory(
545 fake_drive_service_
->GetRootResourceId(),
547 DriveServiceInterface::AddNewDirectoryOptions(),
548 ClientContext(BACKGROUND
),
549 base::Bind(&CopyTitleFromGetResourceEntryCallback
, &titles
));
550 scheduler_
->AddNewDirectory(
551 fake_drive_service_
->GetRootResourceId(),
553 DriveServiceInterface::AddNewDirectoryOptions(),
554 ClientContext(BACKGROUND
),
555 base::Bind(&CopyTitleFromGetResourceEntryCallback
, &titles
));
556 scheduler_
->AddNewDirectory(
557 fake_drive_service_
->GetRootResourceId(),
559 DriveServiceInterface::AddNewDirectoryOptions(),
560 ClientContext(USER_INITIATED
),
561 base::Bind(&CopyTitleFromGetResourceEntryCallback
, &titles
));
563 base::RunLoop().RunUntilIdle();
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]);
572 TEST_F(JobSchedulerTest
, NoConnectionUserInitiated
) {
575 std::string
resource_id("file:2_file_resource_id");
577 google_apis::GDataErrorCode error
= google_apis::GDATA_OTHER_ERROR
;
578 scoped_ptr
<google_apis::ResourceEntry
> entry
;
579 scheduler_
->GetResourceEntry(
581 ClientContext(USER_INITIATED
),
582 google_apis::test_util::CreateCopyResultCallback(&error
, &entry
));
583 base::RunLoop().RunUntilIdle();
585 EXPECT_EQ(google_apis::GDATA_NO_CONNECTION
, error
);
588 TEST_F(JobSchedulerTest
, NoConnectionBackground
) {
591 std::string
resource_id("file:2_file_resource_id");
593 google_apis::GDataErrorCode error
= google_apis::GDATA_OTHER_ERROR
;
594 scoped_ptr
<google_apis::ResourceEntry
> entry
;
595 scheduler_
->GetResourceEntry(
597 ClientContext(BACKGROUND
),
598 google_apis::test_util::CreateCopyResultCallback(&error
, &entry
));
599 base::RunLoop().RunUntilIdle();
603 // Reconnect to the net.
606 base::RunLoop().RunUntilIdle();
608 EXPECT_EQ(google_apis::HTTP_SUCCESS
, error
);
612 TEST_F(JobSchedulerTest
, DownloadFileCellularDisabled
) {
615 // Disable fetching over cellular network.
616 pref_service_
->SetBoolean(prefs::kDisableDriveOverCellular
, true);
618 // Try to get a file in the background
619 base::ScopedTempDir temp_dir
;
620 ASSERT_TRUE(temp_dir
.CreateUniqueTempDir());
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
,
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
;
639 // Try to get the metadata
640 scheduler_
->GetAboutResource(
641 google_apis::test_util::CreateCopyResultCallback(
642 &metadata_error
, &about_resource
));
643 base::RunLoop().RunUntilIdle();
645 // Check the metadata
646 ASSERT_EQ(google_apis::HTTP_SUCCESS
, metadata_error
);
647 ASSERT_TRUE(about_resource
);
649 // Check the download
650 EXPECT_EQ(google_apis::GDATA_OTHER_ERROR
, download_error
);
652 // Switch to a Wifi connection
655 base::RunLoop().RunUntilIdle();
657 // Check the download again
658 EXPECT_EQ(google_apis::HTTP_SUCCESS
, download_error
);
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
);
665 TEST_F(JobSchedulerTest
, DownloadFileWimaxDisabled
) {
668 // Disable fetching over cellular network.
669 pref_service_
->SetBoolean(prefs::kDisableDriveOverCellular
, true);
671 // Try to get a file in the background
672 base::ScopedTempDir temp_dir
;
673 ASSERT_TRUE(temp_dir
.CreateUniqueTempDir());
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
,
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
;
692 // Try to get the metadata
693 scheduler_
->GetAboutResource(
694 google_apis::test_util::CreateCopyResultCallback(
695 &metadata_error
, &about_resource
));
696 base::RunLoop().RunUntilIdle();
698 // Check the metadata
699 ASSERT_EQ(google_apis::HTTP_SUCCESS
, metadata_error
);
700 ASSERT_TRUE(about_resource
);
702 // Check the download
703 EXPECT_EQ(google_apis::GDATA_OTHER_ERROR
, download_error
);
705 // Switch to a Wifi connection
708 base::RunLoop().RunUntilIdle();
710 // Check the download again
711 EXPECT_EQ(google_apis::HTTP_SUCCESS
, download_error
);
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
);
718 TEST_F(JobSchedulerTest
, DownloadFileCellularEnabled
) {
721 // Enable fetching over cellular network.
722 pref_service_
->SetBoolean(prefs::kDisableDriveOverCellular
, false);
724 // Try to get a file in the background
725 base::ScopedTempDir temp_dir
;
726 ASSERT_TRUE(temp_dir
.CreateUniqueTempDir());
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
,
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
;
745 // Try to get the metadata
746 scheduler_
->GetAboutResource(
747 google_apis::test_util::CreateCopyResultCallback(
748 &metadata_error
, &about_resource
));
749 base::RunLoop().RunUntilIdle();
751 // Check the metadata
752 ASSERT_EQ(google_apis::HTTP_SUCCESS
, metadata_error
);
753 ASSERT_TRUE(about_resource
);
755 // Check the download
756 EXPECT_EQ(google_apis::HTTP_SUCCESS
, download_error
);
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
);
763 TEST_F(JobSchedulerTest
, DownloadFileWimaxEnabled
) {
766 // Enable fetching over cellular network.
767 pref_service_
->SetBoolean(prefs::kDisableDriveOverCellular
, false);
769 // Try to get a file in the background
770 base::ScopedTempDir temp_dir
;
771 ASSERT_TRUE(temp_dir
.CreateUniqueTempDir());
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
,
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
;
790 // Try to get the metadata
791 scheduler_
->GetAboutResource(
792 google_apis::test_util::CreateCopyResultCallback(
793 &metadata_error
, &about_resource
));
794 base::RunLoop().RunUntilIdle();
796 // Check the metadata
797 ASSERT_EQ(google_apis::HTTP_SUCCESS
, metadata_error
);
798 ASSERT_TRUE(about_resource
);
800 // Check the download
801 EXPECT_EQ(google_apis::HTTP_SUCCESS
, download_error
);
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
);
808 TEST_F(JobSchedulerTest
, JobInfo
) {
809 JobListLogger logger
;
810 scheduler_
->AddObserver(&logger
);
812 // Disable background upload/download.
814 pref_service_
->SetBoolean(prefs::kDisableDriveOverCellular
, true);
816 base::ScopedTempDir temp_dir
;
817 ASSERT_TRUE(temp_dir
.CreateUniqueTempDir());
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
;
824 std::set
<JobType
> expected_types
;
827 expected_types
.insert(TYPE_ADD_NEW_DIRECTORY
);
828 scheduler_
->AddNewDirectory(
829 fake_drive_service_
->GetRootResourceId(),
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",
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());
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
));
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(),
875 base::Time(), // last_modified
876 google_apis::test_util::CreateCopyResultCallback(&error
, &entry
));
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
);
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
));
895 base::RunLoop().RunUntilIdle();
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
);
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
));
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
));
918 // Run the background downloading job as well.
920 base::RunLoop().RunUntilIdle();
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
));
928 TEST_F(JobSchedulerTest
, JobInfoProgress
) {
929 JobListLogger logger
;
930 scheduler_
->AddObserver(&logger
);
934 base::ScopedTempDir temp_dir
;
935 ASSERT_TRUE(temp_dir
.CreateUniqueTempDir());
937 google_apis::GDataErrorCode error
= google_apis::GDATA_OTHER_ERROR
;
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();
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);
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
;
965 scheduler_
->UploadNewFile(
966 fake_drive_service_
->GetRootResourceId(),
967 base::FilePath::FromUTF8Unsafe("drive/new_file.txt"),
971 DriveUploader::UploadNewFileOptions(),
972 ClientContext(BACKGROUND
),
973 google_apis::test_util::CreateCopyResultCallback(&upload_error
, &entry
));
974 base::RunLoop().RunUntilIdle();
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);
984 TEST_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"));
990 // To create a pending job for testing, set the mode to cellular connection
991 // and issue BACKGROUND jobs.
993 pref_service_
->SetBoolean(prefs::kDisableDriveOverCellular
, true);
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"),
1004 DriveUploader::UploadNewFileOptions(),
1005 ClientContext(BACKGROUND
),
1006 google_apis::test_util::CreateCopyResultCallback(&error1
, &entry
));
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
;
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"),
1021 DriveUploader::UploadNewFileOptions(),
1022 ClientContext(BACKGROUND
),
1023 google_apis::test_util::CreateCopyResultCallback(&error2
, &entry
));
1025 // Cancel the first one.
1026 scheduler_
->CancelJob(first_job_id
);
1028 // Only the first job should be cancelled.
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());
1036 TEST_F(JobSchedulerTest
, CancelRunningJob
) {
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"));
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"),
1054 DriveUploader::UploadNewFileOptions(),
1055 ClientContext(USER_INITIATED
),
1056 google_apis::test_util::CreateCopyResultCallback(&error1
, &entry
));
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
;
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"),
1072 DriveUploader::UploadNewFileOptions(),
1073 ClientContext(USER_INITIATED
),
1074 google_apis::test_util::CreateCopyResultCallback(&error2
, &entry
));
1076 // Cancel the first one.
1077 scheduler_
->CancelJob(first_job_id
);
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());
1086 } // namespace drive