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