remote_to_local_syncer_unittest.cc revision 03b57e008b61dfcb1fbad3aea950ae0e001748b0
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) {
125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SyncStatusCode status = SYNC_STATUS_FAILED;
126effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    context_->GetMetadataDatabase()->RegisterApp(app_id, app_root_folder_id,
127effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                                 CreateResultReceiver(&status));
128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    base::RunLoop().RunUntilIdle();
129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(SYNC_STATUS_OK, status);
130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
132effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  MetadataDatabase* GetMetadataDatabase() {
133effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return context_->GetMetadataDatabase();
134f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
135f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
136f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) protected:
137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::string CreateSyncRoot() {
138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    std::string sync_root_folder_id;
139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(google_apis::HTTP_CREATED,
140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)              fake_drive_helper_->AddOrphanedFolder(
141f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                  kSyncRootFolderTitle, &sync_root_folder_id));
142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return sync_root_folder_id;
143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
144f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::string CreateRemoteFolder(const std::string& parent_folder_id,
146a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                 const std::string& title) {
147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    std::string folder_id;
148f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(google_apis::HTTP_CREATED,
149f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)              fake_drive_helper_->AddFolder(
150a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                  parent_folder_id, title, &folder_id));
151f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return folder_id;
152f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::string CreateRemoteFile(const std::string& parent_folder_id,
155f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                               const std::string& title,
156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                               const std::string& content) {
157f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    std::string file_id;
158f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(google_apis::HTTP_SUCCESS,
159f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)              fake_drive_helper_->AddFile(
160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                  parent_folder_id, title, content, &file_id));
161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return file_id;
162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
163f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
164f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void DeleteRemoteFile(const std::string& file_id) {
1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(google_apis::HTTP_NO_CONTENT,
1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              fake_drive_helper_->DeleteResource(file_id));
167f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
16903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void CreateLocalFolder(const storage::FileSystemURL& url) {
170010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    remote_change_processor_->UpdateLocalFileMetadata(
171f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        url, FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
172f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                        SYNC_FILE_TYPE_DIRECTORY));
173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
174f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
17503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void CreateLocalFile(const storage::FileSystemURL& url) {
176010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    remote_change_processor_->UpdateLocalFileMetadata(
177f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        url, FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                        SYNC_FILE_TYPE_FILE));
179f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
180f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
181f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SyncStatusCode RunSyncer() {
182f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SyncStatusCode status = SYNC_STATUS_UNKNOWN;
183effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    scoped_ptr<RemoteToLocalSyncer>
184effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        syncer(new RemoteToLocalSyncer(context_.get()));
185116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    syncer->RunPreflight(SyncTaskToken::CreateForTesting(
186116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        CreateResultReceiver(&status)));
187f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    base::RunLoop().RunUntilIdle();
188f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return status;
189f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
190f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  SyncStatusCode RunSyncerUntilIdle() {
1926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    const int kRetryLimit = 100;
193f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SyncStatusCode status = SYNC_STATUS_UNKNOWN;
1946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    int count = 0;
1956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    do {
1966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      if (count++ > kRetryLimit)
1976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        return status;
198f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      status = RunSyncer();
1996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    } while (status == SYNC_STATUS_OK ||
2006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)             status == SYNC_STATUS_RETRY);
2016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return status;
2026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
2036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
2046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  SyncStatusCode RunSyncerAndPromoteUntilIdle() {
2056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    const int kRetryLimit = 100;
2066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    SyncStatusCode status = SYNC_STATUS_UNKNOWN;
2076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    MetadataDatabase* metadata_database = context_->GetMetadataDatabase();
2086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    int count = 0;
2096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    do {
2106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      if (count++ > kRetryLimit)
2116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        return status;
2126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      status = RunSyncer();
2136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    } while (status == SYNC_STATUS_OK ||
2146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)             status == SYNC_STATUS_RETRY ||
2156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)             metadata_database->PromoteLowerPriorityTrackersToNormal());
2166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return status;
217f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
218f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
219f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SyncStatusCode ListChanges() {
220f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SyncStatusCode status = SYNC_STATUS_UNKNOWN;
221effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    sync_task_manager_->ScheduleSyncTask(
222effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        FROM_HERE,
223effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        scoped_ptr<SyncTask>(new ListChangesTask(context_.get())),
224effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        SyncTaskManager::PRIORITY_MED,
225effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        CreateResultReceiver(&status));
226f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    base::RunLoop().RunUntilIdle();
227f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return status;
228f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
229f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
23003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void AppendExpectedChange(const storage::FileSystemURL& url,
231f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                            FileChange::ChangeType change_type,
232f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                            SyncFileType file_type) {
233f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    expected_changes_[url].push_back(FileChange(change_type, file_type));
234f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
235f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
236f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void VerifyConsistency() {
237010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    remote_change_processor_->VerifyConsistency(expected_changes_);
238f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
239f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
240f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) private:
241f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  content::TestBrowserThreadBundle thread_bundle_;
242f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::ScopedTempDir database_dir_;
2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<leveldb::Env> in_memory_env_;
244f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
245effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  scoped_ptr<SyncEngineContext> context_;
246f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<FakeDriveServiceHelper> fake_drive_helper_;
247010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  scoped_ptr<FakeRemoteChangeProcessor> remote_change_processor_;
248f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
249effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  scoped_ptr<SyncTaskManager> sync_task_manager_;
250effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
251f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  URLToFileChangesMap expected_changes_;
252f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
253f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(RemoteToLocalSyncerTest);
254f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
255f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
256f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(RemoteToLocalSyncerTest, AddNewFile) {
257f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const GURL kOrigin("chrome-extension://example");
258f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string sync_root = CreateSyncRoot();
259f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host());
260f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  InitializeMetadataDatabase();
261f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RegisterApp(kOrigin.host(), app_root);
262f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
263f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string folder1 = CreateRemoteFolder(app_root, "folder1");
264f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string file1 = CreateRemoteFile(app_root, "file1", "data1");
265f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string folder2 = CreateRemoteFolder(folder1, "folder2");
266f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string file2 = CreateRemoteFile(folder1, "file2", "data2");
267f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_NO_CHANGE_TO_SYNC, RunSyncerAndPromoteUntilIdle());
269f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
270f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Create expected changes.
271f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // TODO(nhiroki): Clean up creating URL part.
272a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AppendExpectedChange(URL(kOrigin, "folder1"),
273f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       FileChange::FILE_CHANGE_ADD_OR_UPDATE,
274f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       SYNC_FILE_TYPE_DIRECTORY);
275a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AppendExpectedChange(URL(kOrigin, "file1"),
276f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       FileChange::FILE_CHANGE_ADD_OR_UPDATE,
277f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       SYNC_FILE_TYPE_FILE);
278a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AppendExpectedChange(URL(kOrigin, "folder1/folder2"),
279f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       FileChange::FILE_CHANGE_ADD_OR_UPDATE,
280f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       SYNC_FILE_TYPE_DIRECTORY);
281a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AppendExpectedChange(URL(kOrigin, "folder1/file2"),
282f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       FileChange::FILE_CHANGE_ADD_OR_UPDATE,
283f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       SYNC_FILE_TYPE_FILE);
284f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
285f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  VerifyConsistency();
286a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
287a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(GetMetadataDatabase()->HasDirtyTracker());
288f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
289f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
290f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(RemoteToLocalSyncerTest, DeleteFile) {
291f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const GURL kOrigin("chrome-extension://example");
292f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string sync_root = CreateSyncRoot();
293f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host());
294f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  InitializeMetadataDatabase();
295f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RegisterApp(kOrigin.host(), app_root);
296f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
297f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string folder = CreateRemoteFolder(app_root, "folder");
298f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string file = CreateRemoteFile(app_root, "file", "data");
299f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
300a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AppendExpectedChange(URL(kOrigin, "folder"),
301f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       FileChange::FILE_CHANGE_ADD_OR_UPDATE,
302f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       SYNC_FILE_TYPE_DIRECTORY);
303a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AppendExpectedChange(URL(kOrigin, "file"),
304f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       FileChange::FILE_CHANGE_ADD_OR_UPDATE,
305f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       SYNC_FILE_TYPE_FILE);
306f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
3076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_NO_CHANGE_TO_SYNC, RunSyncerAndPromoteUntilIdle());
308f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  VerifyConsistency();
309f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
310f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DeleteRemoteFile(folder);
311f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DeleteRemoteFile(file);
312f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
313a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AppendExpectedChange(URL(kOrigin, "folder"),
314f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       FileChange::FILE_CHANGE_DELETE,
315f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       SYNC_FILE_TYPE_UNKNOWN);
316a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AppendExpectedChange(URL(kOrigin, "file"),
317f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       FileChange::FILE_CHANGE_DELETE,
318f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       SYNC_FILE_TYPE_UNKNOWN);
319f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
320a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, ListChanges());
3216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_NO_CHANGE_TO_SYNC, RunSyncerUntilIdle());
322f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  VerifyConsistency();
323a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
324a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(GetMetadataDatabase()->HasDirtyTracker());
325f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
326f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
327f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(RemoteToLocalSyncerTest, DeleteNestedFiles) {
328f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const GURL kOrigin("chrome-extension://example");
329f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string sync_root = CreateSyncRoot();
330f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host());
331f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  InitializeMetadataDatabase();
332f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RegisterApp(kOrigin.host(), app_root);
333f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
334f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string folder1 = CreateRemoteFolder(app_root, "folder1");
335f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string file1 = CreateRemoteFile(app_root, "file1", "data1");
336f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string folder2 = CreateRemoteFolder(folder1, "folder2");
337f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string file2 = CreateRemoteFile(folder1, "file2", "data2");
338f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
339a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AppendExpectedChange(URL(kOrigin, "folder1"),
340f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       FileChange::FILE_CHANGE_ADD_OR_UPDATE,
341f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       SYNC_FILE_TYPE_DIRECTORY);
342a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AppendExpectedChange(URL(kOrigin, "file1"),
343f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       FileChange::FILE_CHANGE_ADD_OR_UPDATE,
344f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       SYNC_FILE_TYPE_FILE);
345a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AppendExpectedChange(URL(kOrigin, "folder1/folder2"),
346f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       FileChange::FILE_CHANGE_ADD_OR_UPDATE,
347f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       SYNC_FILE_TYPE_DIRECTORY);
348a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AppendExpectedChange(URL(kOrigin, "folder1/file2"),
349f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       FileChange::FILE_CHANGE_ADD_OR_UPDATE,
350f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       SYNC_FILE_TYPE_FILE);
351f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
3526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_NO_CHANGE_TO_SYNC, RunSyncerAndPromoteUntilIdle());
353f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  VerifyConsistency();
354f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
355f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DeleteRemoteFile(folder1);
356f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
357a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AppendExpectedChange(URL(kOrigin, "folder1"),
358f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       FileChange::FILE_CHANGE_DELETE,
359f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       SYNC_FILE_TYPE_UNKNOWN);
360f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Changes for descendant files ("folder2" and "file2") should be ignored.
361f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
362a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, ListChanges());
3636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_NO_CHANGE_TO_SYNC, RunSyncerUntilIdle());
364f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  VerifyConsistency();
365a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
366a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(GetMetadataDatabase()->HasDirtyTracker());
367f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
368f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
369f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(RemoteToLocalSyncerTest, Conflict_CreateFileOnFolder) {
370f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const GURL kOrigin("chrome-extension://example");
371f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string sync_root = CreateSyncRoot();
372f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host());
373f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  InitializeMetadataDatabase();
374f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RegisterApp(kOrigin.host(), app_root);
375f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
376a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateLocalFolder(URL(kOrigin, "folder"));
377f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CreateRemoteFile(app_root, "folder", "data");
378f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
379f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Folder-File conflict happens. File creation should be ignored.
380f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
381a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, ListChanges());
3826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_NO_CHANGE_TO_SYNC, RunSyncerUntilIdle());
383f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  VerifyConsistency();
384a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
3856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Tracker for the remote file should has low priority.
386a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_FALSE(GetMetadataDatabase()->GetNormalPriorityDirtyTracker(NULL));
387a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(GetMetadataDatabase()->HasLowPriorityDirtyTracker());
388f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
389f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
390f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(RemoteToLocalSyncerTest, Conflict_CreateFolderOnFile) {
391f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const GURL kOrigin("chrome-extension://example");
392f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string sync_root = CreateSyncRoot();
393f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host());
394f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  InitializeMetadataDatabase();
395f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RegisterApp(kOrigin.host(), app_root);
396f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
3976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_NO_CHANGE_TO_SYNC, RunSyncerUntilIdle());
398f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  VerifyConsistency();
399f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
400a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateLocalFile(URL(kOrigin, "file"));
401f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CreateRemoteFolder(app_root, "file");
402f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
403f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // File-Folder conflict happens. Folder should override the existing file.
404a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AppendExpectedChange(URL(kOrigin, "file"),
405f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       FileChange::FILE_CHANGE_ADD_OR_UPDATE,
406f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       SYNC_FILE_TYPE_DIRECTORY);
407f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
408a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, ListChanges());
4096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_NO_CHANGE_TO_SYNC, RunSyncerUntilIdle());
410f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  VerifyConsistency();
411a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
412a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(GetMetadataDatabase()->HasDirtyTracker());
413f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
414f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
415f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(RemoteToLocalSyncerTest, Conflict_CreateFolderOnFolder) {
416f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const GURL kOrigin("chrome-extension://example");
417f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string sync_root = CreateSyncRoot();
418f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host());
419f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  InitializeMetadataDatabase();
420f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RegisterApp(kOrigin.host(), app_root);
421f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
422a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateLocalFolder(URL(kOrigin, "folder"));
423f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CreateRemoteFolder(app_root, "folder");
424f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
425f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Folder-Folder conflict happens. Folder creation should be ignored.
426f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
427a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, ListChanges());
4286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_NO_CHANGE_TO_SYNC, RunSyncerUntilIdle());
429a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  VerifyConsistency();
430a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
431a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(GetMetadataDatabase()->HasDirtyTracker());
432a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
433a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
434a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(RemoteToLocalSyncerTest, Conflict_CreateFileOnFile) {
435a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const GURL kOrigin("chrome-extension://example");
436a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string sync_root = CreateSyncRoot();
437a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host());
438a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  InitializeMetadataDatabase();
439a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  RegisterApp(kOrigin.host(), app_root);
440a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
441a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateLocalFile(URL(kOrigin, "file"));
442a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateRemoteFile(app_root, "file", "data");
443a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
444a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // File-File conflict happens. File creation should be ignored.
445a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
446a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, ListChanges());
4476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_NO_CHANGE_TO_SYNC, RunSyncerUntilIdle());
448f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  VerifyConsistency();
449a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
450a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Tracker for the remote file should be lowered.
451a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_FALSE(GetMetadataDatabase()->GetNormalPriorityDirtyTracker(NULL));
452a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(GetMetadataDatabase()->HasLowPriorityDirtyTracker());
453f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
454f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
455a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(RemoteToLocalSyncerTest, Conflict_CreateNestedFolderOnFile) {
456a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const GURL kOrigin("chrome-extension://example");
457a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string sync_root = CreateSyncRoot();
458a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host());
459a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  InitializeMetadataDatabase();
460a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  RegisterApp(kOrigin.host(), app_root);
461a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
4626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_NO_CHANGE_TO_SYNC, RunSyncerUntilIdle());
463a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  VerifyConsistency();
464a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
465a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string folder = CreateRemoteFolder(app_root, "folder");
466a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateLocalFile(URL(kOrigin, "/folder"));
467a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateRemoteFile(folder, "file", "data");
468a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
469a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // File-Folder conflict happens. Folder should override the existing file.
470a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AppendExpectedChange(URL(kOrigin, "/folder"),
471a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       FileChange::FILE_CHANGE_ADD_OR_UPDATE,
472a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       SYNC_FILE_TYPE_DIRECTORY);
473a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
474a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, ListChanges());
4756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_NO_CHANGE_TO_SYNC, RunSyncerUntilIdle());
476a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  VerifyConsistency();
477a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
478a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
479a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(RemoteToLocalSyncerTest, AppRootDeletion) {
480a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const GURL kOrigin("chrome-extension://example");
481a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string sync_root = CreateSyncRoot();
482a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host());
483a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  InitializeMetadataDatabase();
484a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  RegisterApp(kOrigin.host(), app_root);
485a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
4866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_NO_CHANGE_TO_SYNC, RunSyncerUntilIdle());
487a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  VerifyConsistency();
488a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
489a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DeleteRemoteFile(app_root);
490a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
491a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AppendExpectedChange(URL(kOrigin, "/"),
492a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       FileChange::FILE_CHANGE_DELETE,
493a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       SYNC_FILE_TYPE_UNKNOWN);
494a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
495a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, ListChanges());
4966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_NO_CHANGE_TO_SYNC, RunSyncerUntilIdle());
497a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  VerifyConsistency();
498a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
499a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // SyncEngine will re-register the app and resurrect the app root later.
500a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
501f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
502f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace drive_backend
503f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace sync_file_system
504