190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/local/local_file_change_tracker.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <deque>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/scoped_temp_dir.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
13ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/message_loop/message_loop.h"
14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/message_loop/message_loop_proxy.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h"
162385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/local/canned_syncable_file_system.h"
172385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/local/local_file_sync_context.h"
182385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/local/sync_file_system_backend.h"
192385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/sync_status_code.h"
202385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/syncable_file_system_util.h"
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/test/mock_blob_url_request_context.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "third_party/leveldatabase/src/helpers/memenv/memenv.h"
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "third_party/leveldatabase/src/include/leveldb/env.h"
2590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/browser/fileapi/file_system_context.h"
26868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "webkit/browser/quota/quota_manager.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using fileapi::FileSystemContext;
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using fileapi::FileSystemURL;
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using fileapi::FileSystemURLSet;
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using content::MockBlobURLRequestContext;
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using content::ScopedTextBlob;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace sync_file_system {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class LocalFileChangeTrackerTest : public testing::Test {
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LocalFileChangeTrackerTest()
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      : in_memory_env_(leveldb::NewMemEnv(leveldb::Env::Default())),
40b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        file_system_(GURL("http://example.com"),
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     in_memory_env_.get(),
427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                     base::MessageLoopProxy::current().get(),
437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                     base::MessageLoopProxy::current().get()) {}
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() OVERRIDE {
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    file_system_.SetUp(CannedSyncableFileSystem::QUOTA_ENABLED);
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    sync_context_ =
49d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        new LocalFileSyncContext(base::FilePath(),
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                 in_memory_env_.get(),
51d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                 base::MessageLoopProxy::current().get(),
527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                 base::MessageLoopProxy::current().get());
53868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ASSERT_EQ(
54868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        sync_file_system::SYNC_STATUS_OK,
55868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        file_system_.MaybeInitializeFileSystemContext(sync_context_.get()));
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void TearDown() OVERRIDE {
59868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (sync_context_.get())
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sync_context_->ShutdownOnUIThread();
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sync_context_ = NULL;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    message_loop_.RunUntilIdle();
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    file_system_.TearDown();
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Make sure we don't leave the external filesystem.
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // (CannedSyncableFileSystem::TearDown does not do this as there may be
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // multiple syncable file systems registered for the name)
68868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    RevokeSyncableFileSystem();
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileSystemURL URL(const std::string& path) {
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return file_system_.URL(path);
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileSystemContext* file_system_context() {
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return file_system_.file_system_context();
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LocalFileChangeTracker* change_tracker() {
81a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return file_system_.backend()->change_tracker();
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void VerifyAndClearChange(const FileSystemURL& url,
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const FileChange& expected_change) {
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SCOPED_TRACE(testing::Message() << url.DebugString() <<
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 " expecting:" << expected_change.DebugString());
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Get the changes for URL and verify.
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FileChangeList changes;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    change_tracker()->GetChangesForURL(url, &changes);
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(1U, changes.size());
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SCOPED_TRACE(testing::Message() << url.DebugString() <<
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 " actual:" << changes.DebugString());
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(expected_change, changes.list()[0]);
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Clear the URL from the change tracker.
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    change_tracker()->ClearChangesForURL(url);
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DropChangesInTracker() {
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    change_tracker()->DropAllChanges();
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RestoreChangesFromTrackerDB() {
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    change_tracker()->CollectLastDirtyChanges(file_system_context());
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void GetAllChangedURLs(fileapi::FileSystemURLSet* urls) {
109a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    change_tracker()->GetAllChangedURLs(urls);
110a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
111a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
112eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ScopedEnableSyncFSDirectoryOperation enable_directory_operation_;
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::MessageLoopForIO message_loop_;
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<leveldb::Env> in_memory_env_;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CannedSyncableFileSystem file_system_;
116424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
117424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) private:
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<LocalFileSyncContext> sync_context_;
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(LocalFileChangeTrackerTest);
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(LocalFileChangeTrackerTest, GetChanges) {
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK, file_system_.OpenFileSystem());
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test URLs (no parent/child relationships, as we test such cases
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // mainly in LocalFileSyncStatusTest).
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kPath0[] = "test/dir a/dir";
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kPath1[] = "test/dir b";
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kPath2[] = "test/foo.txt";
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kPath3[] = "test/bar";
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kPath4[] = "temporary/dir a";
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kPath5[] = "temporary/foo";
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  change_tracker()->OnCreateDirectory(URL(kPath0));
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  change_tracker()->OnRemoveDirectory(URL(kPath0));  // Offset the create.
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  change_tracker()->OnRemoveDirectory(URL(kPath1));
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  change_tracker()->OnCreateDirectory(URL(kPath2));
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  change_tracker()->OnRemoveFile(URL(kPath3));
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  change_tracker()->OnModifyFile(URL(kPath4));
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  change_tracker()->OnCreateFile(URL(kPath5));
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  change_tracker()->OnRemoveFile(URL(kPath5));  // Recorded as 'delete'.
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileSystemURLSet urls;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system_.GetChangedURLsInTracker(&urls);
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(5U, urls.size());
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(ContainsKey(urls, URL(kPath1)));
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(ContainsKey(urls, URL(kPath2)));
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(ContainsKey(urls, URL(kPath3)));
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(ContainsKey(urls, URL(kPath4)));
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(ContainsKey(urls, URL(kPath5)));
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Changes for kPath0 must have been offset and removed.
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(ContainsKey(urls, URL(kPath0)));
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // GetNextChangedURLs only returns up to max_urls (i.e. 3) urls.
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::deque<FileSystemURL> urls_to_process;
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  change_tracker()->GetNextChangedURLs(&urls_to_process, 3);
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(3U, urls_to_process.size());
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Let it return all.
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  urls_to_process.clear();
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  change_tracker()->GetNextChangedURLs(&urls_to_process, 0);
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(5U, urls_to_process.size());
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The changes must be in the last-modified-time order.
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(URL(kPath1), urls_to_process[0]);
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(URL(kPath2), urls_to_process[1]);
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(URL(kPath3), urls_to_process[2]);
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(URL(kPath4), urls_to_process[3]);
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(URL(kPath5), urls_to_process[4]);
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Modify kPath4 again.
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  change_tracker()->OnModifyFile(URL(kPath4));
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now the order must be changed.
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  urls_to_process.clear();
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  change_tracker()->GetNextChangedURLs(&urls_to_process, 0);
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(5U, urls_to_process.size());
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(URL(kPath1), urls_to_process[0]);
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(URL(kPath2), urls_to_process[1]);
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(URL(kPath3), urls_to_process[2]);
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(URL(kPath5), urls_to_process[3]);
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(URL(kPath4), urls_to_process[4]);
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // No changes to promote yet, we've demoted no changes.
1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(change_tracker()->PromoteDemotedChanges());
1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Demote changes for kPath1 and kPath3.
1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  change_tracker()->DemoteChangesForURL(URL(kPath1));
1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  change_tracker()->DemoteChangesForURL(URL(kPath3));
1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Now we'll get no changes for kPath1 and kPath3 (it's in a separate queue).
1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  urls_to_process.clear();
1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  change_tracker()->GetNextChangedURLs(&urls_to_process, 0);
1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(3U, urls_to_process.size());
1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(URL(kPath2), urls_to_process[0]);
1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(URL(kPath5), urls_to_process[1]);
2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(URL(kPath4), urls_to_process[2]);
2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Promote changes.
2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(change_tracker()->PromoteDemotedChanges());
2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Now we should have kPath1 and kPath3.
2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  urls_to_process.clear();
2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  change_tracker()->GetNextChangedURLs(&urls_to_process, 0);
2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(5U, urls_to_process.size());
2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(URL(kPath2), urls_to_process[0]);
2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(URL(kPath5), urls_to_process[1]);
2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(URL(kPath4), urls_to_process[2]);
2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(URL(kPath1) == urls_to_process[3] ||
2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              URL(kPath1) == urls_to_process[4]);
2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(URL(kPath3) == urls_to_process[3] ||
2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              URL(kPath3) == urls_to_process[4]);
2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // No changes to promote any more.
2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(change_tracker()->PromoteDemotedChanges());
2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VerifyAndClearChange(URL(kPath1),
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               FileChange(FileChange::FILE_CHANGE_DELETE,
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          sync_file_system::SYNC_FILE_TYPE_DIRECTORY));
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VerifyAndClearChange(URL(kPath2),
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          sync_file_system::SYNC_FILE_TYPE_DIRECTORY));
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VerifyAndClearChange(URL(kPath3),
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               FileChange(FileChange::FILE_CHANGE_DELETE,
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          sync_file_system::SYNC_FILE_TYPE_FILE));
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VerifyAndClearChange(URL(kPath4),
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          sync_file_system::SYNC_FILE_TYPE_FILE));
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VerifyAndClearChange(URL(kPath5),
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               FileChange(FileChange::FILE_CHANGE_DELETE,
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          sync_file_system::SYNC_FILE_TYPE_FILE));
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(LocalFileChangeTrackerTest, RestoreCreateAndModifyChanges) {
2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK, file_system_.OpenFileSystem());
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileSystemURLSet urls;
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kPath0[] = "file a";
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kPath1[] = "dir a";
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kPath2[] = "dir a/dir";
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kPath3[] = "dir a/file a";
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kPath4[] = "dir a/file b";
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system_.GetChangedURLsInTracker(&urls);
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0U, urls.size());
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string kData("Lorem ipsum.");
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockBlobURLRequestContext url_request_context(file_system_context());
25458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ScopedTextBlob blob(url_request_context, "blob_id:test", kData);
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Create files and nested directories.
2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK,
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system_.CreateFile(URL(kPath0)));       // Creates a file.
2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK,
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system_.CreateDirectory(URL(kPath1)));  // Creates a dir.
2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK,
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system_.CreateDirectory(URL(kPath2)));  // Creates another dir.
2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK,
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system_.CreateFile(URL(kPath3)));       // Creates a file.
2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK,
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system_.TruncateFile(URL(kPath3), 1));  // Modifies the file.
2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK,
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system_.CreateFile(URL(kPath4)));    // Creates another file.
26958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_EQ(static_cast<int64>(kData.size()),         // Modifies the file.
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system_.Write(&url_request_context,
27158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                               URL(kPath4), blob.GetBlobDataHandle()));
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Verify the changes.
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system_.GetChangedURLsInTracker(&urls);
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(5U, urls.size());
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Reset the changes in in-memory tracker.
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DropChangesInTracker();
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure we have no in-memory changes in the tracker.
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system_.GetChangedURLsInTracker(&urls);
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0U, urls.size());
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RestoreChangesFromTrackerDB();
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure the changes are restored from the DB.
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system_.GetChangedURLsInTracker(&urls);
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(5U, urls.size());
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VerifyAndClearChange(URL(kPath0),
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  sync_file_system::SYNC_FILE_TYPE_FILE));
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VerifyAndClearChange(URL(kPath1),
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  sync_file_system::SYNC_FILE_TYPE_DIRECTORY));
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VerifyAndClearChange(URL(kPath2),
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  sync_file_system::SYNC_FILE_TYPE_DIRECTORY));
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VerifyAndClearChange(URL(kPath3),
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  sync_file_system::SYNC_FILE_TYPE_FILE));
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VerifyAndClearChange(URL(kPath4),
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  sync_file_system::SYNC_FILE_TYPE_FILE));
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(LocalFileChangeTrackerTest, RestoreRemoveChanges) {
3085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK, file_system_.OpenFileSystem());
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileSystemURLSet urls;
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kPath0[] = "file";
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kPath1[] = "dir a";
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kPath2[] = "dir b";
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kPath3[] = "dir b/file";
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kPath4[] = "dir b/dir c";
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kPath5[] = "dir b/dir c/file";
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system_.GetChangedURLsInTracker(&urls);
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0U, urls.size());
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creates and removes a same file.
3235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK,
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system_.CreateFile(URL(kPath0)));
3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK,
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system_.Remove(URL(kPath0), false /* recursive */));
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creates and removes a same directory.
3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK,
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system_.CreateDirectory(URL(kPath1)));
3315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK,
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system_.Remove(URL(kPath1), false /* recursive */));
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creates files and nested directories, then removes the parent directory.
3355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK,
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system_.CreateDirectory(URL(kPath2)));
3375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK,
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system_.CreateFile(URL(kPath3)));
3395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK,
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system_.CreateDirectory(URL(kPath4)));
3415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK,
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system_.CreateFile(URL(kPath5)));
3435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK,
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system_.Remove(URL(kPath2), true /* recursive */));
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system_.GetChangedURLsInTracker(&urls);
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3U, urls.size());
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DropChangesInTracker();
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure we have no in-memory changes in the tracker.
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system_.GetChangedURLsInTracker(&urls);
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0U, urls.size());
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RestoreChangesFromTrackerDB();
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure the changes are restored from the DB.
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system_.GetChangedURLsInTracker(&urls);
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since directories to have been reverted (kPath1, kPath2, kPath4) are
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // treated as FILE_CHANGE_DELETE, the number of changes should be 6.
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(6U, urls.size());
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VerifyAndClearChange(URL(kPath0),
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       FileChange(FileChange::FILE_CHANGE_DELETE,
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  sync_file_system::SYNC_FILE_TYPE_UNKNOWN));
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VerifyAndClearChange(URL(kPath1),
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       FileChange(FileChange::FILE_CHANGE_DELETE,
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  sync_file_system::SYNC_FILE_TYPE_UNKNOWN));
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VerifyAndClearChange(URL(kPath2),
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       FileChange(FileChange::FILE_CHANGE_DELETE,
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  sync_file_system::SYNC_FILE_TYPE_UNKNOWN));
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VerifyAndClearChange(URL(kPath3),
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       FileChange(FileChange::FILE_CHANGE_DELETE,
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  sync_file_system::SYNC_FILE_TYPE_UNKNOWN));
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VerifyAndClearChange(URL(kPath4),
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       FileChange(FileChange::FILE_CHANGE_DELETE,
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  sync_file_system::SYNC_FILE_TYPE_UNKNOWN));
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VerifyAndClearChange(URL(kPath5),
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       FileChange(FileChange::FILE_CHANGE_DELETE,
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  sync_file_system::SYNC_FILE_TYPE_UNKNOWN));
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(LocalFileChangeTrackerTest, RestoreCopyChanges) {
3845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK, file_system_.OpenFileSystem());
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURLSet urls;
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char kPath0[] = "file a";
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char kPath1[] = "dir a";
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char kPath2[] = "dir a/dir";
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char kPath3[] = "dir a/file a";
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char kPath4[] = "dir a/file b";
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char kPath0Copy[] = "file b";      // To be copied from kPath0
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char kPath1Copy[] = "dir b";       // To be copied from kPath1
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char kPath2Copy[] = "dir b/dir";   // To be copied from kPath2
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char kPath3Copy[] = "dir b/file a";  // To be copied from kPath3
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char kPath4Copy[] = "dir b/file b";  // To be copied from kPath4
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  file_system_.GetChangedURLsInTracker(&urls);
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(0U, urls.size());
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const std::string kData("Lorem ipsum.");
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockBlobURLRequestContext url_request_context(file_system_context());
40558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ScopedTextBlob blob(url_request_context, "blob_id:test", kData);
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Create files and nested directories.
4085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK,
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            file_system_.CreateFile(URL(kPath0)));       // Creates a file.
4105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK,
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            file_system_.CreateDirectory(URL(kPath1)));  // Creates a dir.
4125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK,
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            file_system_.CreateDirectory(URL(kPath2)));  // Creates another dir.
4145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK,
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            file_system_.CreateFile(URL(kPath3)));       // Creates a file.
4165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK,
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            file_system_.TruncateFile(URL(kPath3), 1));  // Modifies the file.
4185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK,
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            file_system_.CreateFile(URL(kPath4)));    // Creates another file.
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(static_cast<int64>(kData.size()),
42158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            file_system_.Write(&url_request_context,   // Modifies the file.
42258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                               URL(kPath4), blob.GetBlobDataHandle()));
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Verify we have 5 changes for preparation.
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  file_system_.GetChangedURLsInTracker(&urls);
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(5U, urls.size());
4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  change_tracker()->ClearChangesForURL(URL(kPath0));
4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  change_tracker()->ClearChangesForURL(URL(kPath1));
4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  change_tracker()->ClearChangesForURL(URL(kPath2));
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  change_tracker()->ClearChangesForURL(URL(kPath3));
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  change_tracker()->ClearChangesForURL(URL(kPath4));
4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Make sure we have no changes.
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  file_system_.GetChangedURLsInTracker(&urls);
4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(urls.empty());
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Copy the file and the parent directory.
4385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK,
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            file_system_.Copy(URL(kPath0), URL(kPath0Copy)));  // Copy the file.
4405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK,
4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            file_system_.Copy(URL(kPath1), URL(kPath1Copy)));  // Copy the dir.
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  file_system_.GetChangedURLsInTracker(&urls);
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(5U, urls.size());
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DropChangesInTracker();
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Make sure we have no in-memory changes in the tracker.
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  file_system_.GetChangedURLsInTracker(&urls);
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(0U, urls.size());
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RestoreChangesFromTrackerDB();
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Make sure the changes are restored from the DB.
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  file_system_.GetChangedURLsInTracker(&urls);
4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(5U, urls.size());
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  VerifyAndClearChange(URL(kPath0Copy),
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  sync_file_system::SYNC_FILE_TYPE_FILE));
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  VerifyAndClearChange(URL(kPath1Copy),
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  sync_file_system::SYNC_FILE_TYPE_DIRECTORY));
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  VerifyAndClearChange(URL(kPath2Copy),
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  sync_file_system::SYNC_FILE_TYPE_DIRECTORY));
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  VerifyAndClearChange(URL(kPath3Copy),
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  sync_file_system::SYNC_FILE_TYPE_FILE));
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  VerifyAndClearChange(URL(kPath4Copy),
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  sync_file_system::SYNC_FILE_TYPE_FILE));
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(LocalFileChangeTrackerTest, RestoreMoveChanges) {
4755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK, file_system_.OpenFileSystem());
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileSystemURLSet urls;
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kPath0[] = "file a";
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kPath1[] = "dir a";
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kPath2[] = "dir a/file";
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kPath3[] = "dir a/dir";
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kPath4[] = "dir a/dir/file";
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kPath5[] = "file b";          // To be moved from kPath0.
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kPath6[] = "dir b";           // To be moved from kPath1.
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kPath7[] = "dir b/file";      // To be moved from kPath2.
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kPath8[] = "dir b/dir";       // To be moved from kPath3.
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kPath9[] = "dir b/dir/file";  // To be moved from kPath4.
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system_.GetChangedURLsInTracker(&urls);
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0U, urls.size());
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Create files and nested directories.
4955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK,
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system_.CreateFile(URL(kPath0)));
4975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK,
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system_.CreateDirectory(URL(kPath1)));
4995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK,
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system_.CreateFile(URL(kPath2)));
5015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK,
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system_.CreateDirectory(URL(kPath3)));
5035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK,
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system_.CreateFile(URL(kPath4)));
5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Verify we have 5 changes for preparation.
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  file_system_.GetChangedURLsInTracker(&urls);
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(5U, urls.size());
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  change_tracker()->ClearChangesForURL(URL(kPath0));
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  change_tracker()->ClearChangesForURL(URL(kPath1));
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  change_tracker()->ClearChangesForURL(URL(kPath2));
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  change_tracker()->ClearChangesForURL(URL(kPath3));
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  change_tracker()->ClearChangesForURL(URL(kPath4));
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Make sure we have no changes.
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  file_system_.GetChangedURLsInTracker(&urls);
5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(urls.empty());
5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Move the file and the parent directory.
5205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK,
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            file_system_.Move(URL(kPath0), URL(kPath5)));
5225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK,
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system_.Move(URL(kPath1), URL(kPath6)));
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system_.GetChangedURLsInTracker(&urls);
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(10U, urls.size());
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DropChangesInTracker();
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure we have no in-memory changes in the tracker.
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system_.GetChangedURLsInTracker(&urls);
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0U, urls.size());
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RestoreChangesFromTrackerDB();
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure the changes are restored from the DB.
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system_.GetChangedURLsInTracker(&urls);
538d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Deletion for child files in the deleted directory cannot be restored,
539d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // so we will only have 8 changes.
540d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  EXPECT_EQ(8U, urls.size());
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VerifyAndClearChange(URL(kPath0),
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       FileChange(FileChange::FILE_CHANGE_DELETE,
5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  sync_file_system::SYNC_FILE_TYPE_UNKNOWN));
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VerifyAndClearChange(URL(kPath1),
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       FileChange(FileChange::FILE_CHANGE_DELETE,
5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  sync_file_system::SYNC_FILE_TYPE_UNKNOWN));
548d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  VerifyAndClearChange(URL(kPath3),
549d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                       FileChange(FileChange::FILE_CHANGE_DELETE,
550d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                  sync_file_system::SYNC_FILE_TYPE_UNKNOWN));
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VerifyAndClearChange(URL(kPath5),
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  sync_file_system::SYNC_FILE_TYPE_FILE));
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VerifyAndClearChange(URL(kPath6),
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  sync_file_system::SYNC_FILE_TYPE_DIRECTORY));
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VerifyAndClearChange(URL(kPath7),
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  sync_file_system::SYNC_FILE_TYPE_FILE));
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VerifyAndClearChange(URL(kPath8),
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  sync_file_system::SYNC_FILE_TYPE_DIRECTORY));
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VerifyAndClearChange(URL(kPath9),
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  sync_file_system::SYNC_FILE_TYPE_FILE));
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(LocalFileChangeTrackerTest, NextChangedURLsWithRecursiveCopy) {
5695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK, file_system_.OpenFileSystem());
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileSystemURLSet urls;
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kPath0[] = "dir a";
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kPath1[] = "dir a/file";
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kPath2[] = "dir a/dir";
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kPath0Copy[] = "dir b";
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kPath1Copy[] = "dir b/file";
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kPath2Copy[] = "dir b/dir";
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creates kPath0,1,2 and then copies them all.
5825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK,
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system_.CreateDirectory(URL(kPath0)));
5845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK,
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system_.CreateFile(URL(kPath1)));
5865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK,
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system_.CreateDirectory(URL(kPath2)));
5885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK,
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system_.Copy(URL(kPath0), URL(kPath0Copy)));
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::deque<FileSystemURL> urls_to_process;
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  change_tracker()->GetNextChangedURLs(&urls_to_process, 0);
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(6U, urls_to_process.size());
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creation must have occured first.
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(URL(kPath0), urls_to_process[0]);
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(URL(kPath1), urls_to_process[1]);
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(URL(kPath2), urls_to_process[2]);
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Then recursive copy took place. The exact order cannot be determined
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // but the parent directory must have been created first.
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(URL(kPath0Copy), urls_to_process[3]);
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(URL(kPath1Copy) == urls_to_process[4] ||
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              URL(kPath2Copy) == urls_to_process[4]);
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(URL(kPath1Copy) == urls_to_process[5] ||
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              URL(kPath2Copy) == urls_to_process[5]);
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(LocalFileChangeTrackerTest, NextChangedURLsWithRecursiveRemove) {
6105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK, file_system_.OpenFileSystem());
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kPath0[] = "dir a";
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kPath1[] = "dir a/file1";
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kPath2[] = "dir a/file2";
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creates kPath0,1,2 and then removes them all.
6175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK,
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system_.CreateDirectory(URL(kPath0)));
6195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK,
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system_.CreateFile(URL(kPath1)));
6215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK,
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system_.CreateFile(URL(kPath2)));
6235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK,
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system_.Remove(URL(kPath0), true /* recursive */));
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
626a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  FileSystemURLSet urls;
627a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GetAllChangedURLs(&urls);
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This is actually not really desirable, but since the directory
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // creation and deletion have been offset now we only have two
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // file deletion changes.
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // NOTE: This will cause 2 local sync for deleting nonexistent files
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // on the remote side.
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(kinuko): For micro optimization we could probably restore the ADD
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // change type (other than ADD_OR_UPDATE) and offset file ADD+DELETE
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // changes too.
639a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(2U, urls.size());
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The exact order of recursive removal cannot be determined.
642a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(ContainsKey(urls, URL(kPath1)));
643a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(ContainsKey(urls, URL(kPath2)));
644a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
645a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
646a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(LocalFileChangeTrackerTest, ResetForFileSystem) {
6475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK, file_system_.OpenFileSystem());
648a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
649a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const char kPath0[] = "dir a";
650a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const char kPath1[] = "dir a/file";
651a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const char kPath2[] = "dir a/subdir";
652a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const char kPath3[] = "dir b";
653a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
6545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK,
655a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            file_system_.CreateDirectory(URL(kPath0)));
6565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK,
657a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            file_system_.CreateFile(URL(kPath1)));
6585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK,
659a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            file_system_.CreateDirectory(URL(kPath2)));
6605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK,
661a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            file_system_.CreateDirectory(URL(kPath3)));
662a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
663a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  FileSystemURLSet urls;
664a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GetAllChangedURLs(&urls);
665a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(4u, urls.size());
666a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(ContainsKey(urls, URL(kPath0)));
667a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(ContainsKey(urls, URL(kPath1)));
668a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(ContainsKey(urls, URL(kPath2)));
669a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(ContainsKey(urls, URL(kPath3)));
670a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
671a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Reset all changes for the file system.
672a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  change_tracker()->ResetForFileSystem(
673a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      file_system_.origin(), file_system_.type());
674a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
675a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GetAllChangedURLs(&urls);
676a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(urls.empty());
677a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
678a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Make sure they're gone from the database too.
679a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DropChangesInTracker();
680a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  RestoreChangesFromTrackerDB();
681a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
682a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GetAllChangedURLs(&urls);
683a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(urls.empty());
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace sync_file_system
687