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