1 // Copyright 2014 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.
5 #include "chrome/browser/sync_file_system/drive_backend/sync_worker.h"
7 #include "base/files/scoped_temp_dir.h"
8 #include "base/run_loop.h"
9 #include "base/strings/stringprintf.h"
10 #include "base/thread_task_runner_handle.h"
11 #include "chrome/browser/drive/drive_uploader.h"
12 #include "chrome/browser/drive/fake_drive_service.h"
13 #include "chrome/browser/extensions/test_extension_service.h"
14 #include "chrome/browser/sync_file_system/drive_backend/metadata_database.h"
15 #include "chrome/browser/sync_file_system/drive_backend/metadata_database.pb.h"
16 #include "chrome/browser/sync_file_system/drive_backend/sync_engine_context.h"
17 #include "chrome/browser/sync_file_system/drive_backend/sync_task.h"
18 #include "chrome/browser/sync_file_system/drive_backend/sync_task_manager.h"
19 #include "chrome/browser/sync_file_system/sync_file_system_test_util.h"
20 #include "content/public/test/test_browser_thread_bundle.h"
21 #include "extensions/common/extension.h"
22 #include "extensions/common/extension_builder.h"
23 #include "extensions/common/extension_set.h"
24 #include "extensions/common/value_builder.h"
25 #include "testing/gtest/include/gtest/gtest.h"
26 #include "third_party/leveldatabase/src/helpers/memenv/memenv.h"
27 #include "third_party/leveldatabase/src/include/leveldb/env.h"
29 namespace sync_file_system
{
30 namespace drive_backend
{
34 const char kAppID
[] = "app_id";
36 void EmptyTask(SyncStatusCode status
, const SyncStatusCallback
& callback
) {
37 base::MessageLoop::current()->PostTask(
38 FROM_HERE
, base::Bind(callback
, status
));
43 class MockSyncTask
: public ExclusiveTask
{
45 explicit MockSyncTask(bool used_network
) {
46 set_used_network(used_network
);
48 ~MockSyncTask() override
{}
50 void RunExclusive(const SyncStatusCallback
& callback
) override
{
51 callback
.Run(SYNC_STATUS_OK
);
55 DISALLOW_COPY_AND_ASSIGN(MockSyncTask
);
58 class MockExtensionService
: public TestExtensionService
{
60 MockExtensionService() {}
61 ~MockExtensionService() override
{}
63 void AddExtension(const extensions::Extension
* extension
) override
{
64 extensions_
.Insert(make_scoped_refptr(extension
));
67 const extensions::Extension
* GetInstalledExtension(
68 const std::string
& extension_id
) const override
{
69 return extensions_
.GetByID(extension_id
);
72 bool IsExtensionEnabled(const std::string
& extension_id
) const override
{
73 return extensions_
.Contains(extension_id
) &&
74 !disabled_extensions_
.Contains(extension_id
);
77 void UninstallExtension(const std::string
& extension_id
) {
78 extensions_
.Remove(extension_id
);
79 disabled_extensions_
.Remove(extension_id
);
82 void DisableExtension(const std::string
& extension_id
) {
83 if (!IsExtensionEnabled(extension_id
))
85 const extensions::Extension
* extension
= extensions_
.GetByID(extension_id
);
86 disabled_extensions_
.Insert(make_scoped_refptr(extension
));
90 extensions::ExtensionSet extensions_
;
91 extensions::ExtensionSet disabled_extensions_
;
93 DISALLOW_COPY_AND_ASSIGN(MockExtensionService
);
96 class SyncWorkerTest
: public testing::Test
,
97 public base::SupportsWeakPtr
<SyncWorkerTest
> {
100 ~SyncWorkerTest() override
{}
102 void SetUp() override
{
103 ASSERT_TRUE(profile_dir_
.CreateUniqueTempDir());
104 in_memory_env_
.reset(leveldb::NewMemEnv(leveldb::Env::Default()));
106 extension_service_
.reset(new MockExtensionService
);
107 scoped_ptr
<drive::DriveServiceInterface
>
108 fake_drive_service(new drive::FakeDriveService
);
110 scoped_ptr
<SyncEngineContext
>
111 sync_engine_context(new SyncEngineContext(
112 fake_drive_service
.Pass(),
113 nullptr /* drive_uploader */,
114 nullptr /* task_logger */,
115 base::ThreadTaskRunnerHandle::Get() /* ui_task_runner */,
116 base::ThreadTaskRunnerHandle::Get() /* worker_task_runner */));
118 sync_worker_
.reset(new SyncWorker(
120 extension_service_
->AsWeakPtr(),
121 in_memory_env_
.get()));
122 sync_worker_
->Initialize(sync_engine_context
.Pass());
124 sync_worker_
->SetSyncEnabled(true);
125 base::RunLoop().RunUntilIdle();
128 void TearDown() override
{
129 sync_worker_
.reset();
130 extension_service_
.reset();
131 base::RunLoop().RunUntilIdle();
134 MockExtensionService
* extension_service() { return extension_service_
.get(); }
135 SyncWorker
* sync_worker() { return sync_worker_
.get(); }
137 void UpdateRegisteredApps() {
138 sync_worker_
->UpdateRegisteredApps();
141 SyncTaskManager
* GetSyncTaskManager() {
142 return sync_worker_
->task_manager_
.get();
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_worker_
->GetCurrentState());
152 MetadataDatabase
* metadata_database() {
153 return sync_worker_
->GetMetadataDatabase();
157 content::TestBrowserThreadBundle browser_threads_
;
158 base::ScopedTempDir profile_dir_
;
159 scoped_ptr
<leveldb::Env
> in_memory_env_
;
161 scoped_ptr
<MockExtensionService
> extension_service_
;
162 scoped_ptr
<SyncWorker
> sync_worker_
;
164 DISALLOW_COPY_AND_ASSIGN(SyncWorkerTest
);
167 TEST_F(SyncWorkerTest
, EnableOrigin
) {
169 SyncStatusCode sync_status
= SYNC_STATUS_UNKNOWN
;
170 GURL origin
= extensions::Extension::GetBaseURLFromExtensionId(kAppID
);
172 sync_worker()->RegisterOrigin(origin
, CreateResultReceiver(&sync_status
));
173 base::RunLoop().RunUntilIdle();
174 EXPECT_EQ(SYNC_STATUS_OK
, sync_status
);
175 ASSERT_TRUE(metadata_database()->FindAppRootTracker(kAppID
, &tracker
));
176 EXPECT_EQ(TRACKER_KIND_APP_ROOT
, tracker
.tracker_kind());
178 sync_worker()->DisableOrigin(origin
, CreateResultReceiver(&sync_status
));
179 base::RunLoop().RunUntilIdle();
180 EXPECT_EQ(SYNC_STATUS_OK
, sync_status
);
181 ASSERT_TRUE(metadata_database()->FindAppRootTracker(kAppID
, &tracker
));
182 EXPECT_EQ(TRACKER_KIND_DISABLED_APP_ROOT
, tracker
.tracker_kind());
184 sync_worker()->EnableOrigin(origin
, CreateResultReceiver(&sync_status
));
185 base::RunLoop().RunUntilIdle();
186 EXPECT_EQ(SYNC_STATUS_OK
, sync_status
);
187 ASSERT_TRUE(metadata_database()->FindAppRootTracker(kAppID
, &tracker
));
188 EXPECT_EQ(TRACKER_KIND_APP_ROOT
, tracker
.tracker_kind());
190 sync_worker()->UninstallOrigin(
192 RemoteFileSyncService::UNINSTALL_AND_KEEP_REMOTE
,
193 CreateResultReceiver(&sync_status
));
194 base::RunLoop().RunUntilIdle();
195 EXPECT_EQ(SYNC_STATUS_OK
, sync_status
);
196 ASSERT_FALSE(metadata_database()->FindAppRootTracker(kAppID
, &tracker
));
199 TEST_F(SyncWorkerTest
, UpdateRegisteredApps
) {
200 SyncStatusCode sync_status
= SYNC_STATUS_UNKNOWN
;
201 for (int i
= 0; i
< 3; i
++) {
202 scoped_refptr
<const extensions::Extension
> extension
=
203 extensions::ExtensionBuilder()
204 .SetManifest(extensions::DictionaryBuilder()
206 .Set("version", "1.0")
207 .Set("manifest_version", 2))
208 .SetID(base::StringPrintf("app_%d", i
))
210 extension_service()->AddExtension(extension
.get());
211 GURL origin
= extensions::Extension::GetBaseURLFromExtensionId(
213 sync_status
= SYNC_STATUS_UNKNOWN
;
214 sync_worker()->RegisterOrigin(origin
, CreateResultReceiver(&sync_status
));
215 base::RunLoop().RunUntilIdle();
216 EXPECT_EQ(SYNC_STATUS_OK
, sync_status
);
221 ASSERT_TRUE(metadata_database()->FindAppRootTracker("app_0", &tracker
));
222 EXPECT_EQ(TRACKER_KIND_APP_ROOT
, tracker
.tracker_kind());
224 ASSERT_TRUE(metadata_database()->FindAppRootTracker("app_1", &tracker
));
225 EXPECT_EQ(TRACKER_KIND_APP_ROOT
, tracker
.tracker_kind());
227 ASSERT_TRUE(metadata_database()->FindAppRootTracker("app_2", &tracker
));
228 EXPECT_EQ(TRACKER_KIND_APP_ROOT
, tracker
.tracker_kind());
230 extension_service()->DisableExtension("app_1");
231 extension_service()->UninstallExtension("app_2");
232 ASSERT_FALSE(extension_service()->GetInstalledExtension("app_2"));
233 UpdateRegisteredApps();
234 base::RunLoop().RunUntilIdle();
236 ASSERT_TRUE(metadata_database()->FindAppRootTracker("app_0", &tracker
));
237 EXPECT_EQ(TRACKER_KIND_APP_ROOT
, tracker
.tracker_kind());
239 ASSERT_TRUE(metadata_database()->FindAppRootTracker("app_1", &tracker
));
240 EXPECT_EQ(TRACKER_KIND_DISABLED_APP_ROOT
, tracker
.tracker_kind());
242 ASSERT_FALSE(metadata_database()->FindAppRootTracker("app_2", &tracker
));
245 TEST_F(SyncWorkerTest
, GetOriginStatusMap
) {
247 SyncStatusCode sync_status
= SYNC_STATUS_UNKNOWN
;
248 GURL origin
= extensions::Extension::GetBaseURLFromExtensionId(kAppID
);
250 sync_worker()->RegisterOrigin(GURL("chrome-extension://app_0"),
251 CreateResultReceiver(&sync_status
));
252 base::RunLoop().RunUntilIdle();
253 EXPECT_EQ(SYNC_STATUS_OK
, sync_status
);
255 sync_worker()->RegisterOrigin(GURL("chrome-extension://app_1"),
256 CreateResultReceiver(&sync_status
));
257 base::RunLoop().RunUntilIdle();
258 EXPECT_EQ(SYNC_STATUS_OK
, sync_status
);
260 scoped_ptr
<RemoteFileSyncService::OriginStatusMap
> status_map
;
261 sync_worker()->GetOriginStatusMap(CreateResultReceiver(&status_map
));
262 base::RunLoop().RunUntilIdle();
263 ASSERT_EQ(2u, status_map
->size());
264 EXPECT_EQ("Enabled", (*status_map
)[GURL("chrome-extension://app_0")]);
265 EXPECT_EQ("Enabled", (*status_map
)[GURL("chrome-extension://app_1")]);
267 sync_worker()->DisableOrigin(GURL("chrome-extension://app_1"),
268 CreateResultReceiver(&sync_status
));
269 base::RunLoop().RunUntilIdle();
270 EXPECT_EQ(SYNC_STATUS_OK
, sync_status
);
272 sync_worker()->GetOriginStatusMap(CreateResultReceiver(&status_map
));
273 base::RunLoop().RunUntilIdle();
274 ASSERT_EQ(2u, status_map
->size());
275 EXPECT_EQ("Enabled", (*status_map
)[GURL("chrome-extension://app_0")]);
276 EXPECT_EQ("Disabled", (*status_map
)[GURL("chrome-extension://app_1")]);
279 TEST_F(SyncWorkerTest
, UpdateServiceState
) {
280 EXPECT_EQ(REMOTE_SERVICE_OK
, sync_worker()->GetCurrentState());
282 GetSyncTaskManager()->ScheduleTask(
284 base::Bind(&EmptyTask
, SYNC_STATUS_AUTHENTICATION_FAILED
),
285 SyncTaskManager::PRIORITY_MED
,
286 base::Bind(&SyncWorkerTest::CheckServiceState
,
288 SYNC_STATUS_AUTHENTICATION_FAILED
,
289 REMOTE_SERVICE_AUTHENTICATION_REQUIRED
));
291 GetSyncTaskManager()->ScheduleTask(
293 base::Bind(&EmptyTask
, SYNC_STATUS_ACCESS_FORBIDDEN
),
294 SyncTaskManager::PRIORITY_MED
,
295 base::Bind(&SyncWorkerTest::CheckServiceState
,
297 SYNC_STATUS_ACCESS_FORBIDDEN
,
298 REMOTE_SERVICE_ACCESS_FORBIDDEN
));
300 GetSyncTaskManager()->ScheduleTask(
302 base::Bind(&EmptyTask
, SYNC_STATUS_SERVICE_TEMPORARILY_UNAVAILABLE
),
303 SyncTaskManager::PRIORITY_MED
,
304 base::Bind(&SyncWorkerTest::CheckServiceState
,
306 SYNC_STATUS_SERVICE_TEMPORARILY_UNAVAILABLE
,
307 REMOTE_SERVICE_TEMPORARY_UNAVAILABLE
));
309 GetSyncTaskManager()->ScheduleTask(
311 base::Bind(&EmptyTask
, SYNC_STATUS_NETWORK_ERROR
),
312 SyncTaskManager::PRIORITY_MED
,
313 base::Bind(&SyncWorkerTest::CheckServiceState
,
315 SYNC_STATUS_NETWORK_ERROR
,
316 REMOTE_SERVICE_TEMPORARY_UNAVAILABLE
));
318 GetSyncTaskManager()->ScheduleTask(
320 base::Bind(&EmptyTask
, SYNC_STATUS_ABORT
),
321 SyncTaskManager::PRIORITY_MED
,
322 base::Bind(&SyncWorkerTest::CheckServiceState
,
325 REMOTE_SERVICE_TEMPORARY_UNAVAILABLE
));
327 GetSyncTaskManager()->ScheduleTask(
329 base::Bind(&EmptyTask
, SYNC_STATUS_FAILED
),
330 SyncTaskManager::PRIORITY_MED
,
331 base::Bind(&SyncWorkerTest::CheckServiceState
,
334 REMOTE_SERVICE_TEMPORARY_UNAVAILABLE
));
336 GetSyncTaskManager()->ScheduleTask(
338 base::Bind(&EmptyTask
, SYNC_DATABASE_ERROR_CORRUPTION
),
339 SyncTaskManager::PRIORITY_MED
,
340 base::Bind(&SyncWorkerTest::CheckServiceState
,
342 SYNC_DATABASE_ERROR_CORRUPTION
,
343 REMOTE_SERVICE_DISABLED
));
345 GetSyncTaskManager()->ScheduleTask(
347 base::Bind(&EmptyTask
, SYNC_DATABASE_ERROR_IO_ERROR
),
348 SyncTaskManager::PRIORITY_MED
,
349 base::Bind(&SyncWorkerTest::CheckServiceState
,
351 SYNC_DATABASE_ERROR_IO_ERROR
,
352 REMOTE_SERVICE_DISABLED
));
354 GetSyncTaskManager()->ScheduleTask(
356 base::Bind(&EmptyTask
, SYNC_DATABASE_ERROR_FAILED
),
357 SyncTaskManager::PRIORITY_MED
,
358 base::Bind(&SyncWorkerTest::CheckServiceState
,
360 SYNC_DATABASE_ERROR_FAILED
,
361 REMOTE_SERVICE_DISABLED
));
363 GetSyncTaskManager()->ScheduleSyncTask(
365 scoped_ptr
<SyncTask
>(new MockSyncTask(false)),
366 SyncTaskManager::PRIORITY_MED
,
367 base::Bind(&SyncWorkerTest::CheckServiceState
,
370 REMOTE_SERVICE_DISABLED
));
372 GetSyncTaskManager()->ScheduleSyncTask(
374 scoped_ptr
<SyncTask
>(new MockSyncTask(true)),
375 SyncTaskManager::PRIORITY_MED
,
376 base::Bind(&SyncWorkerTest::CheckServiceState
,
381 base::RunLoop().RunUntilIdle();
384 } // namespace drive_backend
385 } // namespace sync_file_system