Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(29)

Side by Side Diff: chrome/browser/sync_file_system/drive_backend/conflict_resolver_unittest.cc

Issue 98053002: SyncFS: Add ConflictResolverTest (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | chrome/chrome_tests_unit.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/sync_file_system/drive_backend/local_to_remote_syncer.h " 5 #include "chrome/browser/sync_file_system/drive_backend/conflict_resolver.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/callback.h" 8 #include "base/callback.h"
9 #include "base/files/scoped_temp_dir.h" 9 #include "base/files/scoped_temp_dir.h"
10 #include "base/logging.h"
11 #include "base/run_loop.h" 10 #include "base/run_loop.h"
12 #include "chrome/browser/drive/drive_uploader.h" 11 #include "chrome/browser/drive/drive_uploader.h"
13 #include "chrome/browser/drive/fake_drive_service.h" 12 #include "chrome/browser/drive/fake_drive_service.h"
14 #include "chrome/browser/google_apis/gdata_errorcode.h" 13 #include "chrome/browser/google_apis/gdata_errorcode.h"
15 #include "chrome/browser/sync_file_system/drive_backend/drive_backend_constants. h" 14 #include "chrome/browser/sync_file_system/drive_backend/drive_backend_constants. h"
16 #include "chrome/browser/sync_file_system/drive_backend/drive_backend_test_util. h" 15 #include "chrome/browser/sync_file_system/drive_backend/drive_backend_test_util. h"
17 #include "chrome/browser/sync_file_system/drive_backend/list_changes_task.h" 16 #include "chrome/browser/sync_file_system/drive_backend/list_changes_task.h"
18 #include "chrome/browser/sync_file_system/drive_backend/metadata_database.h" 17 #include "chrome/browser/sync_file_system/drive_backend/metadata_database.h"
18 #include "chrome/browser/sync_file_system/drive_backend/remote_to_local_syncer.h "
19 #include "chrome/browser/sync_file_system/drive_backend/sync_engine_context.h" 19 #include "chrome/browser/sync_file_system/drive_backend/sync_engine_context.h"
20 #include "chrome/browser/sync_file_system/drive_backend/sync_engine_initializer. h" 20 #include "chrome/browser/sync_file_system/drive_backend/sync_engine_initializer. h"
21 #include "chrome/browser/sync_file_system/drive_backend_v1/fake_drive_service_he lper.h" 21 #include "chrome/browser/sync_file_system/drive_backend_v1/fake_drive_service_he lper.h"
22 #include "chrome/browser/sync_file_system/drive_backend_v1/fake_drive_uploader.h " 22 #include "chrome/browser/sync_file_system/drive_backend_v1/fake_drive_uploader.h "
23 #include "chrome/browser/sync_file_system/fake_remote_change_processor.h" 23 #include "chrome/browser/sync_file_system/fake_remote_change_processor.h"
24 #include "chrome/browser/sync_file_system/sync_file_system_test_util.h" 24 #include "chrome/browser/sync_file_system/sync_file_system_test_util.h"
25 #include "chrome/browser/sync_file_system/syncable_file_system_util.h" 25 #include "chrome/browser/sync_file_system/syncable_file_system_util.h"
26 #include "content/public/test/test_browser_thread_bundle.h" 26 #include "content/public/test/test_browser_thread_bundle.h"
27 #include "testing/gtest/include/gtest/gtest.h" 27 #include "testing/gtest/include/gtest/gtest.h"
28 28
29 namespace sync_file_system { 29 namespace sync_file_system {
30 namespace drive_backend { 30 namespace drive_backend {
31 31
32 namespace { 32 class ConflictResolverTest : public testing::Test,
33 33 public SyncEngineContext {
34 fileapi::FileSystemURL URL(const GURL& origin,
35 const std::string& path) {
36 return CreateSyncableFileSystemURL(
37 origin, base::FilePath::FromUTF8Unsafe(path));
38 }
39
40 } // namespace
41
42 class LocalToRemoteSyncerTest : public testing::Test,
43 public SyncEngineContext {
44 public: 34 public:
45 LocalToRemoteSyncerTest() 35 ConflictResolverTest()
46 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP) {} 36 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP) {}
47 virtual ~LocalToRemoteSyncerTest() {} 37 virtual ~ConflictResolverTest() {}
48 38
49 virtual void SetUp() OVERRIDE { 39 virtual void SetUp() OVERRIDE {
50 ASSERT_TRUE(database_dir_.CreateUniqueTempDir()); 40 ASSERT_TRUE(database_dir_.CreateUniqueTempDir());
51 41
52 fake_drive_service_.reset(new FakeDriveServiceWrapper); 42 fake_drive_service_.reset(new FakeDriveServiceWrapper);
53 ASSERT_TRUE(fake_drive_service_->LoadAccountMetadataForWapi( 43 ASSERT_TRUE(fake_drive_service_->LoadAccountMetadataForWapi(
54 "sync_file_system/account_metadata.json")); 44 "sync_file_system/account_metadata.json"));
55 ASSERT_TRUE(fake_drive_service_->LoadResourceListForWapi( 45 ASSERT_TRUE(fake_drive_service_->LoadResourceListForWapi(
56 "gdata/empty_feed.json")); 46 "gdata/empty_feed.json"));
57 47
(...skipping 29 matching lines...) Expand all
87 77
88 void RegisterApp(const std::string& app_id, 78 void RegisterApp(const std::string& app_id,
89 const std::string& app_root_folder_id) { 79 const std::string& app_root_folder_id) {
90 SyncStatusCode status = SYNC_STATUS_FAILED; 80 SyncStatusCode status = SYNC_STATUS_FAILED;
91 metadata_database_->RegisterApp(app_id, app_root_folder_id, 81 metadata_database_->RegisterApp(app_id, app_root_folder_id,
92 CreateResultReceiver(&status)); 82 CreateResultReceiver(&status));
93 base::RunLoop().RunUntilIdle(); 83 base::RunLoop().RunUntilIdle();
94 EXPECT_EQ(SYNC_STATUS_OK, status); 84 EXPECT_EQ(SYNC_STATUS_OK, status);
95 } 85 }
96 86
87 SyncStatusCode RunRemoteSyncer() {
88 SyncStatusCode status = SYNC_STATUS_UNKNOWN;
89 scoped_ptr<RemoteToLocalSyncer> syncer(new RemoteToLocalSyncer(this));
90 syncer->Run(CreateResultReceiver(&status));
91 base::RunLoop().RunUntilIdle();
92 return status;
93 }
94
97 virtual drive::DriveServiceInterface* GetDriveService() OVERRIDE { 95 virtual drive::DriveServiceInterface* GetDriveService() OVERRIDE {
98 return fake_drive_service_.get(); 96 return fake_drive_service_.get();
99 } 97 }
100 98
101 virtual drive::DriveUploaderInterface* GetDriveUploader() OVERRIDE { 99 virtual drive::DriveUploaderInterface* GetDriveUploader() OVERRIDE {
102 return drive_uploader_.get(); 100 return drive_uploader_.get();
103 } 101 }
104 102
105 virtual MetadataDatabase* GetMetadataDatabase() OVERRIDE { 103 virtual MetadataDatabase* GetMetadataDatabase() OVERRIDE {
106 return metadata_database_.get(); 104 return metadata_database_.get();
(...skipping 28 matching lines...) Expand all
135 std::string CreateRemoteFile(const std::string& parent_folder_id, 133 std::string CreateRemoteFile(const std::string& parent_folder_id,
136 const std::string& title, 134 const std::string& title,
137 const std::string& content) { 135 const std::string& content) {
138 std::string file_id; 136 std::string file_id;
139 EXPECT_EQ(google_apis::HTTP_SUCCESS, 137 EXPECT_EQ(google_apis::HTTP_SUCCESS,
140 fake_drive_helper_->AddFile( 138 fake_drive_helper_->AddFile(
141 parent_folder_id, title, content, &file_id)); 139 parent_folder_id, title, content, &file_id));
142 return file_id; 140 return file_id;
143 } 141 }
144 142
145 SyncStatusCode RunSyncer(FileChange file_change, 143 SyncStatusCode RunSyncer() {
146 const fileapi::FileSystemURL& url) {
147 SyncStatusCode status = SYNC_STATUS_UNKNOWN; 144 SyncStatusCode status = SYNC_STATUS_UNKNOWN;
148 base::FilePath local_path = base::FilePath::FromUTF8Unsafe("dummy"); 145 scoped_ptr<RemoteToLocalSyncer> syncer(new RemoteToLocalSyncer(this));
149 scoped_ptr<LocalToRemoteSyncer> syncer(new LocalToRemoteSyncer(
150 this, file_change, local_path, url));
151 syncer->Run(CreateResultReceiver(&status)); 146 syncer->Run(CreateResultReceiver(&status));
152 base::RunLoop().RunUntilIdle(); 147 base::RunLoop().RunUntilIdle();
153 return status; 148 return status;
154 } 149 }
155 150
151 void RunSyncerUntilIdle() {
152 SyncStatusCode status = SYNC_STATUS_UNKNOWN;
153 while (status != SYNC_STATUS_NO_CHANGE_TO_SYNC)
154 status = RunSyncer();
155 }
156
157 SyncStatusCode RunConflictResolver() {
158 SyncStatusCode status = SYNC_STATUS_UNKNOWN;
159 ConflictResolver resolver(this);
160 resolver.Run(CreateResultReceiver(&status));
161 base::RunLoop().RunUntilIdle();
162 return status;
163 }
164
156 SyncStatusCode ListChanges() { 165 SyncStatusCode ListChanges() {
157 ListChangesTask list_changes(this); 166 ListChangesTask list_changes(this);
158 SyncStatusCode status = SYNC_STATUS_UNKNOWN; 167 SyncStatusCode status = SYNC_STATUS_UNKNOWN;
159 list_changes.Run(CreateResultReceiver(&status)); 168 list_changes.Run(CreateResultReceiver(&status));
160 base::RunLoop().RunUntilIdle(); 169 base::RunLoop().RunUntilIdle();
161 return status; 170 return status;
162 } 171 }
163 172
164 ScopedVector<google_apis::ResourceEntry> 173 ScopedVector<google_apis::ResourceEntry>
165 GetResourceEntriesForParentAndTitle(const std::string& parent_folder_id, 174 GetResourceEntriesForParentAndTitle(const std::string& parent_folder_id,
166 const std::string& title) { 175 const std::string& title) {
167 ScopedVector<google_apis::ResourceEntry> entries; 176 ScopedVector<google_apis::ResourceEntry> entries;
168 EXPECT_EQ(google_apis::HTTP_SUCCESS, 177 EXPECT_EQ(google_apis::HTTP_SUCCESS,
169 fake_drive_helper_->SearchByTitle( 178 fake_drive_helper_->SearchByTitle(
170 parent_folder_id, title, &entries)); 179 parent_folder_id, title, &entries));
171 return entries.Pass(); 180 return entries.Pass();
172 } 181 }
173 182
174 std::string GetFileIDForParentAndTitle(const std::string& parent_folder_id, 183 void VerifyConflictResolution(const std::string& parent_folder_id,
175 const std::string& title) { 184 const std::string& title,
176 ScopedVector<google_apis::ResourceEntry> entries = 185 const std::string& primary_file_id,
177 GetResourceEntriesForParentAndTitle(parent_folder_id, title); 186 google_apis::DriveEntryKind kind) {
178 if (entries.size() != 1)
179 return std::string();
180 return entries[0]->resource_id();
181 }
182
183 void VerifyTitleUniqueness(const std::string& parent_folder_id,
184 const std::string& title,
185 google_apis::DriveEntryKind kind) {
186 ScopedVector<google_apis::ResourceEntry> entries; 187 ScopedVector<google_apis::ResourceEntry> entries;
187 EXPECT_EQ(google_apis::HTTP_SUCCESS, 188 EXPECT_EQ(google_apis::HTTP_SUCCESS,
188 fake_drive_helper_->SearchByTitle( 189 fake_drive_helper_->SearchByTitle(
189 parent_folder_id, title, &entries)); 190 parent_folder_id, title, &entries));
190 ASSERT_EQ(1u, entries.size()); 191 ASSERT_EQ(1u, entries.size());
192 EXPECT_EQ(primary_file_id, entries[0]->resource_id());
191 EXPECT_EQ(kind, entries[0]->kind()); 193 EXPECT_EQ(kind, entries[0]->kind());
192 } 194 }
193 195
194 void VerifyFileDeletion(const std::string& parent_folder_id,
195 const std::string& title) {
196 ScopedVector<google_apis::ResourceEntry> entries;
197 EXPECT_EQ(google_apis::HTTP_SUCCESS,
198 fake_drive_helper_->SearchByTitle(
199 parent_folder_id, title, &entries));
200 EXPECT_TRUE(entries.empty());
201 }
202
203 private: 196 private:
204 content::TestBrowserThreadBundle thread_bundle_; 197 content::TestBrowserThreadBundle thread_bundle_;
205 base::ScopedTempDir database_dir_; 198 base::ScopedTempDir database_dir_;
206 199
207 scoped_ptr<FakeDriveServiceWrapper> fake_drive_service_; 200 scoped_ptr<FakeDriveServiceWrapper> fake_drive_service_;
208 scoped_ptr<FakeDriveUploader> drive_uploader_; 201 scoped_ptr<FakeDriveUploader> drive_uploader_;
209 scoped_ptr<FakeDriveServiceHelper> fake_drive_helper_; 202 scoped_ptr<FakeDriveServiceHelper> fake_drive_helper_;
210 scoped_ptr<MetadataDatabase> metadata_database_; 203 scoped_ptr<MetadataDatabase> metadata_database_;
211 scoped_ptr<FakeRemoteChangeProcessor> fake_remote_change_processor_; 204 scoped_ptr<FakeRemoteChangeProcessor> fake_remote_change_processor_;
212 205
213 DISALLOW_COPY_AND_ASSIGN(LocalToRemoteSyncerTest); 206 DISALLOW_COPY_AND_ASSIGN(ConflictResolverTest);
214 }; 207 };
215 208
216 TEST_F(LocalToRemoteSyncerTest, CreateFile) { 209 TEST_F(ConflictResolverTest, NoFileToBeResolved) {
217 const GURL kOrigin("chrome-extension://example"); 210 const GURL kOrigin("chrome-extension://example");
218 const std::string sync_root = CreateSyncRoot(); 211 const std::string sync_root = CreateSyncRoot();
219 const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host()); 212 const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host());
220 InitializeMetadataDatabase(); 213 InitializeMetadataDatabase();
221 RegisterApp(kOrigin.host(), app_root); 214 RegisterApp(kOrigin.host(), app_root);
215 RunSyncerUntilIdle();
222 216
223 EXPECT_EQ(SYNC_STATUS_OK, RunSyncer( 217 EXPECT_EQ(SYNC_STATUS_NO_CHANGE_TO_SYNC, RunConflictResolver());
224 FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
225 SYNC_FILE_TYPE_FILE),
226 URL(kOrigin, "file1")));
227 EXPECT_EQ(SYNC_STATUS_OK, RunSyncer(
228 FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
229 SYNC_FILE_TYPE_DIRECTORY),
230 URL(kOrigin, "folder")));
231 EXPECT_EQ(SYNC_STATUS_OK, RunSyncer(
232 FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
233 SYNC_FILE_TYPE_FILE),
234 URL(kOrigin, "folder/file2")));
235
236 std::string folder_id = GetFileIDForParentAndTitle(app_root, "folder");
237 ASSERT_FALSE(folder_id.empty());
238
239 VerifyTitleUniqueness(app_root, "file1", google_apis::ENTRY_KIND_FILE);
240 VerifyTitleUniqueness(app_root, "folder", google_apis::ENTRY_KIND_FOLDER);
241 VerifyTitleUniqueness(folder_id, "file2", google_apis::ENTRY_KIND_FILE);
242 } 218 }
243 219
244 TEST_F(LocalToRemoteSyncerTest, CreateFileOnMissingPath) { 220 TEST_F(ConflictResolverTest, ResolveConflict_Files) {
245 const GURL kOrigin("chrome-extension://example"); 221 const GURL kOrigin("chrome-extension://example");
246 const std::string sync_root = CreateSyncRoot(); 222 const std::string sync_root = CreateSyncRoot();
247 const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host()); 223 const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host());
248 InitializeMetadataDatabase(); 224 InitializeMetadataDatabase();
249 RegisterApp(kOrigin.host(), app_root); 225 RegisterApp(kOrigin.host(), app_root);
226 RunSyncerUntilIdle();
250 227
251 // Run the syncer 3 times to create missing folder1 and folder2. 228 const std::string kTitle = "foo";
252 EXPECT_EQ(SYNC_STATUS_RETRY, RunSyncer( 229 const std::string primary = CreateRemoteFile(app_root, kTitle, "data1");
253 FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE, 230 CreateRemoteFile(app_root, kTitle, "data2");
254 SYNC_FILE_TYPE_FILE), 231 CreateRemoteFile(app_root, kTitle, "data3");
255 URL(kOrigin, "folder1/folder2/file"))); 232 CreateRemoteFile(app_root, kTitle, "data4");
256 EXPECT_EQ(SYNC_STATUS_RETRY, RunSyncer( 233 EXPECT_EQ(SYNC_STATUS_OK, ListChanges());
257 FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE, 234 RunSyncerUntilIdle();
258 SYNC_FILE_TYPE_FILE),
259 URL(kOrigin, "folder1/folder2/file")));
260 EXPECT_EQ(SYNC_STATUS_OK, RunSyncer(
261 FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
262 SYNC_FILE_TYPE_FILE),
263 URL(kOrigin, "folder1/folder2/file")));
264 235
265 std::string folder_id1 = GetFileIDForParentAndTitle(app_root, "folder1"); 236 ScopedVector<google_apis::ResourceEntry> entries =
266 ASSERT_FALSE(folder_id1.empty()); 237 GetResourceEntriesForParentAndTitle(app_root, kTitle);
267 std::string folder_id2 = GetFileIDForParentAndTitle(folder_id1, "folder2"); 238 ASSERT_EQ(4u, entries.size());
268 ASSERT_FALSE(folder_id2.empty());
269 239
270 VerifyTitleUniqueness(app_root, "folder1", google_apis::ENTRY_KIND_FOLDER); 240 // Only primary file should survive.
271 VerifyTitleUniqueness(folder_id1, "folder2", google_apis::ENTRY_KIND_FOLDER); 241 EXPECT_EQ(SYNC_STATUS_OK, RunConflictResolver());
272 VerifyTitleUniqueness(folder_id2, "file", google_apis::ENTRY_KIND_FILE); 242 VerifyConflictResolution(app_root, kTitle, primary,
243 google_apis::ENTRY_KIND_FILE);
273 } 244 }
274 245
275 TEST_F(LocalToRemoteSyncerTest, DeleteFile) { 246 TEST_F(ConflictResolverTest, ResolveConflict_Folders) {
276 const GURL kOrigin("chrome-extension://example"); 247 const GURL kOrigin("chrome-extension://example");
277 const std::string sync_root = CreateSyncRoot(); 248 const std::string sync_root = CreateSyncRoot();
278 const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host()); 249 const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host());
279 InitializeMetadataDatabase(); 250 InitializeMetadataDatabase();
280 RegisterApp(kOrigin.host(), app_root); 251 RegisterApp(kOrigin.host(), app_root);
252 RunSyncerUntilIdle();
281 253
282 EXPECT_EQ(SYNC_STATUS_OK, RunSyncer( 254 const std::string kTitle = "foo";
283 FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE, 255 const std::string primary = CreateRemoteFolder(app_root, kTitle);
284 SYNC_FILE_TYPE_FILE), 256 CreateRemoteFolder(app_root, kTitle);
285 URL(kOrigin, "file"))); 257 CreateRemoteFolder(app_root, kTitle);
286 EXPECT_EQ(SYNC_STATUS_OK, RunSyncer( 258 CreateRemoteFolder(app_root, kTitle);
287 FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE, 259 EXPECT_EQ(SYNC_STATUS_OK, ListChanges());
288 SYNC_FILE_TYPE_DIRECTORY), 260 RunSyncerUntilIdle();
289 URL(kOrigin, "folder")));
290 261
291 VerifyTitleUniqueness(app_root, "file", google_apis::ENTRY_KIND_FILE); 262 ScopedVector<google_apis::ResourceEntry> entries =
292 VerifyTitleUniqueness(app_root, "folder", google_apis::ENTRY_KIND_FOLDER); 263 GetResourceEntriesForParentAndTitle(app_root, kTitle);
264 ASSERT_EQ(4u, entries.size());
293 265
294 EXPECT_EQ(SYNC_STATUS_OK, RunSyncer( 266 // Only primary file should survive.
295 FileChange(FileChange::FILE_CHANGE_DELETE, 267 EXPECT_EQ(SYNC_STATUS_OK, RunConflictResolver());
296 SYNC_FILE_TYPE_FILE), 268 VerifyConflictResolution(app_root, kTitle, primary,
297 URL(kOrigin, "file"))); 269 google_apis::ENTRY_KIND_FOLDER);
298 EXPECT_EQ(SYNC_STATUS_OK, RunSyncer(
299 FileChange(FileChange::FILE_CHANGE_DELETE,
300 SYNC_FILE_TYPE_DIRECTORY),
301 URL(kOrigin, "folder")));
302
303 VerifyFileDeletion(app_root, "file");
304 VerifyFileDeletion(app_root, "folder");
305 } 270 }
306 271
307 TEST_F(LocalToRemoteSyncerTest, Conflict_CreateFileOnFolder) { 272 TEST_F(ConflictResolverTest, ResolveConflict_FilesAndFolders) {
308 const GURL kOrigin("chrome-extension://example"); 273 const GURL kOrigin("chrome-extension://example");
309 const std::string sync_root = CreateSyncRoot(); 274 const std::string sync_root = CreateSyncRoot();
310 const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host()); 275 const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host());
311 InitializeMetadataDatabase(); 276 InitializeMetadataDatabase();
312 RegisterApp(kOrigin.host(), app_root); 277 RegisterApp(kOrigin.host(), app_root);
278 RunSyncerUntilIdle();
313 279
314 CreateRemoteFolder(app_root, "foo"); 280 const std::string kTitle = "foo";
281 CreateRemoteFile(app_root, kTitle, "data");
282 const std::string primary = CreateRemoteFolder(app_root, kTitle);
283 CreateRemoteFile(app_root, kTitle, "data2");
284 CreateRemoteFolder(app_root, kTitle);
315 EXPECT_EQ(SYNC_STATUS_OK, ListChanges()); 285 EXPECT_EQ(SYNC_STATUS_OK, ListChanges());
316 EXPECT_EQ(SYNC_STATUS_OK, RunSyncer( 286 RunSyncerUntilIdle();
317 FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
318 SYNC_FILE_TYPE_FILE),
319 URL(kOrigin, "foo")));
320 287
321 // There should exist both file and folder on remote.
322 ScopedVector<google_apis::ResourceEntry> entries = 288 ScopedVector<google_apis::ResourceEntry> entries =
323 GetResourceEntriesForParentAndTitle(app_root, "foo"); 289 GetResourceEntriesForParentAndTitle(app_root, kTitle);
324 ASSERT_EQ(2u, entries.size()); 290 ASSERT_EQ(4u, entries.size());
325 EXPECT_EQ(google_apis::ENTRY_KIND_FOLDER, entries[0]->kind()); 291
326 EXPECT_EQ(google_apis::ENTRY_KIND_FILE, entries[1]->kind()); 292 // Only primary file should survive.
293 EXPECT_EQ(SYNC_STATUS_OK, RunConflictResolver());
294 VerifyConflictResolution(app_root, kTitle, primary,
295 google_apis::ENTRY_KIND_FOLDER);
327 } 296 }
328 297
329 TEST_F(LocalToRemoteSyncerTest, Conflict_CreateFolderOnFile) { 298 // TODO(nhiroki): Add multi-parent resolution cases.
330 const GURL kOrigin("chrome-extension://example");
331 const std::string sync_root = CreateSyncRoot();
332 const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host());
333 InitializeMetadataDatabase();
334 RegisterApp(kOrigin.host(), app_root);
335
336 CreateRemoteFile(app_root, "foo", "data");
337 EXPECT_EQ(SYNC_STATUS_OK, ListChanges());
338
339 EXPECT_EQ(SYNC_STATUS_OK, RunSyncer(
340 FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
341 SYNC_FILE_TYPE_DIRECTORY),
342 URL(kOrigin, "foo")));
343
344 // There should exist both file and folder on remote.
345 ScopedVector<google_apis::ResourceEntry> entries =
346 GetResourceEntriesForParentAndTitle(app_root, "foo");
347 ASSERT_EQ(2u, entries.size());
348 EXPECT_EQ(google_apis::ENTRY_KIND_FILE, entries[0]->kind());
349 EXPECT_EQ(google_apis::ENTRY_KIND_FOLDER, entries[1]->kind());
350 }
351
352 TEST_F(LocalToRemoteSyncerTest, Conflict_CreateFileOnFile) {
353 const GURL kOrigin("chrome-extension://example");
354 const std::string sync_root = CreateSyncRoot();
355 const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host());
356 InitializeMetadataDatabase();
357 RegisterApp(kOrigin.host(), app_root);
358
359 CreateRemoteFile(app_root, "foo", "data");
360 EXPECT_EQ(SYNC_STATUS_OK, ListChanges());
361
362 EXPECT_EQ(SYNC_STATUS_OK, RunSyncer(
363 FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
364 SYNC_FILE_TYPE_FILE),
365 URL(kOrigin, "foo")));
366
367 // There should exist both files on remote.
368 ScopedVector<google_apis::ResourceEntry> entries =
369 GetResourceEntriesForParentAndTitle(app_root, "foo");
370 ASSERT_EQ(2u, entries.size());
371 EXPECT_EQ(google_apis::ENTRY_KIND_FILE, entries[0]->kind());
372 EXPECT_EQ(google_apis::ENTRY_KIND_FILE, entries[1]->kind());
373 }
374
375 // TODO(nhiroki): Add folder-folder conflict (reusing remote folder) case.
376 299
377 } // namespace drive_backend 300 } // namespace drive_backend
378 } // namespace sync_file_system 301 } // namespace sync_file_system
OLDNEW
« no previous file with comments | « no previous file | chrome/chrome_tests_unit.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698