remote_to_local_syncer_unittest.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
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"
14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/drive/drive_uploader.h"
15f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/drive/fake_drive_service.h"
16f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/sync_file_system/drive_backend/drive_backend_constants.h"
17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/sync_file_system/drive_backend/drive_backend_test_util.h"
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/sync_file_system/drive_backend/fake_drive_service_helper.h"
19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/sync_file_system/drive_backend/list_changes_task.h"
20f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/sync_file_system/drive_backend/metadata_database.h"
21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/sync_file_system/drive_backend/sync_engine_context.h"
22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/sync_file_system/drive_backend/sync_engine_initializer.h"
23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/sync_file_system/fake_remote_change_processor.h"
24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/sync_file_system/sync_file_system_test_util.h"
25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/sync_file_system/syncable_file_system_util.h"
26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/public/test/test_browser_thread_bundle.h"
27a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "google_apis/drive/gdata_errorcode.h"
28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "third_party/leveldatabase/src/helpers/memenv/memenv.h"
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "third_party/leveldatabase/src/include/leveldb/env.h"
31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace sync_file_system {
33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace drive_backend {
34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace {
36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)fileapi::FileSystemURL URL(const GURL& origin,
38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                           const std::string& path) {
39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return CreateSyncableFileSystemURL(
40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      origin, base::FilePath::FromUTF8Unsafe(path));
41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace
44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class RemoteToLocalSyncerTest : public testing::Test,
46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                public SyncEngineContext {
47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) public:
48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  typedef FakeRemoteChangeProcessor::URLToFileChangesMap URLToFileChangesMap;
49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RemoteToLocalSyncerTest()
51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP) {}
52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual ~RemoteToLocalSyncerTest() {}
53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual void SetUp() OVERRIDE {
55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ASSERT_TRUE(database_dir_.CreateUniqueTempDir());
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    in_memory_env_.reset(leveldb::NewMemEnv(leveldb::Env::Default()));
57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
58f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    fake_drive_service_.reset(new drive::FakeDriveService);
59f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ASSERT_TRUE(fake_drive_service_->LoadAccountMetadataForWapi(
60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        "sync_file_system/account_metadata.json"));
61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ASSERT_TRUE(fake_drive_service_->LoadResourceListForWapi(
62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        "gdata/empty_feed.json"));
63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    drive_uploader_.reset(new drive::DriveUploader(
65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        fake_drive_service_.get(), base::MessageLoopProxy::current().get()));
66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    fake_drive_helper_.reset(new FakeDriveServiceHelper(
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        fake_drive_service_.get(), drive_uploader_.get(),
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        kSyncRootFolderTitle));
69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    fake_remote_change_processor_.reset(new FakeRemoteChangeProcessor);
70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    RegisterSyncableFileSystem();
72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual void TearDown() OVERRIDE {
75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    RevokeSyncableFileSystem();
76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    fake_remote_change_processor_.reset();
78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    metadata_database_.reset();
79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    fake_drive_helper_.reset();
80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    drive_uploader_.reset();
81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    fake_drive_service_.reset();
82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    base::RunLoop().RunUntilIdle();
83f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void InitializeMetadataDatabase() {
86a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    SyncEngineInitializer initializer(this,
87a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                      base::MessageLoopProxy::current(),
88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                      fake_drive_service_.get(),
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                      database_dir_.path(),
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                      in_memory_env_.get());
91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SyncStatusCode status = SYNC_STATUS_UNKNOWN;
92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    initializer.Run(CreateResultReceiver(&status));
93f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    base::RunLoop().RunUntilIdle();
94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(SYNC_STATUS_OK, status);
95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    metadata_database_ = initializer.PassMetadataDatabase();
96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void RegisterApp(const std::string& app_id,
99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                   const std::string& app_root_folder_id) {
100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SyncStatusCode status = SYNC_STATUS_FAILED;
101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    metadata_database_->RegisterApp(app_id, app_root_folder_id,
102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                    CreateResultReceiver(&status));
103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    base::RunLoop().RunUntilIdle();
104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(SYNC_STATUS_OK, status);
105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual drive::DriveServiceInterface* GetDriveService() OVERRIDE {
108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return fake_drive_service_.get();
109f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual drive::DriveUploaderInterface* GetDriveUploader() OVERRIDE {
112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return drive_uploader_.get();
113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
115f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual MetadataDatabase* GetMetadataDatabase() OVERRIDE {
116f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return metadata_database_.get();
117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
119f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual RemoteChangeProcessor* GetRemoteChangeProcessor() OVERRIDE {
120f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return fake_remote_change_processor_.get();
121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
123f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual base::SequencedTaskRunner* GetBlockingTaskRunner() OVERRIDE {
124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return base::MessageLoopProxy::current().get();
125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
126f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) protected:
128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::string CreateSyncRoot() {
129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    std::string sync_root_folder_id;
130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(google_apis::HTTP_CREATED,
131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)              fake_drive_helper_->AddOrphanedFolder(
132f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                  kSyncRootFolderTitle, &sync_root_folder_id));
133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return sync_root_folder_id;
134f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
135f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
136f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::string CreateRemoteFolder(const std::string& parent_folder_id,
137a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                 const std::string& title) {
138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    std::string folder_id;
139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(google_apis::HTTP_CREATED,
140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)              fake_drive_helper_->AddFolder(
141a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                  parent_folder_id, title, &folder_id));
142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return folder_id;
143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
144f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::string CreateRemoteFile(const std::string& parent_folder_id,
146f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                               const std::string& title,
147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                               const std::string& content) {
148f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    std::string file_id;
149f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(google_apis::HTTP_SUCCESS,
150f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)              fake_drive_helper_->AddFile(
151f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                  parent_folder_id, title, content, &file_id));
152f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return file_id;
153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
155f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void DeleteRemoteFile(const std::string& file_id) {
1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(google_apis::HTTP_NO_CONTENT,
1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              fake_drive_helper_->DeleteResource(file_id));
158f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
159f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void CreateLocalFolder(const fileapi::FileSystemURL& url) {
161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    fake_remote_change_processor_->UpdateLocalFileMetadata(
162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        url, FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
163f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                        SYNC_FILE_TYPE_DIRECTORY));
164f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
165f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
166f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void CreateLocalFile(const fileapi::FileSystemURL& url) {
167f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    fake_remote_change_processor_->UpdateLocalFileMetadata(
168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        url, FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                        SYNC_FILE_TYPE_FILE));
170f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
171f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
172f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SyncStatusCode RunSyncer() {
173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SyncStatusCode status = SYNC_STATUS_UNKNOWN;
174a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    scoped_ptr<RemoteToLocalSyncer> syncer(new RemoteToLocalSyncer(this));
175f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    syncer->Run(CreateResultReceiver(&status));
176f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    base::RunLoop().RunUntilIdle();
177f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return status;
178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
179f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
180f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void RunSyncerUntilIdle() {
181f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SyncStatusCode status = SYNC_STATUS_UNKNOWN;
182f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    while (status != SYNC_STATUS_NO_CHANGE_TO_SYNC)
183f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      status = RunSyncer();
184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
186f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SyncStatusCode ListChanges() {
187f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ListChangesTask list_changes(this);
188f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SyncStatusCode status = SYNC_STATUS_UNKNOWN;
189f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    list_changes.Run(CreateResultReceiver(&status));
190f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    base::RunLoop().RunUntilIdle();
191f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return status;
192f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
193f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
194f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void AppendExpectedChange(const fileapi::FileSystemURL& url,
195f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                            FileChange::ChangeType change_type,
196f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                            SyncFileType file_type) {
197f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    expected_changes_[url].push_back(FileChange(change_type, file_type));
198f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
199f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
200f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void VerifyConsistency() {
2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    fake_remote_change_processor_->VerifyConsistency(expected_changes_);
202f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
203f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
204f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) private:
205f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  content::TestBrowserThreadBundle thread_bundle_;
206f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::ScopedTempDir database_dir_;
2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<leveldb::Env> in_memory_env_;
208f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
209f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<drive::FakeDriveService> fake_drive_service_;
210f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<drive::DriveUploader> drive_uploader_;
211f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<FakeDriveServiceHelper> fake_drive_helper_;
212f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<MetadataDatabase> metadata_database_;
213f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<FakeRemoteChangeProcessor> fake_remote_change_processor_;
214f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
215f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  URLToFileChangesMap expected_changes_;
216f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
217f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(RemoteToLocalSyncerTest);
218f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
219f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
220f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(RemoteToLocalSyncerTest, AddNewFile) {
221f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const GURL kOrigin("chrome-extension://example");
222f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string sync_root = CreateSyncRoot();
223f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host());
224f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  InitializeMetadataDatabase();
225f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RegisterApp(kOrigin.host(), app_root);
226f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
227f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string folder1 = CreateRemoteFolder(app_root, "folder1");
228f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string file1 = CreateRemoteFile(app_root, "file1", "data1");
229f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string folder2 = CreateRemoteFolder(folder1, "folder2");
230f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string file2 = CreateRemoteFile(folder1, "file2", "data2");
231f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
232f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RunSyncerUntilIdle();
233f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
234f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Create expected changes.
235f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // TODO(nhiroki): Clean up creating URL part.
236a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AppendExpectedChange(URL(kOrigin, "folder1"),
237f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       FileChange::FILE_CHANGE_ADD_OR_UPDATE,
238f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       SYNC_FILE_TYPE_DIRECTORY);
239a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AppendExpectedChange(URL(kOrigin, "file1"),
240f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       FileChange::FILE_CHANGE_ADD_OR_UPDATE,
241f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       SYNC_FILE_TYPE_FILE);
242a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AppendExpectedChange(URL(kOrigin, "folder1/folder2"),
243f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       FileChange::FILE_CHANGE_ADD_OR_UPDATE,
244f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       SYNC_FILE_TYPE_DIRECTORY);
245a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AppendExpectedChange(URL(kOrigin, "folder1/file2"),
246f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       FileChange::FILE_CHANGE_ADD_OR_UPDATE,
247f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       SYNC_FILE_TYPE_FILE);
248f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
249f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  VerifyConsistency();
250a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
251a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_FALSE(GetMetadataDatabase()->GetNormalPriorityDirtyTracker(NULL));
252a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_FALSE(GetMetadataDatabase()->GetLowPriorityDirtyTracker(NULL));
253f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
254f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
255f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(RemoteToLocalSyncerTest, DeleteFile) {
256f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const GURL kOrigin("chrome-extension://example");
257f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string sync_root = CreateSyncRoot();
258f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host());
259f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  InitializeMetadataDatabase();
260f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RegisterApp(kOrigin.host(), app_root);
261f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
262f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string folder = CreateRemoteFolder(app_root, "folder");
263f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string file = CreateRemoteFile(app_root, "file", "data");
264f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
265a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AppendExpectedChange(URL(kOrigin, "folder"),
266f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       FileChange::FILE_CHANGE_ADD_OR_UPDATE,
267f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       SYNC_FILE_TYPE_DIRECTORY);
268a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AppendExpectedChange(URL(kOrigin, "file"),
269f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       FileChange::FILE_CHANGE_ADD_OR_UPDATE,
270f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       SYNC_FILE_TYPE_FILE);
271f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
272f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RunSyncerUntilIdle();
273f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  VerifyConsistency();
274f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
275f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DeleteRemoteFile(folder);
276f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DeleteRemoteFile(file);
277f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
278a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AppendExpectedChange(URL(kOrigin, "folder"),
279f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       FileChange::FILE_CHANGE_DELETE,
280f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       SYNC_FILE_TYPE_UNKNOWN);
281a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AppendExpectedChange(URL(kOrigin, "file"),
282f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       FileChange::FILE_CHANGE_DELETE,
283f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       SYNC_FILE_TYPE_UNKNOWN);
284f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
285a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, ListChanges());
286f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RunSyncerUntilIdle();
287f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  VerifyConsistency();
288a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
289a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_FALSE(GetMetadataDatabase()->GetNormalPriorityDirtyTracker(NULL));
290a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_FALSE(GetMetadataDatabase()->GetLowPriorityDirtyTracker(NULL));
291f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
292f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
293f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(RemoteToLocalSyncerTest, DeleteNestedFiles) {
294f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const GURL kOrigin("chrome-extension://example");
295f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string sync_root = CreateSyncRoot();
296f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host());
297f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  InitializeMetadataDatabase();
298f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RegisterApp(kOrigin.host(), app_root);
299f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
300f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string folder1 = CreateRemoteFolder(app_root, "folder1");
301f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string file1 = CreateRemoteFile(app_root, "file1", "data1");
302f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string folder2 = CreateRemoteFolder(folder1, "folder2");
303f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string file2 = CreateRemoteFile(folder1, "file2", "data2");
304f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
305a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AppendExpectedChange(URL(kOrigin, "folder1"),
306f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       FileChange::FILE_CHANGE_ADD_OR_UPDATE,
307f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       SYNC_FILE_TYPE_DIRECTORY);
308a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AppendExpectedChange(URL(kOrigin, "file1"),
309f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       FileChange::FILE_CHANGE_ADD_OR_UPDATE,
310f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       SYNC_FILE_TYPE_FILE);
311a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AppendExpectedChange(URL(kOrigin, "folder1/folder2"),
312f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       FileChange::FILE_CHANGE_ADD_OR_UPDATE,
313f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       SYNC_FILE_TYPE_DIRECTORY);
314a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AppendExpectedChange(URL(kOrigin, "folder1/file2"),
315f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       FileChange::FILE_CHANGE_ADD_OR_UPDATE,
316f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       SYNC_FILE_TYPE_FILE);
317f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
318f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RunSyncerUntilIdle();
319f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  VerifyConsistency();
320f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
321f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DeleteRemoteFile(folder1);
322f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
323a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AppendExpectedChange(URL(kOrigin, "folder1"),
324f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       FileChange::FILE_CHANGE_DELETE,
325f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       SYNC_FILE_TYPE_UNKNOWN);
326f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Changes for descendant files ("folder2" and "file2") should be ignored.
327f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
328a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, ListChanges());
329f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RunSyncerUntilIdle();
330f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  VerifyConsistency();
331a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
332a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_FALSE(GetMetadataDatabase()->GetNormalPriorityDirtyTracker(NULL));
333a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_FALSE(GetMetadataDatabase()->GetLowPriorityDirtyTracker(NULL));
334f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
335f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
336f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(RemoteToLocalSyncerTest, Conflict_CreateFileOnFolder) {
337f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const GURL kOrigin("chrome-extension://example");
338f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string sync_root = CreateSyncRoot();
339f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host());
340f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  InitializeMetadataDatabase();
341f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RegisterApp(kOrigin.host(), app_root);
342f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
343a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateLocalFolder(URL(kOrigin, "folder"));
344f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CreateRemoteFile(app_root, "folder", "data");
345f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
346f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Folder-File conflict happens. File creation should be ignored.
347f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
348a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, ListChanges());
349f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RunSyncerUntilIdle();
350f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  VerifyConsistency();
351a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
352a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Tracker for the remote file should be lowered.
353a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_FALSE(GetMetadataDatabase()->GetNormalPriorityDirtyTracker(NULL));
354a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(GetMetadataDatabase()->GetLowPriorityDirtyTracker(NULL));
355f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
356f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
357f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(RemoteToLocalSyncerTest, Conflict_CreateFolderOnFile) {
358f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const GURL kOrigin("chrome-extension://example");
359f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string sync_root = CreateSyncRoot();
360f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host());
361f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  InitializeMetadataDatabase();
362f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RegisterApp(kOrigin.host(), app_root);
363f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
364f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RunSyncerUntilIdle();
365f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  VerifyConsistency();
366f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
367a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateLocalFile(URL(kOrigin, "file"));
368f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CreateRemoteFolder(app_root, "file");
369f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
370f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // File-Folder conflict happens. Folder should override the existing file.
371a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AppendExpectedChange(URL(kOrigin, "file"),
372f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       FileChange::FILE_CHANGE_ADD_OR_UPDATE,
373f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       SYNC_FILE_TYPE_DIRECTORY);
374f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
375a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, ListChanges());
376f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RunSyncerUntilIdle();
377f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  VerifyConsistency();
378a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
379a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_FALSE(GetMetadataDatabase()->GetNormalPriorityDirtyTracker(NULL));
380a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_FALSE(GetMetadataDatabase()->GetLowPriorityDirtyTracker(NULL));
381f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
382f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
383f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(RemoteToLocalSyncerTest, Conflict_CreateFolderOnFolder) {
384f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const GURL kOrigin("chrome-extension://example");
385f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string sync_root = CreateSyncRoot();
386f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host());
387f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  InitializeMetadataDatabase();
388f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RegisterApp(kOrigin.host(), app_root);
389f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
390a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateLocalFolder(URL(kOrigin, "folder"));
391f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CreateRemoteFolder(app_root, "folder");
392f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
393f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Folder-Folder conflict happens. Folder creation should be ignored.
394f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
395a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, ListChanges());
396a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  RunSyncerUntilIdle();
397a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  VerifyConsistency();
398a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
399a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_FALSE(GetMetadataDatabase()->GetNormalPriorityDirtyTracker(NULL));
400a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_FALSE(GetMetadataDatabase()->GetLowPriorityDirtyTracker(NULL));
401a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
402a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
403a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(RemoteToLocalSyncerTest, Conflict_CreateFileOnFile) {
404a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const GURL kOrigin("chrome-extension://example");
405a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string sync_root = CreateSyncRoot();
406a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host());
407a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  InitializeMetadataDatabase();
408a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  RegisterApp(kOrigin.host(), app_root);
409a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
410a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateLocalFile(URL(kOrigin, "file"));
411a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateRemoteFile(app_root, "file", "data");
412a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
413a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // File-File conflict happens. File creation should be ignored.
414a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
415a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, ListChanges());
416f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RunSyncerUntilIdle();
417f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  VerifyConsistency();
418a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
419a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Tracker for the remote file should be lowered.
420a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_FALSE(GetMetadataDatabase()->GetNormalPriorityDirtyTracker(NULL));
421a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(GetMetadataDatabase()->GetLowPriorityDirtyTracker(NULL));
422f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
423f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
424a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(RemoteToLocalSyncerTest, Conflict_CreateNestedFolderOnFile) {
425a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const GURL kOrigin("chrome-extension://example");
426a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string sync_root = CreateSyncRoot();
427a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host());
428a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  InitializeMetadataDatabase();
429a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  RegisterApp(kOrigin.host(), app_root);
430a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
431a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  RunSyncerUntilIdle();
432a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  VerifyConsistency();
433a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
434a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string folder = CreateRemoteFolder(app_root, "folder");
435a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateLocalFile(URL(kOrigin, "/folder"));
436a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateRemoteFile(folder, "file", "data");
437a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
438a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // File-Folder conflict happens. Folder should override the existing file.
439a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AppendExpectedChange(URL(kOrigin, "/folder"),
440a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       FileChange::FILE_CHANGE_ADD_OR_UPDATE,
441a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       SYNC_FILE_TYPE_DIRECTORY);
442a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
443a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, ListChanges());
444a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  RunSyncerUntilIdle();
445a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  VerifyConsistency();
446a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
447a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
448a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(RemoteToLocalSyncerTest, AppRootDeletion) {
449a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const GURL kOrigin("chrome-extension://example");
450a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string sync_root = CreateSyncRoot();
451a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host());
452a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  InitializeMetadataDatabase();
453a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  RegisterApp(kOrigin.host(), app_root);
454a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
455a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  RunSyncerUntilIdle();
456a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  VerifyConsistency();
457a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
458a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DeleteRemoteFile(app_root);
459a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
460a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AppendExpectedChange(URL(kOrigin, "/"),
461a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       FileChange::FILE_CHANGE_DELETE,
462a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       SYNC_FILE_TYPE_UNKNOWN);
463a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
464a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, ListChanges());
465a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  RunSyncerUntilIdle();
466a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  VerifyConsistency();
467a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
468a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // SyncEngine will re-register the app and resurrect the app root later.
469a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
470f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
471f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace drive_backend
472f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace sync_file_system
473