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)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h"
6116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/thread_task_runner_handle.h"
72385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/local/canned_syncable_file_system.h"
82385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/local/local_file_change_tracker.h"
92385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/local/local_file_sync_context.h"
102385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/local/sync_file_system_backend.h"
112385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/syncable_file_system_util.h"
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/test/async_file_test_helper.h"
134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/public/test/sandbox_file_system_test_helper.h"
14d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "content/public/test/test_browser_thread_bundle.h"
151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_context.h"
161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_operation_context.h"
171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/isolated_context.h"
181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/quota/quota_manager.h"
191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/common/fileapi/file_system_types.h"
201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/common/quota/quota_types.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "third_party/leveldatabase/src/helpers/memenv/memenv.h"
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "third_party/leveldatabase/src/include/leveldb/env.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using content::SandboxFileSystemTestHelper;
2603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::FileSystemContext;
2703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::FileSystemOperationContext;
2803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::FileSystemURL;
2903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::FileSystemURLSet;
3003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::QuotaManager;
3103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::QuotaStatusCode;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace sync_file_system {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SyncableFileSystemTest : public testing::Test {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SyncableFileSystemTest()
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      : in_memory_env_(leveldb::NewMemEnv(leveldb::Env::Default())),
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        file_system_(GURL("http://example.com/"),
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     in_memory_env_.get(),
41116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                     base::ThreadTaskRunnerHandle::Get().get(),
42116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                     base::ThreadTaskRunnerHandle::Get().get()),
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        weak_factory_(this) {}
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void SetUp() {
46d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    ASSERT_TRUE(data_dir_.CreateUniqueTempDir());
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    file_system_.SetUp(CannedSyncableFileSystem::QUOTA_ENABLED);
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    sync_context_ =
50d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        new LocalFileSyncContext(data_dir_.path(),
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                 in_memory_env_.get(),
52116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                 base::ThreadTaskRunnerHandle::Get().get(),
53116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                 base::ThreadTaskRunnerHandle::Get().get());
54868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ASSERT_EQ(
55868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        sync_file_system::SYNC_STATUS_OK,
56868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        file_system_.MaybeInitializeFileSystemContext(sync_context_.get()));
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void TearDown() {
60868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (sync_context_.get())
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sync_context_->ShutdownOnUIThread();
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sync_context_ = NULL;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    file_system_.TearDown();
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Make sure we don't leave the external filesystem.
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // (CannedSyncableFileSystem::TearDown does not do this as there may be
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // multiple syncable file systems registered for the name)
69868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    RevokeSyncableFileSystem();
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void VerifyAndClearChange(const FileSystemURL& url,
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const FileChange& expected_change) {
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SCOPED_TRACE(testing::Message() << url.DebugString() <<
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 " expecting:" << expected_change.DebugString());
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Get the changes for URL and verify.
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FileChangeList changes;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    change_tracker()->GetChangesForURL(url, &changes);
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(1U, changes.size());
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SCOPED_TRACE(testing::Message() << url.DebugString() <<
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 " actual:" << changes.DebugString());
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(expected_change, changes.front());
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Clear the URL from the change tracker.
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    change_tracker()->ClearChangesForURL(url);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileSystemURL URL(const std::string& path) {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return file_system_.URL(path);
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileSystemContext* file_system_context() {
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return file_system_.file_system_context();
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LocalFileChangeTracker* change_tracker() {
98a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return file_system_.backend()->change_tracker();
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ScopedTempDir data_dir_;
102d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  content::TestBrowserThreadBundle thread_bundle_;
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<leveldb::Env> in_memory_env_;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CannedSyncableFileSystem file_system_;
105424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
106424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) private:
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<LocalFileSyncContext> sync_context_;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WeakPtrFactory<SyncableFileSystemTest> weak_factory_;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(SyncableFileSystemTest);
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Brief combined testing. Just see if all the sandbox feature works.
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncableFileSystemTest, SyncableLocalSandboxCombined) {
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Opens a syncable file system.
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK,
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system_.OpenFileSystem());
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Do some operations.
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK,
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system_.CreateDirectory(URL("dir")));
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK,
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system_.CreateFile(URL("dir/foo")));
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int64 kOriginalQuota = QuotaManager::kSyncableStorageDefaultHostQuota;
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int64 kQuota = 12345 * 1024;
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuotaManager::kSyncableStorageDefaultHostQuota = kQuota;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 usage, quota;
13103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_EQ(storage::kQuotaStatusOk,
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system_.GetUsageAndQuota(&usage, &quota));
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returned quota must be what we overrode. Usage must be greater than 0
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // as creating a file or directory consumes some space.
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kQuota, quota);
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_GT(usage, 0);
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Truncate to extend an existing file and see if the usage reflects it.
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int64 kFileSizeToExtend = 333;
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK,
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system_.CreateFile(URL("dir/foo")));
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK,
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system_.TruncateFile(URL("dir/foo"), kFileSizeToExtend));
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 new_usage;
14803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_EQ(storage::kQuotaStatusOk,
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system_.GetUsageAndQuota(&new_usage, &quota));
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kFileSizeToExtend, new_usage - usage);
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Shrink the quota to the current usage, try to extend the file further
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and see if it fails.
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuotaManager::kSyncableStorageDefaultHostQuota = new_usage;
1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_ERROR_NO_SPACE,
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system_.TruncateFile(URL("dir/foo"), kFileSizeToExtend + 1));
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  usage = new_usage;
15903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_EQ(storage::kQuotaStatusOk,
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system_.GetUsageAndQuota(&new_usage, &quota));
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(usage, new_usage);
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Deletes the file system.
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK,
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system_.DeleteFileSystem());
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now the usage must be zero.
16803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_EQ(storage::kQuotaStatusOk,
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system_.GetUsageAndQuota(&usage, &quota));
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, usage);
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Restore the system default quota.
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuotaManager::kSyncableStorageDefaultHostQuota = kOriginalQuota;
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Combined testing with LocalFileChangeTracker.
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SyncableFileSystemTest, ChangeTrackerSimple) {
1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK,
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system_.OpenFileSystem());
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kPath0[] = "dir a";
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kPath1[] = "dir a/dir";   // child of kPath0
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kPath2[] = "dir a/file";  // child of kPath0
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kPath3[] = "dir b";
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Do some operations.
1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK,
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system_.CreateDirectory(URL(kPath0)));  // Creates a dir.
1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK,
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system_.CreateDirectory(URL(kPath1)));  // Creates another.
1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK,
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system_.CreateFile(URL(kPath2)));       // Creates a file.
1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK,
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system_.TruncateFile(URL(kPath2), 1));  // Modifies the file.
1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK,
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system_.TruncateFile(URL(kPath2), 2));  // Modifies it again.
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileSystemURLSet urls;
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system_.GetChangedURLsInTracker(&urls);
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3U, urls.size());
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(ContainsKey(urls, URL(kPath0)));
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(ContainsKey(urls, URL(kPath1)));
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(ContainsKey(urls, URL(kPath2)));
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VerifyAndClearChange(URL(kPath0),
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  sync_file_system::SYNC_FILE_TYPE_DIRECTORY));
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VerifyAndClearChange(URL(kPath1),
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  sync_file_system::SYNC_FILE_TYPE_DIRECTORY));
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VerifyAndClearChange(URL(kPath2),
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  sync_file_system::SYNC_FILE_TYPE_FILE));
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creates and removes a same directory.
2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK,
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system_.CreateDirectory(URL(kPath3)));
2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK,
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system_.Remove(URL(kPath3), false /* recursive */));
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The changes will be offset.
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  urls.clear();
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system_.GetChangedURLsInTracker(&urls);
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(urls.empty());
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Recursively removes the kPath0 directory.
2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK,
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system_.Remove(URL(kPath0), true /* recursive */));
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  urls.clear();
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system_.GetChangedURLsInTracker(&urls);
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // kPath0 and its all chidren (kPath1 and kPath2) must have been deleted.
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3U, urls.size());
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(ContainsKey(urls, URL(kPath0)));
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(ContainsKey(urls, URL(kPath1)));
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(ContainsKey(urls, URL(kPath2)));
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VerifyAndClearChange(URL(kPath0),
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       FileChange(FileChange::FILE_CHANGE_DELETE,
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  sync_file_system::SYNC_FILE_TYPE_DIRECTORY));
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VerifyAndClearChange(URL(kPath1),
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       FileChange(FileChange::FILE_CHANGE_DELETE,
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  sync_file_system::SYNC_FILE_TYPE_DIRECTORY));
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VerifyAndClearChange(URL(kPath2),
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       FileChange(FileChange::FILE_CHANGE_DELETE,
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  sync_file_system::SYNC_FILE_TYPE_FILE));
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace sync_file_system
252