Fix Win8 metro startup crash from window switcher button
[chromium-blink-merge.git] / webkit / fileapi / syncable / local_file_change_tracker_unittest.cc
blob4179e9d2d325c6a243feaea2ebdce397f8712008
1 // Copyright (c) 2012 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 "webkit/fileapi/syncable/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.h"
14 #include "base/message_loop_proxy.h"
15 #include "base/stl_util.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17 #include "webkit/blob/mock_blob_url_request_context.h"
18 #include "webkit/browser/fileapi/file_system_task_runners.h"
19 #include "webkit/fileapi/file_system_context.h"
20 #include "webkit/fileapi/syncable/canned_syncable_file_system.h"
21 #include "webkit/fileapi/syncable/local_file_sync_context.h"
22 #include "webkit/fileapi/syncable/sync_status_code.h"
23 #include "webkit/fileapi/syncable/syncable_file_system_util.h"
24 #include "webkit/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 : message_loop_(base::MessageLoop::TYPE_IO),
38 file_system_(GURL("http://example.com"),
39 "test",
40 base::MessageLoopProxy::current(),
41 base::MessageLoopProxy::current()) {}
43 virtual void SetUp() OVERRIDE {
44 file_system_.SetUp();
46 sync_context_ = new LocalFileSyncContext(base::MessageLoopProxy::current(),
47 base::MessageLoopProxy::current());
48 ASSERT_EQ(sync_file_system::SYNC_STATUS_OK,
49 file_system_.MaybeInitializeFileSystemContext(sync_context_));
52 virtual void TearDown() OVERRIDE {
53 if (sync_context_)
54 sync_context_->ShutdownOnUIThread();
55 sync_context_ = NULL;
57 message_loop_.RunUntilIdle();
58 file_system_.TearDown();
59 // Make sure we don't leave the external filesystem.
60 // (CannedSyncableFileSystem::TearDown does not do this as there may be
61 // multiple syncable file systems registered for the name)
62 RevokeSyncableFileSystem("test");
65 protected:
66 FileSystemURL URL(const std::string& path) {
67 return file_system_.URL(path);
70 FileSystemContext* file_system_context() {
71 return file_system_.file_system_context();
74 LocalFileChangeTracker* change_tracker() {
75 return file_system_context()->change_tracker();
78 void VerifyAndClearChange(const FileSystemURL& url,
79 const FileChange& expected_change) {
80 SCOPED_TRACE(testing::Message() << url.DebugString() <<
81 " expecting:" << expected_change.DebugString());
82 // Get the changes for URL and verify.
83 FileChangeList changes;
84 change_tracker()->GetChangesForURL(url, &changes);
85 ASSERT_EQ(1U, changes.size());
86 SCOPED_TRACE(testing::Message() << url.DebugString() <<
87 " actual:" << changes.DebugString());
88 EXPECT_EQ(expected_change, changes.list()[0]);
90 // Clear the URL from the change tracker.
91 change_tracker()->ClearChangesForURL(url);
94 void DropChangesInTracker() {
95 change_tracker()->DropAllChanges();
98 void RestoreChangesFromTrackerDB() {
99 change_tracker()->CollectLastDirtyChanges(file_system_context());
102 base::MessageLoop message_loop_;
104 CannedSyncableFileSystem file_system_;
105 scoped_refptr<LocalFileSyncContext> sync_context_;
107 DISALLOW_COPY_AND_ASSIGN(LocalFileChangeTrackerTest);
110 TEST_F(LocalFileChangeTrackerTest, GetChanges) {
111 EXPECT_EQ(base::PLATFORM_FILE_OK, file_system_.OpenFileSystem());
113 // Test URLs (no parent/child relationships, as we test such cases
114 // mainly in LocalFileSyncStatusTest).
115 const char kPath0[] = "test/dir a/dir";
116 const char kPath1[] = "test/dir b";
117 const char kPath2[] = "test/foo.txt";
118 const char kPath3[] = "test/bar";
119 const char kPath4[] = "temporary/dir a";
120 const char kPath5[] = "temporary/foo";
122 change_tracker()->OnCreateDirectory(URL(kPath0));
123 change_tracker()->OnRemoveDirectory(URL(kPath0)); // Offset the create.
124 change_tracker()->OnRemoveDirectory(URL(kPath1));
125 change_tracker()->OnCreateDirectory(URL(kPath2));
126 change_tracker()->OnRemoveFile(URL(kPath3));
127 change_tracker()->OnModifyFile(URL(kPath4));
128 change_tracker()->OnCreateFile(URL(kPath5));
129 change_tracker()->OnRemoveFile(URL(kPath5)); // Recorded as 'delete'.
131 FileSystemURLSet urls;
132 file_system_.GetChangedURLsInTracker(&urls);
134 EXPECT_EQ(5U, urls.size());
135 EXPECT_TRUE(ContainsKey(urls, URL(kPath1)));
136 EXPECT_TRUE(ContainsKey(urls, URL(kPath2)));
137 EXPECT_TRUE(ContainsKey(urls, URL(kPath3)));
138 EXPECT_TRUE(ContainsKey(urls, URL(kPath4)));
139 EXPECT_TRUE(ContainsKey(urls, URL(kPath5)));
141 // Changes for kPath0 must have been offset and removed.
142 EXPECT_FALSE(ContainsKey(urls, URL(kPath0)));
144 // GetNextChangedURLs only returns up to max_urls (i.e. 3) urls.
145 std::deque<FileSystemURL> urls_to_process;
146 change_tracker()->GetNextChangedURLs(&urls_to_process, 3);
147 ASSERT_EQ(3U, urls_to_process.size());
149 // Let it return all.
150 urls_to_process.clear();
151 change_tracker()->GetNextChangedURLs(&urls_to_process, 0);
152 ASSERT_EQ(5U, urls_to_process.size());
154 // The changes must be in the last-modified-time order.
155 EXPECT_EQ(URL(kPath1), urls_to_process[0]);
156 EXPECT_EQ(URL(kPath2), urls_to_process[1]);
157 EXPECT_EQ(URL(kPath3), urls_to_process[2]);
158 EXPECT_EQ(URL(kPath4), urls_to_process[3]);
159 EXPECT_EQ(URL(kPath5), urls_to_process[4]);
161 // Modify kPath4 again.
162 change_tracker()->OnModifyFile(URL(kPath4));
164 // Now the order must be changed.
165 urls_to_process.clear();
166 change_tracker()->GetNextChangedURLs(&urls_to_process, 0);
167 ASSERT_EQ(5U, urls_to_process.size());
168 EXPECT_EQ(URL(kPath1), urls_to_process[0]);
169 EXPECT_EQ(URL(kPath2), urls_to_process[1]);
170 EXPECT_EQ(URL(kPath3), urls_to_process[2]);
171 EXPECT_EQ(URL(kPath5), urls_to_process[3]);
172 EXPECT_EQ(URL(kPath4), urls_to_process[4]);
174 VerifyAndClearChange(URL(kPath1),
175 FileChange(FileChange::FILE_CHANGE_DELETE,
176 sync_file_system::SYNC_FILE_TYPE_DIRECTORY));
177 VerifyAndClearChange(URL(kPath2),
178 FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
179 sync_file_system::SYNC_FILE_TYPE_DIRECTORY));
180 VerifyAndClearChange(URL(kPath3),
181 FileChange(FileChange::FILE_CHANGE_DELETE,
182 sync_file_system::SYNC_FILE_TYPE_FILE));
183 VerifyAndClearChange(URL(kPath4),
184 FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
185 sync_file_system::SYNC_FILE_TYPE_FILE));
186 VerifyAndClearChange(URL(kPath5),
187 FileChange(FileChange::FILE_CHANGE_DELETE,
188 sync_file_system::SYNC_FILE_TYPE_FILE));
191 TEST_F(LocalFileChangeTrackerTest, RestoreCreateAndModifyChanges) {
192 EXPECT_EQ(base::PLATFORM_FILE_OK, file_system_.OpenFileSystem());
194 FileSystemURLSet urls;
196 const char kPath0[] = "file a";
197 const char kPath1[] = "dir a";
198 const char kPath2[] = "dir a/dir";
199 const char kPath3[] = "dir a/file a";
200 const char kPath4[] = "dir a/file b";
202 file_system_.GetChangedURLsInTracker(&urls);
203 ASSERT_EQ(0U, urls.size());
205 const GURL blob_url("blob:test");
206 const std::string kData("Lorem ipsum.");
207 MockBlobURLRequestContext url_request_context(file_system_context());
208 ScopedTextBlob blob(url_request_context, blob_url, kData);
210 // Create files and nested directories.
211 EXPECT_EQ(base::PLATFORM_FILE_OK,
212 file_system_.CreateFile(URL(kPath0))); // Creates a file.
213 EXPECT_EQ(base::PLATFORM_FILE_OK,
214 file_system_.CreateDirectory(URL(kPath1))); // Creates a dir.
215 EXPECT_EQ(base::PLATFORM_FILE_OK,
216 file_system_.CreateDirectory(URL(kPath2))); // Creates another dir.
217 EXPECT_EQ(base::PLATFORM_FILE_OK,
218 file_system_.CreateFile(URL(kPath3))); // Creates a file.
219 EXPECT_EQ(base::PLATFORM_FILE_OK,
220 file_system_.TruncateFile(URL(kPath3), 1)); // Modifies the file.
221 EXPECT_EQ(base::PLATFORM_FILE_OK,
222 file_system_.CreateFile(URL(kPath4))); // Creates another file.
223 EXPECT_EQ(static_cast<int64>(kData.size()),
224 file_system_.Write(&url_request_context,
225 URL(kPath4), blob_url)); // Modifies the file.
227 // Verify the changes.
228 file_system_.GetChangedURLsInTracker(&urls);
229 EXPECT_EQ(5U, urls.size());
231 // Reset the changes in in-memory tracker.
232 DropChangesInTracker();
234 // Make sure we have no in-memory changes in the tracker.
235 file_system_.GetChangedURLsInTracker(&urls);
236 ASSERT_EQ(0U, urls.size());
238 RestoreChangesFromTrackerDB();
240 // Make sure the changes are restored from the DB.
241 file_system_.GetChangedURLsInTracker(&urls);
242 EXPECT_EQ(5U, urls.size());
244 VerifyAndClearChange(URL(kPath0),
245 FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
246 sync_file_system::SYNC_FILE_TYPE_FILE));
247 VerifyAndClearChange(URL(kPath1),
248 FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
249 sync_file_system::SYNC_FILE_TYPE_DIRECTORY));
250 VerifyAndClearChange(URL(kPath2),
251 FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
252 sync_file_system::SYNC_FILE_TYPE_DIRECTORY));
253 VerifyAndClearChange(URL(kPath3),
254 FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
255 sync_file_system::SYNC_FILE_TYPE_FILE));
256 VerifyAndClearChange(URL(kPath4),
257 FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
258 sync_file_system::SYNC_FILE_TYPE_FILE));
261 TEST_F(LocalFileChangeTrackerTest, RestoreRemoveChanges) {
262 EXPECT_EQ(base::PLATFORM_FILE_OK, file_system_.OpenFileSystem());
264 FileSystemURLSet urls;
266 const char kPath0[] = "file";
267 const char kPath1[] = "dir a";
268 const char kPath2[] = "dir b";
269 const char kPath3[] = "dir b/file";
270 const char kPath4[] = "dir b/dir c";
271 const char kPath5[] = "dir b/dir c/file";
273 file_system_.GetChangedURLsInTracker(&urls);
274 ASSERT_EQ(0U, urls.size());
276 // Creates and removes a same file.
277 EXPECT_EQ(base::PLATFORM_FILE_OK,
278 file_system_.CreateFile(URL(kPath0)));
279 EXPECT_EQ(base::PLATFORM_FILE_OK,
280 file_system_.Remove(URL(kPath0), false /* recursive */));
282 // Creates and removes a same directory.
283 EXPECT_EQ(base::PLATFORM_FILE_OK,
284 file_system_.CreateDirectory(URL(kPath1)));
285 EXPECT_EQ(base::PLATFORM_FILE_OK,
286 file_system_.Remove(URL(kPath1), false /* recursive */));
288 // Creates files and nested directories, then removes the parent directory.
289 EXPECT_EQ(base::PLATFORM_FILE_OK,
290 file_system_.CreateDirectory(URL(kPath2)));
291 EXPECT_EQ(base::PLATFORM_FILE_OK,
292 file_system_.CreateFile(URL(kPath3)));
293 EXPECT_EQ(base::PLATFORM_FILE_OK,
294 file_system_.CreateDirectory(URL(kPath4)));
295 EXPECT_EQ(base::PLATFORM_FILE_OK,
296 file_system_.CreateFile(URL(kPath5)));
297 EXPECT_EQ(base::PLATFORM_FILE_OK,
298 file_system_.Remove(URL(kPath2), true /* recursive */));
300 file_system_.GetChangedURLsInTracker(&urls);
301 EXPECT_EQ(3U, urls.size());
303 DropChangesInTracker();
305 // Make sure we have no in-memory changes in the tracker.
306 file_system_.GetChangedURLsInTracker(&urls);
307 ASSERT_EQ(0U, urls.size());
309 RestoreChangesFromTrackerDB();
311 // Make sure the changes are restored from the DB.
312 file_system_.GetChangedURLsInTracker(&urls);
313 // Since directories to have been reverted (kPath1, kPath2, kPath4) are
314 // treated as FILE_CHANGE_DELETE, the number of changes should be 6.
315 EXPECT_EQ(6U, urls.size());
317 VerifyAndClearChange(URL(kPath0),
318 FileChange(FileChange::FILE_CHANGE_DELETE,
319 sync_file_system::SYNC_FILE_TYPE_UNKNOWN));
320 VerifyAndClearChange(URL(kPath1),
321 FileChange(FileChange::FILE_CHANGE_DELETE,
322 sync_file_system::SYNC_FILE_TYPE_UNKNOWN));
323 VerifyAndClearChange(URL(kPath2),
324 FileChange(FileChange::FILE_CHANGE_DELETE,
325 sync_file_system::SYNC_FILE_TYPE_UNKNOWN));
326 VerifyAndClearChange(URL(kPath3),
327 FileChange(FileChange::FILE_CHANGE_DELETE,
328 sync_file_system::SYNC_FILE_TYPE_UNKNOWN));
329 VerifyAndClearChange(URL(kPath4),
330 FileChange(FileChange::FILE_CHANGE_DELETE,
331 sync_file_system::SYNC_FILE_TYPE_UNKNOWN));
332 VerifyAndClearChange(URL(kPath5),
333 FileChange(FileChange::FILE_CHANGE_DELETE,
334 sync_file_system::SYNC_FILE_TYPE_UNKNOWN));
337 TEST_F(LocalFileChangeTrackerTest, RestoreCopyChanges) {
338 EXPECT_EQ(base::PLATFORM_FILE_OK, file_system_.OpenFileSystem());
340 FileSystemURLSet urls;
342 const char kPath0[] = "file a";
343 const char kPath1[] = "dir a";
344 const char kPath2[] = "dir a/dir";
345 const char kPath3[] = "dir a/file a";
346 const char kPath4[] = "dir a/file b";
348 const char kPath0Copy[] = "file b"; // To be copied from kPath0
349 const char kPath1Copy[] = "dir b"; // To be copied from kPath1
350 const char kPath2Copy[] = "dir b/dir"; // To be copied from kPath2
351 const char kPath3Copy[] = "dir b/file a"; // To be copied from kPath3
352 const char kPath4Copy[] = "dir b/file b"; // To be copied from kPath4
354 file_system_.GetChangedURLsInTracker(&urls);
355 ASSERT_EQ(0U, urls.size());
357 const GURL blob_url("blob:test");
358 const std::string kData("Lorem ipsum.");
359 MockBlobURLRequestContext url_request_context(file_system_context());
360 ScopedTextBlob blob(url_request_context, blob_url, kData);
362 // Create files and nested directories.
363 EXPECT_EQ(base::PLATFORM_FILE_OK,
364 file_system_.CreateFile(URL(kPath0))); // Creates a file.
365 EXPECT_EQ(base::PLATFORM_FILE_OK,
366 file_system_.CreateDirectory(URL(kPath1))); // Creates a dir.
367 EXPECT_EQ(base::PLATFORM_FILE_OK,
368 file_system_.CreateDirectory(URL(kPath2))); // Creates another dir.
369 EXPECT_EQ(base::PLATFORM_FILE_OK,
370 file_system_.CreateFile(URL(kPath3))); // Creates a file.
371 EXPECT_EQ(base::PLATFORM_FILE_OK,
372 file_system_.TruncateFile(URL(kPath3), 1)); // Modifies the file.
373 EXPECT_EQ(base::PLATFORM_FILE_OK,
374 file_system_.CreateFile(URL(kPath4))); // Creates another file.
375 EXPECT_EQ(static_cast<int64>(kData.size()),
376 file_system_.Write(&url_request_context,
377 URL(kPath4), blob_url)); // Modifies the file.
379 // Verify we have 5 changes for preparation.
380 file_system_.GetChangedURLsInTracker(&urls);
381 EXPECT_EQ(5U, urls.size());
382 change_tracker()->ClearChangesForURL(URL(kPath0));
383 change_tracker()->ClearChangesForURL(URL(kPath1));
384 change_tracker()->ClearChangesForURL(URL(kPath2));
385 change_tracker()->ClearChangesForURL(URL(kPath3));
386 change_tracker()->ClearChangesForURL(URL(kPath4));
388 // Make sure we have no changes.
389 file_system_.GetChangedURLsInTracker(&urls);
390 EXPECT_TRUE(urls.empty());
392 // Copy the file and the parent directory.
393 EXPECT_EQ(base::PLATFORM_FILE_OK,
394 file_system_.Copy(URL(kPath0), URL(kPath0Copy))); // Copy the file.
395 EXPECT_EQ(base::PLATFORM_FILE_OK,
396 file_system_.Copy(URL(kPath1), URL(kPath1Copy))); // Copy the dir.
398 file_system_.GetChangedURLsInTracker(&urls);
399 EXPECT_EQ(5U, urls.size());
400 DropChangesInTracker();
402 // Make sure we have no in-memory changes in the tracker.
403 file_system_.GetChangedURLsInTracker(&urls);
404 ASSERT_EQ(0U, urls.size());
406 RestoreChangesFromTrackerDB();
408 // Make sure the changes are restored from the DB.
409 file_system_.GetChangedURLsInTracker(&urls);
410 EXPECT_EQ(5U, urls.size());
412 VerifyAndClearChange(URL(kPath0Copy),
413 FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
414 sync_file_system::SYNC_FILE_TYPE_FILE));
415 VerifyAndClearChange(URL(kPath1Copy),
416 FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
417 sync_file_system::SYNC_FILE_TYPE_DIRECTORY));
418 VerifyAndClearChange(URL(kPath2Copy),
419 FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
420 sync_file_system::SYNC_FILE_TYPE_DIRECTORY));
421 VerifyAndClearChange(URL(kPath3Copy),
422 FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
423 sync_file_system::SYNC_FILE_TYPE_FILE));
424 VerifyAndClearChange(URL(kPath4Copy),
425 FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
426 sync_file_system::SYNC_FILE_TYPE_FILE));
429 TEST_F(LocalFileChangeTrackerTest, RestoreMoveChanges) {
430 EXPECT_EQ(base::PLATFORM_FILE_OK, file_system_.OpenFileSystem());
432 FileSystemURLSet urls;
434 const char kPath0[] = "file a";
435 const char kPath1[] = "dir a";
436 const char kPath2[] = "dir a/file";
437 const char kPath3[] = "dir a/dir";
438 const char kPath4[] = "dir a/dir/file";
440 const char kPath5[] = "file b"; // To be moved from kPath0.
441 const char kPath6[] = "dir b"; // To be moved from kPath1.
442 const char kPath7[] = "dir b/file"; // To be moved from kPath2.
443 const char kPath8[] = "dir b/dir"; // To be moved from kPath3.
444 const char kPath9[] = "dir b/dir/file"; // To be moved from kPath4.
446 file_system_.GetChangedURLsInTracker(&urls);
447 ASSERT_EQ(0U, urls.size());
449 // Create files and nested directories.
450 EXPECT_EQ(base::PLATFORM_FILE_OK,
451 file_system_.CreateFile(URL(kPath0)));
452 EXPECT_EQ(base::PLATFORM_FILE_OK,
453 file_system_.CreateDirectory(URL(kPath1)));
454 EXPECT_EQ(base::PLATFORM_FILE_OK,
455 file_system_.CreateFile(URL(kPath2)));
456 EXPECT_EQ(base::PLATFORM_FILE_OK,
457 file_system_.CreateDirectory(URL(kPath3)));
458 EXPECT_EQ(base::PLATFORM_FILE_OK,
459 file_system_.CreateFile(URL(kPath4)));
461 // Verify we have 5 changes for preparation.
462 file_system_.GetChangedURLsInTracker(&urls);
463 EXPECT_EQ(5U, urls.size());
464 change_tracker()->ClearChangesForURL(URL(kPath0));
465 change_tracker()->ClearChangesForURL(URL(kPath1));
466 change_tracker()->ClearChangesForURL(URL(kPath2));
467 change_tracker()->ClearChangesForURL(URL(kPath3));
468 change_tracker()->ClearChangesForURL(URL(kPath4));
470 // Make sure we have no changes.
471 file_system_.GetChangedURLsInTracker(&urls);
472 EXPECT_TRUE(urls.empty());
474 // Move the file and the parent directory.
475 EXPECT_EQ(base::PLATFORM_FILE_OK,
476 file_system_.Move(URL(kPath0), URL(kPath5)));
477 EXPECT_EQ(base::PLATFORM_FILE_OK,
478 file_system_.Move(URL(kPath1), URL(kPath6)));
480 file_system_.GetChangedURLsInTracker(&urls);
481 EXPECT_EQ(10U, urls.size());
483 DropChangesInTracker();
485 // Make sure we have no in-memory changes in the tracker.
486 file_system_.GetChangedURLsInTracker(&urls);
487 ASSERT_EQ(0U, urls.size());
489 RestoreChangesFromTrackerDB();
491 // Make sure the changes are restored from the DB.
492 file_system_.GetChangedURLsInTracker(&urls);
493 // Deletion for children in the deleted directory cannot be restored,
494 // so we will only have 7 changes.
495 EXPECT_EQ(7U, urls.size());
497 VerifyAndClearChange(URL(kPath0),
498 FileChange(FileChange::FILE_CHANGE_DELETE,
499 sync_file_system::SYNC_FILE_TYPE_UNKNOWN));
500 VerifyAndClearChange(URL(kPath1),
501 FileChange(FileChange::FILE_CHANGE_DELETE,
502 sync_file_system::SYNC_FILE_TYPE_UNKNOWN));
503 VerifyAndClearChange(URL(kPath5),
504 FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
505 sync_file_system::SYNC_FILE_TYPE_FILE));
506 VerifyAndClearChange(URL(kPath6),
507 FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
508 sync_file_system::SYNC_FILE_TYPE_DIRECTORY));
509 VerifyAndClearChange(URL(kPath7),
510 FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
511 sync_file_system::SYNC_FILE_TYPE_FILE));
512 VerifyAndClearChange(URL(kPath8),
513 FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
514 sync_file_system::SYNC_FILE_TYPE_DIRECTORY));
515 VerifyAndClearChange(URL(kPath9),
516 FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
517 sync_file_system::SYNC_FILE_TYPE_FILE));
520 TEST_F(LocalFileChangeTrackerTest, NextChangedURLsWithRecursiveCopy) {
521 EXPECT_EQ(base::PLATFORM_FILE_OK, file_system_.OpenFileSystem());
523 FileSystemURLSet urls;
525 const char kPath0[] = "dir a";
526 const char kPath1[] = "dir a/file";
527 const char kPath2[] = "dir a/dir";
529 const char kPath0Copy[] = "dir b";
530 const char kPath1Copy[] = "dir b/file";
531 const char kPath2Copy[] = "dir b/dir";
533 // Creates kPath0,1,2 and then copies them all.
534 EXPECT_EQ(base::PLATFORM_FILE_OK,
535 file_system_.CreateDirectory(URL(kPath0)));
536 EXPECT_EQ(base::PLATFORM_FILE_OK,
537 file_system_.CreateFile(URL(kPath1)));
538 EXPECT_EQ(base::PLATFORM_FILE_OK,
539 file_system_.CreateDirectory(URL(kPath2)));
540 EXPECT_EQ(base::PLATFORM_FILE_OK,
541 file_system_.Copy(URL(kPath0), URL(kPath0Copy)));
543 std::deque<FileSystemURL> urls_to_process;
544 change_tracker()->GetNextChangedURLs(&urls_to_process, 0);
545 ASSERT_EQ(6U, urls_to_process.size());
547 // Creation must have occured first.
548 EXPECT_EQ(URL(kPath0), urls_to_process[0]);
549 EXPECT_EQ(URL(kPath1), urls_to_process[1]);
550 EXPECT_EQ(URL(kPath2), urls_to_process[2]);
552 // Then recursive copy took place. The exact order cannot be determined
553 // but the parent directory must have been created first.
554 EXPECT_EQ(URL(kPath0Copy), urls_to_process[3]);
555 EXPECT_TRUE(URL(kPath1Copy) == urls_to_process[4] ||
556 URL(kPath2Copy) == urls_to_process[4]);
557 EXPECT_TRUE(URL(kPath1Copy) == urls_to_process[5] ||
558 URL(kPath2Copy) == urls_to_process[5]);
561 TEST_F(LocalFileChangeTrackerTest, NextChangedURLsWithRecursiveRemove) {
562 EXPECT_EQ(base::PLATFORM_FILE_OK, file_system_.OpenFileSystem());
564 FileSystemURLSet urls;
566 const char kPath0[] = "dir a";
567 const char kPath1[] = "dir a/file1";
568 const char kPath2[] = "dir a/file2";
570 // Creates kPath0,1,2 and then removes them all.
571 EXPECT_EQ(base::PLATFORM_FILE_OK,
572 file_system_.CreateDirectory(URL(kPath0)));
573 EXPECT_EQ(base::PLATFORM_FILE_OK,
574 file_system_.CreateFile(URL(kPath1)));
575 EXPECT_EQ(base::PLATFORM_FILE_OK,
576 file_system_.CreateFile(URL(kPath2)));
577 EXPECT_EQ(base::PLATFORM_FILE_OK,
578 file_system_.Remove(URL(kPath0), true /* recursive */));
580 std::deque<FileSystemURL> urls_to_process;
581 change_tracker()->GetNextChangedURLs(&urls_to_process, 0);
583 // This is actually not really desirable, but since the directory
584 // creation and deletion have been offset now we only have two
585 // file deletion changes.
587 // NOTE: This will cause 2 local sync for deleting nonexistent files
588 // on the remote side.
590 // TODO(kinuko): For micro optimization we could probably restore the ADD
591 // change type (other than ADD_OR_UPDATE) and offset file ADD+DELETE
592 // changes too.
593 ASSERT_EQ(2U, urls_to_process.size());
595 // The exact order of recursive removal cannot be determined.
596 EXPECT_TRUE(URL(kPath1) == urls_to_process[0] ||
597 URL(kPath2) == urls_to_process[0]);
598 EXPECT_TRUE(URL(kPath1) == urls_to_process[1] ||
599 URL(kPath2) == urls_to_process[1]);
602 } // namespace sync_file_system