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/location.h"
9 #include "base/run_loop.h"
10 #include "base/single_thread_task_runner.h"
11 #include "base/strings/stringprintf.h"
12 #include "base/thread_task_runner_handle.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 "components/drive/drive_uploader.h"
21 #include "components/drive/service/fake_drive_service.h"
22 #include "content/public/test/test_browser_thread_bundle.h"
23 #include "extensions/common/extension.h"
24 #include "extensions/common/extension_builder.h"
25 #include "extensions/common/extension_set.h"
26 #include "extensions/common/value_builder.h"
27 #include "testing/gtest/include/gtest/gtest.h"
28 #include "third_party/leveldatabase/src/helpers/memenv/memenv.h"
29 #include "third_party/leveldatabase/src/include/leveldb/env.h"
31 namespace sync_file_system
{
32 namespace drive_backend
{
36 const char kAppID
[] = "app_id";
38 void EmptyTask(SyncStatusCode status
, const SyncStatusCallback
& callback
) {
39 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE
,
40 base::Bind(callback
, status
));
45 class MockSyncTask
: public ExclusiveTask
{
47 explicit MockSyncTask(bool used_network
) {
48 set_used_network(used_network
);
50 ~MockSyncTask() override
{}
52 void RunExclusive(const SyncStatusCallback
& callback
) override
{
53 callback
.Run(SYNC_STATUS_OK
);
57 DISALLOW_COPY_AND_ASSIGN(MockSyncTask
);
60 class MockExtensionService
: public TestExtensionService
{
62 MockExtensionService() {}
63 ~MockExtensionService() override
{}
65 void AddExtension(const extensions::Extension
* extension
) override
{
66 extensions_
.Insert(make_scoped_refptr(extension
));
69 const extensions::Extension
* GetInstalledExtension(
70 const std::string
& extension_id
) const override
{
71 return extensions_
.GetByID(extension_id
);
74 bool IsExtensionEnabled(const std::string
& extension_id
) const override
{
75 return extensions_
.Contains(extension_id
) &&
76 !disabled_extensions_
.Contains(extension_id
);
79 void UninstallExtension(const std::string
& extension_id
) {
80 extensions_
.Remove(extension_id
);
81 disabled_extensions_
.Remove(extension_id
);
84 void DisableExtension(const std::string
& extension_id
) {
85 if (!IsExtensionEnabled(extension_id
))
87 const extensions::Extension
* extension
= extensions_
.GetByID(extension_id
);
88 disabled_extensions_
.Insert(make_scoped_refptr(extension
));
92 extensions::ExtensionSet extensions_
;
93 extensions::ExtensionSet disabled_extensions_
;
95 DISALLOW_COPY_AND_ASSIGN(MockExtensionService
);
98 class SyncWorkerTest
: public testing::Test
,
99 public base::SupportsWeakPtr
<SyncWorkerTest
> {
102 ~SyncWorkerTest() override
{}
104 void SetUp() override
{
105 ASSERT_TRUE(profile_dir_
.CreateUniqueTempDir());
106 in_memory_env_
.reset(leveldb::NewMemEnv(leveldb::Env::Default()));
108 extension_service_
.reset(new MockExtensionService
);
109 scoped_ptr
<drive::DriveServiceInterface
>
110 fake_drive_service(new drive::FakeDriveService
);
112 scoped_ptr
<SyncEngineContext
>
113 sync_engine_context(new SyncEngineContext(
114 fake_drive_service
.Pass(),
115 nullptr /* drive_uploader */,
116 nullptr /* task_logger */,
117 base::ThreadTaskRunnerHandle::Get() /* ui_task_runner */,
118 base::ThreadTaskRunnerHandle::Get() /* worker_task_runner */,
119 nullptr /* worker_pool */));
121 sync_worker_
.reset(new SyncWorker(
123 extension_service_
->AsWeakPtr(),
124 in_memory_env_
.get()));
125 sync_worker_
->Initialize(sync_engine_context
.Pass());
127 sync_worker_
->SetSyncEnabled(true);
128 base::RunLoop().RunUntilIdle();
131 void TearDown() override
{
132 sync_worker_
.reset();
133 extension_service_
.reset();
134 base::RunLoop().RunUntilIdle();
137 MockExtensionService
* extension_service() { return extension_service_
.get(); }
138 SyncWorker
* sync_worker() { return sync_worker_
.get(); }
140 void UpdateRegisteredApps() {
141 sync_worker_
->UpdateRegisteredApps();
144 SyncTaskManager
* GetSyncTaskManager() {
145 return sync_worker_
->task_manager_
.get();
148 void CheckServiceState(SyncStatusCode expected_sync_status
,
149 RemoteServiceState expected_service_status
,
150 SyncStatusCode sync_status
) {
151 EXPECT_EQ(expected_sync_status
, sync_status
);
152 EXPECT_EQ(expected_service_status
, sync_worker_
->GetCurrentState());
155 MetadataDatabase
* metadata_database() {
156 return sync_worker_
->GetMetadataDatabase();
160 content::TestBrowserThreadBundle browser_threads_
;
161 base::ScopedTempDir profile_dir_
;
162 scoped_ptr
<leveldb::Env
> in_memory_env_
;
164 scoped_ptr
<MockExtensionService
> extension_service_
;
165 scoped_ptr
<SyncWorker
> sync_worker_
;
167 DISALLOW_COPY_AND_ASSIGN(SyncWorkerTest
);
170 TEST_F(SyncWorkerTest
, EnableOrigin
) {
172 SyncStatusCode sync_status
= SYNC_STATUS_UNKNOWN
;
173 GURL origin
= extensions::Extension::GetBaseURLFromExtensionId(kAppID
);
175 sync_worker()->RegisterOrigin(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_APP_ROOT
, tracker
.tracker_kind());
181 sync_worker()->DisableOrigin(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_DISABLED_APP_ROOT
, tracker
.tracker_kind());
187 sync_worker()->EnableOrigin(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_APP_ROOT
, tracker
.tracker_kind());
193 sync_worker()->UninstallOrigin(
195 RemoteFileSyncService::UNINSTALL_AND_KEEP_REMOTE
,
196 CreateResultReceiver(&sync_status
));
197 base::RunLoop().RunUntilIdle();
198 EXPECT_EQ(SYNC_STATUS_OK
, sync_status
);
199 ASSERT_FALSE(metadata_database()->FindAppRootTracker(kAppID
, &tracker
));
202 TEST_F(SyncWorkerTest
, UpdateRegisteredApps
) {
203 SyncStatusCode sync_status
= SYNC_STATUS_UNKNOWN
;
204 for (int i
= 0; i
< 3; i
++) {
205 scoped_refptr
<const extensions::Extension
> extension
=
206 extensions::ExtensionBuilder()
207 .SetManifest(extensions::DictionaryBuilder()
209 .Set("version", "1.0")
210 .Set("manifest_version", 2))
211 .SetID(base::StringPrintf("app_%d", i
))
213 extension_service()->AddExtension(extension
.get());
214 GURL origin
= extensions::Extension::GetBaseURLFromExtensionId(
216 sync_status
= SYNC_STATUS_UNKNOWN
;
217 sync_worker()->RegisterOrigin(origin
, CreateResultReceiver(&sync_status
));
218 base::RunLoop().RunUntilIdle();
219 EXPECT_EQ(SYNC_STATUS_OK
, sync_status
);
224 ASSERT_TRUE(metadata_database()->FindAppRootTracker("app_0", &tracker
));
225 EXPECT_EQ(TRACKER_KIND_APP_ROOT
, tracker
.tracker_kind());
227 ASSERT_TRUE(metadata_database()->FindAppRootTracker("app_1", &tracker
));
228 EXPECT_EQ(TRACKER_KIND_APP_ROOT
, tracker
.tracker_kind());
230 ASSERT_TRUE(metadata_database()->FindAppRootTracker("app_2", &tracker
));
231 EXPECT_EQ(TRACKER_KIND_APP_ROOT
, tracker
.tracker_kind());
233 extension_service()->DisableExtension("app_1");
234 extension_service()->UninstallExtension("app_2");
235 ASSERT_FALSE(extension_service()->GetInstalledExtension("app_2"));
236 UpdateRegisteredApps();
237 base::RunLoop().RunUntilIdle();
239 ASSERT_TRUE(metadata_database()->FindAppRootTracker("app_0", &tracker
));
240 EXPECT_EQ(TRACKER_KIND_APP_ROOT
, tracker
.tracker_kind());
242 ASSERT_TRUE(metadata_database()->FindAppRootTracker("app_1", &tracker
));
243 EXPECT_EQ(TRACKER_KIND_DISABLED_APP_ROOT
, tracker
.tracker_kind());
245 ASSERT_FALSE(metadata_database()->FindAppRootTracker("app_2", &tracker
));
248 TEST_F(SyncWorkerTest
, GetOriginStatusMap
) {
250 SyncStatusCode sync_status
= SYNC_STATUS_UNKNOWN
;
251 GURL origin
= extensions::Extension::GetBaseURLFromExtensionId(kAppID
);
253 sync_worker()->RegisterOrigin(GURL("chrome-extension://app_0"),
254 CreateResultReceiver(&sync_status
));
255 base::RunLoop().RunUntilIdle();
256 EXPECT_EQ(SYNC_STATUS_OK
, sync_status
);
258 sync_worker()->RegisterOrigin(GURL("chrome-extension://app_1"),
259 CreateResultReceiver(&sync_status
));
260 base::RunLoop().RunUntilIdle();
261 EXPECT_EQ(SYNC_STATUS_OK
, sync_status
);
263 scoped_ptr
<RemoteFileSyncService::OriginStatusMap
> status_map
;
264 sync_worker()->GetOriginStatusMap(CreateResultReceiver(&status_map
));
265 base::RunLoop().RunUntilIdle();
266 ASSERT_EQ(2u, status_map
->size());
267 EXPECT_EQ("Enabled", (*status_map
)[GURL("chrome-extension://app_0")]);
268 EXPECT_EQ("Enabled", (*status_map
)[GURL("chrome-extension://app_1")]);
270 sync_worker()->DisableOrigin(GURL("chrome-extension://app_1"),
271 CreateResultReceiver(&sync_status
));
272 base::RunLoop().RunUntilIdle();
273 EXPECT_EQ(SYNC_STATUS_OK
, sync_status
);
275 sync_worker()->GetOriginStatusMap(CreateResultReceiver(&status_map
));
276 base::RunLoop().RunUntilIdle();
277 ASSERT_EQ(2u, status_map
->size());
278 EXPECT_EQ("Enabled", (*status_map
)[GURL("chrome-extension://app_0")]);
279 EXPECT_EQ("Disabled", (*status_map
)[GURL("chrome-extension://app_1")]);
282 TEST_F(SyncWorkerTest
, UpdateServiceState
) {
283 EXPECT_EQ(REMOTE_SERVICE_OK
, sync_worker()->GetCurrentState());
285 GetSyncTaskManager()->ScheduleTask(
287 base::Bind(&EmptyTask
, SYNC_STATUS_AUTHENTICATION_FAILED
),
288 SyncTaskManager::PRIORITY_MED
,
289 base::Bind(&SyncWorkerTest::CheckServiceState
,
291 SYNC_STATUS_AUTHENTICATION_FAILED
,
292 REMOTE_SERVICE_AUTHENTICATION_REQUIRED
));
294 GetSyncTaskManager()->ScheduleTask(
296 base::Bind(&EmptyTask
, SYNC_STATUS_ACCESS_FORBIDDEN
),
297 SyncTaskManager::PRIORITY_MED
,
298 base::Bind(&SyncWorkerTest::CheckServiceState
,
300 SYNC_STATUS_ACCESS_FORBIDDEN
,
301 REMOTE_SERVICE_ACCESS_FORBIDDEN
));
303 GetSyncTaskManager()->ScheduleTask(
305 base::Bind(&EmptyTask
, SYNC_STATUS_SERVICE_TEMPORARILY_UNAVAILABLE
),
306 SyncTaskManager::PRIORITY_MED
,
307 base::Bind(&SyncWorkerTest::CheckServiceState
,
309 SYNC_STATUS_SERVICE_TEMPORARILY_UNAVAILABLE
,
310 REMOTE_SERVICE_TEMPORARY_UNAVAILABLE
));
312 GetSyncTaskManager()->ScheduleTask(
314 base::Bind(&EmptyTask
, SYNC_STATUS_NETWORK_ERROR
),
315 SyncTaskManager::PRIORITY_MED
,
316 base::Bind(&SyncWorkerTest::CheckServiceState
,
318 SYNC_STATUS_NETWORK_ERROR
,
319 REMOTE_SERVICE_TEMPORARY_UNAVAILABLE
));
321 GetSyncTaskManager()->ScheduleTask(
323 base::Bind(&EmptyTask
, SYNC_STATUS_ABORT
),
324 SyncTaskManager::PRIORITY_MED
,
325 base::Bind(&SyncWorkerTest::CheckServiceState
,
328 REMOTE_SERVICE_TEMPORARY_UNAVAILABLE
));
330 GetSyncTaskManager()->ScheduleTask(
332 base::Bind(&EmptyTask
, SYNC_STATUS_FAILED
),
333 SyncTaskManager::PRIORITY_MED
,
334 base::Bind(&SyncWorkerTest::CheckServiceState
,
337 REMOTE_SERVICE_TEMPORARY_UNAVAILABLE
));
339 GetSyncTaskManager()->ScheduleTask(
341 base::Bind(&EmptyTask
, SYNC_DATABASE_ERROR_CORRUPTION
),
342 SyncTaskManager::PRIORITY_MED
,
343 base::Bind(&SyncWorkerTest::CheckServiceState
,
345 SYNC_DATABASE_ERROR_CORRUPTION
,
346 REMOTE_SERVICE_DISABLED
));
348 GetSyncTaskManager()->ScheduleTask(
350 base::Bind(&EmptyTask
, SYNC_DATABASE_ERROR_IO_ERROR
),
351 SyncTaskManager::PRIORITY_MED
,
352 base::Bind(&SyncWorkerTest::CheckServiceState
,
354 SYNC_DATABASE_ERROR_IO_ERROR
,
355 REMOTE_SERVICE_DISABLED
));
357 GetSyncTaskManager()->ScheduleTask(
359 base::Bind(&EmptyTask
, SYNC_DATABASE_ERROR_FAILED
),
360 SyncTaskManager::PRIORITY_MED
,
361 base::Bind(&SyncWorkerTest::CheckServiceState
,
363 SYNC_DATABASE_ERROR_FAILED
,
364 REMOTE_SERVICE_DISABLED
));
366 GetSyncTaskManager()->ScheduleSyncTask(
368 scoped_ptr
<SyncTask
>(new MockSyncTask(false)),
369 SyncTaskManager::PRIORITY_MED
,
370 base::Bind(&SyncWorkerTest::CheckServiceState
,
373 REMOTE_SERVICE_DISABLED
));
375 GetSyncTaskManager()->ScheduleSyncTask(
377 scoped_ptr
<SyncTask
>(new MockSyncTask(true)),
378 SyncTaskManager::PRIORITY_MED
,
379 base::Bind(&SyncWorkerTest::CheckServiceState
,
384 base::RunLoop().RunUntilIdle();
387 } // namespace drive_backend
388 } // namespace sync_file_system