sync_file_system_service_unittest.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <vector>
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/basictypes.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/run_loop.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/stl_util.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/synchronization/waitable_event.h"
122385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/local/canned_syncable_file_system.h"
132385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/local/local_file_sync_context.h"
142385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/local/local_file_sync_service.h"
152385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/local/mock_sync_status_observer.h"
162385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/local/sync_file_system_backend.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/sync_file_system/mock_remote_file_sync_service.h"
182385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/sync_callbacks.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/sync_file_system/sync_event_observer.h"
202385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/sync_file_metadata.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/sync_file_system/sync_file_system_service.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/sync_file_system/sync_file_system_test_util.h"
232385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/sync_status_code.h"
242385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/syncable_file_system_util.h"
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/base/testing_profile.h"
26a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#include "content/public/browser/browser_thread.h"
27a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#include "content/public/test/test_browser_thread_bundle.h"
28a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#include "content/public/test/test_utils.h"
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "third_party/leveldatabase/src/helpers/memenv/memenv.h"
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "third_party/leveldatabase/src/include/leveldb/env.h"
3290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/browser/fileapi/file_system_context.h"
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
34a3f7b4e666c476898878fa745f637129375cd889Ben Murdochusing content::BrowserThread;
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using fileapi::FileSystemURL;
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using fileapi::FileSystemURLSet;
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using ::testing::AnyNumber;
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using ::testing::AtLeast;
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using ::testing::InSequence;
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using ::testing::InvokeWithoutArgs;
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using ::testing::Return;
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using ::testing::StrictMock;
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using ::testing::_;
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace sync_file_system {
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kOrigin[] = "http://example.com";
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template <typename R> struct AssignTrait {
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  typedef const R& ArgumentType;
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template <> struct AssignTrait<SyncFileStatus> {
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  typedef SyncFileStatus ArgumentType;
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template <typename R>
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AssignValueAndQuit(base::RunLoop* run_loop,
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        SyncStatusCode* status_out, R* value_out,
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        SyncStatusCode status,
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        typename AssignTrait<R>::ArgumentType value) {
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(status_out);
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(value_out);
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(run_loop);
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *status_out = status;
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *value_out = value;
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  run_loop->Quit();
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This is called on IO thread.
73a3f7b4e666c476898878fa745f637129375cd889Ben Murdochvoid VerifyFileError(base::RunLoop* run_loop,
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     base::File::Error error) {
75a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  DCHECK(run_loop);
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK, error);
77a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  run_loop->Quit();
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class MockSyncEventObserver : public SyncEventObserver {
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockSyncEventObserver() {}
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~MockSyncEventObserver() {}
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MOCK_METHOD3(OnSyncStateUpdated,
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               void(const GURL& app_origin,
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    SyncServiceState state,
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    const std::string& description));
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MOCK_METHOD4(OnFileSynced,
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               void(const fileapi::FileSystemURL& url,
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    SyncFileStatus status,
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    SyncAction action,
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    SyncDirection direction));
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ACTION_P3(NotifyStateAndCallback,
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          mock_remote_service, service_state, operation_status) {
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mock_remote_service->NotifyRemoteServiceStateUpdated(
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      service_state, "Test event.");
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::MessageLoopProxy::current()->PostTask(
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE, base::Bind(arg1, operation_status));
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ACTION_P(RecordState, states) {
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  states->push_back(arg1);
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ACTION_P(MockStatusCallback, status) {
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::MessageLoopProxy::current()->PostTask(
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE, base::Bind(arg4, status));
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ACTION_P2(MockSyncFileCallback, status, url) {
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::MessageLoopProxy::current()->PostTask(
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE, base::Bind(arg0, status, url));
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class SyncFileSystemServiceTest : public testing::Test {
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
122a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  SyncFileSystemServiceTest()
123a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      : thread_bundle_(content::TestBrowserThreadBundle::REAL_FILE_THREAD |
124a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                       content::TestBrowserThreadBundle::REAL_IO_THREAD) {}
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void SetUp() OVERRIDE {
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    in_memory_env_.reset(leveldb::NewMemEnv(leveldb::Env::Default()));
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    file_system_.reset(new CannedSyncableFileSystem(
129868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        GURL(kOrigin),
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        in_memory_env_.get(),
131a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch        BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO),
132a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch        BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE)));
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    scoped_ptr<LocalFileSyncService> local_service =
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        LocalFileSyncService::CreateForTesting(&profile_, in_memory_env_.get());
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    remote_service_ = new StrictMock<MockRemoteFileSyncService>;
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sync_service_.reset(new SyncFileSystemService(&profile_));
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(*mock_remote_service(),
140a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                AddServiceObserver(_)).Times(1);
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(*mock_remote_service(),
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                AddFileStatusObserver(sync_service_.get())).Times(1);
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(*mock_remote_service(),
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                GetLocalChangeProcessor())
145a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        .WillRepeatedly(Return(&local_change_processor_));
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(*mock_remote_service(),
1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                SetRemoteChangeProcessor(local_service.get())).Times(1);
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sync_service_->Initialize(
1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        local_service.Pass(),
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        scoped_ptr<RemoteFileSyncService>(remote_service_));
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Disable auto sync by default.
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(*mock_remote_service(), SetSyncEnabled(false)).Times(1);
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sync_service_->SetSyncEnabledForTesting(false);
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    file_system_->SetUp(CannedSyncableFileSystem::QUOTA_ENABLED);
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void TearDown() OVERRIDE {
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sync_service_->Shutdown();
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    file_system_->TearDown();
163868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    RevokeSyncableFileSystem();
164a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    content::RunAllPendingInMessageLoop(BrowserThread::FILE);
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void InitializeApp() {
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::RunLoop run_loop;
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SyncStatusCode status = SYNC_STATUS_UNKNOWN;
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(*mock_remote_service(),
17258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                RegisterOrigin(GURL(kOrigin), _)).Times(1);
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // GetCurrentState may be called when a remote or local sync is scheduled
17568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // by change notifications or by a timer.
17668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_CALL(*mock_remote_service(), GetCurrentState())
17768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        .Times(AnyNumber())
17868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        .WillRepeatedly(Return(REMOTE_SERVICE_OK));
17968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sync_service_->InitializeForApp(
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        file_system_->file_system_context(),
182868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        GURL(kOrigin),
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        AssignAndQuitCallback(&run_loop, &status));
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    run_loop.Run();
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(SYNC_STATUS_OK, status);
1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(base::File::FILE_OK, file_system_->OpenFileSystem());
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Calls InitializeForApp after setting up the mock remote service to
19158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // perform following when RegisterOrigin is called:
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //  1. Notify RemoteFileSyncService's observers of |state_to_notify|
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //  2. Run the given callback with |status_to_return|.
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // ..and verifies if following conditions are met:
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //  1. The SyncEventObserver of the service is called with
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //     |expected_states| service state values.
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //  2. InitializeForApp's callback is called with |expected_status|
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void InitializeAppForObserverTest(
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      RemoteServiceState state_to_notify,
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      SyncStatusCode status_to_return,
2023240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      const std::vector<SyncServiceState>& expected_states,
203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      SyncStatusCode expected_status) {
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    StrictMock<MockSyncEventObserver> event_observer;
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sync_service_->AddSyncEventObserver(&event_observer);
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EnableSync();
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_CALL(*mock_remote_service(), GetCurrentState())
21068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        .Times(AnyNumber())
21168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        .WillRepeatedly(Return(state_to_notify));
21268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(*mock_remote_service(),
21458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                RegisterOrigin(GURL(kOrigin), _))
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        .WillOnce(NotifyStateAndCallback(mock_remote_service(),
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         state_to_notify,
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         status_to_return));
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    std::vector<SyncServiceState> actual_states;
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(event_observer, OnSyncStateUpdated(GURL(), _, _))
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        .WillRepeatedly(RecordState(&actual_states));
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SyncStatusCode actual_status = SYNC_STATUS_UNKNOWN;
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::RunLoop run_loop;
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sync_service_->InitializeForApp(
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        file_system_->file_system_context(),
227868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        GURL(kOrigin),
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        AssignAndQuitCallback(&run_loop, &actual_status));
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    run_loop.Run();
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(expected_status, actual_status);
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_EQ(expected_states.size(), actual_states.size());
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (size_t i = 0; i < actual_states.size(); ++i)
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(expected_states[i], actual_states[i]);
23568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
23668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    sync_service_->RemoveSyncEventObserver(&event_observer);
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL URL(const std::string& path) const {
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return file_system_->URL(path);
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StrictMock<MockRemoteFileSyncService>* mock_remote_service() {
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return remote_service_;
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StrictMock<MockLocalChangeProcessor>* mock_local_change_processor() {
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return &local_change_processor_;
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void EnableSync() {
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(*mock_remote_service(), SetSyncEnabled(true)).Times(1);
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sync_service_->SetSyncEnabledForTesting(true);
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
256eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ScopedEnableSyncFSDirectoryOperation enable_directory_operation_;
257eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
258a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  content::TestBrowserThreadBundle thread_bundle_;
2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<leveldb::Env> in_memory_env_;
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestingProfile profile_;
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<CannedSyncableFileSystem> file_system_;
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Their ownerships are transferred to SyncFileSystemService.
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StrictMock<MockRemoteFileSyncService>* remote_service_;
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StrictMock<MockLocalChangeProcessor> local_change_processor_;
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SyncFileSystemService> sync_service_;
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncFileSystemServiceTest, InitializeForApp) {
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  InitializeApp();
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncFileSystemServiceTest, InitializeForAppSuccess) {
275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::vector<SyncServiceState> expected_states;
276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  expected_states.push_back(SYNC_SERVICE_RUNNING);
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  InitializeAppForObserverTest(
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      REMOTE_SERVICE_OK,
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      SYNC_STATUS_OK,
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      expected_states,
282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      SYNC_STATUS_OK);
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncFileSystemServiceTest, InitializeForAppWithNetworkFailure) {
286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::vector<SyncServiceState> expected_states;
287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  expected_states.push_back(SYNC_SERVICE_TEMPORARY_UNAVAILABLE);
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Notify REMOTE_SERVICE_TEMPORARY_UNAVAILABLE and callback with
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // SYNC_STATUS_NETWORK_ERROR.  This should let the
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // InitializeApp fail.
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  InitializeAppForObserverTest(
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      REMOTE_SERVICE_TEMPORARY_UNAVAILABLE,
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      SYNC_STATUS_NETWORK_ERROR,
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      expected_states,
296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      SYNC_STATUS_NETWORK_ERROR);
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncFileSystemServiceTest, InitializeForAppWithError) {
300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::vector<SyncServiceState> expected_states;
301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  expected_states.push_back(SYNC_SERVICE_DISABLED);
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Notify REMOTE_SERVICE_DISABLED and callback with
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // SYNC_STATUS_FAILED.  This should let the InitializeApp fail.
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  InitializeAppForObserverTest(
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      REMOTE_SERVICE_DISABLED,
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      SYNC_STATUS_FAILED,
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      expected_states,
309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      SYNC_STATUS_FAILED);
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(SyncFileSystemServiceTest, SimpleLocalSyncFlow) {
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  InitializeApp();
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StrictMock<MockSyncStatusObserver> status_observer;
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EnableSync();
318a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  file_system_->backend()->sync_context()->
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      set_mock_notify_changes_duration_in_sec(0);
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  file_system_->AddSyncStatusObserver(&status_observer);
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We'll test one local sync for this file.
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const FileSystemURL kFile(file_system_->URL("foo"));
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::RunLoop run_loop;
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // We should get called OnSyncEnabled and OnWriteEnabled on kFile as in:
3284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // 1. OnWriteEnabled when PrepareForSync(SYNC_SHARED) is finished and
3294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  //    the target file is unlocked for writing
3304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // 2. OnSyncEnabled x 3 times; 1) when CreateFile is finished, 2) when
3314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  //    file is unlocked after PrepareForSync, and 3) when the sync is
3324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  //    finished.
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(status_observer, OnWriteEnabled(kFile))
3344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      .Times(AtLeast(1));
3354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  {
3374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    ::testing::InSequence sequence;
3384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    EXPECT_CALL(status_observer, OnSyncEnabled(kFile))
3394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        .Times(AtLeast(2));
3404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    EXPECT_CALL(status_observer, OnSyncEnabled(kFile))
3414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
3424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The local_change_processor's ApplyLocalChange should be called once
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // with ADD_OR_UPDATE change for TYPE_FILE.
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const FileChange change(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          SYNC_FILE_TYPE_FILE);
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*mock_local_change_processor(),
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              ApplyLocalChange(change, _, _, kFile, _))
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .WillOnce(MockStatusCallback(SYNC_STATUS_OK));
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK, file_system_->CreateFile(kFile));
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  run_loop.Run();
35568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
35668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  file_system_->RemoveSyncStatusObserver(&status_observer);
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncFileSystemServiceTest, SimpleRemoteSyncFlow) {
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  InitializeApp();
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EnableSync();
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::RunLoop run_loop;
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We expect a set of method calls for starting a remote sync.
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*mock_remote_service(), ProcessRemoteChange(_))
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This should trigger a remote sync.
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mock_remote_service()->NotifyRemoteChangeQueueUpdated(1);
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  run_loop.Run();
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncFileSystemServiceTest, SimpleSyncFlowWithFileBusy) {
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  InitializeApp();
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EnableSync();
380a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  file_system_->backend()->sync_context()->
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      set_mock_notify_changes_duration_in_sec(0);
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const FileSystemURL kFile(file_system_->URL("foo"));
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::RunLoop run_loop;
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    InSequence sequence;
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Return with SYNC_STATUS_FILE_BUSY once.
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(*mock_remote_service(), ProcessRemoteChange(_))
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        .WillOnce(MockSyncFileCallback(SYNC_STATUS_FILE_BUSY,
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                       kFile));
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // ProcessRemoteChange should be called again when the becomes
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // not busy.
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(*mock_remote_service(), ProcessRemoteChange(_))
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We might also see an activity for local sync as we're going to make
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // a local write operation on kFile.
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*mock_local_change_processor(),
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              ApplyLocalChange(_, _, _, kFile, _))
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .Times(AnyNumber());
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This should trigger a remote sync.
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mock_remote_service()->NotifyRemoteChangeQueueUpdated(1);
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Start a local operation on the same file (to make it BUSY).
411a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  base::RunLoop verify_file_error_run_loop;
412a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  BrowserThread::PostTask(
413a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      BrowserThread::IO,
414a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      FROM_HERE,
415a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      base::Bind(&CannedSyncableFileSystem::DoCreateFile,
416a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                 base::Unretained(file_system_.get()),
417a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                 kFile, base::Bind(&VerifyFileError,
418a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                                   &verify_file_error_run_loop)));
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  run_loop.Run();
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mock_remote_service()->NotifyRemoteChangeQueueUpdated(0);
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
424a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  verify_file_error_run_loop.Run();
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
42768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#if defined(THREAD_SANITIZER)
42868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// SyncFileSystemServiceTest.GetFileSyncStatus fails under ThreadSanitizer,
42968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// see http://crbug.com/294904.
43068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#define MAYBE_GetFileSyncStatus DISABLED_GetFileSyncStatus
43168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#else
43268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#define MAYBE_GetFileSyncStatus GetFileSyncStatus
43368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#endif
43468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)TEST_F(SyncFileSystemServiceTest, MAYBE_GetFileSyncStatus) {
4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  InitializeApp();
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const FileSystemURL kFile(file_system_->URL("foo"));
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SyncStatusCode status;
4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SyncFileStatus sync_file_status;
4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // 1. The file is not in conflicting nor in pending change state.
4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::RunLoop run_loop;
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(*mock_remote_service(), IsConflicting(kFile))
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        .WillOnce(Return(false));
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    status = SYNC_STATUS_UNKNOWN;
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sync_file_status = SYNC_FILE_STATUS_UNKNOWN;
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sync_service_->GetFileSyncStatus(
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        kFile,
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(&AssignValueAndQuit<SyncFileStatus>,
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   &run_loop, &status, &sync_file_status));
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    run_loop.Run();
4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(SYNC_STATUS_OK, status);
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(SYNC_FILE_STATUS_SYNCED, sync_file_status);
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // 2. Conflicting case.
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::RunLoop run_loop;
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(*mock_remote_service(), IsConflicting(kFile))
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        .WillOnce(Return(true));
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    status = SYNC_STATUS_UNKNOWN;
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sync_file_status = SYNC_FILE_STATUS_UNKNOWN;
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sync_service_->GetFileSyncStatus(
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        kFile,
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(&AssignValueAndQuit<SyncFileStatus>,
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   &run_loop, &status, &sync_file_status));
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    run_loop.Run();
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(SYNC_STATUS_OK, status);
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(SYNC_FILE_STATUS_CONFLICTING, sync_file_status);
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // 3. The file has pending local changes.
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
4805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(base::File::FILE_OK, file_system_->CreateFile(kFile));
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::RunLoop run_loop;
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(*mock_remote_service(), IsConflicting(kFile))
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        .WillOnce(Return(false));
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    status = SYNC_STATUS_UNKNOWN;
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sync_file_status = SYNC_FILE_STATUS_UNKNOWN;
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sync_service_->GetFileSyncStatus(
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        kFile,
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(&AssignValueAndQuit<SyncFileStatus>,
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   &run_loop, &status, &sync_file_status));
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    run_loop.Run();
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(SYNC_STATUS_OK, status);
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(SYNC_FILE_STATUS_HAS_PENDING_CHANGES, sync_file_status);
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // 4. The file has a conflict and pending local changes. In this case
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // we return SYNC_FILE_STATUS_CONFLICTING.
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
5015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(base::File::FILE_OK, file_system_->TruncateFile(kFile, 1U));
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::RunLoop run_loop;
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(*mock_remote_service(), IsConflicting(kFile))
5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        .WillOnce(Return(true));
5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    status = SYNC_STATUS_UNKNOWN;
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sync_file_status = SYNC_FILE_STATUS_UNKNOWN;
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sync_service_->GetFileSyncStatus(
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        kFile,
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(&AssignValueAndQuit<SyncFileStatus>,
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   &run_loop, &status, &sync_file_status));
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    run_loop.Run();
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(SYNC_STATUS_OK, status);
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(SYNC_FILE_STATUS_CONFLICTING, sync_file_status);
5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace sync_file_system
521