local_file_sync_context_unittest.cc revision a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7
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"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_util.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
13ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/message_loop/message_loop.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/platform_file.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h"
162385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/local/canned_syncable_file_system.h"
172385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/local/local_file_change_tracker.h"
182385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/local/sync_file_system_backend.h"
192385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/sync_file_metadata.h"
202385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/sync_status_code.h"
212385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/syncable_file_system_util.h"
22d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "content/public/browser/browser_thread.h"
23d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "content/public/test/test_browser_thread_bundle.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
2590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/browser/blob/mock_blob_url_request_context.h"
2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/browser/fileapi/file_system_context.h"
27868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "webkit/browser/fileapi/file_system_operation_runner.h"
2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/browser/fileapi/isolated_context.h"
29d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "webkit/common/blob/scoped_file.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define FPL FILE_PATH_LITERAL
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)using content::BrowserThread;
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using fileapi::FileSystemContext;
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using fileapi::FileSystemURL;
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using fileapi::FileSystemURLSet;
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This tests LocalFileSyncContext behavior in multi-thread /
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// multi-file-system-context environment.
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Basic combined tests (single-thread / single-file-system-context)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// that involve LocalFileSyncContext are also in
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// syncable_file_system_unittests.cc.
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace sync_file_system {
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kOrigin1[] = "http://example.com";
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kOrigin2[] = "http://chromium.org";
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class LocalFileSyncContextTest : public testing::Test {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LocalFileSyncContextTest()
54d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      : thread_bundle_(
55d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)            content::TestBrowserThreadBundle::REAL_FILE_THREAD |
56d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)            content::TestBrowserThreadBundle::REAL_IO_THREAD),
57d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        status_(SYNC_FILE_ERROR_FAILED),
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        file_error_(base::PLATFORM_FILE_ERROR_FAILED),
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        async_modify_finished_(false),
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        has_inflight_prepare_for_sync_(false) {}
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() OVERRIDE {
63868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    RegisterSyncableFileSystem();
64d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    ASSERT_TRUE(dir_.CreateUniqueTempDir());
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    ui_task_runner_ = base::MessageLoop::current()->message_loop_proxy();
67d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    io_task_runner_ = BrowserThread::GetMessageLoopProxyForThread(
68d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        BrowserThread::IO);
69d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    file_task_runner_ = BrowserThread::GetMessageLoopProxyForThread(
70d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        BrowserThread::IO);
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void TearDown() OVERRIDE {
74868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    RevokeSyncableFileSystem();
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void StartPrepareForSync(FileSystemContext* file_system_context,
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           const FileSystemURL& url,
79d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                           LocalFileSyncContext::SyncMode sync_mode,
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           SyncFileMetadata* metadata,
81d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                           FileChangeList* changes,
82d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                           webkit_blob::ScopedFile* snapshot) {
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(changes != NULL);
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_FALSE(has_inflight_prepare_for_sync_);
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    status_ = SYNC_STATUS_UNKNOWN;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    has_inflight_prepare_for_sync_ = true;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sync_context_->PrepareForSync(
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        file_system_context,
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        url,
90d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        sync_mode,
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&LocalFileSyncContextTest::DidPrepareForSync,
92d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                   base::Unretained(this), metadata, changes, snapshot));
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SyncStatusCode PrepareForSync(FileSystemContext* file_system_context,
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                const FileSystemURL& url,
97d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                LocalFileSyncContext::SyncMode sync_mode,
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                SyncFileMetadata* metadata,
99d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                FileChangeList* changes,
100d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                webkit_blob::ScopedFile* snapshot) {
101d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    StartPrepareForSync(file_system_context, url, sync_mode,
102d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                        metadata, changes, snapshot);
103b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    base::MessageLoop::current()->Run();
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return status_;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  base::Closure GetPrepareForSyncClosure(
108d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      FileSystemContext* file_system_context,
109d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      const FileSystemURL& url,
110d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      LocalFileSyncContext::SyncMode sync_mode,
111d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      SyncFileMetadata* metadata,
112d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      FileChangeList* changes,
113d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      webkit_blob::ScopedFile* snapshot) {
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return base::Bind(&LocalFileSyncContextTest::StartPrepareForSync,
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      base::Unretained(this),
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      base::Unretained(file_system_context),
117d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                      url, sync_mode, metadata, changes, snapshot);
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DidPrepareForSync(SyncFileMetadata* metadata_out,
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         FileChangeList* changes_out,
122d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                         webkit_blob::ScopedFile* snapshot_out,
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         SyncStatusCode status,
124d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                         const LocalFileSyncInfo& sync_file_info,
1251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                         webkit_blob::ScopedFile snapshot) {
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(ui_task_runner_->RunsTasksOnCurrentThread());
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    has_inflight_prepare_for_sync_ = false;
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    status_ = status;
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *metadata_out = sync_file_info.metadata;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *changes_out = sync_file_info.changes;
1311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (snapshot_out)
1321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      *snapshot_out = snapshot.Pass();
133b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    base::MessageLoop::current()->Quit();
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SyncStatusCode ApplyRemoteChange(FileSystemContext* file_system_context,
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   const FileChange& change,
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   const base::FilePath& local_path,
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   const FileSystemURL& url,
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   SyncFileType expected_file_type) {
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SCOPED_TRACE(testing::Message() << "ApplyChange for " <<
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 url.DebugString());
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // First we should call PrepareForSync to disable writing.
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SyncFileMetadata metadata;
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FileChangeList changes;
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(SYNC_STATUS_OK,
148d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)              PrepareForSync(file_system_context, url,
149d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                             LocalFileSyncContext::SYNC_EXCLUSIVE,
150d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                             &metadata, &changes, NULL));
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(expected_file_type, metadata.file_type);
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    status_ = SYNC_STATUS_UNKNOWN;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sync_context_->ApplyRemoteChange(
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        file_system_context, change, local_path, url,
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&LocalFileSyncContextTest::DidApplyRemoteChange,
1574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                   base::Unretained(this),
1584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                   make_scoped_refptr(file_system_context), url));
159b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    base::MessageLoop::current()->Run();
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return status_;
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void DidApplyRemoteChange(FileSystemContext* file_system_context,
1644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                            const FileSystemURL& url,
1654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                            SyncStatusCode status) {
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    status_ = status;
1674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    sync_context_->FinalizeExclusiveSync(
1684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        file_system_context, url,
1694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        status == SYNC_STATUS_OK /* clear_local_changes */,
1704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        base::MessageLoop::QuitClosure());
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void StartModifyFileOnIOThread(CannedSyncableFileSystem* file_system,
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 const FileSystemURL& url) {
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(file_system != NULL);
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!io_task_runner_->RunsTasksOnCurrentThread()) {
177d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      async_modify_finished_ = false;
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ASSERT_TRUE(ui_task_runner_->RunsTasksOnCurrentThread());
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      io_task_runner_->PostTask(
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          FROM_HERE,
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base::Bind(&LocalFileSyncContextTest::StartModifyFileOnIOThread,
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     base::Unretained(this), file_system, url));
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(io_task_runner_->RunsTasksOnCurrentThread());
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    file_error_ = base::PLATFORM_FILE_ERROR_FAILED;
187868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    file_system->operation_runner()->Truncate(
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        url, 1, base::Bind(&LocalFileSyncContextTest::DidModifyFile,
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           base::Unretained(this)));
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::PlatformFileError WaitUntilModifyFileIsDone() {
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (!async_modify_finished_)
194b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      base::MessageLoop::current()->RunUntilIdle();
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return file_error_;
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DidModifyFile(base::PlatformFileError error) {
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ui_task_runner_->RunsTasksOnCurrentThread()) {
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ASSERT_TRUE(io_task_runner_->RunsTasksOnCurrentThread());
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ui_task_runner_->PostTask(
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          FROM_HERE,
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base::Bind(&LocalFileSyncContextTest::DidModifyFile,
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     base::Unretained(this), error));
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(ui_task_runner_->RunsTasksOnCurrentThread());
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    file_error_ = error;
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    async_modify_finished_ = true;
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
212d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  void SimulateFinishSync(FileSystemContext* file_system_context,
213d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                          const FileSystemURL& url,
2144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                          SyncStatusCode status,
2154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                          LocalFileSyncContext::SyncMode sync_mode) {
2164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (sync_mode == LocalFileSyncContext::SYNC_SNAPSHOT) {
2174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      sync_context_->FinalizeSnapshotSync(
2184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          file_system_context, url, status,
2194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          base::Bind(&base::DoNothing));
2204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    } else {
2214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      sync_context_->FinalizeExclusiveSync(
2224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          file_system_context, url,
2234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          status == SYNC_STATUS_OK /* clear_local_changes */,
2244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          base::Bind(&base::DoNothing));
2254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
226d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
227d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
228d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  void PrepareForSync_Basic(LocalFileSyncContext::SyncMode sync_mode,
229d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                            SyncStatusCode simulate_sync_finish_status) {
230d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    CannedSyncableFileSystem file_system(GURL(kOrigin1),
231d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                         io_task_runner_.get(),
232d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                         file_task_runner_.get());
233d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    file_system.SetUp();
234d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    sync_context_ = new LocalFileSyncContext(
235d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        dir_.path(), ui_task_runner_.get(), io_task_runner_.get());
236d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    ASSERT_EQ(SYNC_STATUS_OK,
237d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)              file_system.MaybeInitializeFileSystemContext(
238d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                  sync_context_.get()));
239d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    ASSERT_EQ(base::PLATFORM_FILE_OK, file_system.OpenFileSystem());
240d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
241d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    const FileSystemURL kFile(file_system.URL("file"));
242d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    EXPECT_EQ(base::PLATFORM_FILE_OK, file_system.CreateFile(kFile));
243d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
244d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    SyncFileMetadata metadata;
245d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    FileChangeList changes;
246d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    EXPECT_EQ(SYNC_STATUS_OK,
247d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)              PrepareForSync(file_system.file_system_context(), kFile,
248d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                             sync_mode, &metadata, &changes, NULL));
249d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    EXPECT_EQ(1U, changes.size());
250d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    EXPECT_TRUE(changes.list().back().IsFile());
251d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    EXPECT_TRUE(changes.list().back().IsAddOrUpdate());
252d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
253d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // We should see the same set of changes.
254d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    file_system.GetChangesForURLInTracker(kFile, &changes);
255d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    EXPECT_EQ(1U, changes.size());
256d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    EXPECT_TRUE(changes.list().back().IsFile());
257d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    EXPECT_TRUE(changes.list().back().IsAddOrUpdate());
258d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
259d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    SimulateFinishSync(file_system.file_system_context(), kFile,
2604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                       simulate_sync_finish_status, sync_mode);
261d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
262d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    file_system.GetChangesForURLInTracker(kFile, &changes);
263d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    if (simulate_sync_finish_status == SYNC_STATUS_OK) {
264d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      // The change's cleared.
265d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      EXPECT_TRUE(changes.empty());
266d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    } else {
267d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      EXPECT_EQ(1U, changes.size());
268d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      EXPECT_TRUE(changes.list().back().IsFile());
269d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      EXPECT_TRUE(changes.list().back().IsAddOrUpdate());
270d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    }
271d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
272d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    sync_context_->ShutdownOnUIThread();
273d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    sync_context_ = NULL;
274d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
275d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    file_system.TearDown();
276d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
277d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
278d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  void PrepareForSync_WriteDuringSync(
279d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      LocalFileSyncContext::SyncMode sync_mode) {
280d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    CannedSyncableFileSystem file_system(GURL(kOrigin1),
281d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                         io_task_runner_.get(),
282d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                         file_task_runner_.get());
283d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    file_system.SetUp();
284d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    sync_context_ = new LocalFileSyncContext(
285d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        dir_.path(), ui_task_runner_.get(), io_task_runner_.get());
286d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    ASSERT_EQ(SYNC_STATUS_OK,
287d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)              file_system.MaybeInitializeFileSystemContext(
288d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                  sync_context_.get()));
289d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    ASSERT_EQ(base::PLATFORM_FILE_OK, file_system.OpenFileSystem());
290d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
291d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    const FileSystemURL kFile(file_system.URL("file"));
292d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    EXPECT_EQ(base::PLATFORM_FILE_OK, file_system.CreateFile(kFile));
293d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
294d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    SyncFileMetadata metadata;
295d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    FileChangeList changes;
296d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    webkit_blob::ScopedFile snapshot;
297d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    EXPECT_EQ(SYNC_STATUS_OK,
298d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)              PrepareForSync(file_system.file_system_context(), kFile,
299d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                             sync_mode, &metadata, &changes, &snapshot));
300d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    EXPECT_EQ(1U, changes.size());
301d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    EXPECT_TRUE(changes.list().back().IsFile());
302d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    EXPECT_TRUE(changes.list().back().IsAddOrUpdate());
303d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
304d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    EXPECT_EQ(sync_mode == LocalFileSyncContext::SYNC_SNAPSHOT,
305d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)              !snapshot.path().empty());
306d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
307d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // Tracker keeps same set of changes.
308d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    file_system.GetChangesForURLInTracker(kFile, &changes);
309d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    EXPECT_EQ(1U, changes.size());
310d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    EXPECT_TRUE(changes.list().back().IsFile());
311d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    EXPECT_TRUE(changes.list().back().IsAddOrUpdate());
312d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
313d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    StartModifyFileOnIOThread(&file_system, kFile);
314d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
315d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    if (sync_mode == LocalFileSyncContext::SYNC_SNAPSHOT) {
316d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      // Write should succeed.
317d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      EXPECT_EQ(base::PLATFORM_FILE_OK, WaitUntilModifyFileIsDone());
318d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    } else {
319d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      base::MessageLoop::current()->RunUntilIdle();
320d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      EXPECT_FALSE(async_modify_finished_);
321d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    }
322d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
323d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    SimulateFinishSync(file_system.file_system_context(), kFile,
3244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                       SYNC_STATUS_OK, sync_mode);
325d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
326d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    EXPECT_EQ(base::PLATFORM_FILE_OK, WaitUntilModifyFileIsDone());
327d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
328d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // Sync succeeded, but the other change that was made during or
329d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // after sync is recorded.
330d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    file_system.GetChangesForURLInTracker(kFile, &changes);
331d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    EXPECT_EQ(1U, changes.size());
332d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    EXPECT_TRUE(changes.list().back().IsFile());
333d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    EXPECT_TRUE(changes.list().back().IsAddOrUpdate());
334d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
335d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    sync_context_->ShutdownOnUIThread();
336d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    sync_context_ = NULL;
337d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
338d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    file_system.TearDown();
339d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
340d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
341eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ScopedEnableSyncFSDirectoryOperation enable_directory_operation_;
342eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
343d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  base::ScopedTempDir dir_;
344d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // These need to remain until the very end.
346d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  content::TestBrowserThreadBundle thread_bundle_;
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_;
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<base::SingleThreadTaskRunner> file_task_runner_;
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<LocalFileSyncContext> sync_context_;
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SyncStatusCode status_;
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::PlatformFileError file_error_;
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool async_modify_finished_;
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool has_inflight_prepare_for_sync_;
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(LocalFileSyncContextTest, ConstructAndDestruct) {
361868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  sync_context_ =
362d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      new LocalFileSyncContext(
363d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          dir_.path(), ui_task_runner_.get(), io_task_runner_.get());
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_context_->ShutdownOnUIThread();
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(LocalFileSyncContextTest, InitializeFileSystemContext) {
368868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CannedSyncableFileSystem file_system(GURL(kOrigin1),
369868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                       io_task_runner_.get(),
370868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                       file_task_runner_.get());
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system.SetUp();
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
373d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  sync_context_ = new LocalFileSyncContext(
374d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      dir_.path(), ui_task_runner_.get(), io_task_runner_.get());
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Initializes file_system using |sync_context_|.
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK,
378868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            file_system.MaybeInitializeFileSystemContext(sync_context_.get()));
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure everything's set up for file_system to be able to handle
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // syncable file system operations.
382a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_TRUE(file_system.backend()->sync_context() != NULL);
383a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_TRUE(file_system.backend()->change_tracker() != NULL);
384a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(sync_context_.get(), file_system.backend()->sync_context());
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Calling MaybeInitialize for the same context multiple times must be ok.
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK,
388868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            file_system.MaybeInitializeFileSystemContext(sync_context_.get()));
389a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(sync_context_.get(), file_system.backend()->sync_context());
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Opens the file_system, perform some operation and see if the change tracker
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // correctly captures the change.
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(base::PLATFORM_FILE_OK, file_system.OpenFileSystem());
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileSystemURL kURL(file_system.URL("foo"));
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(base::PLATFORM_FILE_OK, file_system.CreateFile(kURL));
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileSystemURLSet urls;
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system.GetChangedURLsInTracker(&urls);
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1U, urls.size());
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(ContainsKey(urls, kURL));
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Finishing the test.
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_context_->ShutdownOnUIThread();
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system.TearDown();
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(LocalFileSyncContextTest, MultipleFileSystemContexts) {
409868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CannedSyncableFileSystem file_system1(GURL(kOrigin1),
410868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                        io_task_runner_.get(),
411868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                        file_task_runner_.get());
412868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CannedSyncableFileSystem file_system2(GURL(kOrigin2),
413868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                        io_task_runner_.get(),
414868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                        file_task_runner_.get());
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system1.SetUp();
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system2.SetUp();
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
418d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  sync_context_ = new LocalFileSyncContext(
419d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      dir_.path(), ui_task_runner_.get(), io_task_runner_.get());
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Initializes file_system1 and file_system2.
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK,
423868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            file_system1.MaybeInitializeFileSystemContext(sync_context_.get()));
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK,
425868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            file_system2.MaybeInitializeFileSystemContext(sync_context_.get()));
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(base::PLATFORM_FILE_OK, file_system1.OpenFileSystem());
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(base::PLATFORM_FILE_OK, file_system2.OpenFileSystem());
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileSystemURL kURL1(file_system1.URL("foo"));
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileSystemURL kURL2(file_system2.URL("bar"));
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creates a file in file_system1.
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(base::PLATFORM_FILE_OK, file_system1.CreateFile(kURL1));
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // file_system1's tracker must have recorded the change.
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileSystemURLSet urls;
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system1.GetChangedURLsInTracker(&urls);
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1U, urls.size());
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(ContainsKey(urls, kURL1));
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // file_system1's tracker must have no change.
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  urls.clear();
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system2.GetChangedURLsInTracker(&urls);
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(urls.empty());
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creates a directory in file_system2.
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(base::PLATFORM_FILE_OK, file_system2.CreateDirectory(kURL2));
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // file_system1's tracker must have the change for kURL1 as before.
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  urls.clear();
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system1.GetChangedURLsInTracker(&urls);
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1U, urls.size());
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(ContainsKey(urls, kURL1));
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // file_system2's tracker now must have the change for kURL2.
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  urls.clear();
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system2.GetChangedURLsInTracker(&urls);
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1U, urls.size());
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(ContainsKey(urls, kURL2));
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SyncFileMetadata metadata;
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileChangeList changes;
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK,
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            PrepareForSync(file_system1.file_system_context(), kURL1,
466d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                           LocalFileSyncContext::SYNC_EXCLUSIVE,
467d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                           &metadata, &changes, NULL));
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1U, changes.size());
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(changes.list().back().IsFile());
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(changes.list().back().IsAddOrUpdate());
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SYNC_FILE_TYPE_FILE, metadata.file_type);
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, metadata.size);
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  changes.clear();
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK,
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            PrepareForSync(file_system2.file_system_context(), kURL2,
477d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                           LocalFileSyncContext::SYNC_EXCLUSIVE,
478d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                           &metadata, &changes, NULL));
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1U, changes.size());
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(changes.list().back().IsFile());
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(changes.list().back().IsAddOrUpdate());
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SYNC_FILE_TYPE_DIRECTORY, metadata.file_type);
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, metadata.size);
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_context_->ShutdownOnUIThread();
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_context_ = NULL;
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system1.TearDown();
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system2.TearDown();
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
492d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)TEST_F(LocalFileSyncContextTest, PrepareSync_SyncSuccess_Exclusive) {
493d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  PrepareForSync_Basic(LocalFileSyncContext::SYNC_EXCLUSIVE,
494d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                       SYNC_STATUS_OK);
495d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
496d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
497d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)TEST_F(LocalFileSyncContextTest, PrepareSync_SyncSuccess_Snapshot) {
498d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  PrepareForSync_Basic(LocalFileSyncContext::SYNC_SNAPSHOT,
499d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                       SYNC_STATUS_OK);
500d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
501d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
502d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)TEST_F(LocalFileSyncContextTest, PrepareSync_SyncFailure_Exclusive) {
503d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  PrepareForSync_Basic(LocalFileSyncContext::SYNC_EXCLUSIVE,
504d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                       SYNC_STATUS_FAILED);
505d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
506d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
507d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)TEST_F(LocalFileSyncContextTest, PrepareSync_SyncFailure_Snapshot) {
508d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  PrepareForSync_Basic(LocalFileSyncContext::SYNC_SNAPSHOT,
509d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                       SYNC_STATUS_FAILED);
510d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
511d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
512d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)TEST_F(LocalFileSyncContextTest, PrepareSync_WriteDuringSync_Exclusive) {
513d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  PrepareForSync_WriteDuringSync(LocalFileSyncContext::SYNC_EXCLUSIVE);
514d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
515d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
516d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)TEST_F(LocalFileSyncContextTest, PrepareSync_WriteDuringSync_Snapshot) {
517d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  PrepareForSync_WriteDuringSync(LocalFileSyncContext::SYNC_SNAPSHOT);
518d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
519d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
520a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// LocalFileSyncContextTest.PrepareSyncWhileWriting is flaky on android.
521a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// http://crbug.com/239793
5224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// It is also flaky on the TSAN v2 bots, and hangs other bots.
5234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// http://crbug.com/305905.
5244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(LocalFileSyncContextTest, DISABLED_PrepareSyncWhileWriting) {
525868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CannedSyncableFileSystem file_system(GURL(kOrigin1),
526868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                       io_task_runner_.get(),
527868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                       file_task_runner_.get());
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system.SetUp();
529d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  sync_context_ = new LocalFileSyncContext(
530d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      dir_.path(), ui_task_runner_.get(), io_task_runner_.get());
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK,
532868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            file_system.MaybeInitializeFileSystemContext(sync_context_.get()));
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(base::PLATFORM_FILE_OK, file_system.OpenFileSystem());
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileSystemURL kURL1(file_system.URL("foo"));
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creates a file in file_system.
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(base::PLATFORM_FILE_OK, file_system.CreateFile(kURL1));
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Kick file write on IO thread.
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartModifyFileOnIOThread(&file_system, kURL1);
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Until the operation finishes PrepareForSync should return BUSY error.
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SyncFileMetadata metadata;
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  metadata.file_type = SYNC_FILE_TYPE_UNKNOWN;
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileChangeList changes;
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_FILE_BUSY,
549d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)            PrepareForSync(file_system.file_system_context(), kURL1,
550d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                           LocalFileSyncContext::SYNC_EXCLUSIVE,
551d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                           &metadata, &changes, NULL));
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SYNC_FILE_TYPE_FILE, metadata.file_type);
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Register PrepareForSync method to be invoked when kURL1 becomes
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // syncable. (Actually this may be done after all operations are done
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // on IO thread in this test.)
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  metadata.file_type = SYNC_FILE_TYPE_UNKNOWN;
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  changes.clear();
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_context_->RegisterURLForWaitingSync(
560d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      kURL1, GetPrepareForSyncClosure(file_system.file_system_context(), kURL1,
561d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                      LocalFileSyncContext::SYNC_EXCLUSIVE,
562d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                      &metadata, &changes, NULL));
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Wait for the completion.
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(base::PLATFORM_FILE_OK, WaitUntilModifyFileIsDone());
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The PrepareForSync must have been started; wait until DidPrepareForSync
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // is done.
569b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  base::MessageLoop::current()->Run();
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(has_inflight_prepare_for_sync_);
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now PrepareForSync should have run and returned OK.
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, status_);
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1U, changes.size());
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(changes.list().back().IsFile());
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(changes.list().back().IsAddOrUpdate());
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SYNC_FILE_TYPE_FILE, metadata.file_type);
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, metadata.size);
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_context_->ShutdownOnUIThread();
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_context_ = NULL;
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system.TearDown();
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(LocalFileSyncContextTest, ApplyRemoteChangeForDeletion) {
586868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CannedSyncableFileSystem file_system(GURL(kOrigin1),
587868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                       io_task_runner_.get(),
588868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                       file_task_runner_.get());
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system.SetUp();
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
591d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  sync_context_ = new LocalFileSyncContext(
592d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      dir_.path(), ui_task_runner_.get(), io_task_runner_.get());
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(SYNC_STATUS_OK,
594868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            file_system.MaybeInitializeFileSystemContext(sync_context_.get()));
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(base::PLATFORM_FILE_OK, file_system.OpenFileSystem());
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Record the initial usage (likely 0).
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 initial_usage = -1;
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 quota = -1;
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(quota::kQuotaStatusOk,
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system.GetUsageAndQuota(&initial_usage, &quota));
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a file and directory in the file_system.
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileSystemURL kFile(file_system.URL("file"));
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileSystemURL kDir(file_system.URL("dir"));
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileSystemURL kChild(file_system.URL("dir/child"));
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(base::PLATFORM_FILE_OK, file_system.CreateFile(kFile));
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(base::PLATFORM_FILE_OK, file_system.CreateDirectory(kDir));
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(base::PLATFORM_FILE_OK, file_system.CreateFile(kChild));
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // file_system's change tracker must have recorded the creation.
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileSystemURLSet urls;
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system.GetChangedURLsInTracker(&urls);
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(3U, urls.size());
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(ContainsKey(urls, kFile));
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(ContainsKey(urls, kDir));
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(ContainsKey(urls, kChild));
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (FileSystemURLSet::iterator iter = urls.begin();
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       iter != urls.end(); ++iter) {
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    file_system.ClearChangeForURLInTracker(*iter);
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // At this point the usage must be greater than the initial usage.
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 new_usage = -1;
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(quota::kQuotaStatusOk,
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system.GetUsageAndQuota(&new_usage, &quota));
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_GT(new_usage, initial_usage);
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now let's apply remote deletion changes.
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileChange change(FileChange::FILE_CHANGE_DELETE,
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    SYNC_FILE_TYPE_FILE);
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK,
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ApplyRemoteChange(file_system.file_system_context(),
6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              change, base::FilePath(), kFile,
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              SYNC_FILE_TYPE_FILE));
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The implementation doesn't check file type for deletion, and it must be ok
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // even if we don't know if the deletion change was for a file or a directory.
6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  change = FileChange(FileChange::FILE_CHANGE_DELETE,
6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      SYNC_FILE_TYPE_UNKNOWN);
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK,
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ApplyRemoteChange(file_system.file_system_context(),
6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              change, base::FilePath(), kDir,
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              SYNC_FILE_TYPE_DIRECTORY));
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check the directory/files are deleted successfully.
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND,
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system.FileExists(kFile));
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND,
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system.DirectoryExists(kDir));
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND,
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system.FileExists(kChild));
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The changes applied by ApplyRemoteChange should not be recorded in
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the change tracker.
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  urls.clear();
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system.GetChangedURLsInTracker(&urls);
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(urls.empty());
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The quota usage data must have reflected the deletion.
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(quota::kQuotaStatusOk,
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system.GetUsageAndQuota(&new_usage, &quota));
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(new_usage, initial_usage);
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_context_->ShutdownOnUIThread();
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_context_ = NULL;
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system.TearDown();
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
671a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(LocalFileSyncContextTest, ApplyRemoteChangeForDeletion_ForRoot) {
672a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CannedSyncableFileSystem file_system(GURL(kOrigin1),
673a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                       io_task_runner_.get(),
674a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                       file_task_runner_.get());
675a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  file_system.SetUp();
676a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
677a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  sync_context_ = new LocalFileSyncContext(
678a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      dir_.path(), ui_task_runner_.get(), io_task_runner_.get());
679a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(SYNC_STATUS_OK,
680a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            file_system.MaybeInitializeFileSystemContext(sync_context_.get()));
681a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(base::PLATFORM_FILE_OK, file_system.OpenFileSystem());
682a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
683a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Record the initial usage (likely 0).
684a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  int64 initial_usage = -1;
685a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  int64 quota = -1;
686a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(quota::kQuotaStatusOk,
687a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            file_system.GetUsageAndQuota(&initial_usage, &quota));
688a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
689a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Create a file and directory in the file_system.
690a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const FileSystemURL kFile(file_system.URL("file"));
691a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const FileSystemURL kDir(file_system.URL("dir"));
692a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const FileSystemURL kChild(file_system.URL("dir/child"));
693a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
694a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(base::PLATFORM_FILE_OK, file_system.CreateFile(kFile));
695a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(base::PLATFORM_FILE_OK, file_system.CreateDirectory(kDir));
696a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(base::PLATFORM_FILE_OK, file_system.CreateFile(kChild));
697a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
698a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // At this point the usage must be greater than the initial usage.
699a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  int64 new_usage = -1;
700a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(quota::kQuotaStatusOk,
701a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            file_system.GetUsageAndQuota(&new_usage, &quota));
702a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_GT(new_usage, initial_usage);
703a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
704a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const FileSystemURL kRoot(file_system.URL(""));
705a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
706a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Now let's apply remote deletion changes for the root.
707a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  FileChange change(FileChange::FILE_CHANGE_DELETE, SYNC_FILE_TYPE_DIRECTORY);
708a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK,
709a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            ApplyRemoteChange(file_system.file_system_context(),
710a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                              change, base::FilePath(), kRoot,
711a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                              SYNC_FILE_TYPE_DIRECTORY));
712a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
713a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Check the directory/files are deleted successfully.
714a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND,
715a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            file_system.FileExists(kFile));
716a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND,
717a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            file_system.DirectoryExists(kDir));
718a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND,
719a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            file_system.FileExists(kChild));
720a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
721a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // All changes made for the previous creation must have been also reset.
722a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  FileSystemURLSet urls;
723a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  file_system.GetChangedURLsInTracker(&urls);
724a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(urls.empty());
725a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
726a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // The quota usage data must have reflected the deletion.
727a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(quota::kQuotaStatusOk,
728a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            file_system.GetUsageAndQuota(&new_usage, &quota));
729a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(new_usage, initial_usage);
730a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
731a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  sync_context_->ShutdownOnUIThread();
732a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  sync_context_ = NULL;
733a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  file_system.TearDown();
734a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
735a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(LocalFileSyncContextTest, ApplyRemoteChangeForAddOrUpdate) {
7372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ScopedTempDir temp_dir;
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
740868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CannedSyncableFileSystem file_system(GURL(kOrigin1),
741868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                       io_task_runner_.get(),
742868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                       file_task_runner_.get());
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system.SetUp();
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  sync_context_ = new LocalFileSyncContext(
746d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      dir_.path(), ui_task_runner_.get(), io_task_runner_.get());
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(SYNC_STATUS_OK,
748868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            file_system.MaybeInitializeFileSystemContext(sync_context_.get()));
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(base::PLATFORM_FILE_OK, file_system.OpenFileSystem());
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileSystemURL kFile1(file_system.URL("file1"));
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileSystemURL kFile2(file_system.URL("file2"));
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileSystemURL kDir(file_system.URL("dir"));
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kTestFileData0[] = "0123456789";
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kTestFileData1[] = "Lorem ipsum!";
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kTestFileData2[] = "This is sample test data.";
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create kFile1 and populate it with kTestFileData0.
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(base::PLATFORM_FILE_OK, file_system.CreateFile(kFile1));
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(static_cast<int64>(arraysize(kTestFileData0) - 1),
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system.WriteString(kFile1, kTestFileData0));
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // kFile2 and kDir are not there yet.
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND,
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system.FileExists(kFile2));
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND,
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system.DirectoryExists(kDir));
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // file_system's change tracker must have recorded the creation.
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileSystemURLSet urls;
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system.GetChangedURLsInTracker(&urls);
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1U, urls.size());
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(ContainsKey(urls, kFile1));
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system.ClearChangeForURLInTracker(*urls.begin());
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Prepare temporary files which represent the remote file data.
7782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::FilePath kFilePath1(temp_dir.path().Append(FPL("file1")));
7792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::FilePath kFilePath2(temp_dir.path().Append(FPL("file2")));
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(static_cast<int>(arraysize(kTestFileData1) - 1),
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_util::WriteFile(kFilePath1, kTestFileData1,
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 arraysize(kTestFileData1) - 1));
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(static_cast<int>(arraysize(kTestFileData2) - 1),
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_util::WriteFile(kFilePath2, kTestFileData2,
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 arraysize(kTestFileData2) - 1));
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Record the usage.
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 usage = -1, new_usage = -1;
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 quota = -1;
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(quota::kQuotaStatusOk,
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system.GetUsageAndQuota(&usage, &quota));
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Here in the local filesystem we have:
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  * kFile1 with kTestFileData0
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // In the remote side let's assume we have:
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  * kFile1 with kTestFileData1
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  * kFile2 with kTestFileData2
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  * kDir
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // By calling ApplyChange's:
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  * kFile1 will be updated to have kTestFileData1
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  * kFile2 will be created
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  * kDir will be created
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Apply the remote change to kFile1 (which will update the file).
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileChange change(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    SYNC_FILE_TYPE_FILE);
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK,
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ApplyRemoteChange(file_system.file_system_context(),
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              change, kFilePath1, kFile1,
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              SYNC_FILE_TYPE_FILE));
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check if the usage has been increased by (kTestFileData1 - kTestFileData0).
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int updated_size =
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      arraysize(kTestFileData1) - arraysize(kTestFileData0);
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(quota::kQuotaStatusOk,
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system.GetUsageAndQuota(&new_usage, &quota));
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(updated_size, new_usage - usage);
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Apply remote changes to kFile2 and kDir (should create a file and
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // directory respectively).
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // They are non-existent yet so their expected file type (the last
8252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // parameter of ApplyRemoteChange) are
8262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // SYNC_FILE_TYPE_UNKNOWN.
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  change = FileChange(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, kFilePath2, kFile2,
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              SYNC_FILE_TYPE_UNKNOWN));
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  change = FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      SYNC_FILE_TYPE_DIRECTORY);
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK,
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ApplyRemoteChange(file_system.file_system_context(),
8382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              change, base::FilePath(), kDir,
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              SYNC_FILE_TYPE_UNKNOWN));
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
841c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Calling ApplyRemoteChange with different file type should be handled as
842c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // overwrite.
843c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  change =
844c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE, SYNC_FILE_TYPE_FILE);
845c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK,
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ApplyRemoteChange(file_system.file_system_context(),
847c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              change,
848c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              kFilePath1,
849c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              kDir,
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              SYNC_FILE_TYPE_DIRECTORY));
851c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(base::PLATFORM_FILE_OK, file_system.FileExists(kDir));
852c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
853c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  change = FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
854c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                      SYNC_FILE_TYPE_DIRECTORY);
855c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK,
856c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            ApplyRemoteChange(file_system.file_system_context(),
857c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              change,
858c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              kFilePath1,
859c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              kDir,
860c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              SYNC_FILE_TYPE_FILE));
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creating a file/directory must have increased the usage more than
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the size of kTestFileData2.
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  new_usage = usage;
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(quota::kQuotaStatusOk,
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system.GetUsageAndQuota(&new_usage, &quota));
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_GT(new_usage,
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            static_cast<int64>(usage + arraysize(kTestFileData2) - 1));
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The changes applied by ApplyRemoteChange should not be recorded in
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the change tracker.
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  urls.clear();
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system.GetChangedURLsInTracker(&urls);
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(urls.empty());
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure all three files/directory exist.
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(base::PLATFORM_FILE_OK, file_system.FileExists(kFile1));
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(base::PLATFORM_FILE_OK, file_system.FileExists(kFile2));
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(base::PLATFORM_FILE_OK, file_system.DirectoryExists(kDir));
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_context_->ShutdownOnUIThread();
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system.TearDown();
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(LocalFileSyncContextTest, ApplyRemoteChangeForAddOrUpdate_NoParent) {
886c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::ScopedTempDir temp_dir;
887c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
888c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
889868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CannedSyncableFileSystem file_system(GURL(kOrigin1),
890868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                       io_task_runner_.get(),
891868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                       file_task_runner_.get());
892c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  file_system.SetUp();
893c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
894d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  sync_context_ = new LocalFileSyncContext(
895d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      dir_.path(), ui_task_runner_.get(), io_task_runner_.get());
896c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(SYNC_STATUS_OK,
897868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            file_system.MaybeInitializeFileSystemContext(sync_context_.get()));
898c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(base::PLATFORM_FILE_OK, file_system.OpenFileSystem());
899c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
900c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const char kTestFileData[] = "Lorem ipsum!";
901c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const FileSystemURL kDir(file_system.URL("dir"));
902c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const FileSystemURL kFile(file_system.URL("dir/file"));
903c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
904c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Either kDir or kFile not exist yet.
905c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, file_system.FileExists(kDir));
906c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, file_system.FileExists(kFile));
907c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
908c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Prepare a temporary file which represents remote file data.
909c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const base::FilePath kFilePath(temp_dir.path().Append(FPL("file")));
910c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(static_cast<int>(arraysize(kTestFileData) - 1),
911c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            file_util::WriteFile(kFilePath, kTestFileData,
912c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 arraysize(kTestFileData) - 1));
913c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
914c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Calling ApplyChange's with kFilePath should create
915c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // kFile along with kDir.
916c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  FileChange change(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
917c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    SYNC_FILE_TYPE_FILE);
918c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK,
919c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            ApplyRemoteChange(file_system.file_system_context(),
920c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              change, kFilePath, kFile,
921c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              SYNC_FILE_TYPE_UNKNOWN));
922c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
923c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The changes applied by ApplyRemoteChange should not be recorded in
924c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // the change tracker.
925c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  FileSystemURLSet urls;
926c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  urls.clear();
927c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  file_system.GetChangedURLsInTracker(&urls);
928c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(urls.empty());
929c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
930c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Make sure kDir and kFile are created by ApplyRemoteChange.
931c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(base::PLATFORM_FILE_OK, file_system.FileExists(kFile));
932c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(base::PLATFORM_FILE_OK, file_system.DirectoryExists(kDir));
933c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
934c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  sync_context_->ShutdownOnUIThread();
935c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  file_system.TearDown();
936c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
937c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
9382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace sync_file_system
939