1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// found in the LICENSE file.
4f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/sync_file_system/drive_backend/remote_to_local_syncer.h"
6f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
7f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include <map>
8f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/bind.h"
10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/callback.h"
11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/files/scoped_temp_dir.h"
12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/logging.h"
13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/run_loop.h"
14116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/thread_task_runner_handle.h"
15f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/drive/drive_uploader.h"
16f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/drive/fake_drive_service.h"
17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/sync_file_system/drive_backend/drive_backend_constants.h"
18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/sync_file_system/drive_backend/drive_backend_test_util.h"
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/sync_file_system/drive_backend/fake_drive_service_helper.h"
20f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/sync_file_system/drive_backend/list_changes_task.h"
21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/sync_file_system/drive_backend/metadata_database.h"
22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/sync_file_system/drive_backend/sync_engine_context.h"
23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/sync_file_system/drive_backend/sync_engine_initializer.h"
24effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "chrome/browser/sync_file_system/drive_backend/sync_task_manager.h"
25116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/sync_file_system/drive_backend/sync_task_token.h"
26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/sync_file_system/fake_remote_change_processor.h"
27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/sync_file_system/sync_file_system_test_util.h"
28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/sync_file_system/syncable_file_system_util.h"
29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/public/test/test_browser_thread_bundle.h"
30a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "google_apis/drive/gdata_errorcode.h"
31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "third_party/leveldatabase/src/helpers/memenv/memenv.h"
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "third_party/leveldatabase/src/include/leveldb/env.h"
34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace sync_file_system {
36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace drive_backend {
37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace {
39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
4003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)storage::FileSystemURL URL(const GURL& origin, const std::string& path) {
41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return CreateSyncableFileSystemURL(
42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      origin, base::FilePath::FromUTF8Unsafe(path));
43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace
46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
47effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochclass RemoteToLocalSyncerTest : public testing::Test {
48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) public:
49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  typedef FakeRemoteChangeProcessor::URLToFileChangesMap URLToFileChangesMap;
50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RemoteToLocalSyncerTest()
52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP) {}
53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual ~RemoteToLocalSyncerTest() {}
54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual void SetUp() OVERRIDE {
56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ASSERT_TRUE(database_dir_.CreateUniqueTempDir());
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    in_memory_env_.reset(leveldb::NewMemEnv(leveldb::Env::Default()));
58f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
59010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    scoped_ptr<drive::FakeDriveService>
60010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        fake_drive_service(new drive::FakeDriveService);
61a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
62010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    scoped_ptr<drive::DriveUploaderInterface>
63010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        drive_uploader(new drive::DriveUploader(
64010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)            fake_drive_service.get(),
65116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            base::ThreadTaskRunnerHandle::Get().get()));
66a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    fake_drive_helper_.reset(
67010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        new FakeDriveServiceHelper(fake_drive_service.get(),
68010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                   drive_uploader.get(),
69a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                                   kSyncRootFolderTitle));
70010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    remote_change_processor_.reset(new FakeRemoteChangeProcessor);
71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
72010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    context_.reset(new SyncEngineContext(
73010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        fake_drive_service.PassAs<drive::DriveServiceInterface>(),
74010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        drive_uploader.Pass(),
75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        NULL,
76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        base::ThreadTaskRunnerHandle::Get(),
77116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        base::ThreadTaskRunnerHandle::Get()));
78010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    context_->SetRemoteChangeProcessor(remote_change_processor_.get());
79effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    RegisterSyncableFileSystem();
81effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
82effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    sync_task_manager_.reset(new SyncTaskManager(
83effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        base::WeakPtr<SyncTaskManager::Client>(),
846d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        10 /* max_parallel_task */,
85116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        base::ThreadTaskRunnerHandle::Get()));
86effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    sync_task_manager_->Initialize(SYNC_STATUS_OK);
87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual void TearDown() OVERRIDE {
90effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    sync_task_manager_.reset();
91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    RevokeSyncableFileSystem();
92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    fake_drive_helper_.reset();
93effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    context_.reset();
94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    base::RunLoop().RunUntilIdle();
95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void InitializeMetadataDatabase() {
98effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    SyncEngineInitializer* initializer =
99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        new SyncEngineInitializer(context_.get(),
100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                  database_dir_.path(),
101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                  in_memory_env_.get());
102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SyncStatusCode status = SYNC_STATUS_UNKNOWN;
103effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    sync_task_manager_->ScheduleSyncTask(
104effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        FROM_HERE,
105effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        scoped_ptr<SyncTask>(initializer),
106effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        SyncTaskManager::PRIORITY_MED,
107effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        base::Bind(&RemoteToLocalSyncerTest::DidInitializeMetadataDatabase,
108effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                   base::Unretained(this),
109effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                   initializer, &status));
110effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    base::RunLoop().RunUntilIdle();
112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(SYNC_STATUS_OK, status);
113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
115effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  void DidInitializeMetadataDatabase(SyncEngineInitializer* initializer,
116effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                     SyncStatusCode* status_out,
117effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                     SyncStatusCode status) {
118effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    *status_out = status;
119effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    context_->SetMetadataDatabase(initializer->PassMetadataDatabase());
120effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
121effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
122effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
123f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void RegisterApp(const std::string& app_id,
124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                   const std::string& app_root_folder_id) {
1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    SyncStatusCode status = context_->GetMetadataDatabase()->RegisterApp(
1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        app_id, app_root_folder_id);
127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(SYNC_STATUS_OK, status);
128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
130effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  MetadataDatabase* GetMetadataDatabase() {
131effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return context_->GetMetadataDatabase();
132f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
134f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) protected:
135f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::string CreateSyncRoot() {
136f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    std::string sync_root_folder_id;
137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(google_apis::HTTP_CREATED,
138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)              fake_drive_helper_->AddOrphanedFolder(
139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                  kSyncRootFolderTitle, &sync_root_folder_id));
140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return sync_root_folder_id;
141f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::string CreateRemoteFolder(const std::string& parent_folder_id,
144a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                 const std::string& title) {
145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    std::string folder_id;
146f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(google_apis::HTTP_CREATED,
147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)              fake_drive_helper_->AddFolder(
148a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                  parent_folder_id, title, &folder_id));
149f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return folder_id;
150f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
151f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
152f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::string CreateRemoteFile(const std::string& parent_folder_id,
153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                               const std::string& title,
154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                               const std::string& content) {
155f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    std::string file_id;
156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(google_apis::HTTP_SUCCESS,
157f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)              fake_drive_helper_->AddFile(
158f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                  parent_folder_id, title, content, &file_id));
159f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return file_id;
160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void DeleteRemoteFile(const std::string& file_id) {
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(google_apis::HTTP_NO_CONTENT,
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              fake_drive_helper_->DeleteResource(file_id));
165f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
166f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
16703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void CreateLocalFolder(const storage::FileSystemURL& url) {
168010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    remote_change_processor_->UpdateLocalFileMetadata(
169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        url, FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
170f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                        SYNC_FILE_TYPE_DIRECTORY));
171f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
172f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
17303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void CreateLocalFile(const storage::FileSystemURL& url) {
174010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    remote_change_processor_->UpdateLocalFileMetadata(
175f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        url, FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
176f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                        SYNC_FILE_TYPE_FILE));
177f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
179f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SyncStatusCode RunSyncer() {
180f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SyncStatusCode status = SYNC_STATUS_UNKNOWN;
181effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    scoped_ptr<RemoteToLocalSyncer>
182effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        syncer(new RemoteToLocalSyncer(context_.get()));
183116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    syncer->RunPreflight(SyncTaskToken::CreateForTesting(
184116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        CreateResultReceiver(&status)));
185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    base::RunLoop().RunUntilIdle();
186f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return status;
187f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
188f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  SyncStatusCode RunSyncerUntilIdle() {
1906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    const int kRetryLimit = 100;
191f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SyncStatusCode status = SYNC_STATUS_UNKNOWN;
1926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    int count = 0;
1936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    do {
1946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      if (count++ > kRetryLimit)
1956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        return status;
196f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      status = RunSyncer();
1976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    } while (status == SYNC_STATUS_OK ||
1986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)             status == SYNC_STATUS_RETRY);
1996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return status;
2006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
2016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
2026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  SyncStatusCode RunSyncerAndPromoteUntilIdle() {
2036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    const int kRetryLimit = 100;
2046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    SyncStatusCode status = SYNC_STATUS_UNKNOWN;
2056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    MetadataDatabase* metadata_database = context_->GetMetadataDatabase();
2066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    int count = 0;
2076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    do {
2086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      if (count++ > kRetryLimit)
2096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        return status;
2106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      status = RunSyncer();
2116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    } while (status == SYNC_STATUS_OK ||
2126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)             status == SYNC_STATUS_RETRY ||
2131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci             metadata_database->PromoteDemotedTrackers());
2146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return status;
215f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
216f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
217f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SyncStatusCode ListChanges() {
218f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SyncStatusCode status = SYNC_STATUS_UNKNOWN;
219effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    sync_task_manager_->ScheduleSyncTask(
220effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        FROM_HERE,
221effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        scoped_ptr<SyncTask>(new ListChangesTask(context_.get())),
222effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        SyncTaskManager::PRIORITY_MED,
223effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        CreateResultReceiver(&status));
224f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    base::RunLoop().RunUntilIdle();
225f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return status;
226f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
227f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
22803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void AppendExpectedChange(const storage::FileSystemURL& url,
229f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                            FileChange::ChangeType change_type,
230f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                            SyncFileType file_type) {
231f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    expected_changes_[url].push_back(FileChange(change_type, file_type));
232f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
233f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
234f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void VerifyConsistency() {
235010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    remote_change_processor_->VerifyConsistency(expected_changes_);
236f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
237f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
238f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) private:
239f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  content::TestBrowserThreadBundle thread_bundle_;
240f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::ScopedTempDir database_dir_;
2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<leveldb::Env> in_memory_env_;
242f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
243effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  scoped_ptr<SyncEngineContext> context_;
244f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<FakeDriveServiceHelper> fake_drive_helper_;
245010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  scoped_ptr<FakeRemoteChangeProcessor> remote_change_processor_;
246f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
247effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  scoped_ptr<SyncTaskManager> sync_task_manager_;
248effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
249f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  URLToFileChangesMap expected_changes_;
250f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
251f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(RemoteToLocalSyncerTest);
252f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
253f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
254f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(RemoteToLocalSyncerTest, AddNewFile) {
255f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const GURL kOrigin("chrome-extension://example");
256f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string sync_root = CreateSyncRoot();
257f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host());
258f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  InitializeMetadataDatabase();
259f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RegisterApp(kOrigin.host(), app_root);
260f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
261f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string folder1 = CreateRemoteFolder(app_root, "folder1");
262f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string file1 = CreateRemoteFile(app_root, "file1", "data1");
263f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string folder2 = CreateRemoteFolder(folder1, "folder2");
264f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string file2 = CreateRemoteFile(folder1, "file2", "data2");
265f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_NO_CHANGE_TO_SYNC, RunSyncerAndPromoteUntilIdle());
267f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
268f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Create expected changes.
269f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // TODO(nhiroki): Clean up creating URL part.
270a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AppendExpectedChange(URL(kOrigin, "folder1"),
271f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       FileChange::FILE_CHANGE_ADD_OR_UPDATE,
272f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       SYNC_FILE_TYPE_DIRECTORY);
273a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AppendExpectedChange(URL(kOrigin, "file1"),
274f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       FileChange::FILE_CHANGE_ADD_OR_UPDATE,
275f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       SYNC_FILE_TYPE_FILE);
276a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AppendExpectedChange(URL(kOrigin, "folder1/folder2"),
277f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       FileChange::FILE_CHANGE_ADD_OR_UPDATE,
278f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       SYNC_FILE_TYPE_DIRECTORY);
279a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AppendExpectedChange(URL(kOrigin, "folder1/file2"),
280f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       FileChange::FILE_CHANGE_ADD_OR_UPDATE,
281f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       SYNC_FILE_TYPE_FILE);
282f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
283f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  VerifyConsistency();
284a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
285a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(GetMetadataDatabase()->HasDirtyTracker());
286f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
287f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
288f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(RemoteToLocalSyncerTest, DeleteFile) {
289f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const GURL kOrigin("chrome-extension://example");
290f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string sync_root = CreateSyncRoot();
291f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host());
292f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  InitializeMetadataDatabase();
293f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RegisterApp(kOrigin.host(), app_root);
294f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
295f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string folder = CreateRemoteFolder(app_root, "folder");
296f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string file = CreateRemoteFile(app_root, "file", "data");
297f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
298a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AppendExpectedChange(URL(kOrigin, "folder"),
299f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       FileChange::FILE_CHANGE_ADD_OR_UPDATE,
300f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       SYNC_FILE_TYPE_DIRECTORY);
301a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AppendExpectedChange(URL(kOrigin, "file"),
302f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       FileChange::FILE_CHANGE_ADD_OR_UPDATE,
303f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       SYNC_FILE_TYPE_FILE);
304f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
3056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_NO_CHANGE_TO_SYNC, RunSyncerAndPromoteUntilIdle());
306f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  VerifyConsistency();
307f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
308f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DeleteRemoteFile(folder);
309f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DeleteRemoteFile(file);
310f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
311a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AppendExpectedChange(URL(kOrigin, "folder"),
312f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       FileChange::FILE_CHANGE_DELETE,
313f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       SYNC_FILE_TYPE_UNKNOWN);
314a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AppendExpectedChange(URL(kOrigin, "file"),
315f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       FileChange::FILE_CHANGE_DELETE,
316f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       SYNC_FILE_TYPE_UNKNOWN);
317f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
318a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, ListChanges());
3196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_NO_CHANGE_TO_SYNC, RunSyncerUntilIdle());
320f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  VerifyConsistency();
321a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
322a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(GetMetadataDatabase()->HasDirtyTracker());
323f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
324f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
325f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(RemoteToLocalSyncerTest, DeleteNestedFiles) {
326f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const GURL kOrigin("chrome-extension://example");
327f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string sync_root = CreateSyncRoot();
328f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host());
329f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  InitializeMetadataDatabase();
330f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RegisterApp(kOrigin.host(), app_root);
331f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
332f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string folder1 = CreateRemoteFolder(app_root, "folder1");
333f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string file1 = CreateRemoteFile(app_root, "file1", "data1");
334f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string folder2 = CreateRemoteFolder(folder1, "folder2");
335f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string file2 = CreateRemoteFile(folder1, "file2", "data2");
336f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
337a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AppendExpectedChange(URL(kOrigin, "folder1"),
338f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       FileChange::FILE_CHANGE_ADD_OR_UPDATE,
339f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       SYNC_FILE_TYPE_DIRECTORY);
340a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AppendExpectedChange(URL(kOrigin, "file1"),
341f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       FileChange::FILE_CHANGE_ADD_OR_UPDATE,
342f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       SYNC_FILE_TYPE_FILE);
343a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AppendExpectedChange(URL(kOrigin, "folder1/folder2"),
344f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       FileChange::FILE_CHANGE_ADD_OR_UPDATE,
345f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       SYNC_FILE_TYPE_DIRECTORY);
346a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AppendExpectedChange(URL(kOrigin, "folder1/file2"),
347f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       FileChange::FILE_CHANGE_ADD_OR_UPDATE,
348f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       SYNC_FILE_TYPE_FILE);
349f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
3506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_NO_CHANGE_TO_SYNC, RunSyncerAndPromoteUntilIdle());
351f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  VerifyConsistency();
352f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
353f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DeleteRemoteFile(folder1);
354f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
355a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AppendExpectedChange(URL(kOrigin, "folder1"),
356f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       FileChange::FILE_CHANGE_DELETE,
357f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       SYNC_FILE_TYPE_UNKNOWN);
358f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Changes for descendant files ("folder2" and "file2") should be ignored.
359f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
360a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, ListChanges());
3616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_NO_CHANGE_TO_SYNC, RunSyncerUntilIdle());
362f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  VerifyConsistency();
363a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
364a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(GetMetadataDatabase()->HasDirtyTracker());
365f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
366f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
367f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(RemoteToLocalSyncerTest, Conflict_CreateFileOnFolder) {
368f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const GURL kOrigin("chrome-extension://example");
369f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string sync_root = CreateSyncRoot();
370f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host());
371f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  InitializeMetadataDatabase();
372f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RegisterApp(kOrigin.host(), app_root);
373f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
374a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateLocalFolder(URL(kOrigin, "folder"));
375f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CreateRemoteFile(app_root, "folder", "data");
376f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
377f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Folder-File conflict happens. File creation should be ignored.
378f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
379a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, ListChanges());
3806e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_NO_CHANGE_TO_SYNC, RunSyncerUntilIdle());
381f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  VerifyConsistency();
382a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
3836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Tracker for the remote file should has low priority.
3841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_FALSE(GetMetadataDatabase()->GetDirtyTracker(NULL));
3851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(GetMetadataDatabase()->HasDemotedDirtyTracker());
386f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
387f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
388f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(RemoteToLocalSyncerTest, Conflict_CreateFolderOnFile) {
389f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const GURL kOrigin("chrome-extension://example");
390f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string sync_root = CreateSyncRoot();
391f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host());
392f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  InitializeMetadataDatabase();
393f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RegisterApp(kOrigin.host(), app_root);
394f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
3956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_NO_CHANGE_TO_SYNC, RunSyncerUntilIdle());
396f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  VerifyConsistency();
397f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
398a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateLocalFile(URL(kOrigin, "file"));
399f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CreateRemoteFolder(app_root, "file");
400f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
401f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // File-Folder conflict happens. Folder should override the existing file.
402a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AppendExpectedChange(URL(kOrigin, "file"),
403f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       FileChange::FILE_CHANGE_ADD_OR_UPDATE,
404f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       SYNC_FILE_TYPE_DIRECTORY);
405f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
406a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, ListChanges());
4076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_NO_CHANGE_TO_SYNC, RunSyncerUntilIdle());
408f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  VerifyConsistency();
409a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
410a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(GetMetadataDatabase()->HasDirtyTracker());
411f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
412f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
413f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(RemoteToLocalSyncerTest, Conflict_CreateFolderOnFolder) {
414f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const GURL kOrigin("chrome-extension://example");
415f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string sync_root = CreateSyncRoot();
416f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host());
417f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  InitializeMetadataDatabase();
418f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RegisterApp(kOrigin.host(), app_root);
419f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
420a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateLocalFolder(URL(kOrigin, "folder"));
421f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CreateRemoteFolder(app_root, "folder");
422f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
423f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Folder-Folder conflict happens. Folder creation should be ignored.
424f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
425a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, ListChanges());
4266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_NO_CHANGE_TO_SYNC, RunSyncerUntilIdle());
427a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  VerifyConsistency();
428a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
429a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(GetMetadataDatabase()->HasDirtyTracker());
430a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
431a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
432a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(RemoteToLocalSyncerTest, Conflict_CreateFileOnFile) {
433a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const GURL kOrigin("chrome-extension://example");
434a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string sync_root = CreateSyncRoot();
435a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host());
436a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  InitializeMetadataDatabase();
437a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  RegisterApp(kOrigin.host(), app_root);
438a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
439a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateLocalFile(URL(kOrigin, "file"));
440a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateRemoteFile(app_root, "file", "data");
441a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
442a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // File-File conflict happens. File creation should be ignored.
443a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
444a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, ListChanges());
4456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_NO_CHANGE_TO_SYNC, RunSyncerUntilIdle());
446f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  VerifyConsistency();
447a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
448a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Tracker for the remote file should be lowered.
4491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_FALSE(GetMetadataDatabase()->GetDirtyTracker(NULL));
4501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(GetMetadataDatabase()->HasDemotedDirtyTracker());
451f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
452f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
453a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(RemoteToLocalSyncerTest, Conflict_CreateNestedFolderOnFile) {
454a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const GURL kOrigin("chrome-extension://example");
455a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string sync_root = CreateSyncRoot();
456a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host());
457a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  InitializeMetadataDatabase();
458a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  RegisterApp(kOrigin.host(), app_root);
459a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
4606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_NO_CHANGE_TO_SYNC, RunSyncerUntilIdle());
461a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  VerifyConsistency();
462a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
463a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string folder = CreateRemoteFolder(app_root, "folder");
464a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateLocalFile(URL(kOrigin, "/folder"));
465a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateRemoteFile(folder, "file", "data");
466a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
467a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // File-Folder conflict happens. Folder should override the existing file.
468a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AppendExpectedChange(URL(kOrigin, "/folder"),
469a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       FileChange::FILE_CHANGE_ADD_OR_UPDATE,
470a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       SYNC_FILE_TYPE_DIRECTORY);
471a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
472a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, ListChanges());
4736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_NO_CHANGE_TO_SYNC, RunSyncerUntilIdle());
474a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  VerifyConsistency();
475a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
476a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
477a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(RemoteToLocalSyncerTest, AppRootDeletion) {
478a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const GURL kOrigin("chrome-extension://example");
479a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string sync_root = CreateSyncRoot();
480a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host());
481a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  InitializeMetadataDatabase();
482a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  RegisterApp(kOrigin.host(), app_root);
483a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
4846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_NO_CHANGE_TO_SYNC, RunSyncerUntilIdle());
485a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  VerifyConsistency();
486a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
487a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DeleteRemoteFile(app_root);
488a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
489a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AppendExpectedChange(URL(kOrigin, "/"),
490a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       FileChange::FILE_CHANGE_DELETE,
491a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       SYNC_FILE_TYPE_UNKNOWN);
492a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
493a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, ListChanges());
4946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_NO_CHANGE_TO_SYNC, RunSyncerUntilIdle());
495a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  VerifyConsistency();
496a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
497a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // SyncEngine will re-register the app and resurrect the app root later.
498a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
499f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
500f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace drive_backend
501f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace sync_file_system
502