Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / sync_file_system / local / local_file_change_tracker_unittest.cc
blob2171858432b2deed6956864b46084a1d1f6ad724
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
3 // found in the LICENSE file.
5 #include "chrome/browser/sync_file_system/local/local_file_change_tracker.h"
7 #include <deque>
8 #include <set>
10 #include "base/basictypes.h"
11 #include "base/files/scoped_temp_dir.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/message_loop/message_loop.h"
14 #include "base/message_loop/message_loop_proxy.h"
15 #include "base/stl_util.h"
16 #include "chrome/browser/sync_file_system/local/canned_syncable_file_system.h"
17 #include "chrome/browser/sync_file_system/local/local_file_sync_context.h"
18 #include "chrome/browser/sync_file_system/local/sync_file_system_backend.h"
19 #include "chrome/browser/sync_file_system/sync_status_code.h"
20 #include "chrome/browser/sync_file_system/syncable_file_system_util.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22 #include "webkit/browser/blob/mock_blob_url_request_context.h"
23 #include "webkit/browser/fileapi/file_system_context.h"
24 #include "webkit/browser/quota/quota_manager.h"
26 using fileapi::FileSystemContext;
27 using fileapi::FileSystemURL;
28 using fileapi::FileSystemURLSet;
29 using webkit_blob::MockBlobURLRequestContext;
30 using webkit_blob::ScopedTextBlob;
32 namespace sync_file_system {
34 class LocalFileChangeTrackerTest : public testing::Test {
35 public:
36 LocalFileChangeTrackerTest()
37 : file_system_(GURL("http://example.com"),
38 base::MessageLoopProxy::current().get(),
39 base::MessageLoopProxy::current().get()) {}
41 virtual void SetUp() OVERRIDE {
42 file_system_.SetUp();
44 sync_context_ =
45 new LocalFileSyncContext(base::FilePath(),
46 base::MessageLoopProxy::current().get(),
47 base::MessageLoopProxy::current().get());
48 ASSERT_EQ(
49 sync_file_system::SYNC_STATUS_OK,
50 file_system_.MaybeInitializeFileSystemContext(sync_context_.get()));
53 virtual void TearDown() OVERRIDE {
54 if (sync_context_.get())
55 sync_context_->ShutdownOnUIThread();
56 sync_context_ = NULL;
58 message_loop_.RunUntilIdle();
59 file_system_.TearDown();
60 // Make sure we don't leave the external filesystem.
61 // (CannedSyncableFileSystem::TearDown does not do this as there may be
62 // multiple syncable file systems registered for the name)
63 RevokeSyncableFileSystem();
66 protected:
67 FileSystemURL URL(const std::string& path) {
68 return file_system_.URL(path);
71 FileSystemContext* file_system_context() {
72 return file_system_.file_system_context();
75 LocalFileChangeTracker* change_tracker() {
76 return file_system_.backend()->change_tracker();
79 void VerifyAndClearChange(const FileSystemURL& url,
80 const FileChange& expected_change) {
81 SCOPED_TRACE(testing::Message() << url.DebugString() <<
82 " expecting:" << expected_change.DebugString());
83 // Get the changes for URL and verify.
84 FileChangeList changes;
85 change_tracker()->GetChangesForURL(url, &changes);
86 ASSERT_EQ(1U, changes.size());
87 SCOPED_TRACE(testing::Message() << url.DebugString() <<
88 " actual:" << changes.DebugString());
89 EXPECT_EQ(expected_change, changes.list()[0]);
91 // Clear the URL from the change tracker.
92 change_tracker()->ClearChangesForURL(url);
95 void DropChangesInTracker() {
96 change_tracker()->DropAllChanges();
99 void RestoreChangesFromTrackerDB() {
100 change_tracker()->CollectLastDirtyChanges(file_system_context());
103 void GetAllChangedURLs(fileapi::FileSystemURLSet* urls) {
104 change_tracker()->GetAllChangedURLs(urls);
107 ScopedEnableSyncFSDirectoryOperation enable_directory_operation_;
108 base::MessageLoopForIO message_loop_;
109 CannedSyncableFileSystem file_system_;
111 private:
112 scoped_refptr<LocalFileSyncContext> sync_context_;
114 DISALLOW_COPY_AND_ASSIGN(LocalFileChangeTrackerTest);
117 TEST_F(LocalFileChangeTrackerTest, GetChanges) {
118 EXPECT_EQ(base::PLATFORM_FILE_OK, file_system_.OpenFileSystem());
120 // Test URLs (no parent/child relationships, as we test such cases
121 // mainly in LocalFileSyncStatusTest).
122 const char kPath0[] = "test/dir a/dir";
123 const char kPath1[] = "test/dir b";
124 const char kPath2[] = "test/foo.txt";
125 const char kPath3[] = "test/bar";
126 const char kPath4[] = "temporary/dir a";
127 const char kPath5[] = "temporary/foo";
129 change_tracker()->OnCreateDirectory(URL(kPath0));
130 change_tracker()->OnRemoveDirectory(URL(kPath0)); // Offset the create.
131 change_tracker()->OnRemoveDirectory(URL(kPath1));
132 change_tracker()->OnCreateDirectory(URL(kPath2));
133 change_tracker()->OnRemoveFile(URL(kPath3));
134 change_tracker()->OnModifyFile(URL(kPath4));
135 change_tracker()->OnCreateFile(URL(kPath5));
136 change_tracker()->OnRemoveFile(URL(kPath5)); // Recorded as 'delete'.
138 FileSystemURLSet urls;
139 file_system_.GetChangedURLsInTracker(&urls);
141 EXPECT_EQ(5U, urls.size());
142 EXPECT_TRUE(ContainsKey(urls, URL(kPath1)));
143 EXPECT_TRUE(ContainsKey(urls, URL(kPath2)));
144 EXPECT_TRUE(ContainsKey(urls, URL(kPath3)));
145 EXPECT_TRUE(ContainsKey(urls, URL(kPath4)));
146 EXPECT_TRUE(ContainsKey(urls, URL(kPath5)));
148 // Changes for kPath0 must have been offset and removed.
149 EXPECT_FALSE(ContainsKey(urls, URL(kPath0)));
151 // GetNextChangedURLs only returns up to max_urls (i.e. 3) urls.
152 std::deque<FileSystemURL> urls_to_process;
153 change_tracker()->GetNextChangedURLs(&urls_to_process, 3);
154 ASSERT_EQ(3U, urls_to_process.size());
156 // Let it return all.
157 urls_to_process.clear();
158 change_tracker()->GetNextChangedURLs(&urls_to_process, 0);
159 ASSERT_EQ(5U, urls_to_process.size());
161 // The changes must be in the last-modified-time order.
162 EXPECT_EQ(URL(kPath1), urls_to_process[0]);
163 EXPECT_EQ(URL(kPath2), urls_to_process[1]);
164 EXPECT_EQ(URL(kPath3), urls_to_process[2]);
165 EXPECT_EQ(URL(kPath4), urls_to_process[3]);
166 EXPECT_EQ(URL(kPath5), urls_to_process[4]);
168 // Modify kPath4 again.
169 change_tracker()->OnModifyFile(URL(kPath4));
171 // Now the order must be changed.
172 urls_to_process.clear();
173 change_tracker()->GetNextChangedURLs(&urls_to_process, 0);
174 ASSERT_EQ(5U, urls_to_process.size());
175 EXPECT_EQ(URL(kPath1), urls_to_process[0]);
176 EXPECT_EQ(URL(kPath2), urls_to_process[1]);
177 EXPECT_EQ(URL(kPath3), urls_to_process[2]);
178 EXPECT_EQ(URL(kPath5), urls_to_process[3]);
179 EXPECT_EQ(URL(kPath4), urls_to_process[4]);
181 // No changes to promote yet, we've demoted no changes.
182 EXPECT_FALSE(change_tracker()->PromoteDemotedChanges());
184 // Demote changes for kPath1 and kPath3.
185 change_tracker()->DemoteChangesForURL(URL(kPath1));
186 change_tracker()->DemoteChangesForURL(URL(kPath3));
188 // Now we'll get no changes for kPath1 and kPath3 (it's in a separate queue).
189 urls_to_process.clear();
190 change_tracker()->GetNextChangedURLs(&urls_to_process, 0);
191 ASSERT_EQ(3U, urls_to_process.size());
192 EXPECT_EQ(URL(kPath2), urls_to_process[0]);
193 EXPECT_EQ(URL(kPath5), urls_to_process[1]);
194 EXPECT_EQ(URL(kPath4), urls_to_process[2]);
196 // Promote changes.
197 EXPECT_TRUE(change_tracker()->PromoteDemotedChanges());
199 // Now we should have kPath1 and kPath3.
200 urls_to_process.clear();
201 change_tracker()->GetNextChangedURLs(&urls_to_process, 0);
202 ASSERT_EQ(5U, urls_to_process.size());
203 EXPECT_EQ(URL(kPath2), urls_to_process[0]);
204 EXPECT_EQ(URL(kPath5), urls_to_process[1]);
205 EXPECT_EQ(URL(kPath4), urls_to_process[2]);
206 EXPECT_TRUE(URL(kPath1) == urls_to_process[3] ||
207 URL(kPath1) == urls_to_process[4]);
208 EXPECT_TRUE(URL(kPath3) == urls_to_process[3] ||
209 URL(kPath3) == urls_to_process[4]);
211 // No changes to promote any more.
212 EXPECT_FALSE(change_tracker()->PromoteDemotedChanges());
215 VerifyAndClearChange(URL(kPath1),
216 FileChange(FileChange::FILE_CHANGE_DELETE,
217 sync_file_system::SYNC_FILE_TYPE_DIRECTORY));
218 VerifyAndClearChange(URL(kPath2),
219 FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
220 sync_file_system::SYNC_FILE_TYPE_DIRECTORY));
221 VerifyAndClearChange(URL(kPath3),
222 FileChange(FileChange::FILE_CHANGE_DELETE,
223 sync_file_system::SYNC_FILE_TYPE_FILE));
224 VerifyAndClearChange(URL(kPath4),
225 FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
226 sync_file_system::SYNC_FILE_TYPE_FILE));
227 VerifyAndClearChange(URL(kPath5),
228 FileChange(FileChange::FILE_CHANGE_DELETE,
229 sync_file_system::SYNC_FILE_TYPE_FILE));
232 TEST_F(LocalFileChangeTrackerTest, RestoreCreateAndModifyChanges) {
233 EXPECT_EQ(base::PLATFORM_FILE_OK, file_system_.OpenFileSystem());
235 FileSystemURLSet urls;
237 const char kPath0[] = "file a";
238 const char kPath1[] = "dir a";
239 const char kPath2[] = "dir a/dir";
240 const char kPath3[] = "dir a/file a";
241 const char kPath4[] = "dir a/file b";
243 file_system_.GetChangedURLsInTracker(&urls);
244 ASSERT_EQ(0U, urls.size());
246 const std::string kData("Lorem ipsum.");
247 MockBlobURLRequestContext url_request_context(file_system_context());
248 ScopedTextBlob blob(url_request_context, "blob_id:test", kData);
250 // Create files and nested directories.
251 EXPECT_EQ(base::PLATFORM_FILE_OK,
252 file_system_.CreateFile(URL(kPath0))); // Creates a file.
253 EXPECT_EQ(base::PLATFORM_FILE_OK,
254 file_system_.CreateDirectory(URL(kPath1))); // Creates a dir.
255 EXPECT_EQ(base::PLATFORM_FILE_OK,
256 file_system_.CreateDirectory(URL(kPath2))); // Creates another dir.
257 EXPECT_EQ(base::PLATFORM_FILE_OK,
258 file_system_.CreateFile(URL(kPath3))); // Creates a file.
259 EXPECT_EQ(base::PLATFORM_FILE_OK,
260 file_system_.TruncateFile(URL(kPath3), 1)); // Modifies the file.
261 EXPECT_EQ(base::PLATFORM_FILE_OK,
262 file_system_.CreateFile(URL(kPath4))); // Creates another file.
263 EXPECT_EQ(static_cast<int64>(kData.size()), // Modifies the file.
264 file_system_.Write(&url_request_context,
265 URL(kPath4), blob.GetBlobDataHandle()));
267 // Verify the changes.
268 file_system_.GetChangedURLsInTracker(&urls);
269 EXPECT_EQ(5U, urls.size());
271 // Reset the changes in in-memory tracker.
272 DropChangesInTracker();
274 // Make sure we have no in-memory changes in the tracker.
275 file_system_.GetChangedURLsInTracker(&urls);
276 ASSERT_EQ(0U, urls.size());
278 RestoreChangesFromTrackerDB();
280 // Make sure the changes are restored from the DB.
281 file_system_.GetChangedURLsInTracker(&urls);
282 EXPECT_EQ(5U, urls.size());
284 VerifyAndClearChange(URL(kPath0),
285 FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
286 sync_file_system::SYNC_FILE_TYPE_FILE));
287 VerifyAndClearChange(URL(kPath1),
288 FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
289 sync_file_system::SYNC_FILE_TYPE_DIRECTORY));
290 VerifyAndClearChange(URL(kPath2),
291 FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
292 sync_file_system::SYNC_FILE_TYPE_DIRECTORY));
293 VerifyAndClearChange(URL(kPath3),
294 FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
295 sync_file_system::SYNC_FILE_TYPE_FILE));
296 VerifyAndClearChange(URL(kPath4),
297 FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
298 sync_file_system::SYNC_FILE_TYPE_FILE));
301 TEST_F(LocalFileChangeTrackerTest, RestoreRemoveChanges) {
302 EXPECT_EQ(base::PLATFORM_FILE_OK, file_system_.OpenFileSystem());
304 FileSystemURLSet urls;
306 const char kPath0[] = "file";
307 const char kPath1[] = "dir a";
308 const char kPath2[] = "dir b";
309 const char kPath3[] = "dir b/file";
310 const char kPath4[] = "dir b/dir c";
311 const char kPath5[] = "dir b/dir c/file";
313 file_system_.GetChangedURLsInTracker(&urls);
314 ASSERT_EQ(0U, urls.size());
316 // Creates and removes a same file.
317 EXPECT_EQ(base::PLATFORM_FILE_OK,
318 file_system_.CreateFile(URL(kPath0)));
319 EXPECT_EQ(base::PLATFORM_FILE_OK,
320 file_system_.Remove(URL(kPath0), false /* recursive */));
322 // Creates and removes a same directory.
323 EXPECT_EQ(base::PLATFORM_FILE_OK,
324 file_system_.CreateDirectory(URL(kPath1)));
325 EXPECT_EQ(base::PLATFORM_FILE_OK,
326 file_system_.Remove(URL(kPath1), false /* recursive */));
328 // Creates files and nested directories, then removes the parent directory.
329 EXPECT_EQ(base::PLATFORM_FILE_OK,
330 file_system_.CreateDirectory(URL(kPath2)));
331 EXPECT_EQ(base::PLATFORM_FILE_OK,
332 file_system_.CreateFile(URL(kPath3)));
333 EXPECT_EQ(base::PLATFORM_FILE_OK,
334 file_system_.CreateDirectory(URL(kPath4)));
335 EXPECT_EQ(base::PLATFORM_FILE_OK,
336 file_system_.CreateFile(URL(kPath5)));
337 EXPECT_EQ(base::PLATFORM_FILE_OK,
338 file_system_.Remove(URL(kPath2), true /* recursive */));
340 file_system_.GetChangedURLsInTracker(&urls);
341 EXPECT_EQ(3U, urls.size());
343 DropChangesInTracker();
345 // Make sure we have no in-memory changes in the tracker.
346 file_system_.GetChangedURLsInTracker(&urls);
347 ASSERT_EQ(0U, urls.size());
349 RestoreChangesFromTrackerDB();
351 // Make sure the changes are restored from the DB.
352 file_system_.GetChangedURLsInTracker(&urls);
353 // Since directories to have been reverted (kPath1, kPath2, kPath4) are
354 // treated as FILE_CHANGE_DELETE, the number of changes should be 6.
355 EXPECT_EQ(6U, urls.size());
357 VerifyAndClearChange(URL(kPath0),
358 FileChange(FileChange::FILE_CHANGE_DELETE,
359 sync_file_system::SYNC_FILE_TYPE_UNKNOWN));
360 VerifyAndClearChange(URL(kPath1),
361 FileChange(FileChange::FILE_CHANGE_DELETE,
362 sync_file_system::SYNC_FILE_TYPE_UNKNOWN));
363 VerifyAndClearChange(URL(kPath2),
364 FileChange(FileChange::FILE_CHANGE_DELETE,
365 sync_file_system::SYNC_FILE_TYPE_UNKNOWN));
366 VerifyAndClearChange(URL(kPath3),
367 FileChange(FileChange::FILE_CHANGE_DELETE,
368 sync_file_system::SYNC_FILE_TYPE_UNKNOWN));
369 VerifyAndClearChange(URL(kPath4),
370 FileChange(FileChange::FILE_CHANGE_DELETE,
371 sync_file_system::SYNC_FILE_TYPE_UNKNOWN));
372 VerifyAndClearChange(URL(kPath5),
373 FileChange(FileChange::FILE_CHANGE_DELETE,
374 sync_file_system::SYNC_FILE_TYPE_UNKNOWN));
377 TEST_F(LocalFileChangeTrackerTest, RestoreCopyChanges) {
378 EXPECT_EQ(base::PLATFORM_FILE_OK, file_system_.OpenFileSystem());
380 FileSystemURLSet urls;
382 const char kPath0[] = "file a";
383 const char kPath1[] = "dir a";
384 const char kPath2[] = "dir a/dir";
385 const char kPath3[] = "dir a/file a";
386 const char kPath4[] = "dir a/file b";
388 const char kPath0Copy[] = "file b"; // To be copied from kPath0
389 const char kPath1Copy[] = "dir b"; // To be copied from kPath1
390 const char kPath2Copy[] = "dir b/dir"; // To be copied from kPath2
391 const char kPath3Copy[] = "dir b/file a"; // To be copied from kPath3
392 const char kPath4Copy[] = "dir b/file b"; // To be copied from kPath4
394 file_system_.GetChangedURLsInTracker(&urls);
395 ASSERT_EQ(0U, urls.size());
397 const std::string kData("Lorem ipsum.");
398 MockBlobURLRequestContext url_request_context(file_system_context());
399 ScopedTextBlob blob(url_request_context, "blob_id:test", kData);
401 // Create files and nested directories.
402 EXPECT_EQ(base::PLATFORM_FILE_OK,
403 file_system_.CreateFile(URL(kPath0))); // Creates a file.
404 EXPECT_EQ(base::PLATFORM_FILE_OK,
405 file_system_.CreateDirectory(URL(kPath1))); // Creates a dir.
406 EXPECT_EQ(base::PLATFORM_FILE_OK,
407 file_system_.CreateDirectory(URL(kPath2))); // Creates another dir.
408 EXPECT_EQ(base::PLATFORM_FILE_OK,
409 file_system_.CreateFile(URL(kPath3))); // Creates a file.
410 EXPECT_EQ(base::PLATFORM_FILE_OK,
411 file_system_.TruncateFile(URL(kPath3), 1)); // Modifies the file.
412 EXPECT_EQ(base::PLATFORM_FILE_OK,
413 file_system_.CreateFile(URL(kPath4))); // Creates another file.
414 EXPECT_EQ(static_cast<int64>(kData.size()),
415 file_system_.Write(&url_request_context, // Modifies the file.
416 URL(kPath4), blob.GetBlobDataHandle()));
418 // Verify we have 5 changes for preparation.
419 file_system_.GetChangedURLsInTracker(&urls);
420 EXPECT_EQ(5U, urls.size());
421 change_tracker()->ClearChangesForURL(URL(kPath0));
422 change_tracker()->ClearChangesForURL(URL(kPath1));
423 change_tracker()->ClearChangesForURL(URL(kPath2));
424 change_tracker()->ClearChangesForURL(URL(kPath3));
425 change_tracker()->ClearChangesForURL(URL(kPath4));
427 // Make sure we have no changes.
428 file_system_.GetChangedURLsInTracker(&urls);
429 EXPECT_TRUE(urls.empty());
431 // Copy the file and the parent directory.
432 EXPECT_EQ(base::PLATFORM_FILE_OK,
433 file_system_.Copy(URL(kPath0), URL(kPath0Copy))); // Copy the file.
434 EXPECT_EQ(base::PLATFORM_FILE_OK,
435 file_system_.Copy(URL(kPath1), URL(kPath1Copy))); // Copy the dir.
437 file_system_.GetChangedURLsInTracker(&urls);
438 EXPECT_EQ(5U, urls.size());
439 DropChangesInTracker();
441 // Make sure we have no in-memory changes in the tracker.
442 file_system_.GetChangedURLsInTracker(&urls);
443 ASSERT_EQ(0U, urls.size());
445 RestoreChangesFromTrackerDB();
447 // Make sure the changes are restored from the DB.
448 file_system_.GetChangedURLsInTracker(&urls);
449 EXPECT_EQ(5U, urls.size());
451 VerifyAndClearChange(URL(kPath0Copy),
452 FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
453 sync_file_system::SYNC_FILE_TYPE_FILE));
454 VerifyAndClearChange(URL(kPath1Copy),
455 FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
456 sync_file_system::SYNC_FILE_TYPE_DIRECTORY));
457 VerifyAndClearChange(URL(kPath2Copy),
458 FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
459 sync_file_system::SYNC_FILE_TYPE_DIRECTORY));
460 VerifyAndClearChange(URL(kPath3Copy),
461 FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
462 sync_file_system::SYNC_FILE_TYPE_FILE));
463 VerifyAndClearChange(URL(kPath4Copy),
464 FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
465 sync_file_system::SYNC_FILE_TYPE_FILE));
468 TEST_F(LocalFileChangeTrackerTest, RestoreMoveChanges) {
469 EXPECT_EQ(base::PLATFORM_FILE_OK, file_system_.OpenFileSystem());
471 FileSystemURLSet urls;
473 const char kPath0[] = "file a";
474 const char kPath1[] = "dir a";
475 const char kPath2[] = "dir a/file";
476 const char kPath3[] = "dir a/dir";
477 const char kPath4[] = "dir a/dir/file";
479 const char kPath5[] = "file b"; // To be moved from kPath0.
480 const char kPath6[] = "dir b"; // To be moved from kPath1.
481 const char kPath7[] = "dir b/file"; // To be moved from kPath2.
482 const char kPath8[] = "dir b/dir"; // To be moved from kPath3.
483 const char kPath9[] = "dir b/dir/file"; // To be moved from kPath4.
485 file_system_.GetChangedURLsInTracker(&urls);
486 ASSERT_EQ(0U, urls.size());
488 // Create files and nested directories.
489 EXPECT_EQ(base::PLATFORM_FILE_OK,
490 file_system_.CreateFile(URL(kPath0)));
491 EXPECT_EQ(base::PLATFORM_FILE_OK,
492 file_system_.CreateDirectory(URL(kPath1)));
493 EXPECT_EQ(base::PLATFORM_FILE_OK,
494 file_system_.CreateFile(URL(kPath2)));
495 EXPECT_EQ(base::PLATFORM_FILE_OK,
496 file_system_.CreateDirectory(URL(kPath3)));
497 EXPECT_EQ(base::PLATFORM_FILE_OK,
498 file_system_.CreateFile(URL(kPath4)));
500 // Verify we have 5 changes for preparation.
501 file_system_.GetChangedURLsInTracker(&urls);
502 EXPECT_EQ(5U, urls.size());
503 change_tracker()->ClearChangesForURL(URL(kPath0));
504 change_tracker()->ClearChangesForURL(URL(kPath1));
505 change_tracker()->ClearChangesForURL(URL(kPath2));
506 change_tracker()->ClearChangesForURL(URL(kPath3));
507 change_tracker()->ClearChangesForURL(URL(kPath4));
509 // Make sure we have no changes.
510 file_system_.GetChangedURLsInTracker(&urls);
511 EXPECT_TRUE(urls.empty());
513 // Move the file and the parent directory.
514 EXPECT_EQ(base::PLATFORM_FILE_OK,
515 file_system_.Move(URL(kPath0), URL(kPath5)));
516 EXPECT_EQ(base::PLATFORM_FILE_OK,
517 file_system_.Move(URL(kPath1), URL(kPath6)));
519 file_system_.GetChangedURLsInTracker(&urls);
520 EXPECT_EQ(10U, urls.size());
522 DropChangesInTracker();
524 // Make sure we have no in-memory changes in the tracker.
525 file_system_.GetChangedURLsInTracker(&urls);
526 ASSERT_EQ(0U, urls.size());
528 RestoreChangesFromTrackerDB();
530 // Make sure the changes are restored from the DB.
531 file_system_.GetChangedURLsInTracker(&urls);
532 // Deletion for child files in the deleted directory cannot be restored,
533 // so we will only have 8 changes.
534 EXPECT_EQ(8U, urls.size());
536 VerifyAndClearChange(URL(kPath0),
537 FileChange(FileChange::FILE_CHANGE_DELETE,
538 sync_file_system::SYNC_FILE_TYPE_UNKNOWN));
539 VerifyAndClearChange(URL(kPath1),
540 FileChange(FileChange::FILE_CHANGE_DELETE,
541 sync_file_system::SYNC_FILE_TYPE_UNKNOWN));
542 VerifyAndClearChange(URL(kPath3),
543 FileChange(FileChange::FILE_CHANGE_DELETE,
544 sync_file_system::SYNC_FILE_TYPE_UNKNOWN));
545 VerifyAndClearChange(URL(kPath5),
546 FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
547 sync_file_system::SYNC_FILE_TYPE_FILE));
548 VerifyAndClearChange(URL(kPath6),
549 FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
550 sync_file_system::SYNC_FILE_TYPE_DIRECTORY));
551 VerifyAndClearChange(URL(kPath7),
552 FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
553 sync_file_system::SYNC_FILE_TYPE_FILE));
554 VerifyAndClearChange(URL(kPath8),
555 FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
556 sync_file_system::SYNC_FILE_TYPE_DIRECTORY));
557 VerifyAndClearChange(URL(kPath9),
558 FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
559 sync_file_system::SYNC_FILE_TYPE_FILE));
562 TEST_F(LocalFileChangeTrackerTest, NextChangedURLsWithRecursiveCopy) {
563 EXPECT_EQ(base::PLATFORM_FILE_OK, file_system_.OpenFileSystem());
565 FileSystemURLSet urls;
567 const char kPath0[] = "dir a";
568 const char kPath1[] = "dir a/file";
569 const char kPath2[] = "dir a/dir";
571 const char kPath0Copy[] = "dir b";
572 const char kPath1Copy[] = "dir b/file";
573 const char kPath2Copy[] = "dir b/dir";
575 // Creates kPath0,1,2 and then copies them all.
576 EXPECT_EQ(base::PLATFORM_FILE_OK,
577 file_system_.CreateDirectory(URL(kPath0)));
578 EXPECT_EQ(base::PLATFORM_FILE_OK,
579 file_system_.CreateFile(URL(kPath1)));
580 EXPECT_EQ(base::PLATFORM_FILE_OK,
581 file_system_.CreateDirectory(URL(kPath2)));
582 EXPECT_EQ(base::PLATFORM_FILE_OK,
583 file_system_.Copy(URL(kPath0), URL(kPath0Copy)));
585 std::deque<FileSystemURL> urls_to_process;
586 change_tracker()->GetNextChangedURLs(&urls_to_process, 0);
587 ASSERT_EQ(6U, urls_to_process.size());
589 // Creation must have occured first.
590 EXPECT_EQ(URL(kPath0), urls_to_process[0]);
591 EXPECT_EQ(URL(kPath1), urls_to_process[1]);
592 EXPECT_EQ(URL(kPath2), urls_to_process[2]);
594 // Then recursive copy took place. The exact order cannot be determined
595 // but the parent directory must have been created first.
596 EXPECT_EQ(URL(kPath0Copy), urls_to_process[3]);
597 EXPECT_TRUE(URL(kPath1Copy) == urls_to_process[4] ||
598 URL(kPath2Copy) == urls_to_process[4]);
599 EXPECT_TRUE(URL(kPath1Copy) == urls_to_process[5] ||
600 URL(kPath2Copy) == urls_to_process[5]);
603 TEST_F(LocalFileChangeTrackerTest, NextChangedURLsWithRecursiveRemove) {
604 EXPECT_EQ(base::PLATFORM_FILE_OK, file_system_.OpenFileSystem());
606 const char kPath0[] = "dir a";
607 const char kPath1[] = "dir a/file1";
608 const char kPath2[] = "dir a/file2";
610 // Creates kPath0,1,2 and then removes them all.
611 EXPECT_EQ(base::PLATFORM_FILE_OK,
612 file_system_.CreateDirectory(URL(kPath0)));
613 EXPECT_EQ(base::PLATFORM_FILE_OK,
614 file_system_.CreateFile(URL(kPath1)));
615 EXPECT_EQ(base::PLATFORM_FILE_OK,
616 file_system_.CreateFile(URL(kPath2)));
617 EXPECT_EQ(base::PLATFORM_FILE_OK,
618 file_system_.Remove(URL(kPath0), true /* recursive */));
620 FileSystemURLSet urls;
621 GetAllChangedURLs(&urls);
623 // This is actually not really desirable, but since the directory
624 // creation and deletion have been offset now we only have two
625 // file deletion changes.
627 // NOTE: This will cause 2 local sync for deleting nonexistent files
628 // on the remote side.
630 // TODO(kinuko): For micro optimization we could probably restore the ADD
631 // change type (other than ADD_OR_UPDATE) and offset file ADD+DELETE
632 // changes too.
633 ASSERT_EQ(2U, urls.size());
635 // The exact order of recursive removal cannot be determined.
636 EXPECT_TRUE(ContainsKey(urls, URL(kPath1)));
637 EXPECT_TRUE(ContainsKey(urls, URL(kPath2)));
640 TEST_F(LocalFileChangeTrackerTest, ResetForFileSystem) {
641 EXPECT_EQ(base::PLATFORM_FILE_OK, file_system_.OpenFileSystem());
643 const char kPath0[] = "dir a";
644 const char kPath1[] = "dir a/file";
645 const char kPath2[] = "dir a/subdir";
646 const char kPath3[] = "dir b";
648 EXPECT_EQ(base::PLATFORM_FILE_OK,
649 file_system_.CreateDirectory(URL(kPath0)));
650 EXPECT_EQ(base::PLATFORM_FILE_OK,
651 file_system_.CreateFile(URL(kPath1)));
652 EXPECT_EQ(base::PLATFORM_FILE_OK,
653 file_system_.CreateDirectory(URL(kPath2)));
654 EXPECT_EQ(base::PLATFORM_FILE_OK,
655 file_system_.CreateDirectory(URL(kPath3)));
657 FileSystemURLSet urls;
658 GetAllChangedURLs(&urls);
659 EXPECT_EQ(4u, urls.size());
660 EXPECT_TRUE(ContainsKey(urls, URL(kPath0)));
661 EXPECT_TRUE(ContainsKey(urls, URL(kPath1)));
662 EXPECT_TRUE(ContainsKey(urls, URL(kPath2)));
663 EXPECT_TRUE(ContainsKey(urls, URL(kPath3)));
665 // Reset all changes for the file system.
666 change_tracker()->ResetForFileSystem(
667 file_system_.origin(), file_system_.type());
669 GetAllChangedURLs(&urls);
670 EXPECT_TRUE(urls.empty());
672 // Make sure they're gone from the database too.
673 DropChangesInTracker();
674 RestoreChangesFromTrackerDB();
676 GetAllChangedURLs(&urls);
677 EXPECT_TRUE(urls.empty());
680 } // namespace sync_file_system