15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/drive/sync_client.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/scoped_temp_dir.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/prefs/testing_pref_service.h"
12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/run_loop.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/test/test_timeouts.h"
14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/chromeos/drive/change_list_loader.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/drive/drive.pb.h"
16eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/browser/chromeos/drive/fake_free_disk_space_getter.h"
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/drive/file_cache.h"
18116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/chromeos/drive/file_change.h"
19a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/chromeos/drive/file_system/move_operation.h"
205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/chromeos/drive/file_system/operation_delegate.h"
21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/chromeos/drive/file_system/remove_operation.h"
22a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/chromeos/drive/file_system_util.h"
23868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/chromeos/drive/job_scheduler.h"
24868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/chromeos/drive/resource_entry_conversion.h"
25868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/chromeos/drive/resource_metadata.h"
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/drive/test_util.h"
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/drive/event_logger.h"
287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chrome/browser/drive/fake_drive_service.h"
29868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/public/test/test_browser_thread_bundle.h"
3046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "google_apis/drive/drive_api_parser.h"
31a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "google_apis/drive/test_util.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace drive {
3590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace internal {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// The content of files initially stored in the cache.
40868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const char kLocalContent[] = "Hello!";
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// The content of files stored in the service.
43868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const char kRemoteContent[] = "World!";
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// SyncClientTestDriveService will return GDATA_CANCELLED when a request is
46868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// made with the specified resource ID.
47eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass SyncClientTestDriveService : public ::drive::FakeDriveService {
48868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public:
49a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SyncClientTestDriveService() : download_file_count_(0) {}
50a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
51868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // FakeDriveService override:
52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  virtual google_apis::CancelCallback DownloadFile(
53eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      const base::FilePath& local_cache_path,
54868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      const std::string& resource_id,
55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      const google_apis::DownloadActionCallback& download_action_callback,
56eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      const google_apis::GetContentCallback& get_content_callback,
57eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      const google_apis::ProgressCallback& progress_callback) OVERRIDE {
58a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    ++download_file_count_;
59868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (resource_id == resource_id_to_be_cancelled_) {
60868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      base::MessageLoopProxy::current()->PostTask(
61868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          FROM_HERE,
62eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          base::Bind(download_action_callback,
63868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                     google_apis::GDATA_CANCELLED,
64eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     base::FilePath()));
657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return google_apis::CancelCallback();
66868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
67a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (resource_id == resource_id_to_be_paused_) {
68a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      paused_action_ = base::Bind(download_action_callback,
69a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                  google_apis::GDATA_OTHER_ERROR,
70a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                  base::FilePath());
71a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return google_apis::CancelCallback();
72a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
73eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return FakeDriveService::DownloadFile(local_cache_path,
74eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                          resource_id,
75eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                          download_action_callback,
76eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                          get_content_callback,
77eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                          progress_callback);
78868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
79868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
80a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  int download_file_count() const { return download_file_count_; }
81a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
82868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  void set_resource_id_to_be_cancelled(const std::string& resource_id) {
83868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    resource_id_to_be_cancelled_ = resource_id;
84868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
85868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
86a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void set_resource_id_to_be_paused(const std::string& resource_id) {
87a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    resource_id_to_be_paused_ = resource_id;
88a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
89a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
90a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const base::Closure& paused_action() const { return paused_action_; }
91a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
92868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private:
93a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  int download_file_count_;
94868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  std::string resource_id_to_be_cancelled_;
95a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::string resource_id_to_be_paused_;
96a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::Closure paused_action_;
97868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)};
98868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class SyncClientTest : public testing::Test {
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() OVERRIDE {
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    pref_service_.reset(new TestingPrefServiceSimple);
1077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    test_util::RegisterDrivePrefs(pref_service_->registry());
108868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
109eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    fake_network_change_notifier_.reset(
110eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        new test_util::FakeNetworkChangeNotifier);
111eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    logger_.reset(new EventLogger);
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
114868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    drive_service_.reset(new SyncClientTestDriveService);
115868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    scheduler_.reset(new JobScheduler(pref_service_.get(),
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                      logger_.get(),
1187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                      drive_service_.get(),
1197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                      base::MessageLoopProxy::current().get()));
120eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
121eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    metadata_storage_.reset(new ResourceMetadataStorage(
1227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        temp_dir_.path(), base::MessageLoopProxy::current().get()));
123eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    ASSERT_TRUE(metadata_storage_->Initialize());
124eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
125eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    cache_.reset(new FileCache(metadata_storage_.get(),
1267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                               temp_dir_.path(),
1277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                               base::MessageLoopProxy::current().get(),
128868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                               NULL /* free_disk_space_getter */));
1297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    ASSERT_TRUE(cache_->Initialize());
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    metadata_.reset(new internal::ResourceMetadata(
132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        metadata_storage_.get(), cache_.get(),
133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        base::MessageLoopProxy::current()));
134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ASSERT_EQ(FILE_ERROR_OK, metadata_->Initialize());
135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    about_resource_loader_.reset(new AboutResourceLoader(scheduler_.get()));
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    loader_controller_.reset(new LoaderController);
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    change_list_loader_.reset(new ChangeListLoader(
1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        logger_.get(),
1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        base::MessageLoopProxy::current().get(),
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        metadata_.get(),
1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        scheduler_.get(),
1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        about_resource_loader_.get(),
1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        loader_controller_.get()));
145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ASSERT_NO_FATAL_FAILURE(SetUpTestData());
146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    sync_client_.reset(new SyncClient(base::MessageLoopProxy::current().get(),
1485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                      &delegate_,
149868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                      scheduler_.get(),
150868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                      metadata_.get(),
1517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                      cache_.get(),
1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                      loader_controller_.get(),
1537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                      temp_dir_.path()));
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Disable delaying so that DoSyncLoop() starts immediately.
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sync_client_->set_delay_for_testing(base::TimeDelta::FromSeconds(0));
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
159868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Adds a file to the service root and |resource_ids_|.
160868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  void AddFileEntry(const std::string& title) {
161868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    google_apis::GDataErrorCode error = google_apis::GDATA_FILE_ERROR;
16246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    scoped_ptr<google_apis::FileResource> entry;
163868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    drive_service_->AddNewFile(
164868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        "text/plain",
165868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        kRemoteContent,
166868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        drive_service_->GetRootResourceId(),
167868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        title,
168868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        false,  // shared_with_me
169868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        google_apis::test_util::CreateCopyResultCallback(&error, &entry));
170868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    base::RunLoop().RunUntilIdle();
171868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ASSERT_EQ(google_apis::HTTP_CREATED, error);
172868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ASSERT_TRUE(entry);
17346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    resource_ids_[title] = entry->file_id();
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
176868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Sets up data for tests.
177868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  void SetUpTestData() {
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Prepare a temp file.
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::FilePath temp_file;
180a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &temp_file));
181868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ASSERT_TRUE(google_apis::test_util::WriteStringToFile(temp_file,
182868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                                          kLocalContent));
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // Add file entries to the service.
185868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ASSERT_NO_FATAL_FAILURE(AddFileEntry("foo"));
186868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ASSERT_NO_FATAL_FAILURE(AddFileEntry("bar"));
187868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ASSERT_NO_FATAL_FAILURE(AddFileEntry("baz"));
188868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ASSERT_NO_FATAL_FAILURE(AddFileEntry("fetched"));
189868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ASSERT_NO_FATAL_FAILURE(AddFileEntry("dirty"));
190f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ASSERT_NO_FATAL_FAILURE(AddFileEntry("removed"));
191a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    ASSERT_NO_FATAL_FAILURE(AddFileEntry("moved"));
192868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
193868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // Load data from the service to the metadata.
194868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    FileError error = FILE_ERROR_FAILED;
195a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    change_list_loader_->LoadIfNeeded(
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        google_apis::test_util::CreateCopyResultCallback(&error));
197868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    base::RunLoop().RunUntilIdle();
198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(FILE_ERROR_OK, error);
1994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // Prepare 3 pinned-but-not-present files.
2014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    EXPECT_EQ(FILE_ERROR_OK, cache_->Pin(GetLocalId("foo")));
2024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    EXPECT_EQ(FILE_ERROR_OK, cache_->Pin(GetLocalId("bar")));
2034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    EXPECT_EQ(FILE_ERROR_OK, cache_->Pin(GetLocalId("baz")));
2044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // Prepare a pinned-and-fetched file.
2064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const std::string md5_fetched = "md5";
2074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    EXPECT_EQ(FILE_ERROR_OK,
2084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)              cache_->Store(GetLocalId("fetched"), md5_fetched,
2094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                            temp_file, FileCache::FILE_OPERATION_COPY));
2104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    EXPECT_EQ(FILE_ERROR_OK, cache_->Pin(GetLocalId("fetched")));
2114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // Prepare a pinned-and-fetched-and-dirty file.
2134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    EXPECT_EQ(FILE_ERROR_OK,
2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              cache_->Store(GetLocalId("dirty"), std::string(),
2154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                            temp_file, FileCache::FILE_OPERATION_COPY));
2164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    EXPECT_EQ(FILE_ERROR_OK, cache_->Pin(GetLocalId("dirty")));
2174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
218f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Prepare a removed file.
219f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    file_system::RemoveOperation remove_operation(
2205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        base::MessageLoopProxy::current().get(), &delegate_, metadata_.get(),
221f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        cache_.get());
222f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    remove_operation.Remove(
223cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        util::GetDriveMyDriveRootPath().AppendASCII("removed"),
224f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        false,  // is_recursive
225f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        google_apis::test_util::CreateCopyResultCallback(&error));
226f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    base::RunLoop().RunUntilIdle();
227f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(FILE_ERROR_OK, error);
228a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
229a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // Prepare a moved file.
230a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    file_system::MoveOperation move_operation(
2315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        base::MessageLoopProxy::current().get(), &delegate_, metadata_.get());
232a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    move_operation.Move(
233cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        util::GetDriveMyDriveRootPath().AppendASCII("moved"),
234a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        util::GetDriveMyDriveRootPath().AppendASCII("moved_new_title"),
235a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        google_apis::test_util::CreateCopyResultCallback(&error));
236a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    base::RunLoop().RunUntilIdle();
237a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_EQ(FILE_ERROR_OK, error);
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
2414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string GetLocalId(const std::string& title) {
2424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    EXPECT_EQ(1U, resource_ids_.count(title));
2434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    std::string local_id;
2444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    EXPECT_EQ(FILE_ERROR_OK,
2454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)              metadata_->GetIdByResourceId(resource_ids_[title], &local_id));
2464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return local_id;
2474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
2484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
249868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  content::TestBrowserThreadBundle thread_bundle_;
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ScopedTempDir temp_dir_;
2517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  scoped_ptr<TestingPrefServiceSimple> pref_service_;
252eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<test_util::FakeNetworkChangeNotifier>
253eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      fake_network_change_notifier_;
2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<EventLogger> logger_;
255868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_ptr<SyncClientTestDriveService> drive_service_;
2565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  file_system::OperationDelegate delegate_;
257868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_ptr<JobScheduler> scheduler_;
258eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<ResourceMetadataStorage,
259eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch             test_util::DestroyHelperForTests> metadata_storage_;
26090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<FileCache, test_util::DestroyHelperForTests> cache_;
261cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<ResourceMetadata, test_util::DestroyHelperForTests> metadata_;
2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<AboutResourceLoader> about_resource_loader_;
2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<LoaderController> loader_controller_;
2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<ChangeListLoader> change_list_loader_;
265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<SyncClient> sync_client_;
266868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
267868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  std::map<std::string, std::string> resource_ids_;  // Name-to-id map.
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
270868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST_F(SyncClientTest, StartProcessingBacklog) {
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_client_->StartProcessingBacklog();
272868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  base::RunLoop().RunUntilIdle();
273868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
274cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ResourceEntry entry;
275868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Pinned files get downloaded.
276cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(FILE_ERROR_OK,
277cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            metadata_->GetResourceEntryById(GetLocalId("foo"), &entry));
278cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(entry.file_specific_info().cache_state().is_present());
279868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
280cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(FILE_ERROR_OK,
281cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            metadata_->GetResourceEntryById(GetLocalId("bar"), &entry));
282cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(entry.file_specific_info().cache_state().is_present());
283868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
284cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(FILE_ERROR_OK,
285cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            metadata_->GetResourceEntryById(GetLocalId("baz"), &entry));
286cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(entry.file_specific_info().cache_state().is_present());
287868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
288868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Dirty file gets uploaded.
289cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(FILE_ERROR_OK,
290cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            metadata_->GetResourceEntryById(GetLocalId("dirty"), &entry));
291cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_FALSE(entry.file_specific_info().cache_state().is_dirty());
292f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
293f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Removed entry is not found.
294f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  google_apis::GDataErrorCode status = google_apis::GDATA_OTHER_ERROR;
29546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<google_apis::FileResource> server_entry;
29646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  drive_service_->GetFileResource(
297f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      resource_ids_["removed"],
29846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      google_apis::test_util::CreateCopyResultCallback(&status, &server_entry));
299f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::RunLoop().RunUntilIdle();
300f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(google_apis::HTTP_SUCCESS, status);
30146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_TRUE(server_entry);
30246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_TRUE(server_entry->labels().is_trashed());
303a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
304a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Moved entry was moved.
305a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  status = google_apis::GDATA_OTHER_ERROR;
30646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  drive_service_->GetFileResource(
307a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      resource_ids_["moved"],
30846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      google_apis::test_util::CreateCopyResultCallback(&status, &server_entry));
309a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::RunLoop().RunUntilIdle();
310a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(google_apis::HTTP_SUCCESS, status);
31146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_TRUE(server_entry);
31246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_EQ("moved_new_title", server_entry->title());
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(SyncClientTest, AddFetchTask) {
3164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  sync_client_->AddFetchTask(GetLocalId("foo"));
317868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  base::RunLoop().RunUntilIdle();
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
319cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ResourceEntry entry;
320cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(FILE_ERROR_OK,
321cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            metadata_->GetResourceEntryById(GetLocalId("foo"), &entry));
322cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(entry.file_specific_info().cache_state().is_present());
323868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(SyncClientTest, AddFetchTaskAndCancelled) {
326868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Trigger fetching of a file which results in cancellation.
3277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  drive_service_->set_resource_id_to_be_cancelled(resource_ids_["foo"]);
3284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  sync_client_->AddFetchTask(GetLocalId("foo"));
329868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  base::RunLoop().RunUntilIdle();
330868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
331868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // The file should be unpinned if the user wants the download to be cancelled.
332cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ResourceEntry entry;
333cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(FILE_ERROR_OK,
334cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            metadata_->GetResourceEntryById(GetLocalId("foo"), &entry));
335cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_FALSE(entry.file_specific_info().cache_state().is_pinned());
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(SyncClientTest, RemoveFetchTask) {
3394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  sync_client_->AddFetchTask(GetLocalId("foo"));
3404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  sync_client_->AddFetchTask(GetLocalId("bar"));
3414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  sync_client_->AddFetchTask(GetLocalId("baz"));
3427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  sync_client_->RemoveFetchTask(GetLocalId("foo"));
3444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  sync_client_->RemoveFetchTask(GetLocalId("baz"));
345868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  base::RunLoop().RunUntilIdle();
346868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
347868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Only "bar" should be fetched.
348cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ResourceEntry entry;
349cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(FILE_ERROR_OK,
350cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            metadata_->GetResourceEntryById(GetLocalId("foo"), &entry));
351cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_FALSE(entry.file_specific_info().cache_state().is_present());
352868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
353cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(FILE_ERROR_OK,
354cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            metadata_->GetResourceEntryById(GetLocalId("bar"), &entry));
355cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(entry.file_specific_info().cache_state().is_present());
356868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
357cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(FILE_ERROR_OK,
358cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            metadata_->GetResourceEntryById(GetLocalId("baz"), &entry));
359cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_FALSE(entry.file_specific_info().cache_state().is_present());
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(SyncClientTest, ExistingPinnedFiles) {
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start checking the existing pinned files. This will collect the resource
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // IDs of pinned files, with stale local cache files.
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_client_->StartCheckingExistingPinnedFiles();
367868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  base::RunLoop().RunUntilIdle();
368868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
369868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // "fetched" and "dirty" are the existing pinned files.
370868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // The non-dirty one should be synced, but the dirty one should not.
371868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  base::FilePath cache_file;
372868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  std::string content;
3734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(FILE_ERROR_OK, cache_->GetFile(GetLocalId("fetched"), &cache_file));
37458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_TRUE(base::ReadFileToString(cache_file, &content));
375868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(kRemoteContent, content);
376868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  content.clear();
377868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(FILE_ERROR_OK, cache_->GetFile(GetLocalId("dirty"), &cache_file));
37958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_TRUE(base::ReadFileToString(cache_file, &content));
380868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(kLocalContent, content);
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
383eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_F(SyncClientTest, RetryOnDisconnection) {
384eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Let the service go down.
385eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  drive_service_->set_offline(true);
386eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Change the network connection state after some delay, to test that
387eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // FILE_ERROR_NO_CONNECTION is handled by SyncClient correctly.
388eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Without this delay, JobScheduler will keep the jobs unrun and SyncClient
389eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // will receive no error.
390eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::MessageLoopProxy::current()->PostDelayedTask(
391eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      FROM_HERE,
392eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      base::Bind(&test_util::FakeNetworkChangeNotifier::SetConnectionType,
393eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                 base::Unretained(fake_network_change_notifier_.get()),
394eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                 net::NetworkChangeNotifier::CONNECTION_NONE),
395eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      TestTimeouts::tiny_timeout());
396eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
397eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Try fetch and upload.
3984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  sync_client_->AddFetchTask(GetLocalId("foo"));
3995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  sync_client_->AddUpdateTask(ClientContext(USER_INITIATED),
400f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                              GetLocalId("dirty"));
401eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::RunLoop().RunUntilIdle();
402eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
403eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Not yet fetched nor uploaded.
404cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ResourceEntry entry;
405cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(FILE_ERROR_OK,
406cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            metadata_->GetResourceEntryById(GetLocalId("foo"), &entry));
407cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_FALSE(entry.file_specific_info().cache_state().is_present());
408cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(FILE_ERROR_OK,
409cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            metadata_->GetResourceEntryById(GetLocalId("dirty"), &entry));
410cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(entry.file_specific_info().cache_state().is_dirty());
411eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
412eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Switch to online.
413eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  fake_network_change_notifier_->SetConnectionType(
414eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      net::NetworkChangeNotifier::CONNECTION_WIFI);
415eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  drive_service_->set_offline(false);
416eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::RunLoop().RunUntilIdle();
417eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
418eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Fetched and uploaded.
419cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(FILE_ERROR_OK,
420cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            metadata_->GetResourceEntryById(GetLocalId("foo"), &entry));
421cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(entry.file_specific_info().cache_state().is_present());
422cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(FILE_ERROR_OK,
423cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            metadata_->GetResourceEntryById(GetLocalId("dirty"), &entry));
424cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_FALSE(entry.file_specific_info().cache_state().is_dirty());
425eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
426eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
427a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(SyncClientTest, ScheduleRerun) {
428a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Add a fetch task for "foo", this should result in being paused.
429a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  drive_service_->set_resource_id_to_be_paused(resource_ids_["foo"]);
430a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  sync_client_->AddFetchTask(GetLocalId("foo"));
431a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::RunLoop().RunUntilIdle();
432a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
433a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // While the first task is paused, add a task again.
434a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // This results in scheduling rerun of the task.
435a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  sync_client_->AddFetchTask(GetLocalId("foo"));
436a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::RunLoop().RunUntilIdle();
437a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
438a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Resume the paused task.
439a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  drive_service_->set_resource_id_to_be_paused(std::string());
440a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_FALSE(drive_service_->paused_action().is_null());
441a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  drive_service_->paused_action().Run();
442a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::RunLoop().RunUntilIdle();
443a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
444a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Task should be run twice.
445a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(2, drive_service_->download_file_count());
446a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
447a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
4485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(SyncClientTest, Dependencies) {
4495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Create directories locally.
4505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::FilePath kPath1(FILE_PATH_LITERAL("drive/root/dir1"));
4515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::FilePath kPath2 = kPath1.AppendASCII("dir2");
4525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ResourceEntry parent;
4545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(FILE_ERROR_OK,
4555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            metadata_->GetResourceEntryByPath(kPath1.DirName(), &parent));
4565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ResourceEntry entry1;
4585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  entry1.set_parent_local_id(parent.local_id());
4595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  entry1.set_title(kPath1.BaseName().AsUTF8Unsafe());
4605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  entry1.mutable_file_info()->set_is_directory(true);
4615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  entry1.set_metadata_edit_state(ResourceEntry::DIRTY);
4625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string local_id1;
4635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(FILE_ERROR_OK, metadata_->AddEntry(entry1, &local_id1));
4645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ResourceEntry entry2;
4665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  entry2.set_parent_local_id(local_id1);
4675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  entry2.set_title(kPath2.BaseName().AsUTF8Unsafe());
4685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  entry2.mutable_file_info()->set_is_directory(true);
4695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  entry2.set_metadata_edit_state(ResourceEntry::DIRTY);
4705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string local_id2;
4715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(FILE_ERROR_OK, metadata_->AddEntry(entry2, &local_id2));
4725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Start syncing the child first.
4745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  sync_client_->AddUpdateTask(ClientContext(USER_INITIATED), local_id2);
4755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Start syncing the parent later.
4765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  sync_client_->AddUpdateTask(ClientContext(USER_INITIATED), local_id1);
4775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::RunLoop().RunUntilIdle();
4785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Both entries are synced.
4805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetResourceEntryById(local_id1, &entry1));
4815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(ResourceEntry::CLEAN, entry1.metadata_edit_state());
4825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetResourceEntryById(local_id2, &entry2));
4835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(ResourceEntry::CLEAN, entry2.metadata_edit_state());
4845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)TEST_F(SyncClientTest, WaitForUpdateTaskToComplete) {
4875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Create a directory locally.
4885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const base::FilePath kPath(FILE_PATH_LITERAL("drive/root/dir1"));
4895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ResourceEntry parent;
4915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(FILE_ERROR_OK,
4925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            metadata_->GetResourceEntryByPath(kPath.DirName(), &parent));
4935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ResourceEntry entry;
4955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  entry.set_parent_local_id(parent.local_id());
4965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  entry.set_title(kPath.BaseName().AsUTF8Unsafe());
4975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  entry.mutable_file_info()->set_is_directory(true);
4985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  entry.set_metadata_edit_state(ResourceEntry::DIRTY);
4995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  std::string local_id;
5005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(FILE_ERROR_OK, metadata_->AddEntry(entry, &local_id));
5015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Sync task is not yet avialable.
5035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  FileError error = FILE_ERROR_FAILED;
5045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_FALSE(sync_client_->WaitForUpdateTaskToComplete(
5055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      local_id, google_apis::test_util::CreateCopyResultCallback(&error)));
5065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Start syncing the directory and wait for it to complete.
5085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  sync_client_->AddUpdateTask(ClientContext(USER_INITIATED), local_id);
5095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_TRUE(sync_client_->WaitForUpdateTaskToComplete(
5115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      local_id, google_apis::test_util::CreateCopyResultCallback(&error)));
5125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  base::RunLoop().RunUntilIdle();
5145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // The callback is called.
5165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(FILE_ERROR_OK, error);
5175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
5185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
51990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}  // namespace internal
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace drive
521