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"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_util.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
12ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/message_loop/message_loop.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/platform_file.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/single_thread_task_runner.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread.h"
172385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/local/canned_syncable_file_system.h"
182385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/local/local_file_change_tracker.h"
192385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/local/sync_file_system_backend.h"
202385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/sync_file_metadata.h"
212385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/sync_status_code.h"
222385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/syncable_file_system_util.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
2490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/browser/blob/mock_blob_url_request_context.h"
2590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/browser/fileapi/file_system_context.h"
26868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "webkit/browser/fileapi/file_system_operation_runner.h"
2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/browser/fileapi/isolated_context.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define FPL FILE_PATH_LITERAL
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using fileapi::FileSystemContext;
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using fileapi::FileSystemURL;
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using fileapi::FileSystemURLSet;
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This tests LocalFileSyncContext behavior in multi-thread /
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// multi-file-system-context environment.
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Basic combined tests (single-thread / single-file-system-context)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// that involve LocalFileSyncContext are also in
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// syncable_file_system_unittests.cc.
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace sync_file_system {
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kOrigin1[] = "http://example.com";
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kOrigin2[] = "http://chromium.org";
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class LocalFileSyncContextTest : public testing::Test {
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LocalFileSyncContextTest()
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : status_(SYNC_FILE_ERROR_FAILED),
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        file_error_(base::PLATFORM_FILE_ERROR_FAILED),
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        async_modify_finished_(false),
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        has_inflight_prepare_for_sync_(false) {}
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() OVERRIDE {
57868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    RegisterSyncableFileSystem();
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    io_thread_.reset(new base::Thread("Thread_IO"));
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    io_thread_->StartWithOptions(
61b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    file_thread_.reset(new base::Thread("Thread_File"));
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    file_thread_->Start();
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    ui_task_runner_ = base::MessageLoop::current()->message_loop_proxy();
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    io_task_runner_ = io_thread_->message_loop_proxy();
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    file_task_runner_ = file_thread_->message_loop_proxy();
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void TearDown() OVERRIDE {
72868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    RevokeSyncableFileSystem();
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    io_thread_->Stop();
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    file_thread_->Stop();
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void StartPrepareForSync(FileSystemContext* file_system_context,
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           const FileSystemURL& url,
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           SyncFileMetadata* metadata,
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           FileChangeList* changes) {
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(changes != NULL);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_FALSE(has_inflight_prepare_for_sync_);
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    status_ = SYNC_STATUS_UNKNOWN;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    has_inflight_prepare_for_sync_ = true;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sync_context_->PrepareForSync(
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        file_system_context,
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        url,
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&LocalFileSyncContextTest::DidPrepareForSync,
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   base::Unretained(this), metadata, changes));
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SyncStatusCode PrepareForSync(FileSystemContext* file_system_context,
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                const FileSystemURL& url,
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                SyncFileMetadata* metadata,
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                FileChangeList* changes) {
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StartPrepareForSync(file_system_context, url, metadata, changes);
97b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    base::MessageLoop::current()->Run();
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return status_;
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Closure GetPrepareForSyncClosure(FileSystemContext* file_system_context,
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         const FileSystemURL& url,
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         SyncFileMetadata* metadata,
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         FileChangeList* changes) {
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return base::Bind(&LocalFileSyncContextTest::StartPrepareForSync,
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      base::Unretained(this),
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      base::Unretained(file_system_context),
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      url, metadata, changes);
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DidPrepareForSync(SyncFileMetadata* metadata_out,
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         FileChangeList* changes_out,
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         SyncStatusCode status,
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         const LocalFileSyncInfo& sync_file_info) {
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(ui_task_runner_->RunsTasksOnCurrentThread());
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    has_inflight_prepare_for_sync_ = false;
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    status_ = status;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *metadata_out = sync_file_info.metadata;
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *changes_out = sync_file_info.changes;
120b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    base::MessageLoop::current()->Quit();
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SyncStatusCode ApplyRemoteChange(FileSystemContext* file_system_context,
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   const FileChange& change,
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   const base::FilePath& local_path,
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   const FileSystemURL& url,
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   SyncFileType expected_file_type) {
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SCOPED_TRACE(testing::Message() << "ApplyChange for " <<
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 url.DebugString());
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // First we should call PrepareForSync to disable writing.
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SyncFileMetadata metadata;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FileChangeList changes;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(SYNC_STATUS_OK,
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              PrepareForSync(file_system_context, url, &metadata, &changes));
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(expected_file_type, metadata.file_type);
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    status_ = SYNC_STATUS_UNKNOWN;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sync_context_->ApplyRemoteChange(
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        file_system_context, change, local_path, url,
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&LocalFileSyncContextTest::DidApplyRemoteChange,
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   base::Unretained(this)));
143b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    base::MessageLoop::current()->Run();
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return status_;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DidApplyRemoteChange(SyncStatusCode status) {
148b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    base::MessageLoop::current()->Quit();
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    status_ = status;
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void StartModifyFileOnIOThread(CannedSyncableFileSystem* file_system,
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 const FileSystemURL& url) {
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    async_modify_finished_ = false;
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(file_system != NULL);
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!io_task_runner_->RunsTasksOnCurrentThread()) {
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ASSERT_TRUE(ui_task_runner_->RunsTasksOnCurrentThread());
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      io_task_runner_->PostTask(
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          FROM_HERE,
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base::Bind(&LocalFileSyncContextTest::StartModifyFileOnIOThread,
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     base::Unretained(this), file_system, url));
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(io_task_runner_->RunsTasksOnCurrentThread());
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    file_error_ = base::PLATFORM_FILE_ERROR_FAILED;
166868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    file_system->operation_runner()->Truncate(
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        url, 1, base::Bind(&LocalFileSyncContextTest::DidModifyFile,
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           base::Unretained(this)));
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::PlatformFileError WaitUntilModifyFileIsDone() {
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (!async_modify_finished_)
173b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      base::MessageLoop::current()->RunUntilIdle();
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return file_error_;
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DidModifyFile(base::PlatformFileError error) {
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ui_task_runner_->RunsTasksOnCurrentThread()) {
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ASSERT_TRUE(io_task_runner_->RunsTasksOnCurrentThread());
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ui_task_runner_->PostTask(
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          FROM_HERE,
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base::Bind(&LocalFileSyncContextTest::DidModifyFile,
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     base::Unretained(this), error));
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(ui_task_runner_->RunsTasksOnCurrentThread());
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    file_error_ = error;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    async_modify_finished_ = true;
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
191eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ScopedEnableSyncFSDirectoryOperation enable_directory_operation_;
192eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // These need to remain until the very end.
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<base::Thread> io_thread_;
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<base::Thread> file_thread_;
196b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  base::MessageLoop loop_;
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_;
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<base::SingleThreadTaskRunner> file_task_runner_;
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<LocalFileSyncContext> sync_context_;
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SyncStatusCode status_;
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::PlatformFileError file_error_;
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool async_modify_finished_;
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool has_inflight_prepare_for_sync_;
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(LocalFileSyncContextTest, ConstructAndDestruct) {
211868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  sync_context_ =
212868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new LocalFileSyncContext(ui_task_runner_.get(), io_task_runner_.get());
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_context_->ShutdownOnUIThread();
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(LocalFileSyncContextTest, InitializeFileSystemContext) {
217868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CannedSyncableFileSystem file_system(GURL(kOrigin1),
218868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                       io_task_runner_.get(),
219868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                       file_task_runner_.get());
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system.SetUp();
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
222868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  sync_context_ =
223868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new LocalFileSyncContext(ui_task_runner_.get(), io_task_runner_.get());
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Initializes file_system using |sync_context_|.
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK,
227868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            file_system.MaybeInitializeFileSystemContext(sync_context_.get()));
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure everything's set up for file_system to be able to handle
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // syncable file system operations.
231a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_TRUE(file_system.backend()->sync_context() != NULL);
232a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_TRUE(file_system.backend()->change_tracker() != NULL);
233a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(sync_context_.get(), file_system.backend()->sync_context());
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Calling MaybeInitialize for the same context multiple times must be ok.
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK,
237868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            file_system.MaybeInitializeFileSystemContext(sync_context_.get()));
238a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(sync_context_.get(), file_system.backend()->sync_context());
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Opens the file_system, perform some operation and see if the change tracker
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // correctly captures the change.
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(base::PLATFORM_FILE_OK, file_system.OpenFileSystem());
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileSystemURL kURL(file_system.URL("foo"));
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(base::PLATFORM_FILE_OK, file_system.CreateFile(kURL));
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileSystemURLSet urls;
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system.GetChangedURLsInTracker(&urls);
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1U, urls.size());
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(ContainsKey(urls, kURL));
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Finishing the test.
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_context_->ShutdownOnUIThread();
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system.TearDown();
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(LocalFileSyncContextTest, MultipleFileSystemContexts) {
258868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CannedSyncableFileSystem file_system1(GURL(kOrigin1),
259868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                        io_task_runner_.get(),
260868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                        file_task_runner_.get());
261868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CannedSyncableFileSystem file_system2(GURL(kOrigin2),
262868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                        io_task_runner_.get(),
263868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                        file_task_runner_.get());
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system1.SetUp();
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system2.SetUp();
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
267868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  sync_context_ =
268868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new LocalFileSyncContext(ui_task_runner_.get(), io_task_runner_.get());
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Initializes file_system1 and file_system2.
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK,
272868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            file_system1.MaybeInitializeFileSystemContext(sync_context_.get()));
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK,
274868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            file_system2.MaybeInitializeFileSystemContext(sync_context_.get()));
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(base::PLATFORM_FILE_OK, file_system1.OpenFileSystem());
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(base::PLATFORM_FILE_OK, file_system2.OpenFileSystem());
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileSystemURL kURL1(file_system1.URL("foo"));
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileSystemURL kURL2(file_system2.URL("bar"));
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creates a file in file_system1.
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(base::PLATFORM_FILE_OK, file_system1.CreateFile(kURL1));
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // file_system1's tracker must have recorded the change.
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileSystemURLSet urls;
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system1.GetChangedURLsInTracker(&urls);
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1U, urls.size());
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(ContainsKey(urls, kURL1));
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // file_system1's tracker must have no change.
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  urls.clear();
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system2.GetChangedURLsInTracker(&urls);
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(urls.empty());
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creates a directory in file_system2.
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(base::PLATFORM_FILE_OK, file_system2.CreateDirectory(kURL2));
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // file_system1's tracker must have the change for kURL1 as before.
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  urls.clear();
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system1.GetChangedURLsInTracker(&urls);
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1U, urls.size());
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(ContainsKey(urls, kURL1));
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // file_system2's tracker now must have the change for kURL2.
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  urls.clear();
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system2.GetChangedURLsInTracker(&urls);
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1U, urls.size());
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(ContainsKey(urls, kURL2));
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SyncFileMetadata metadata;
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileChangeList changes;
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK,
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            PrepareForSync(file_system1.file_system_context(), kURL1,
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           &metadata, &changes));
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1U, changes.size());
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(changes.list().back().IsFile());
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(changes.list().back().IsAddOrUpdate());
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SYNC_FILE_TYPE_FILE, metadata.file_type);
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, metadata.size);
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  changes.clear();
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK,
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            PrepareForSync(file_system2.file_system_context(), kURL2,
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           &metadata, &changes));
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1U, changes.size());
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(changes.list().back().IsFile());
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(changes.list().back().IsAddOrUpdate());
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SYNC_FILE_TYPE_DIRECTORY, metadata.file_type);
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, metadata.size);
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_context_->ShutdownOnUIThread();
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_context_ = NULL;
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system1.TearDown();
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system2.TearDown();
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
339a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// LocalFileSyncContextTest.PrepareSyncWhileWriting is flaky on android.
340a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// http://crbug.com/239793
341a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#if defined(OS_ANDROID)
342a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#define MAYBE_PrepareSyncWhileWriting DISABLED_PrepareSyncWhileWriting
343a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#else
344a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#define MAYBE_PrepareSyncWhileWriting PrepareSyncWhileWriting
345a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#endif
346a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)TEST_F(LocalFileSyncContextTest, MAYBE_PrepareSyncWhileWriting) {
347868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CannedSyncableFileSystem file_system(GURL(kOrigin1),
348868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                       io_task_runner_.get(),
349868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                       file_task_runner_.get());
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system.SetUp();
351868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  sync_context_ =
352868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new LocalFileSyncContext(ui_task_runner_.get(), io_task_runner_.get());
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK,
354868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            file_system.MaybeInitializeFileSystemContext(sync_context_.get()));
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(base::PLATFORM_FILE_OK, file_system.OpenFileSystem());
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileSystemURL kURL1(file_system.URL("foo"));
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creates a file in file_system.
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(base::PLATFORM_FILE_OK, file_system.CreateFile(kURL1));
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Kick file write on IO thread.
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartModifyFileOnIOThread(&file_system, kURL1);
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Until the operation finishes PrepareForSync should return BUSY error.
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SyncFileMetadata metadata;
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  metadata.file_type = SYNC_FILE_TYPE_UNKNOWN;
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileChangeList changes;
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_FILE_BUSY,
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            PrepareForSync(file_system.file_system_context(),
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           kURL1, &metadata, &changes));
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SYNC_FILE_TYPE_FILE, metadata.file_type);
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Register PrepareForSync method to be invoked when kURL1 becomes
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // syncable. (Actually this may be done after all operations are done
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // on IO thread in this test.)
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  metadata.file_type = SYNC_FILE_TYPE_UNKNOWN;
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  changes.clear();
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_context_->RegisterURLForWaitingSync(
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kURL1, GetPrepareForSyncClosure(file_system.file_system_context(),
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      kURL1, &metadata, &changes));
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Wait for the completion.
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(base::PLATFORM_FILE_OK, WaitUntilModifyFileIsDone());
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The PrepareForSync must have been started; wait until DidPrepareForSync
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // is done.
389b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  base::MessageLoop::current()->Run();
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(has_inflight_prepare_for_sync_);
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now PrepareForSync should have run and returned OK.
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, status_);
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1U, changes.size());
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(changes.list().back().IsFile());
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(changes.list().back().IsAddOrUpdate());
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SYNC_FILE_TYPE_FILE, metadata.file_type);
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, metadata.size);
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_context_->ShutdownOnUIThread();
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_context_ = NULL;
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system.TearDown();
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(LocalFileSyncContextTest, ApplyRemoteChangeForDeletion) {
406868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CannedSyncableFileSystem file_system(GURL(kOrigin1),
407868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                       io_task_runner_.get(),
408868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                       file_task_runner_.get());
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system.SetUp();
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
411868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  sync_context_ =
412868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new LocalFileSyncContext(ui_task_runner_.get(), io_task_runner_.get());
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(SYNC_STATUS_OK,
414868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            file_system.MaybeInitializeFileSystemContext(sync_context_.get()));
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(base::PLATFORM_FILE_OK, file_system.OpenFileSystem());
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Record the initial usage (likely 0).
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 initial_usage = -1;
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 quota = -1;
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(quota::kQuotaStatusOk,
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system.GetUsageAndQuota(&initial_usage, &quota));
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a file and directory in the file_system.
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileSystemURL kFile(file_system.URL("file"));
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileSystemURL kDir(file_system.URL("dir"));
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileSystemURL kChild(file_system.URL("dir/child"));
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(base::PLATFORM_FILE_OK, file_system.CreateFile(kFile));
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(base::PLATFORM_FILE_OK, file_system.CreateDirectory(kDir));
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(base::PLATFORM_FILE_OK, file_system.CreateFile(kChild));
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // file_system's change tracker must have recorded the creation.
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileSystemURLSet urls;
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system.GetChangedURLsInTracker(&urls);
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(3U, urls.size());
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(ContainsKey(urls, kFile));
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(ContainsKey(urls, kDir));
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(ContainsKey(urls, kChild));
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (FileSystemURLSet::iterator iter = urls.begin();
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       iter != urls.end(); ++iter) {
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    file_system.ClearChangeForURLInTracker(*iter);
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // At this point the usage must be greater than the initial usage.
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 new_usage = -1;
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(quota::kQuotaStatusOk,
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system.GetUsageAndQuota(&new_usage, &quota));
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_GT(new_usage, initial_usage);
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now let's apply remote deletion changes.
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileChange change(FileChange::FILE_CHANGE_DELETE,
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    SYNC_FILE_TYPE_FILE);
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK,
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ApplyRemoteChange(file_system.file_system_context(),
4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              change, base::FilePath(), kFile,
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              SYNC_FILE_TYPE_FILE));
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The implementation doesn't check file type for deletion, and it must be ok
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // even if we don't know if the deletion change was for a file or a directory.
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  change = FileChange(FileChange::FILE_CHANGE_DELETE,
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      SYNC_FILE_TYPE_UNKNOWN);
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK,
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ApplyRemoteChange(file_system.file_system_context(),
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              change, base::FilePath(), kDir,
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              SYNC_FILE_TYPE_DIRECTORY));
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check the directory/files are deleted successfully.
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND,
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system.FileExists(kFile));
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND,
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system.DirectoryExists(kDir));
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND,
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system.FileExists(kChild));
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The changes applied by ApplyRemoteChange should not be recorded in
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the change tracker.
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  urls.clear();
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system.GetChangedURLsInTracker(&urls);
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(urls.empty());
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The quota usage data must have reflected the deletion.
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(quota::kQuotaStatusOk,
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system.GetUsageAndQuota(&new_usage, &quota));
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(new_usage, initial_usage);
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_context_->ShutdownOnUIThread();
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_context_ = NULL;
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system.TearDown();
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(LocalFileSyncContextTest, ApplyRemoteChangeForAddOrUpdate) {
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ScopedTempDir temp_dir;
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CannedSyncableFileSystem file_system(GURL(kOrigin1),
496868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                       io_task_runner_.get(),
497868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                       file_task_runner_.get());
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system.SetUp();
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
500868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  sync_context_ =
501868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new LocalFileSyncContext(ui_task_runner_.get(), io_task_runner_.get());
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(SYNC_STATUS_OK,
503868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            file_system.MaybeInitializeFileSystemContext(sync_context_.get()));
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(base::PLATFORM_FILE_OK, file_system.OpenFileSystem());
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileSystemURL kFile1(file_system.URL("file1"));
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileSystemURL kFile2(file_system.URL("file2"));
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileSystemURL kDir(file_system.URL("dir"));
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kTestFileData0[] = "0123456789";
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kTestFileData1[] = "Lorem ipsum!";
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kTestFileData2[] = "This is sample test data.";
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create kFile1 and populate it with kTestFileData0.
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(base::PLATFORM_FILE_OK, file_system.CreateFile(kFile1));
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(static_cast<int64>(arraysize(kTestFileData0) - 1),
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system.WriteString(kFile1, kTestFileData0));
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // kFile2 and kDir are not there yet.
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND,
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system.FileExists(kFile2));
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND,
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system.DirectoryExists(kDir));
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // file_system's change tracker must have recorded the creation.
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileSystemURLSet urls;
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system.GetChangedURLsInTracker(&urls);
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1U, urls.size());
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(ContainsKey(urls, kFile1));
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system.ClearChangeForURLInTracker(*urls.begin());
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Prepare temporary files which represent the remote file data.
5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::FilePath kFilePath1(temp_dir.path().Append(FPL("file1")));
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::FilePath kFilePath2(temp_dir.path().Append(FPL("file2")));
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(static_cast<int>(arraysize(kTestFileData1) - 1),
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_util::WriteFile(kFilePath1, kTestFileData1,
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 arraysize(kTestFileData1) - 1));
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(static_cast<int>(arraysize(kTestFileData2) - 1),
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_util::WriteFile(kFilePath2, kTestFileData2,
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 arraysize(kTestFileData2) - 1));
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Record the usage.
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 usage = -1, new_usage = -1;
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 quota = -1;
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(quota::kQuotaStatusOk,
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system.GetUsageAndQuota(&usage, &quota));
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Here in the local filesystem we have:
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  * kFile1 with kTestFileData0
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // In the remote side let's assume we have:
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  * kFile1 with kTestFileData1
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  * kFile2 with kTestFileData2
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  * kDir
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // By calling ApplyChange's:
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  * kFile1 will be updated to have kTestFileData1
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  * kFile2 will be created
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  * kDir will be created
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Apply the remote change to kFile1 (which will update the file).
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileChange change(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    SYNC_FILE_TYPE_FILE);
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK,
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ApplyRemoteChange(file_system.file_system_context(),
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              change, kFilePath1, kFile1,
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              SYNC_FILE_TYPE_FILE));
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check if the usage has been increased by (kTestFileData1 - kTestFileData0).
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int updated_size =
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      arraysize(kTestFileData1) - arraysize(kTestFileData0);
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(quota::kQuotaStatusOk,
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system.GetUsageAndQuota(&new_usage, &quota));
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(updated_size, new_usage - usage);
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Apply remote changes to kFile2 and kDir (should create a file and
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // directory respectively).
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // They are non-existent yet so their expected file type (the last
5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // parameter of ApplyRemoteChange) are
5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // SYNC_FILE_TYPE_UNKNOWN.
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  change = FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      SYNC_FILE_TYPE_FILE);
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK,
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ApplyRemoteChange(file_system.file_system_context(),
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              change, kFilePath2, kFile2,
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              SYNC_FILE_TYPE_UNKNOWN));
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  change = FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      SYNC_FILE_TYPE_DIRECTORY);
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK,
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ApplyRemoteChange(file_system.file_system_context(),
5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              change, base::FilePath(), kDir,
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              SYNC_FILE_TYPE_UNKNOWN));
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
596c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Calling ApplyRemoteChange with different file type should be handled as
597c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // overwrite.
598c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  change =
599c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE, SYNC_FILE_TYPE_FILE);
600c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK,
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ApplyRemoteChange(file_system.file_system_context(),
602c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              change,
603c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              kFilePath1,
604c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              kDir,
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              SYNC_FILE_TYPE_DIRECTORY));
606c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(base::PLATFORM_FILE_OK, file_system.FileExists(kDir));
607c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
608c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  change = FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
609c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                      SYNC_FILE_TYPE_DIRECTORY);
610c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK,
611c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            ApplyRemoteChange(file_system.file_system_context(),
612c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              change,
613c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              kFilePath1,
614c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              kDir,
615c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              SYNC_FILE_TYPE_FILE));
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creating a file/directory must have increased the usage more than
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the size of kTestFileData2.
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  new_usage = usage;
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(quota::kQuotaStatusOk,
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_system.GetUsageAndQuota(&new_usage, &quota));
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_GT(new_usage,
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            static_cast<int64>(usage + arraysize(kTestFileData2) - 1));
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The changes applied by ApplyRemoteChange should not be recorded in
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the change tracker.
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  urls.clear();
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system.GetChangedURLsInTracker(&urls);
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(urls.empty());
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure all three files/directory exist.
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(base::PLATFORM_FILE_OK, file_system.FileExists(kFile1));
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(base::PLATFORM_FILE_OK, file_system.FileExists(kFile2));
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(base::PLATFORM_FILE_OK, file_system.DirectoryExists(kDir));
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_context_->ShutdownOnUIThread();
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_system.TearDown();
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
640c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(LocalFileSyncContextTest, ApplyRemoteChangeForAddOrUpdate_NoParent) {
641c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::ScopedTempDir temp_dir;
642c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
643c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
644868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CannedSyncableFileSystem file_system(GURL(kOrigin1),
645868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                       io_task_runner_.get(),
646868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                       file_task_runner_.get());
647c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  file_system.SetUp();
648c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
649868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  sync_context_ =
650868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new LocalFileSyncContext(ui_task_runner_.get(), io_task_runner_.get());
651c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(SYNC_STATUS_OK,
652868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            file_system.MaybeInitializeFileSystemContext(sync_context_.get()));
653c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(base::PLATFORM_FILE_OK, file_system.OpenFileSystem());
654c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
655c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const char kTestFileData[] = "Lorem ipsum!";
656c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const FileSystemURL kDir(file_system.URL("dir"));
657c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const FileSystemURL kFile(file_system.URL("dir/file"));
658c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
659c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Either kDir or kFile not exist yet.
660c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, file_system.FileExists(kDir));
661c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, file_system.FileExists(kFile));
662c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
663c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Prepare a temporary file which represents remote file data.
664c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const base::FilePath kFilePath(temp_dir.path().Append(FPL("file")));
665c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(static_cast<int>(arraysize(kTestFileData) - 1),
666c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            file_util::WriteFile(kFilePath, kTestFileData,
667c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 arraysize(kTestFileData) - 1));
668c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
669c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Calling ApplyChange's with kFilePath should create
670c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // kFile along with kDir.
671c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  FileChange change(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
672c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    SYNC_FILE_TYPE_FILE);
673c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK,
674c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            ApplyRemoteChange(file_system.file_system_context(),
675c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              change, kFilePath, kFile,
676c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              SYNC_FILE_TYPE_UNKNOWN));
677c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
678c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The changes applied by ApplyRemoteChange should not be recorded in
679c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // the change tracker.
680c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  FileSystemURLSet urls;
681c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  urls.clear();
682c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  file_system.GetChangedURLsInTracker(&urls);
683c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(urls.empty());
684c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
685c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Make sure kDir and kFile are created by ApplyRemoteChange.
686c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(base::PLATFORM_FILE_OK, file_system.FileExists(kFile));
687c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(base::PLATFORM_FILE_OK, file_system.DirectoryExists(kDir));
688c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
689c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  sync_context_->ShutdownOnUIThread();
690c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  file_system.TearDown();
691c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
692c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace sync_file_system
694