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