local_to_remote_syncer_unittest.cc revision 6e8cce623b6e4fe0c9e4af605d675dd9d0338c38
1a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// found in the LICENSE file.
4a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
5a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/sync_file_system/drive_backend/local_to_remote_syncer.h"
6a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
7a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/bind.h"
8a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/callback.h"
9a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/files/scoped_temp_dir.h"
10a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/logging.h"
11a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/run_loop.h"
12116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/thread_task_runner_handle.h"
13a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/drive/drive_api_util.h"
14a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/drive/drive_uploader.h"
15a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/drive/fake_drive_service.h"
16a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/sync_file_system/drive_backend/drive_backend_constants.h"
17a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (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"
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/sync_file_system/drive_backend/fake_drive_uploader.h"
20a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/sync_file_system/drive_backend/list_changes_task.h"
21a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/sync_file_system/drive_backend/metadata_database.h"
22a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/sync_file_system/drive_backend/metadata_database.pb.h"
23a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/sync_file_system/drive_backend/remote_to_local_syncer.h"
24a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/sync_file_system/drive_backend/sync_engine_context.h"
25a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/sync_file_system/drive_backend/sync_engine_initializer.h"
26effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "chrome/browser/sync_file_system/drive_backend/sync_task_manager.h"
27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/sync_file_system/drive_backend/sync_task_token.h"
28a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/sync_file_system/fake_remote_change_processor.h"
29a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/sync_file_system/sync_file_system_test_util.h"
30a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/sync_file_system/syncable_file_system_util.h"
31a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/public/test/test_browser_thread_bundle.h"
32a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "google_apis/drive/drive_api_parser.h"
33a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "google_apis/drive/gdata_errorcode.h"
34a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "third_party/leveldatabase/src/helpers/memenv/memenv.h"
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "third_party/leveldatabase/src/include/leveldb/env.h"
37a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
38a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace sync_file_system {
39a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace drive_backend {
40a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
41a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace {
42a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
43a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)fileapi::FileSystemURL URL(const GURL& origin,
44a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                           const std::string& path) {
45a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return CreateSyncableFileSystemURL(
46a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      origin, base::FilePath::FromUTF8Unsafe(path));
47a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
48a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
49f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)const int kRetryLimit = 100;
50f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
51a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}  // namespace
52a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
53effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochclass LocalToRemoteSyncerTest : public testing::Test {
54a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) public:
55a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  LocalToRemoteSyncerTest()
56a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP) {}
57a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual ~LocalToRemoteSyncerTest() {}
58a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
59a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void SetUp() OVERRIDE {
60a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    ASSERT_TRUE(database_dir_.CreateUniqueTempDir());
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    in_memory_env_.reset(leveldb::NewMemEnv(leveldb::Env::Default()));
62a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
63010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    scoped_ptr<FakeDriveServiceWrapper>
64010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        fake_drive_service(new FakeDriveServiceWrapper);
65010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    scoped_ptr<drive::DriveUploaderInterface>
66010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        drive_uploader(new FakeDriveUploader(fake_drive_service.get()));
67a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    fake_drive_helper_.reset(new FakeDriveServiceHelper(
68010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        fake_drive_service.get(),
69010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        drive_uploader.get(),
70a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        kSyncRootFolderTitle));
71010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    remote_change_processor_.reset(new FakeRemoteChangeProcessor);
72a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
73effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    context_.reset(new SyncEngineContext(
74010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        fake_drive_service.PassAs<drive::DriveServiceInterface>(),
75010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        drive_uploader.Pass(),
76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        NULL,
77116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        base::ThreadTaskRunnerHandle::Get(),
78116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        base::ThreadTaskRunnerHandle::Get()));
79010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    context_->SetRemoteChangeProcessor(remote_change_processor_.get());
80effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
81a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    RegisterSyncableFileSystem();
82effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
83effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    sync_task_manager_.reset(new SyncTaskManager(
84effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        base::WeakPtr<SyncTaskManager::Client>(),
856d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        10 /* maximum_background_task */,
86116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        base::ThreadTaskRunnerHandle::Get()));
87effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    sync_task_manager_->Initialize(SYNC_STATUS_OK);
88a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
89a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
90a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void TearDown() OVERRIDE {
91effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    sync_task_manager_.reset();
92a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    RevokeSyncableFileSystem();
93a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    fake_drive_helper_.reset();
94effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    context_.reset();
95a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    base::RunLoop().RunUntilIdle();
96a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
97a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
98a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void InitializeMetadataDatabase() {
99effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    SyncEngineInitializer* initializer =
100effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        new SyncEngineInitializer(context_.get(),
101effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                  database_dir_.path(),
102effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                  in_memory_env_.get());
103a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    SyncStatusCode status = SYNC_STATUS_UNKNOWN;
104effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
105effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    sync_task_manager_->ScheduleSyncTask(
106effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        FROM_HERE,
107effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        scoped_ptr<SyncTask>(initializer),
108effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        SyncTaskManager::PRIORITY_MED,
109effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        base::Bind(&LocalToRemoteSyncerTest::DidInitializeMetadataDatabase,
110effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                   base::Unretained(this), initializer, &status));
111effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
112a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    base::RunLoop().RunUntilIdle();
113a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_EQ(SYNC_STATUS_OK, status);
114effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
115effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
116effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  void DidInitializeMetadataDatabase(SyncEngineInitializer* initializer,
117effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                     SyncStatusCode* status_out,
118effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                     SyncStatusCode status) {
119effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    *status_out = status;
120effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    context_->SetMetadataDatabase(initializer->PassMetadataDatabase());
121a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
122a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
123a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void RegisterApp(const std::string& app_id,
124a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                   const std::string& app_root_folder_id) {
125a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    SyncStatusCode status = SYNC_STATUS_FAILED;
126effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    context_->GetMetadataDatabase()->RegisterApp(
127effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        app_id, app_root_folder_id, CreateResultReceiver(&status));
128a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    base::RunLoop().RunUntilIdle();
129a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_EQ(SYNC_STATUS_OK, status);
130a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
131a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
132effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  MetadataDatabase* GetMetadataDatabase() {
133effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return context_->GetMetadataDatabase();
134a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
135a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
136a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) protected:
137a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::string CreateSyncRoot() {
138a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    std::string sync_root_folder_id;
139a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_EQ(google_apis::HTTP_CREATED,
140a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)              fake_drive_helper_->AddOrphanedFolder(
141a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                  kSyncRootFolderTitle, &sync_root_folder_id));
142a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return sync_root_folder_id;
143a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
144a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
145a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::string CreateRemoteFolder(const std::string& parent_folder_id,
146a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                 const std::string& title) {
147a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    std::string folder_id;
148a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_EQ(google_apis::HTTP_CREATED,
149a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)              fake_drive_helper_->AddFolder(
150a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                  parent_folder_id, title, &folder_id));
151a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return folder_id;
152a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
153a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
154a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::string CreateRemoteFile(const std::string& parent_folder_id,
155a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                               const std::string& title,
156a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                               const std::string& content) {
157a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    std::string file_id;
158a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_EQ(google_apis::HTTP_SUCCESS,
159a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)              fake_drive_helper_->AddFile(
160a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                  parent_folder_id, title, content, &file_id));
161a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return file_id;
162a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
163a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void DeleteResource(const std::string& file_id) {
1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(google_apis::HTTP_NO_CONTENT,
1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              fake_drive_helper_->DeleteResource(file_id));
167a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
168a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
169a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SyncStatusCode RunLocalToRemoteSyncer(FileChange file_change,
170a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                           const fileapi::FileSystemURL& url) {
171a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    SyncStatusCode status = SYNC_STATUS_UNKNOWN;
172a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    base::FilePath local_path = base::FilePath::FromUTF8Unsafe("dummy");
173a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    scoped_ptr<LocalToRemoteSyncer> syncer(new LocalToRemoteSyncer(
174effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        context_.get(),
175effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        SyncFileMetadata(file_change.file_type(), 0, base::Time()),
176a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        file_change, local_path, url));
177cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    syncer->RunPreflight(SyncTaskToken::CreateForTesting(
178cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        CreateResultReceiver(&status)));
179a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    base::RunLoop().RunUntilIdle();
180a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return status;
181a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
182a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
183a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SyncStatusCode ListChanges() {
184a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    SyncStatusCode status = SYNC_STATUS_UNKNOWN;
185effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    sync_task_manager_->ScheduleSyncTask(
186effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        FROM_HERE,
187effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        scoped_ptr<SyncTask>(new ListChangesTask(context_.get())),
188effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        SyncTaskManager::PRIORITY_MED,
189effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        CreateResultReceiver(&status));
190a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    base::RunLoop().RunUntilIdle();
191a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return status;
192a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
193a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
194a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SyncStatusCode RunRemoteToLocalSyncer() {
195a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    SyncStatusCode status = SYNC_STATUS_UNKNOWN;
196effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    scoped_ptr<RemoteToLocalSyncer>
197effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        syncer(new RemoteToLocalSyncer(context_.get()));
198116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    syncer->RunPreflight(SyncTaskToken::CreateForTesting(
199116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        CreateResultReceiver(&status)));
200a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    base::RunLoop().RunUntilIdle();
201a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return status;
202a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
203a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  SyncStatusCode RunRemoteToLocalSyncerUntilIdle() {
2056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    SyncStatusCode status;
2066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    int retry_count = 0;
2076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    do {
2086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      if (retry_count++ > kRetryLimit)
2096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        break;
2106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      status = RunRemoteToLocalSyncer();
2116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    } while (status == SYNC_STATUS_OK ||
2126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)             status == SYNC_STATUS_RETRY ||
2136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)             GetMetadataDatabase()->PromoteLowerPriorityTrackersToNormal());
2146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    EXPECT_EQ(SYNC_STATUS_NO_CHANGE_TO_SYNC, status);
2156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return status;
2166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
2176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
218a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ScopedVector<google_apis::ResourceEntry>
219a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GetResourceEntriesForParentAndTitle(const std::string& parent_folder_id,
220a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                      const std::string& title) {
221a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    ScopedVector<google_apis::ResourceEntry> entries;
222a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_EQ(google_apis::HTTP_SUCCESS,
223a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)              fake_drive_helper_->SearchByTitle(
224a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                  parent_folder_id, title, &entries));
225a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return entries.Pass();
226a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
227a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
228a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::string GetFileIDForParentAndTitle(const std::string& parent_folder_id,
229a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                         const std::string& title) {
230a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    ScopedVector<google_apis::ResourceEntry> entries =
231a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        GetResourceEntriesForParentAndTitle(parent_folder_id, title);
232a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (entries.size() != 1)
233a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return std::string();
234a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return entries[0]->resource_id();
235a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
236a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
237116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void VerifyTitleUniqueness(
238116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      const std::string& parent_folder_id,
239116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      const std::string& title,
240116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      google_apis::ResourceEntry::ResourceEntryKind kind) {
241a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    ScopedVector<google_apis::ResourceEntry> entries;
242a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_EQ(google_apis::HTTP_SUCCESS,
243a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)              fake_drive_helper_->SearchByTitle(
244a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                  parent_folder_id, title, &entries));
245a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    ASSERT_EQ(1u, entries.size());
246a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_EQ(kind, entries[0]->kind());
247a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
248a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
249a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void VerifyFileDeletion(const std::string& parent_folder_id,
250a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                          const std::string& title) {
251a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    ScopedVector<google_apis::ResourceEntry> entries;
252a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_EQ(google_apis::HTTP_SUCCESS,
253a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)              fake_drive_helper_->SearchByTitle(
254a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                  parent_folder_id, title, &entries));
255a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_TRUE(entries.empty());
256a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
257a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
258a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) private:
259a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  content::TestBrowserThreadBundle thread_bundle_;
260a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::ScopedTempDir database_dir_;
2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<leveldb::Env> in_memory_env_;
262a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
263effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  scoped_ptr<SyncEngineContext> context_;
264a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_ptr<FakeDriveServiceHelper> fake_drive_helper_;
265010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  scoped_ptr<FakeRemoteChangeProcessor> remote_change_processor_;
266effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  scoped_ptr<SyncTaskManager> sync_task_manager_;
267a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
268a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(LocalToRemoteSyncerTest);
269a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)};
270a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
271a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(LocalToRemoteSyncerTest, CreateFile) {
272a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const GURL kOrigin("chrome-extension://example");
273a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string sync_root = CreateSyncRoot();
274a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host());
275a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  InitializeMetadataDatabase();
276a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  RegisterApp(kOrigin.host(), app_root);
277a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
278a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, RunLocalToRemoteSyncer(
279a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
280a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 SYNC_FILE_TYPE_FILE),
281a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      URL(kOrigin, "file1")));
282a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, RunLocalToRemoteSyncer(
283a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
284a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 SYNC_FILE_TYPE_DIRECTORY),
285a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      URL(kOrigin, "folder")));
286a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, RunLocalToRemoteSyncer(
287a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
288a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 SYNC_FILE_TYPE_FILE),
289a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      URL(kOrigin, "folder/file2")));
290a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
291a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::string folder_id = GetFileIDForParentAndTitle(app_root, "folder");
292a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_FALSE(folder_id.empty());
293a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
294116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  VerifyTitleUniqueness(
295116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      app_root, "file1", google_apis::ResourceEntry::ENTRY_KIND_FILE);
296116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  VerifyTitleUniqueness(
297116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      app_root, "folder", google_apis::ResourceEntry::ENTRY_KIND_FOLDER);
298116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  VerifyTitleUniqueness(
299116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      folder_id, "file2", google_apis::ResourceEntry::ENTRY_KIND_FILE);
300a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
301a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
302a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(LocalToRemoteSyncerTest, CreateFileOnMissingPath) {
303a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const GURL kOrigin("chrome-extension://example");
304a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string sync_root = CreateSyncRoot();
305a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host());
306a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  InitializeMetadataDatabase();
307a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  RegisterApp(kOrigin.host(), app_root);
308a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
309a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Run the syncer 3 times to create missing folder1 and folder2.
310a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_RETRY, RunLocalToRemoteSyncer(
311a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
312a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 SYNC_FILE_TYPE_FILE),
313a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      URL(kOrigin, "folder1/folder2/file")));
314a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_RETRY, RunLocalToRemoteSyncer(
315a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
316a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 SYNC_FILE_TYPE_FILE),
317a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      URL(kOrigin, "folder1/folder2/file")));
318a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, RunLocalToRemoteSyncer(
319a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
320a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 SYNC_FILE_TYPE_FILE),
321a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      URL(kOrigin, "folder1/folder2/file")));
322a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
323a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::string folder_id1 = GetFileIDForParentAndTitle(app_root, "folder1");
324a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_FALSE(folder_id1.empty());
325a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::string folder_id2 = GetFileIDForParentAndTitle(folder_id1, "folder2");
326a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_FALSE(folder_id2.empty());
327a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
328116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  VerifyTitleUniqueness(
329116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      app_root, "folder1", google_apis::ResourceEntry::ENTRY_KIND_FOLDER);
330116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  VerifyTitleUniqueness(
331116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      folder_id1, "folder2", google_apis::ResourceEntry::ENTRY_KIND_FOLDER);
332116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  VerifyTitleUniqueness(
333116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      folder_id2, "file", google_apis::ResourceEntry::ENTRY_KIND_FILE);
334a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
335a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
336a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(LocalToRemoteSyncerTest, DeleteFile) {
337a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const GURL kOrigin("chrome-extension://example");
338a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string sync_root = CreateSyncRoot();
339a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host());
340a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  InitializeMetadataDatabase();
341a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  RegisterApp(kOrigin.host(), app_root);
342a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
343a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, RunLocalToRemoteSyncer(
344a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
345a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 SYNC_FILE_TYPE_FILE),
346a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      URL(kOrigin, "file")));
347a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, RunLocalToRemoteSyncer(
348a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
349a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 SYNC_FILE_TYPE_DIRECTORY),
350a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      URL(kOrigin, "folder")));
351a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
352116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  VerifyTitleUniqueness(
353116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      app_root, "file", google_apis::ResourceEntry::ENTRY_KIND_FILE);
354116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  VerifyTitleUniqueness(
355116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      app_root, "folder", google_apis::ResourceEntry::ENTRY_KIND_FOLDER);
356a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
357a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, RunLocalToRemoteSyncer(
358a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      FileChange(FileChange::FILE_CHANGE_DELETE,
359a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 SYNC_FILE_TYPE_FILE),
360a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      URL(kOrigin, "file")));
361a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, RunLocalToRemoteSyncer(
362a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      FileChange(FileChange::FILE_CHANGE_DELETE,
363a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 SYNC_FILE_TYPE_DIRECTORY),
364a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      URL(kOrigin, "folder")));
365a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
366a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  VerifyFileDeletion(app_root, "file");
367a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  VerifyFileDeletion(app_root, "folder");
368a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
369a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
370a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(LocalToRemoteSyncerTest, Conflict_CreateFileOnFolder) {
371a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const GURL kOrigin("chrome-extension://example");
372a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string sync_root = CreateSyncRoot();
373a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host());
374a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  InitializeMetadataDatabase();
375a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  RegisterApp(kOrigin.host(), app_root);
376a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
377a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateRemoteFolder(app_root, "foo");
378a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, ListChanges());
379a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, RunLocalToRemoteSyncer(
380a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
381a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 SYNC_FILE_TYPE_FILE),
382a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      URL(kOrigin, "foo")));
383a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
384a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // There should exist both file and folder on remote.
385a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ScopedVector<google_apis::ResourceEntry> entries =
386a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      GetResourceEntriesForParentAndTitle(app_root, "foo");
387a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(2u, entries.size());
388116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(google_apis::ResourceEntry::ENTRY_KIND_FOLDER, entries[0]->kind());
389116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(google_apis::ResourceEntry::ENTRY_KIND_FILE, entries[1]->kind());
390a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
391a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
392a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(LocalToRemoteSyncerTest, Conflict_CreateFolderOnFile) {
393a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const GURL kOrigin("chrome-extension://example");
394a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string sync_root = CreateSyncRoot();
395a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host());
396a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  InitializeMetadataDatabase();
397a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  RegisterApp(kOrigin.host(), app_root);
398a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
399a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateRemoteFile(app_root, "foo", "data");
400a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, ListChanges());
401a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
402a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, RunLocalToRemoteSyncer(
403a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
404a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 SYNC_FILE_TYPE_DIRECTORY),
405a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      URL(kOrigin, "foo")));
406a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
407a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // There should exist both file and folder on remote.
408a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ScopedVector<google_apis::ResourceEntry> entries =
409a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      GetResourceEntriesForParentAndTitle(app_root, "foo");
410a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(2u, entries.size());
411116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(google_apis::ResourceEntry::ENTRY_KIND_FILE, entries[0]->kind());
412116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(google_apis::ResourceEntry::ENTRY_KIND_FOLDER, entries[1]->kind());
413a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
414a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
415a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(LocalToRemoteSyncerTest, Conflict_CreateFileOnFile) {
416a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const GURL kOrigin("chrome-extension://example");
417a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string sync_root = CreateSyncRoot();
418a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host());
419a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  InitializeMetadataDatabase();
420a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  RegisterApp(kOrigin.host(), app_root);
421a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
422a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateRemoteFile(app_root, "foo", "data");
423a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, ListChanges());
424a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
425a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, RunLocalToRemoteSyncer(
426a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
427a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 SYNC_FILE_TYPE_FILE),
428a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      URL(kOrigin, "foo")));
429a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
430a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // There should exist both files on remote.
431a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ScopedVector<google_apis::ResourceEntry> entries =
432a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      GetResourceEntriesForParentAndTitle(app_root, "foo");
433a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(2u, entries.size());
434116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(google_apis::ResourceEntry::ENTRY_KIND_FILE, entries[0]->kind());
435116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(google_apis::ResourceEntry::ENTRY_KIND_FILE, entries[1]->kind());
436a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
437a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
438a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(LocalToRemoteSyncerTest, Conflict_UpdateDeleteOnFile) {
439a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const GURL kOrigin("chrome-extension://example");
440a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string sync_root = CreateSyncRoot();
441a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host());
442a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  InitializeMetadataDatabase();
443a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  RegisterApp(kOrigin.host(), app_root);
444a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
445a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string file_id = CreateRemoteFile(app_root, "foo", "data");
446a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, ListChanges());
4476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_NO_CHANGE_TO_SYNC,
4486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            RunRemoteToLocalSyncerUntilIdle());
449a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
4505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DeleteResource(file_id);
451a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
4525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_FILE_BUSY, RunLocalToRemoteSyncer(
453a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
454a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 SYNC_FILE_TYPE_FILE),
455a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      URL(kOrigin, "foo")));
456a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, RunLocalToRemoteSyncer(
457a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
458a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 SYNC_FILE_TYPE_FILE),
459a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      URL(kOrigin, "foo")));
460a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
461a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ScopedVector<google_apis::ResourceEntry> entries =
462a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      GetResourceEntriesForParentAndTitle(app_root, "foo");
463a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(1u, entries.size());
464116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(google_apis::ResourceEntry::ENTRY_KIND_FILE, entries[0]->kind());
465a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(!entries[0]->deleted());
466a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_NE(file_id, entries[0]->resource_id());
467a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
468a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
469a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(LocalToRemoteSyncerTest, Conflict_CreateDeleteOnFile) {
470a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const GURL kOrigin("chrome-extension://example");
471a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string sync_root = CreateSyncRoot();
472a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host());
473a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  InitializeMetadataDatabase();
474a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  RegisterApp(kOrigin.host(), app_root);
475a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
476a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string file_id = CreateRemoteFile(app_root, "foo", "data");
477a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, ListChanges());
4786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_NO_CHANGE_TO_SYNC,
4796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            RunRemoteToLocalSyncerUntilIdle());
480a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
4815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DeleteResource(file_id);
482a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
483a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, ListChanges());
484a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
485a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, RunLocalToRemoteSyncer(
486a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
487a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 SYNC_FILE_TYPE_FILE),
488a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      URL(kOrigin, "foo")));
489a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
490a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ScopedVector<google_apis::ResourceEntry> entries =
491a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      GetResourceEntriesForParentAndTitle(app_root, "foo");
492a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(1u, entries.size());
493116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(google_apis::ResourceEntry::ENTRY_KIND_FILE, entries[0]->kind());
494a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(!entries[0]->deleted());
495a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_NE(file_id, entries[0]->resource_id());
496a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
497a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
498a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(LocalToRemoteSyncerTest, Conflict_CreateFolderOnFolder) {
499a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const GURL kOrigin("chrome-extension://example");
500a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string sync_root = CreateSyncRoot();
501a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host());
502a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  InitializeMetadataDatabase();
503a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  RegisterApp(kOrigin.host(), app_root);
504a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
505a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string folder_id = CreateRemoteFolder(app_root, "foo");
506a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
507a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, RunLocalToRemoteSyncer(
508a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
509a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 SYNC_FILE_TYPE_DIRECTORY),
510a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      URL(kOrigin, "foo")));
511a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
512a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ScopedVector<google_apis::ResourceEntry> entries =
513a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      GetResourceEntriesForParentAndTitle(app_root, "foo");
514a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(2u, entries.size());
515116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(google_apis::ResourceEntry::ENTRY_KIND_FOLDER, entries[0]->kind());
516116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(google_apis::ResourceEntry::ENTRY_KIND_FOLDER, entries[1]->kind());
517a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(!entries[0]->deleted());
518a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(!entries[1]->deleted());
519a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(folder_id == entries[0]->resource_id() ||
520a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)              folder_id == entries[1]->resource_id());
521a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
522a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TrackerIDSet trackers;
523a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(GetMetadataDatabase()->FindTrackersByFileID(
524a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      folder_id, &trackers));
525a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(1u, trackers.size());
526a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_TRUE(trackers.has_active());
527a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
528a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
529a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(LocalToRemoteSyncerTest, AppRootDeletion) {
530a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const GURL kOrigin("chrome-extension://example");
531a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string sync_root = CreateSyncRoot();
532a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host());
533a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  InitializeMetadataDatabase();
534a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  RegisterApp(kOrigin.host(), app_root);
535a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
5365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DeleteResource(app_root);
537a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, ListChanges());
5386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_NO_CHANGE_TO_SYNC,
5396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            RunRemoteToLocalSyncerUntilIdle());
540a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
541a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_UNKNOWN_ORIGIN, RunLocalToRemoteSyncer(
542a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
543a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 SYNC_FILE_TYPE_DIRECTORY),
544a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      URL(kOrigin, "foo")));
545a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
546a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // SyncEngine will re-register the app and resurrect the app root later.
547a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
548a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
549a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}  // namespace drive_backend
550a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}  // namespace sync_file_system
551