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_sync_context.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
10d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/bind_helpers.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h"
13ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/message_loop/message_loop.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h"
152385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/local/canned_syncable_file_system.h"
162385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/local/local_file_change_tracker.h"
172385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/local/sync_file_system_backend.h"
182385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/sync_file_metadata.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"
21d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "content/public/browser/browser_thread.h"
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/test/mock_blob_url_request_context.h"
23d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "content/public/test/test_browser_thread_bundle.h"
241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_context.h"
251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_operation_runner.h"
261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/isolated_context.h"
271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/common/blob/scoped_file.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "third_party/leveldatabase/src/helpers/memenv/memenv.h"
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "third_party/leveldatabase/src/include/leveldb/env.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define FPL FILE_PATH_LITERAL
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)using content::BrowserThread;
3503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::FileSystemContext;
3603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::FileSystemURL;
3703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::FileSystemURLSet;
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This tests LocalFileSyncContext behavior in multi-thread /
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// multi-file-system-context environment.
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Basic combined tests (single-thread / single-file-system-context)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// that involve LocalFileSyncContext are also in
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// syncable_file_system_unittests.cc.
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace sync_file_system {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kOrigin1[] = "http://example.com";
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kOrigin2[] = "http://chromium.org";
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class LocalFileSyncContextTest : public testing::Test {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LocalFileSyncContextTest()
55d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      : thread_bundle_(
56d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)            content::TestBrowserThreadBundle::REAL_FILE_THREAD |
57d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)            content::TestBrowserThreadBundle::REAL_IO_THREAD),
58d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        status_(SYNC_FILE_ERROR_FAILED),
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        file_error_(base::File::FILE_ERROR_FAILED),
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        async_modify_finished_(false),
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        has_inflight_prepare_for_sync_(false) {}
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() OVERRIDE {
64868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    RegisterSyncableFileSystem();
65d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    ASSERT_TRUE(dir_.CreateUniqueTempDir());
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    in_memory_env_.reset(leveldb::NewMemEnv(leveldb::Env::Default()));
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    ui_task_runner_ = base::MessageLoop::current()->message_loop_proxy();
69d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    io_task_runner_ = BrowserThread::GetMessageLoopProxyForThread(
70d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        BrowserThread::IO);
71d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    file_task_runner_ = BrowserThread::GetMessageLoopProxyForThread(
72d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        BrowserThread::IO);
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void TearDown() OVERRIDE {
76868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    RevokeSyncableFileSystem();
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void StartPrepareForSync(FileSystemContext* file_system_context,
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           const FileSystemURL& url,
81d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                           LocalFileSyncContext::SyncMode sync_mode,
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           SyncFileMetadata* metadata,
83d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                           FileChangeList* changes,
8403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                           storage::ScopedFile* snapshot) {
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(changes != NULL);
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_FALSE(has_inflight_prepare_for_sync_);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    status_ = SYNC_STATUS_UNKNOWN;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    has_inflight_prepare_for_sync_ = true;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sync_context_->PrepareForSync(
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        file_system_context,
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        url,
92d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        sync_mode,
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&LocalFileSyncContextTest::DidPrepareForSync,
94d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                   base::Unretained(this), metadata, changes, snapshot));
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SyncStatusCode PrepareForSync(FileSystemContext* file_system_context,
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                const FileSystemURL& url,
99d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                LocalFileSyncContext::SyncMode sync_mode,
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                SyncFileMetadata* metadata,
101d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                FileChangeList* changes,
10203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                storage::ScopedFile* snapshot) {
103d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    StartPrepareForSync(file_system_context, url, sync_mode,
104d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                        metadata, changes, snapshot);
105b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    base::MessageLoop::current()->Run();
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return status_;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  base::Closure GetPrepareForSyncClosure(
110d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      FileSystemContext* file_system_context,
111d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      const FileSystemURL& url,
112d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      LocalFileSyncContext::SyncMode sync_mode,
113d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      SyncFileMetadata* metadata,
114d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      FileChangeList* changes,
11503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::ScopedFile* snapshot) {
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return base::Bind(&LocalFileSyncContextTest::StartPrepareForSync,
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      base::Unretained(this),
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      base::Unretained(file_system_context),
119d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                      url, sync_mode, metadata, changes, snapshot);
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DidPrepareForSync(SyncFileMetadata* metadata_out,
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         FileChangeList* changes_out,
12403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                         storage::ScopedFile* snapshot_out,
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         SyncStatusCode status,
126d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                         const LocalFileSyncInfo& sync_file_info,
12703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                         storage::ScopedFile snapshot) {
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(ui_task_runner_->RunsTasksOnCurrentThread());
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    has_inflight_prepare_for_sync_ = false;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    status_ = status;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *metadata_out = sync_file_info.metadata;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *changes_out = sync_file_info.changes;
1331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (snapshot_out)
1341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      *snapshot_out = snapshot.Pass();
135b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    base::MessageLoop::current()->Quit();
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SyncStatusCode ApplyRemoteChange(FileSystemContext* file_system_context,
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   const FileChange& change,
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   const base::FilePath& local_path,
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   const FileSystemURL& url,
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   SyncFileType expected_file_type) {
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SCOPED_TRACE(testing::Message() << "ApplyChange for " <<
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 url.DebugString());
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // First we should call PrepareForSync to disable writing.
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SyncFileMetadata metadata;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FileChangeList changes;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(SYNC_STATUS_OK,
150d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)              PrepareForSync(file_system_context, url,
151d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                             LocalFileSyncContext::SYNC_EXCLUSIVE,
152d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                             &metadata, &changes, NULL));
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(expected_file_type, metadata.file_type);
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    status_ = SYNC_STATUS_UNKNOWN;
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sync_context_->ApplyRemoteChange(
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        file_system_context, change, local_path, url,
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&LocalFileSyncContextTest::DidApplyRemoteChange,
1594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                   base::Unretained(this),
1604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                   make_scoped_refptr(file_system_context), url));
161b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    base::MessageLoop::current()->Run();
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return status_;
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void DidApplyRemoteChange(FileSystemContext* file_system_context,
1664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                            const FileSystemURL& url,
1674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                            SyncStatusCode status) {
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    status_ = status;
1694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    sync_context_->FinalizeExclusiveSync(
1704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        file_system_context, url,
1714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        status == SYNC_STATUS_OK /* clear_local_changes */,
1724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        base::MessageLoop::QuitClosure());
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void StartModifyFileOnIOThread(CannedSyncableFileSystem* file_system,
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 const FileSystemURL& url) {
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(file_system != NULL);
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!io_task_runner_->RunsTasksOnCurrentThread()) {
179d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      async_modify_finished_ = false;
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ASSERT_TRUE(ui_task_runner_->RunsTasksOnCurrentThread());
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      io_task_runner_->PostTask(
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          FROM_HERE,
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base::Bind(&LocalFileSyncContextTest::StartModifyFileOnIOThread,
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     base::Unretained(this), file_system, url));
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(io_task_runner_->RunsTasksOnCurrentThread());
1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    file_error_ = base::File::FILE_ERROR_FAILED;
189868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    file_system->operation_runner()->Truncate(
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        url, 1, base::Bind(&LocalFileSyncContextTest::DidModifyFile,
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           base::Unretained(this)));
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::File::Error WaitUntilModifyFileIsDone() {
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (!async_modify_finished_)
196b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      base::MessageLoop::current()->RunUntilIdle();
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return file_error_;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void DidModifyFile(base::File::Error error) {
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ui_task_runner_->RunsTasksOnCurrentThread()) {
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ASSERT_TRUE(io_task_runner_->RunsTasksOnCurrentThread());
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ui_task_runner_->PostTask(
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          FROM_HERE,
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base::Bind(&LocalFileSyncContextTest::DidModifyFile,
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     base::Unretained(this), error));
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(ui_task_runner_->RunsTasksOnCurrentThread());
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    file_error_ = error;
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    async_modify_finished_ = true;
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
214d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  void SimulateFinishSync(FileSystemContext* file_system_context,
215d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                          const FileSystemURL& url,
2164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                          SyncStatusCode status,
2174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                          LocalFileSyncContext::SyncMode sync_mode) {
2184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (sync_mode == LocalFileSyncContext::SYNC_SNAPSHOT) {
2194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      sync_context_->FinalizeSnapshotSync(
2204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          file_system_context, url, status,
2214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          base::Bind(&base::DoNothing));
2224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    } else {
2234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      sync_context_->FinalizeExclusiveSync(
2244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          file_system_context, url,
2254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          status == SYNC_STATUS_OK /* clear_local_changes */,
2264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          base::Bind(&base::DoNothing));
2274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
228d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
229d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
230d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  void PrepareForSync_Basic(LocalFileSyncContext::SyncMode sync_mode,
231d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                            SyncStatusCode simulate_sync_finish_status) {
232d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    CannedSyncableFileSystem file_system(GURL(kOrigin1),
2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                         in_memory_env_.get(),
234d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                         io_task_runner_.get(),
235d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                         file_task_runner_.get());
2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    file_system.SetUp(CannedSyncableFileSystem::QUOTA_ENABLED);
237d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    sync_context_ = new LocalFileSyncContext(
2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        dir_.path(), in_memory_env_.get(),
2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        ui_task_runner_.get(), io_task_runner_.get());
240d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    ASSERT_EQ(SYNC_STATUS_OK,
241d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)              file_system.MaybeInitializeFileSystemContext(
242d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                  sync_context_.get()));
2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_EQ(base::File::FILE_OK, file_system.OpenFileSystem());
244d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
245d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    const FileSystemURL kFile(file_system.URL("file"));
2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(base::File::FILE_OK, file_system.CreateFile(kFile));
247d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
248d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    SyncFileMetadata metadata;
249d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    FileChangeList changes;
250d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    EXPECT_EQ(SYNC_STATUS_OK,
251d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)              PrepareForSync(file_system.file_system_context(), kFile,
252d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                             sync_mode, &metadata, &changes, NULL));
253d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    EXPECT_EQ(1U, changes.size());
254d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    EXPECT_TRUE(changes.list().back().IsFile());
255d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    EXPECT_TRUE(changes.list().back().IsAddOrUpdate());
256d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
257d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // We should see the same set of changes.
258d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    file_system.GetChangesForURLInTracker(kFile, &changes);
259d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    EXPECT_EQ(1U, changes.size());
260d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    EXPECT_TRUE(changes.list().back().IsFile());
261d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    EXPECT_TRUE(changes.list().back().IsAddOrUpdate());
262d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
263d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    SimulateFinishSync(file_system.file_system_context(), kFile,
2644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                       simulate_sync_finish_status, sync_mode);
265d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
266d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    file_system.GetChangesForURLInTracker(kFile, &changes);
267d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    if (simulate_sync_finish_status == SYNC_STATUS_OK) {
268d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      // The change's cleared.
269d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      EXPECT_TRUE(changes.empty());
270d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    } else {
271d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      EXPECT_EQ(1U, changes.size());
272d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      EXPECT_TRUE(changes.list().back().IsFile());
273d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      EXPECT_TRUE(changes.list().back().IsAddOrUpdate());
274d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    }
275d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
276d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    sync_context_->ShutdownOnUIThread();
277d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    sync_context_ = NULL;
278d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
279d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    file_system.TearDown();
280d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
281d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
282d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  void PrepareForSync_WriteDuringSync(
283d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      LocalFileSyncContext::SyncMode sync_mode) {
284d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    CannedSyncableFileSystem file_system(GURL(kOrigin1),
2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                         in_memory_env_.get(),
286d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                         io_task_runner_.get(),
287d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                         file_task_runner_.get());
2885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    file_system.SetUp(CannedSyncableFileSystem::QUOTA_ENABLED);
289d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    sync_context_ = new LocalFileSyncContext(
2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        dir_.path(), in_memory_env_.get(),
2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        ui_task_runner_.get(), io_task_runner_.get());
292d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    ASSERT_EQ(SYNC_STATUS_OK,
293d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)              file_system.MaybeInitializeFileSystemContext(
294d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                  sync_context_.get()));
2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_EQ(base::File::FILE_OK, file_system.OpenFileSystem());
296d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
297d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    const FileSystemURL kFile(file_system.URL("file"));
2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(base::File::FILE_OK, file_system.CreateFile(kFile));
299d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
300d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    SyncFileMetadata metadata;
301d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    FileChangeList changes;
30203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    storage::ScopedFile snapshot;
303d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    EXPECT_EQ(SYNC_STATUS_OK,
304d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)              PrepareForSync(file_system.file_system_context(), kFile,
305d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                             sync_mode, &metadata, &changes, &snapshot));
306d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    EXPECT_EQ(1U, changes.size());
307d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    EXPECT_TRUE(changes.list().back().IsFile());
308d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    EXPECT_TRUE(changes.list().back().IsAddOrUpdate());
309d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
310d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    EXPECT_EQ(sync_mode == LocalFileSyncContext::SYNC_SNAPSHOT,
311d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)              !snapshot.path().empty());
312d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
313d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // Tracker keeps same set of changes.
314d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    file_system.GetChangesForURLInTracker(kFile, &changes);
315d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    EXPECT_EQ(1U, changes.size());
316d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    EXPECT_TRUE(changes.list().back().IsFile());
317d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    EXPECT_TRUE(changes.list().back().IsAddOrUpdate());
318d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
319d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    StartModifyFileOnIOThread(&file_system, kFile);
320d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
321d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    if (sync_mode == LocalFileSyncContext::SYNC_SNAPSHOT) {
322d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      // Write should succeed.
3235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_EQ(base::File::FILE_OK, WaitUntilModifyFileIsDone());
324d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    } else {
325d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      base::MessageLoop::current()->RunUntilIdle();
326d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      EXPECT_FALSE(async_modify_finished_);
327d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    }
328d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
329d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    SimulateFinishSync(file_system.file_system_context(), kFile,
3304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                       SYNC_STATUS_OK, sync_mode);
331d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(base::File::FILE_OK, WaitUntilModifyFileIsDone());
333d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
334d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // Sync succeeded, but the other change that was made during or
335d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // after sync is recorded.
336d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    file_system.GetChangesForURLInTracker(kFile, &changes);
337d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    EXPECT_EQ(1U, changes.size());
338d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    EXPECT_TRUE(changes.list().back().IsFile());
339d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    EXPECT_TRUE(changes.list().back().IsAddOrUpdate());
340d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
341d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    sync_context_->ShutdownOnUIThread();
342d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    sync_context_ = NULL;
343d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
344d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    file_system.TearDown();
345d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
346d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
347d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  base::ScopedTempDir dir_;
3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<leveldb::Env> in_memory_env_;
349d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // These need to remain until the very end.
351d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  content::TestBrowserThreadBundle thread_bundle_;
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_;
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<base::SingleThreadTaskRunner> file_task_runner_;
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<LocalFileSyncContext> sync_context_;
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SyncStatusCode status_;
3605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::File::Error file_error_;
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool async_modify_finished_;
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool has_inflight_prepare_for_sync_;
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(LocalFileSyncContextTest, ConstructAndDestruct) {
366868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  sync_context_ =
367d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      new LocalFileSyncContext(
3685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          dir_.path(), in_memory_env_.get(),
3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          ui_task_runner_.get(), io_task_runner_.get());
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_context_->ShutdownOnUIThread();
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(LocalFileSyncContextTest, InitializeFileSystemContext) {
374868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CannedSyncableFileSystem file_system(GURL(kOrigin1),
3755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                       in_memory_env_.get(),
376868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                       io_task_runner_.get(),
377868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                       file_task_runner_.get());
3785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  file_system.SetUp(CannedSyncableFileSystem::QUOTA_ENABLED);
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
380d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  sync_context_ = new LocalFileSyncContext(
3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      dir_.path(), in_memory_env_.get(),
3825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ui_task_runner_.get(), io_task_runner_.get());
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Initializes file_system using |sync_context_|.
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK,
386868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            file_system.MaybeInitializeFileSystemContext(sync_context_.get()));
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure everything's set up for file_system to be able to handle
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // syncable file system operations.
390a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_TRUE(file_system.backend()->sync_context() != NULL);
391a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_TRUE(file_system.backend()->change_tracker() != NULL);
392a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(sync_context_.get(), file_system.backend()->sync_context());
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Calling MaybeInitialize for the same context multiple times must be ok.
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK,
396868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            file_system.MaybeInitializeFileSystemContext(sync_context_.get()));
397a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(sync_context_.get(), file_system.backend()->sync_context());
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Opens the file_system, perform some operation and see if the change tracker
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // correctly captures the change.
4015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK, file_system.OpenFileSystem());
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileSystemURL kURL(file_system.URL("foo"));
4045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK, file_system.CreateFile(kURL));
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileSystemURLSet urls;
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system.GetChangedURLsInTracker(&urls);
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1U, urls.size());
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(ContainsKey(urls, kURL));
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Finishing the test.
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_context_->ShutdownOnUIThread();
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system.TearDown();
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(LocalFileSyncContextTest, MultipleFileSystemContexts) {
417868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CannedSyncableFileSystem file_system1(GURL(kOrigin1),
4185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                        in_memory_env_.get(),
419868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                        io_task_runner_.get(),
420868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                        file_task_runner_.get());
421868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CannedSyncableFileSystem file_system2(GURL(kOrigin2),
4225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                        in_memory_env_.get(),
423868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                        io_task_runner_.get(),
424868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                        file_task_runner_.get());
4255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  file_system1.SetUp(CannedSyncableFileSystem::QUOTA_ENABLED);
4265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  file_system2.SetUp(CannedSyncableFileSystem::QUOTA_ENABLED);
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
428d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  sync_context_ = new LocalFileSyncContext(
4295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      dir_.path(), in_memory_env_.get(),
4305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ui_task_runner_.get(), io_task_runner_.get());
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Initializes file_system1 and file_system2.
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK,
434868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            file_system1.MaybeInitializeFileSystemContext(sync_context_.get()));
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK,
436868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            file_system2.MaybeInitializeFileSystemContext(sync_context_.get()));
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK, file_system1.OpenFileSystem());
4395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK, file_system2.OpenFileSystem());
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileSystemURL kURL1(file_system1.URL("foo"));
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileSystemURL kURL2(file_system2.URL("bar"));
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creates a file in file_system1.
4455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK, file_system1.CreateFile(kURL1));
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // file_system1's tracker must have recorded the change.
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileSystemURLSet urls;
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system1.GetChangedURLsInTracker(&urls);
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1U, urls.size());
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(ContainsKey(urls, kURL1));
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // file_system1's tracker must have no change.
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  urls.clear();
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system2.GetChangedURLsInTracker(&urls);
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(urls.empty());
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creates a directory in file_system2.
4595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK, file_system2.CreateDirectory(kURL2));
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // file_system1's tracker must have the change for kURL1 as before.
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  urls.clear();
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system1.GetChangedURLsInTracker(&urls);
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1U, urls.size());
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(ContainsKey(urls, kURL1));
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // file_system2's tracker now must have the change for kURL2.
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  urls.clear();
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system2.GetChangedURLsInTracker(&urls);
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1U, urls.size());
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(ContainsKey(urls, kURL2));
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SyncFileMetadata metadata;
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileChangeList changes;
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK,
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            PrepareForSync(file_system1.file_system_context(), kURL1,
477d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                           LocalFileSyncContext::SYNC_EXCLUSIVE,
478d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                           &metadata, &changes, NULL));
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1U, changes.size());
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(changes.list().back().IsFile());
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(changes.list().back().IsAddOrUpdate());
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SYNC_FILE_TYPE_FILE, metadata.file_type);
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, metadata.size);
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  changes.clear();
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK,
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            PrepareForSync(file_system2.file_system_context(), kURL2,
488d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                           LocalFileSyncContext::SYNC_EXCLUSIVE,
489d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                           &metadata, &changes, NULL));
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1U, changes.size());
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(changes.list().back().IsFile());
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(changes.list().back().IsAddOrUpdate());
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SYNC_FILE_TYPE_DIRECTORY, metadata.file_type);
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, metadata.size);
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_context_->ShutdownOnUIThread();
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_context_ = NULL;
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system1.TearDown();
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system2.TearDown();
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
503d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)TEST_F(LocalFileSyncContextTest, PrepareSync_SyncSuccess_Exclusive) {
504d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  PrepareForSync_Basic(LocalFileSyncContext::SYNC_EXCLUSIVE,
505d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                       SYNC_STATUS_OK);
506d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
507d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
508d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)TEST_F(LocalFileSyncContextTest, PrepareSync_SyncSuccess_Snapshot) {
509d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  PrepareForSync_Basic(LocalFileSyncContext::SYNC_SNAPSHOT,
510d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                       SYNC_STATUS_OK);
511d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
512d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
513d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)TEST_F(LocalFileSyncContextTest, PrepareSync_SyncFailure_Exclusive) {
514d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  PrepareForSync_Basic(LocalFileSyncContext::SYNC_EXCLUSIVE,
515d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                       SYNC_STATUS_FAILED);
516d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
517d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
518d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)TEST_F(LocalFileSyncContextTest, PrepareSync_SyncFailure_Snapshot) {
519d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  PrepareForSync_Basic(LocalFileSyncContext::SYNC_SNAPSHOT,
520d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                       SYNC_STATUS_FAILED);
521d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
522d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
523d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)TEST_F(LocalFileSyncContextTest, PrepareSync_WriteDuringSync_Exclusive) {
524d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  PrepareForSync_WriteDuringSync(LocalFileSyncContext::SYNC_EXCLUSIVE);
525d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
526d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
527d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)TEST_F(LocalFileSyncContextTest, PrepareSync_WriteDuringSync_Snapshot) {
528d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  PrepareForSync_WriteDuringSync(LocalFileSyncContext::SYNC_SNAPSHOT);
529d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
530d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
531a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// LocalFileSyncContextTest.PrepareSyncWhileWriting is flaky on android.
532a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// http://crbug.com/239793
5334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// It is also flaky on the TSAN v2 bots, and hangs other bots.
5344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// http://crbug.com/305905.
5354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(LocalFileSyncContextTest, DISABLED_PrepareSyncWhileWriting) {
536868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CannedSyncableFileSystem file_system(GURL(kOrigin1),
5375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                       in_memory_env_.get(),
538868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                       io_task_runner_.get(),
539868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                       file_task_runner_.get());
5405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  file_system.SetUp(CannedSyncableFileSystem::QUOTA_ENABLED);
541d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  sync_context_ = new LocalFileSyncContext(
5425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      dir_.path(), in_memory_env_.get(),
5435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ui_task_runner_.get(), io_task_runner_.get());
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK,
545868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            file_system.MaybeInitializeFileSystemContext(sync_context_.get()));
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK, file_system.OpenFileSystem());
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileSystemURL kURL1(file_system.URL("foo"));
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creates a file in file_system.
5525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK, file_system.CreateFile(kURL1));
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Kick file write on IO thread.
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartModifyFileOnIOThread(&file_system, kURL1);
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Until the operation finishes PrepareForSync should return BUSY error.
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SyncFileMetadata metadata;
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  metadata.file_type = SYNC_FILE_TYPE_UNKNOWN;
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileChangeList changes;
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_FILE_BUSY,
562d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)            PrepareForSync(file_system.file_system_context(), kURL1,
563d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                           LocalFileSyncContext::SYNC_EXCLUSIVE,
564d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                           &metadata, &changes, NULL));
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SYNC_FILE_TYPE_FILE, metadata.file_type);
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Register PrepareForSync method to be invoked when kURL1 becomes
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // syncable. (Actually this may be done after all operations are done
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // on IO thread in this test.)
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  metadata.file_type = SYNC_FILE_TYPE_UNKNOWN;
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  changes.clear();
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_context_->RegisterURLForWaitingSync(
573d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      kURL1, GetPrepareForSyncClosure(file_system.file_system_context(), kURL1,
574d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                      LocalFileSyncContext::SYNC_EXCLUSIVE,
575d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                      &metadata, &changes, NULL));
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Wait for the completion.
5785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK, WaitUntilModifyFileIsDone());
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The PrepareForSync must have been started; wait until DidPrepareForSync
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // is done.
582b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  base::MessageLoop::current()->Run();
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(has_inflight_prepare_for_sync_);
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now PrepareForSync should have run and returned OK.
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, status_);
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1U, changes.size());
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(changes.list().back().IsFile());
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(changes.list().back().IsAddOrUpdate());
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SYNC_FILE_TYPE_FILE, metadata.file_type);
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, metadata.size);
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_context_->ShutdownOnUIThread();
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_context_ = NULL;
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system.TearDown();
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(LocalFileSyncContextTest, ApplyRemoteChangeForDeletion) {
599868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CannedSyncableFileSystem file_system(GURL(kOrigin1),
6005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                       in_memory_env_.get(),
601868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                       io_task_runner_.get(),
602868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                       file_task_runner_.get());
6035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  file_system.SetUp(CannedSyncableFileSystem::QUOTA_ENABLED);
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  sync_context_ = new LocalFileSyncContext(
6065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      dir_.path(), in_memory_env_.get(),
6075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ui_task_runner_.get(), io_task_runner_.get());
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(SYNC_STATUS_OK,
609868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            file_system.MaybeInitializeFileSystemContext(sync_context_.get()));
6105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(base::File::FILE_OK, file_system.OpenFileSystem());
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Record the initial usage (likely 0).
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 initial_usage = -1;
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 quota = -1;
61503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_EQ(storage::kQuotaStatusOk,
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system.GetUsageAndQuota(&initial_usage, &quota));
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a file and directory in the file_system.
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileSystemURL kFile(file_system.URL("file"));
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileSystemURL kDir(file_system.URL("dir"));
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileSystemURL kChild(file_system.URL("dir/child"));
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK, file_system.CreateFile(kFile));
6245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK, file_system.CreateDirectory(kDir));
6255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK, file_system.CreateFile(kChild));
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // file_system's change tracker must have recorded the creation.
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileSystemURLSet urls;
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system.GetChangedURLsInTracker(&urls);
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(3U, urls.size());
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(ContainsKey(urls, kFile));
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(ContainsKey(urls, kDir));
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(ContainsKey(urls, kChild));
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (FileSystemURLSet::iterator iter = urls.begin();
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       iter != urls.end(); ++iter) {
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    file_system.ClearChangeForURLInTracker(*iter);
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // At this point the usage must be greater than the initial usage.
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 new_usage = -1;
64103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_EQ(storage::kQuotaStatusOk,
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system.GetUsageAndQuota(&new_usage, &quota));
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_GT(new_usage, initial_usage);
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now let's apply remote deletion changes.
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileChange change(FileChange::FILE_CHANGE_DELETE,
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    SYNC_FILE_TYPE_FILE);
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK,
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ApplyRemoteChange(file_system.file_system_context(),
6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              change, base::FilePath(), kFile,
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              SYNC_FILE_TYPE_FILE));
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The implementation doesn't check file type for deletion, and it must be ok
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // even if we don't know if the deletion change was for a file or a directory.
6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  change = FileChange(FileChange::FILE_CHANGE_DELETE,
6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      SYNC_FILE_TYPE_UNKNOWN);
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK,
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ApplyRemoteChange(file_system.file_system_context(),
6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              change, base::FilePath(), kDir,
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              SYNC_FILE_TYPE_DIRECTORY));
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check the directory/files are deleted successfully.
6635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND,
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system.FileExists(kFile));
6655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND,
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system.DirectoryExists(kDir));
6675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND,
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system.FileExists(kChild));
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The changes applied by ApplyRemoteChange should not be recorded in
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the change tracker.
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  urls.clear();
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system.GetChangedURLsInTracker(&urls);
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(urls.empty());
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The quota usage data must have reflected the deletion.
67703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_EQ(storage::kQuotaStatusOk,
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system.GetUsageAndQuota(&new_usage, &quota));
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(new_usage, initial_usage);
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_context_->ShutdownOnUIThread();
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_context_ = NULL;
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system.TearDown();
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
686a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(LocalFileSyncContextTest, ApplyRemoteChangeForDeletion_ForRoot) {
687a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CannedSyncableFileSystem file_system(GURL(kOrigin1),
6885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                       in_memory_env_.get(),
689a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                       io_task_runner_.get(),
690a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                       file_task_runner_.get());
6915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  file_system.SetUp(CannedSyncableFileSystem::QUOTA_ENABLED);
692a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
693a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  sync_context_ = new LocalFileSyncContext(
6945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      dir_.path(), in_memory_env_.get(),
6955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ui_task_runner_.get(), io_task_runner_.get());
696a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(SYNC_STATUS_OK,
697a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            file_system.MaybeInitializeFileSystemContext(sync_context_.get()));
6985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(base::File::FILE_OK, file_system.OpenFileSystem());
699a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
700a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Record the initial usage (likely 0).
701a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  int64 initial_usage = -1;
702a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  int64 quota = -1;
70303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_EQ(storage::kQuotaStatusOk,
704a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            file_system.GetUsageAndQuota(&initial_usage, &quota));
705a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
706a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Create a file and directory in the file_system.
707a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const FileSystemURL kFile(file_system.URL("file"));
708a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const FileSystemURL kDir(file_system.URL("dir"));
709a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const FileSystemURL kChild(file_system.URL("dir/child"));
710a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
7115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK, file_system.CreateFile(kFile));
7125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK, file_system.CreateDirectory(kDir));
7135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK, file_system.CreateFile(kChild));
714a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
715a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // At this point the usage must be greater than the initial usage.
716a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  int64 new_usage = -1;
71703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_EQ(storage::kQuotaStatusOk,
718a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            file_system.GetUsageAndQuota(&new_usage, &quota));
719a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_GT(new_usage, initial_usage);
720a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
721a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const FileSystemURL kRoot(file_system.URL(""));
722a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
723a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Now let's apply remote deletion changes for the root.
724a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  FileChange change(FileChange::FILE_CHANGE_DELETE, SYNC_FILE_TYPE_DIRECTORY);
725a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK,
726a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            ApplyRemoteChange(file_system.file_system_context(),
727a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                              change, base::FilePath(), kRoot,
728a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                              SYNC_FILE_TYPE_DIRECTORY));
729a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
730a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Check the directory/files are deleted successfully.
7315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND,
732a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            file_system.FileExists(kFile));
7335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND,
734a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            file_system.DirectoryExists(kDir));
7355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND,
736a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            file_system.FileExists(kChild));
737a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
738a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // All changes made for the previous creation must have been also reset.
739a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  FileSystemURLSet urls;
740a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  file_system.GetChangedURLsInTracker(&urls);
741a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(urls.empty());
742a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
743a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // The quota usage data must have reflected the deletion.
74403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_EQ(storage::kQuotaStatusOk,
745a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            file_system.GetUsageAndQuota(&new_usage, &quota));
746a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(new_usage, initial_usage);
747a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
748a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  sync_context_->ShutdownOnUIThread();
749a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  sync_context_ = NULL;
750a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  file_system.TearDown();
751a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
752a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(LocalFileSyncContextTest, ApplyRemoteChangeForAddOrUpdate) {
7542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ScopedTempDir temp_dir;
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
757868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CannedSyncableFileSystem file_system(GURL(kOrigin1),
7585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                       in_memory_env_.get(),
759868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                       io_task_runner_.get(),
760868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                       file_task_runner_.get());
7615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  file_system.SetUp(CannedSyncableFileSystem::QUOTA_ENABLED);
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
763d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  sync_context_ = new LocalFileSyncContext(
7645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      dir_.path(), in_memory_env_.get(),
7655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ui_task_runner_.get(), io_task_runner_.get());
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(SYNC_STATUS_OK,
767868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            file_system.MaybeInitializeFileSystemContext(sync_context_.get()));
7685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(base::File::FILE_OK, file_system.OpenFileSystem());
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileSystemURL kFile1(file_system.URL("file1"));
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileSystemURL kFile2(file_system.URL("file2"));
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileSystemURL kDir(file_system.URL("dir"));
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kTestFileData0[] = "0123456789";
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kTestFileData1[] = "Lorem ipsum!";
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kTestFileData2[] = "This is sample test data.";
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create kFile1 and populate it with kTestFileData0.
7795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK, file_system.CreateFile(kFile1));
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(static_cast<int64>(arraysize(kTestFileData0) - 1),
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system.WriteString(kFile1, kTestFileData0));
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // kFile2 and kDir are not there yet.
7845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND,
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system.FileExists(kFile2));
7865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND,
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system.DirectoryExists(kDir));
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // file_system's change tracker must have recorded the creation.
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileSystemURLSet urls;
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system.GetChangedURLsInTracker(&urls);
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1U, urls.size());
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(ContainsKey(urls, kFile1));
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system.ClearChangeForURLInTracker(*urls.begin());
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Prepare temporary files which represent the remote file data.
7972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::FilePath kFilePath1(temp_dir.path().Append(FPL("file1")));
7982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::FilePath kFilePath2(temp_dir.path().Append(FPL("file2")));
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(static_cast<int>(arraysize(kTestFileData1) - 1),
801a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            base::WriteFile(kFilePath1, kTestFileData1,
802a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                            arraysize(kTestFileData1) - 1));
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(static_cast<int>(arraysize(kTestFileData2) - 1),
804a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            base::WriteFile(kFilePath2, kTestFileData2,
805a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                            arraysize(kTestFileData2) - 1));
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Record the usage.
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 usage = -1, new_usage = -1;
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 quota = -1;
81003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_EQ(storage::kQuotaStatusOk,
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system.GetUsageAndQuota(&usage, &quota));
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Here in the local filesystem we have:
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  * kFile1 with kTestFileData0
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // In the remote side let's assume we have:
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  * kFile1 with kTestFileData1
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  * kFile2 with kTestFileData2
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  * kDir
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // By calling ApplyChange's:
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  * kFile1 will be updated to have kTestFileData1
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  * kFile2 will be created
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  * kDir will be created
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Apply the remote change to kFile1 (which will update the file).
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileChange change(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    SYNC_FILE_TYPE_FILE);
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK,
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ApplyRemoteChange(file_system.file_system_context(),
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              change, kFilePath1, kFile1,
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              SYNC_FILE_TYPE_FILE));
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check if the usage has been increased by (kTestFileData1 - kTestFileData0).
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int updated_size =
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      arraysize(kTestFileData1) - arraysize(kTestFileData0);
83703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_EQ(storage::kQuotaStatusOk,
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system.GetUsageAndQuota(&new_usage, &quota));
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(updated_size, new_usage - usage);
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Apply remote changes to kFile2 and kDir (should create a file and
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // directory respectively).
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // They are non-existent yet so their expected file type (the last
8442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // parameter of ApplyRemoteChange) are
8452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // SYNC_FILE_TYPE_UNKNOWN.
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  change = FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      SYNC_FILE_TYPE_FILE);
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK,
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ApplyRemoteChange(file_system.file_system_context(),
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              change, kFilePath2, kFile2,
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              SYNC_FILE_TYPE_UNKNOWN));
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  change = FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      SYNC_FILE_TYPE_DIRECTORY);
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK,
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ApplyRemoteChange(file_system.file_system_context(),
8572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              change, base::FilePath(), kDir,
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              SYNC_FILE_TYPE_UNKNOWN));
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
860c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Calling ApplyRemoteChange with different file type should be handled as
861c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // overwrite.
862c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  change =
863c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE, SYNC_FILE_TYPE_FILE);
864c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK,
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ApplyRemoteChange(file_system.file_system_context(),
866c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              change,
867c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              kFilePath1,
868c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              kDir,
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              SYNC_FILE_TYPE_DIRECTORY));
8705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK, file_system.FileExists(kDir));
871c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
872c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  change = FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
873c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                      SYNC_FILE_TYPE_DIRECTORY);
874c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK,
875c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            ApplyRemoteChange(file_system.file_system_context(),
876c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              change,
877c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              kFilePath1,
878c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              kDir,
879c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              SYNC_FILE_TYPE_FILE));
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creating a file/directory must have increased the usage more than
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the size of kTestFileData2.
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  new_usage = usage;
88403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_EQ(storage::kQuotaStatusOk,
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system.GetUsageAndQuota(&new_usage, &quota));
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_GT(new_usage,
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            static_cast<int64>(usage + arraysize(kTestFileData2) - 1));
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The changes applied by ApplyRemoteChange should not be recorded in
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the change tracker.
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  urls.clear();
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system.GetChangedURLsInTracker(&urls);
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(urls.empty());
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure all three files/directory exist.
8965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK, file_system.FileExists(kFile1));
8975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK, file_system.FileExists(kFile2));
8985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK, file_system.DirectoryExists(kDir));
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_context_->ShutdownOnUIThread();
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system.TearDown();
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
904c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(LocalFileSyncContextTest, ApplyRemoteChangeForAddOrUpdate_NoParent) {
905c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::ScopedTempDir temp_dir;
906c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
907c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
908868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CannedSyncableFileSystem file_system(GURL(kOrigin1),
9095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                       in_memory_env_.get(),
910868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                       io_task_runner_.get(),
911868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                       file_task_runner_.get());
9125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  file_system.SetUp(CannedSyncableFileSystem::QUOTA_ENABLED);
913c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
914d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  sync_context_ = new LocalFileSyncContext(
9155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      dir_.path(), in_memory_env_.get(),
9165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ui_task_runner_.get(), io_task_runner_.get());
917c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(SYNC_STATUS_OK,
918868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            file_system.MaybeInitializeFileSystemContext(sync_context_.get()));
9195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(base::File::FILE_OK, file_system.OpenFileSystem());
920c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
921c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const char kTestFileData[] = "Lorem ipsum!";
922c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const FileSystemURL kDir(file_system.URL("dir"));
923c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const FileSystemURL kFile(file_system.URL("dir/file"));
924c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
925c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Either kDir or kFile not exist yet.
9265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND, file_system.FileExists(kDir));
9275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND, file_system.FileExists(kFile));
928c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
929c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Prepare a temporary file which represents remote file data.
930c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const base::FilePath kFilePath(temp_dir.path().Append(FPL("file")));
931c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(static_cast<int>(arraysize(kTestFileData) - 1),
932a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            base::WriteFile(kFilePath, kTestFileData,
933a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                            arraysize(kTestFileData) - 1));
934c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
935c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Calling ApplyChange's with kFilePath should create
936c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // kFile along with kDir.
937c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  FileChange change(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
938c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    SYNC_FILE_TYPE_FILE);
939c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK,
940c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            ApplyRemoteChange(file_system.file_system_context(),
941c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              change, kFilePath, kFile,
942c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              SYNC_FILE_TYPE_UNKNOWN));
943c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
944c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The changes applied by ApplyRemoteChange should not be recorded in
945c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // the change tracker.
946c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  FileSystemURLSet urls;
947c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  urls.clear();
948c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  file_system.GetChangedURLsInTracker(&urls);
949c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(urls.empty());
950c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
951c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Make sure kDir and kFile are created by ApplyRemoteChange.
9525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK, file_system.FileExists(kFile));
9535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK, file_system.DirectoryExists(kDir));
954c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
955c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  sync_context_->ShutdownOnUIThread();
956c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  file_system.TearDown();
957c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
958c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
9592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace sync_file_system
960