sync_engine_unittest.cc revision 010d83a9304c5a91596085d917d248abff47903a
1// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/sync_file_system/drive_backend/sync_engine.h"
6
7#include "base/files/scoped_temp_dir.h"
8#include "base/run_loop.h"
9#include "base/strings/stringprintf.h"
10#include "chrome/browser/drive/drive_uploader.h"
11#include "chrome/browser/drive/fake_drive_service.h"
12#include "chrome/browser/extensions/test_extension_service.h"
13#include "chrome/browser/sync_file_system/drive_backend/metadata_database.h"
14#include "chrome/browser/sync_file_system/drive_backend/metadata_database.pb.h"
15#include "chrome/browser/sync_file_system/drive_backend/sync_task.h"
16#include "chrome/browser/sync_file_system/drive_backend/sync_task_manager.h"
17#include "chrome/browser/sync_file_system/sync_file_system_test_util.h"
18#include "content/public/test/test_browser_thread_bundle.h"
19#include "extensions/common/extension.h"
20#include "extensions/common/extension_builder.h"
21#include "extensions/common/extension_set.h"
22#include "extensions/common/value_builder.h"
23#include "testing/gtest/include/gtest/gtest.h"
24#include "third_party/leveldatabase/src/helpers/memenv/memenv.h"
25#include "third_party/leveldatabase/src/include/leveldb/env.h"
26
27namespace sync_file_system {
28namespace drive_backend {
29
30namespace {
31
32const char kAppID[] = "app_id";
33
34void EmptyTask(SyncStatusCode status, const SyncStatusCallback& callback) {
35  base::MessageLoop::current()->PostTask(
36      FROM_HERE, base::Bind(callback, status));
37}
38
39}  // namespace
40
41class MockSyncTask : public ExclusiveTask {
42 public:
43  explicit MockSyncTask(bool used_network) {
44    set_used_network(used_network);
45  }
46  virtual ~MockSyncTask() {}
47
48  virtual void RunExclusive(const SyncStatusCallback& callback) OVERRIDE {
49    callback.Run(SYNC_STATUS_OK);
50  }
51
52 private:
53  DISALLOW_COPY_AND_ASSIGN(MockSyncTask);
54};
55
56class MockExtensionService : public TestExtensionService {
57 public:
58  MockExtensionService() {}
59  virtual ~MockExtensionService() {}
60
61  virtual const extensions::ExtensionSet* extensions() const OVERRIDE {
62    return &extensions_;
63  }
64
65  virtual void AddExtension(const extensions::Extension* extension) OVERRIDE {
66    extensions_.Insert(make_scoped_refptr(extension));
67  }
68
69  virtual const extensions::Extension* GetInstalledExtension(
70      const std::string& extension_id) const OVERRIDE {
71    return extensions_.GetByID(extension_id);
72  }
73
74  virtual bool IsExtensionEnabled(
75      const std::string& extension_id) const OVERRIDE {
76    return extensions_.Contains(extension_id) &&
77        !disabled_extensions_.Contains(extension_id);
78  }
79
80  void UninstallExtension(const std::string& extension_id) {
81    extensions_.Remove(extension_id);
82    disabled_extensions_.Remove(extension_id);
83  }
84
85  void DisableExtension(const std::string& extension_id) {
86    if (!IsExtensionEnabled(extension_id))
87      return;
88    const extensions::Extension* extension = extensions_.GetByID(extension_id);
89    disabled_extensions_.Insert(make_scoped_refptr(extension));
90  }
91
92 private:
93  extensions::ExtensionSet extensions_;
94  extensions::ExtensionSet disabled_extensions_;
95
96  DISALLOW_COPY_AND_ASSIGN(MockExtensionService);
97};
98
99class SyncEngineTest
100    : public testing::Test,
101      public base::SupportsWeakPtr<SyncEngineTest> {
102 public:
103  SyncEngineTest() {}
104  virtual ~SyncEngineTest() {}
105
106  virtual void SetUp() OVERRIDE {
107    ASSERT_TRUE(profile_dir_.CreateUniqueTempDir());
108    in_memory_env_.reset(leveldb::NewMemEnv(leveldb::Env::Default()));
109
110    extension_service_.reset(new MockExtensionService);
111    scoped_ptr<drive::DriveServiceInterface>
112        fake_drive_service(new drive::FakeDriveService);
113
114    sync_engine_.reset(new drive_backend::SyncEngine(
115        fake_drive_service.Pass(),
116        scoped_ptr<drive::DriveUploaderInterface>(),
117        base::MessageLoopProxy::current(),
118        NULL /* notification_manager */,
119        extension_service_.get(),
120        NULL /* signin_manager */));
121    sync_engine_->Initialize(profile_dir_.path(),
122                             base::MessageLoopProxy::current(),
123                             in_memory_env_.get());
124    sync_engine_->SetSyncEnabled(true);
125    base::RunLoop().RunUntilIdle();
126  }
127
128  virtual void TearDown() OVERRIDE {
129    sync_engine_.reset();
130    extension_service_.reset();
131    base::RunLoop().RunUntilIdle();
132  }
133
134  MockExtensionService* extension_service() { return extension_service_.get(); }
135  SyncEngine* sync_engine() { return sync_engine_.get(); }
136
137  void UpdateRegisteredApps() {
138    sync_engine_->UpdateRegisteredApps();
139  }
140
141  SyncTaskManager* GetSyncEngineTaskManager() {
142    return sync_engine_->GetSyncTaskManagerForTesting();
143  }
144
145  void CheckServiceState(SyncStatusCode expected_sync_status,
146                         RemoteServiceState expected_service_status,
147                         SyncStatusCode sync_status) {
148    EXPECT_EQ(expected_sync_status, sync_status);
149    EXPECT_EQ(expected_service_status, sync_engine_->GetCurrentState());
150  }
151
152 private:
153  content::TestBrowserThreadBundle browser_threads_;
154  base::ScopedTempDir profile_dir_;
155  scoped_ptr<leveldb::Env> in_memory_env_;
156
157  scoped_ptr<MockExtensionService> extension_service_;
158  scoped_ptr<drive_backend::SyncEngine> sync_engine_;
159
160  DISALLOW_COPY_AND_ASSIGN(SyncEngineTest);
161};
162
163TEST_F(SyncEngineTest, EnableOrigin) {
164  FileTracker tracker;
165  SyncStatusCode sync_status = SYNC_STATUS_UNKNOWN;
166  MetadataDatabase* metadata_database = sync_engine()->GetMetadataDatabase();
167  GURL origin = extensions::Extension::GetBaseURLFromExtensionId(kAppID);
168
169  sync_engine()->RegisterOrigin(origin, CreateResultReceiver(&sync_status));
170  base::RunLoop().RunUntilIdle();
171  EXPECT_EQ(SYNC_STATUS_OK, sync_status);
172  ASSERT_TRUE(metadata_database->FindAppRootTracker(kAppID, &tracker));
173  EXPECT_EQ(TRACKER_KIND_APP_ROOT, tracker.tracker_kind());
174
175  sync_engine()->DisableOrigin(origin, CreateResultReceiver(&sync_status));
176  base::RunLoop().RunUntilIdle();
177  EXPECT_EQ(SYNC_STATUS_OK, sync_status);
178  ASSERT_TRUE(metadata_database->FindAppRootTracker(kAppID, &tracker));
179  EXPECT_EQ(TRACKER_KIND_DISABLED_APP_ROOT, tracker.tracker_kind());
180
181  sync_engine()->EnableOrigin(origin, CreateResultReceiver(&sync_status));
182  base::RunLoop().RunUntilIdle();
183  EXPECT_EQ(SYNC_STATUS_OK, sync_status);
184  ASSERT_TRUE(metadata_database->FindAppRootTracker(kAppID, &tracker));
185  EXPECT_EQ(TRACKER_KIND_APP_ROOT, tracker.tracker_kind());
186
187  sync_engine()->UninstallOrigin(
188      origin,
189      RemoteFileSyncService::UNINSTALL_AND_KEEP_REMOTE,
190      CreateResultReceiver(&sync_status));
191  base::RunLoop().RunUntilIdle();
192  EXPECT_EQ(SYNC_STATUS_OK, sync_status);
193  ASSERT_FALSE(metadata_database->FindAppRootTracker(kAppID, &tracker));
194}
195
196TEST_F(SyncEngineTest, UpdateRegisteredApps) {
197  SyncStatusCode sync_status = SYNC_STATUS_UNKNOWN;
198  for (int i = 0; i < 3; i++) {
199    scoped_refptr<const extensions::Extension> extension =
200        extensions::ExtensionBuilder()
201        .SetManifest(extensions::DictionaryBuilder()
202                     .Set("name", "foo")
203                     .Set("version", "1.0")
204                     .Set("manifest_version", 2))
205        .SetID(base::StringPrintf("app_%d", i))
206        .Build();
207    extension_service()->AddExtension(extension.get());
208    GURL origin = extensions::Extension::GetBaseURLFromExtensionId(
209        extension->id());
210    sync_status = SYNC_STATUS_UNKNOWN;
211    sync_engine()->RegisterOrigin(origin, CreateResultReceiver(&sync_status));
212    base::RunLoop().RunUntilIdle();
213    EXPECT_EQ(SYNC_STATUS_OK, sync_status);
214  }
215
216  MetadataDatabase* metadata_database = sync_engine()->GetMetadataDatabase();
217  FileTracker tracker;
218
219  ASSERT_TRUE(metadata_database->FindAppRootTracker("app_0", &tracker));
220  EXPECT_EQ(TRACKER_KIND_APP_ROOT, tracker.tracker_kind());
221
222  ASSERT_TRUE(metadata_database->FindAppRootTracker("app_1", &tracker));
223  EXPECT_EQ(TRACKER_KIND_APP_ROOT, tracker.tracker_kind());
224
225  ASSERT_TRUE(metadata_database->FindAppRootTracker("app_2", &tracker));
226  EXPECT_EQ(TRACKER_KIND_APP_ROOT, tracker.tracker_kind());
227
228  extension_service()->DisableExtension("app_1");
229  extension_service()->UninstallExtension("app_2");
230  ASSERT_FALSE(extension_service()->GetInstalledExtension("app_2"));
231  UpdateRegisteredApps();
232  base::RunLoop().RunUntilIdle();
233
234  ASSERT_TRUE(metadata_database->FindAppRootTracker("app_0", &tracker));
235  EXPECT_EQ(TRACKER_KIND_APP_ROOT, tracker.tracker_kind());
236
237  ASSERT_TRUE(metadata_database->FindAppRootTracker("app_1", &tracker));
238  EXPECT_EQ(TRACKER_KIND_DISABLED_APP_ROOT, tracker.tracker_kind());
239
240  ASSERT_FALSE(metadata_database->FindAppRootTracker("app_2", &tracker));
241}
242
243TEST_F(SyncEngineTest, GetOriginStatusMap) {
244  FileTracker tracker;
245  SyncStatusCode sync_status = SYNC_STATUS_UNKNOWN;
246  GURL origin = extensions::Extension::GetBaseURLFromExtensionId(kAppID);
247
248  sync_engine()->RegisterOrigin(GURL("chrome-extension://app_0"),
249                                     CreateResultReceiver(&sync_status));
250  base::RunLoop().RunUntilIdle();
251  EXPECT_EQ(SYNC_STATUS_OK, sync_status);
252
253  sync_engine()->RegisterOrigin(GURL("chrome-extension://app_1"),
254                                     CreateResultReceiver(&sync_status));
255  base::RunLoop().RunUntilIdle();
256  EXPECT_EQ(SYNC_STATUS_OK, sync_status);
257
258  RemoteFileSyncService::OriginStatusMap status_map;
259  sync_engine()->GetOriginStatusMap(&status_map);
260  ASSERT_EQ(2u, status_map.size());
261  EXPECT_EQ("Enabled", status_map[GURL("chrome-extension://app_0")]);
262  EXPECT_EQ("Enabled", status_map[GURL("chrome-extension://app_1")]);
263
264  sync_engine()->DisableOrigin(GURL("chrome-extension://app_1"),
265                               CreateResultReceiver(&sync_status));
266  base::RunLoop().RunUntilIdle();
267  EXPECT_EQ(SYNC_STATUS_OK, sync_status);
268
269  sync_engine()->GetOriginStatusMap(&status_map);
270  ASSERT_EQ(2u, status_map.size());
271  EXPECT_EQ("Enabled", status_map[GURL("chrome-extension://app_0")]);
272  EXPECT_EQ("Disabled", status_map[GURL("chrome-extension://app_1")]);
273}
274
275TEST_F(SyncEngineTest, UpdateServiceState) {
276  EXPECT_EQ(REMOTE_SERVICE_OK, sync_engine()->GetCurrentState());
277
278  GetSyncEngineTaskManager()->ScheduleTask(
279      FROM_HERE,
280      base::Bind(&EmptyTask, SYNC_STATUS_AUTHENTICATION_FAILED),
281      SyncTaskManager::PRIORITY_MED,
282      base::Bind(&SyncEngineTest::CheckServiceState,
283                 AsWeakPtr(),
284                 SYNC_STATUS_AUTHENTICATION_FAILED,
285                 REMOTE_SERVICE_AUTHENTICATION_REQUIRED));
286
287  GetSyncEngineTaskManager()->ScheduleTask(
288      FROM_HERE,
289      base::Bind(&EmptyTask, SYNC_STATUS_ACCESS_FORBIDDEN),
290      SyncTaskManager::PRIORITY_MED,
291      base::Bind(&SyncEngineTest::CheckServiceState,
292                 AsWeakPtr(),
293                 SYNC_STATUS_ACCESS_FORBIDDEN,
294                 REMOTE_SERVICE_AUTHENTICATION_REQUIRED));
295
296  GetSyncEngineTaskManager()->ScheduleTask(
297      FROM_HERE,
298      base::Bind(&EmptyTask, SYNC_STATUS_SERVICE_TEMPORARILY_UNAVAILABLE),
299      SyncTaskManager::PRIORITY_MED,
300      base::Bind(&SyncEngineTest::CheckServiceState,
301                 AsWeakPtr(),
302                 SYNC_STATUS_SERVICE_TEMPORARILY_UNAVAILABLE,
303                 REMOTE_SERVICE_TEMPORARY_UNAVAILABLE));
304
305  GetSyncEngineTaskManager()->ScheduleTask(
306      FROM_HERE,
307      base::Bind(&EmptyTask, SYNC_STATUS_NETWORK_ERROR),
308      SyncTaskManager::PRIORITY_MED,
309      base::Bind(&SyncEngineTest::CheckServiceState,
310                 AsWeakPtr(),
311                 SYNC_STATUS_NETWORK_ERROR,
312                 REMOTE_SERVICE_TEMPORARY_UNAVAILABLE));
313
314  GetSyncEngineTaskManager()->ScheduleTask(
315      FROM_HERE,
316      base::Bind(&EmptyTask, SYNC_STATUS_ABORT),
317      SyncTaskManager::PRIORITY_MED,
318      base::Bind(&SyncEngineTest::CheckServiceState,
319                 AsWeakPtr(),
320                 SYNC_STATUS_ABORT,
321                 REMOTE_SERVICE_TEMPORARY_UNAVAILABLE));
322
323  GetSyncEngineTaskManager()->ScheduleTask(
324      FROM_HERE,
325      base::Bind(&EmptyTask, SYNC_STATUS_FAILED),
326      SyncTaskManager::PRIORITY_MED,
327      base::Bind(&SyncEngineTest::CheckServiceState,
328                 AsWeakPtr(),
329                 SYNC_STATUS_FAILED,
330                 REMOTE_SERVICE_TEMPORARY_UNAVAILABLE));
331
332  GetSyncEngineTaskManager()->ScheduleTask(
333      FROM_HERE,
334      base::Bind(&EmptyTask, SYNC_DATABASE_ERROR_CORRUPTION),
335      SyncTaskManager::PRIORITY_MED,
336      base::Bind(&SyncEngineTest::CheckServiceState,
337                 AsWeakPtr(),
338                 SYNC_DATABASE_ERROR_CORRUPTION,
339                 REMOTE_SERVICE_DISABLED));
340
341  GetSyncEngineTaskManager()->ScheduleTask(
342      FROM_HERE,
343      base::Bind(&EmptyTask, SYNC_DATABASE_ERROR_IO_ERROR),
344      SyncTaskManager::PRIORITY_MED,
345      base::Bind(&SyncEngineTest::CheckServiceState,
346                 AsWeakPtr(),
347                 SYNC_DATABASE_ERROR_IO_ERROR,
348                 REMOTE_SERVICE_DISABLED));
349
350  GetSyncEngineTaskManager()->ScheduleTask(
351      FROM_HERE,
352      base::Bind(&EmptyTask, SYNC_DATABASE_ERROR_FAILED),
353      SyncTaskManager::PRIORITY_MED,
354      base::Bind(&SyncEngineTest::CheckServiceState,
355                 AsWeakPtr(),
356                 SYNC_DATABASE_ERROR_FAILED,
357                 REMOTE_SERVICE_DISABLED));
358
359  GetSyncEngineTaskManager()->ScheduleSyncTask(
360      FROM_HERE,
361      scoped_ptr<SyncTask>(new MockSyncTask(false)),
362      SyncTaskManager::PRIORITY_MED,
363      base::Bind(&SyncEngineTest::CheckServiceState,
364                 AsWeakPtr(),
365                 SYNC_STATUS_OK,
366                 REMOTE_SERVICE_DISABLED));
367
368  GetSyncEngineTaskManager()->ScheduleSyncTask(
369      FROM_HERE,
370      scoped_ptr<SyncTask>(new MockSyncTask(true)),
371      SyncTaskManager::PRIORITY_MED,
372      base::Bind(&SyncEngineTest::CheckServiceState,
373                 AsWeakPtr(),
374                 SYNC_STATUS_OK,
375                 REMOTE_SERVICE_OK));
376
377  base::RunLoop().RunUntilIdle();
378}
379
380}  // namespace drive_backend
381}  // namespace sync_file_system
382