sync_engine_unittest.cc revision cedac228d2dd51db4b79ea1e72c7f249408ee061
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                             NULL,
123                             base::MessageLoopProxy::current(),
124                             in_memory_env_.get());
125    sync_engine_->SetSyncEnabled(true);
126    base::RunLoop().RunUntilIdle();
127  }
128
129  virtual void TearDown() OVERRIDE {
130    sync_engine_.reset();
131    extension_service_.reset();
132    base::RunLoop().RunUntilIdle();
133  }
134
135  MockExtensionService* extension_service() { return extension_service_.get(); }
136  SyncEngine* sync_engine() { return sync_engine_.get(); }
137
138  void UpdateRegisteredApps() {
139    sync_engine_->UpdateRegisteredApps();
140  }
141
142  SyncTaskManager* GetSyncEngineTaskManager() {
143    return sync_engine_->GetSyncTaskManagerForTesting();
144  }
145
146  void CheckServiceState(SyncStatusCode expected_sync_status,
147                         RemoteServiceState expected_service_status,
148                         SyncStatusCode sync_status) {
149    EXPECT_EQ(expected_sync_status, sync_status);
150    EXPECT_EQ(expected_service_status, sync_engine_->GetCurrentState());
151  }
152
153 private:
154  content::TestBrowserThreadBundle browser_threads_;
155  base::ScopedTempDir profile_dir_;
156  scoped_ptr<leveldb::Env> in_memory_env_;
157
158  scoped_ptr<MockExtensionService> extension_service_;
159  scoped_ptr<drive_backend::SyncEngine> sync_engine_;
160
161  DISALLOW_COPY_AND_ASSIGN(SyncEngineTest);
162};
163
164TEST_F(SyncEngineTest, EnableOrigin) {
165  FileTracker tracker;
166  SyncStatusCode sync_status = SYNC_STATUS_UNKNOWN;
167  MetadataDatabase* metadata_database = sync_engine()->GetMetadataDatabase();
168  GURL origin = extensions::Extension::GetBaseURLFromExtensionId(kAppID);
169
170  sync_engine()->RegisterOrigin(origin, CreateResultReceiver(&sync_status));
171  base::RunLoop().RunUntilIdle();
172  EXPECT_EQ(SYNC_STATUS_OK, sync_status);
173  ASSERT_TRUE(metadata_database->FindAppRootTracker(kAppID, &tracker));
174  EXPECT_EQ(TRACKER_KIND_APP_ROOT, tracker.tracker_kind());
175
176  sync_engine()->DisableOrigin(origin, CreateResultReceiver(&sync_status));
177  base::RunLoop().RunUntilIdle();
178  EXPECT_EQ(SYNC_STATUS_OK, sync_status);
179  ASSERT_TRUE(metadata_database->FindAppRootTracker(kAppID, &tracker));
180  EXPECT_EQ(TRACKER_KIND_DISABLED_APP_ROOT, tracker.tracker_kind());
181
182  sync_engine()->EnableOrigin(origin, CreateResultReceiver(&sync_status));
183  base::RunLoop().RunUntilIdle();
184  EXPECT_EQ(SYNC_STATUS_OK, sync_status);
185  ASSERT_TRUE(metadata_database->FindAppRootTracker(kAppID, &tracker));
186  EXPECT_EQ(TRACKER_KIND_APP_ROOT, tracker.tracker_kind());
187
188  sync_engine()->UninstallOrigin(
189      origin,
190      RemoteFileSyncService::UNINSTALL_AND_KEEP_REMOTE,
191      CreateResultReceiver(&sync_status));
192  base::RunLoop().RunUntilIdle();
193  EXPECT_EQ(SYNC_STATUS_OK, sync_status);
194  ASSERT_FALSE(metadata_database->FindAppRootTracker(kAppID, &tracker));
195}
196
197TEST_F(SyncEngineTest, UpdateRegisteredApps) {
198  SyncStatusCode sync_status = SYNC_STATUS_UNKNOWN;
199  for (int i = 0; i < 3; i++) {
200    scoped_refptr<const extensions::Extension> extension =
201        extensions::ExtensionBuilder()
202        .SetManifest(extensions::DictionaryBuilder()
203                     .Set("name", "foo")
204                     .Set("version", "1.0")
205                     .Set("manifest_version", 2))
206        .SetID(base::StringPrintf("app_%d", i))
207        .Build();
208    extension_service()->AddExtension(extension.get());
209    GURL origin = extensions::Extension::GetBaseURLFromExtensionId(
210        extension->id());
211    sync_status = SYNC_STATUS_UNKNOWN;
212    sync_engine()->RegisterOrigin(origin, CreateResultReceiver(&sync_status));
213    base::RunLoop().RunUntilIdle();
214    EXPECT_EQ(SYNC_STATUS_OK, sync_status);
215  }
216
217  MetadataDatabase* metadata_database = sync_engine()->GetMetadataDatabase();
218  FileTracker tracker;
219
220  ASSERT_TRUE(metadata_database->FindAppRootTracker("app_0", &tracker));
221  EXPECT_EQ(TRACKER_KIND_APP_ROOT, tracker.tracker_kind());
222
223  ASSERT_TRUE(metadata_database->FindAppRootTracker("app_1", &tracker));
224  EXPECT_EQ(TRACKER_KIND_APP_ROOT, tracker.tracker_kind());
225
226  ASSERT_TRUE(metadata_database->FindAppRootTracker("app_2", &tracker));
227  EXPECT_EQ(TRACKER_KIND_APP_ROOT, tracker.tracker_kind());
228
229  extension_service()->DisableExtension("app_1");
230  extension_service()->UninstallExtension("app_2");
231  ASSERT_FALSE(extension_service()->GetInstalledExtension("app_2"));
232  UpdateRegisteredApps();
233  base::RunLoop().RunUntilIdle();
234
235  ASSERT_TRUE(metadata_database->FindAppRootTracker("app_0", &tracker));
236  EXPECT_EQ(TRACKER_KIND_APP_ROOT, tracker.tracker_kind());
237
238  ASSERT_TRUE(metadata_database->FindAppRootTracker("app_1", &tracker));
239  EXPECT_EQ(TRACKER_KIND_DISABLED_APP_ROOT, tracker.tracker_kind());
240
241  ASSERT_FALSE(metadata_database->FindAppRootTracker("app_2", &tracker));
242}
243
244TEST_F(SyncEngineTest, GetOriginStatusMap) {
245  FileTracker tracker;
246  SyncStatusCode sync_status = SYNC_STATUS_UNKNOWN;
247  GURL origin = extensions::Extension::GetBaseURLFromExtensionId(kAppID);
248
249  sync_engine()->RegisterOrigin(GURL("chrome-extension://app_0"),
250                                CreateResultReceiver(&sync_status));
251  base::RunLoop().RunUntilIdle();
252  EXPECT_EQ(SYNC_STATUS_OK, sync_status);
253
254  sync_engine()->RegisterOrigin(GURL("chrome-extension://app_1"),
255                                CreateResultReceiver(&sync_status));
256  base::RunLoop().RunUntilIdle();
257  EXPECT_EQ(SYNC_STATUS_OK, sync_status);
258
259  scoped_ptr<RemoteFileSyncService::OriginStatusMap> status_map;
260  sync_engine()->GetOriginStatusMap(CreateResultReceiver(&status_map));
261  base::RunLoop().RunUntilIdle();
262  ASSERT_EQ(2u, status_map->size());
263  EXPECT_EQ("Enabled", (*status_map)[GURL("chrome-extension://app_0")]);
264  EXPECT_EQ("Enabled", (*status_map)[GURL("chrome-extension://app_1")]);
265
266  sync_engine()->DisableOrigin(GURL("chrome-extension://app_1"),
267                               CreateResultReceiver(&sync_status));
268  base::RunLoop().RunUntilIdle();
269  EXPECT_EQ(SYNC_STATUS_OK, sync_status);
270
271  sync_engine()->GetOriginStatusMap(CreateResultReceiver(&status_map));
272  base::RunLoop().RunUntilIdle();
273  ASSERT_EQ(2u, status_map->size());
274  EXPECT_EQ("Enabled", (*status_map)[GURL("chrome-extension://app_0")]);
275  EXPECT_EQ("Disabled", (*status_map)[GURL("chrome-extension://app_1")]);
276}
277
278TEST_F(SyncEngineTest, UpdateServiceState) {
279  EXPECT_EQ(REMOTE_SERVICE_OK, sync_engine()->GetCurrentState());
280
281  GetSyncEngineTaskManager()->ScheduleTask(
282      FROM_HERE,
283      base::Bind(&EmptyTask, SYNC_STATUS_AUTHENTICATION_FAILED),
284      SyncTaskManager::PRIORITY_MED,
285      base::Bind(&SyncEngineTest::CheckServiceState,
286                 AsWeakPtr(),
287                 SYNC_STATUS_AUTHENTICATION_FAILED,
288                 REMOTE_SERVICE_AUTHENTICATION_REQUIRED));
289
290  GetSyncEngineTaskManager()->ScheduleTask(
291      FROM_HERE,
292      base::Bind(&EmptyTask, SYNC_STATUS_ACCESS_FORBIDDEN),
293      SyncTaskManager::PRIORITY_MED,
294      base::Bind(&SyncEngineTest::CheckServiceState,
295                 AsWeakPtr(),
296                 SYNC_STATUS_ACCESS_FORBIDDEN,
297                 REMOTE_SERVICE_AUTHENTICATION_REQUIRED));
298
299  GetSyncEngineTaskManager()->ScheduleTask(
300      FROM_HERE,
301      base::Bind(&EmptyTask, SYNC_STATUS_SERVICE_TEMPORARILY_UNAVAILABLE),
302      SyncTaskManager::PRIORITY_MED,
303      base::Bind(&SyncEngineTest::CheckServiceState,
304                 AsWeakPtr(),
305                 SYNC_STATUS_SERVICE_TEMPORARILY_UNAVAILABLE,
306                 REMOTE_SERVICE_TEMPORARY_UNAVAILABLE));
307
308  GetSyncEngineTaskManager()->ScheduleTask(
309      FROM_HERE,
310      base::Bind(&EmptyTask, SYNC_STATUS_NETWORK_ERROR),
311      SyncTaskManager::PRIORITY_MED,
312      base::Bind(&SyncEngineTest::CheckServiceState,
313                 AsWeakPtr(),
314                 SYNC_STATUS_NETWORK_ERROR,
315                 REMOTE_SERVICE_TEMPORARY_UNAVAILABLE));
316
317  GetSyncEngineTaskManager()->ScheduleTask(
318      FROM_HERE,
319      base::Bind(&EmptyTask, SYNC_STATUS_ABORT),
320      SyncTaskManager::PRIORITY_MED,
321      base::Bind(&SyncEngineTest::CheckServiceState,
322                 AsWeakPtr(),
323                 SYNC_STATUS_ABORT,
324                 REMOTE_SERVICE_TEMPORARY_UNAVAILABLE));
325
326  GetSyncEngineTaskManager()->ScheduleTask(
327      FROM_HERE,
328      base::Bind(&EmptyTask, SYNC_STATUS_FAILED),
329      SyncTaskManager::PRIORITY_MED,
330      base::Bind(&SyncEngineTest::CheckServiceState,
331                 AsWeakPtr(),
332                 SYNC_STATUS_FAILED,
333                 REMOTE_SERVICE_TEMPORARY_UNAVAILABLE));
334
335  GetSyncEngineTaskManager()->ScheduleTask(
336      FROM_HERE,
337      base::Bind(&EmptyTask, SYNC_DATABASE_ERROR_CORRUPTION),
338      SyncTaskManager::PRIORITY_MED,
339      base::Bind(&SyncEngineTest::CheckServiceState,
340                 AsWeakPtr(),
341                 SYNC_DATABASE_ERROR_CORRUPTION,
342                 REMOTE_SERVICE_DISABLED));
343
344  GetSyncEngineTaskManager()->ScheduleTask(
345      FROM_HERE,
346      base::Bind(&EmptyTask, SYNC_DATABASE_ERROR_IO_ERROR),
347      SyncTaskManager::PRIORITY_MED,
348      base::Bind(&SyncEngineTest::CheckServiceState,
349                 AsWeakPtr(),
350                 SYNC_DATABASE_ERROR_IO_ERROR,
351                 REMOTE_SERVICE_DISABLED));
352
353  GetSyncEngineTaskManager()->ScheduleTask(
354      FROM_HERE,
355      base::Bind(&EmptyTask, SYNC_DATABASE_ERROR_FAILED),
356      SyncTaskManager::PRIORITY_MED,
357      base::Bind(&SyncEngineTest::CheckServiceState,
358                 AsWeakPtr(),
359                 SYNC_DATABASE_ERROR_FAILED,
360                 REMOTE_SERVICE_DISABLED));
361
362  GetSyncEngineTaskManager()->ScheduleSyncTask(
363      FROM_HERE,
364      scoped_ptr<SyncTask>(new MockSyncTask(false)),
365      SyncTaskManager::PRIORITY_MED,
366      base::Bind(&SyncEngineTest::CheckServiceState,
367                 AsWeakPtr(),
368                 SYNC_STATUS_OK,
369                 REMOTE_SERVICE_DISABLED));
370
371  GetSyncEngineTaskManager()->ScheduleSyncTask(
372      FROM_HERE,
373      scoped_ptr<SyncTask>(new MockSyncTask(true)),
374      SyncTaskManager::PRIORITY_MED,
375      base::Bind(&SyncEngineTest::CheckServiceState,
376                 AsWeakPtr(),
377                 SYNC_STATUS_OK,
378                 REMOTE_SERVICE_OK));
379
380  base::RunLoop().RunUntilIdle();
381}
382
383}  // namespace drive_backend
384}  // namespace sync_file_system
385