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 */,
117 nullptr /* worker_pool */));
119 sync_worker_
.reset(new SyncWorker(
121 extension_service_
->AsWeakPtr(),
122 in_memory_env_
.get()));
123 sync_worker_
->Initialize(sync_engine_context
.Pass());
125 sync_worker_
->SetSyncEnabled(true);
126 base::RunLoop().RunUntilIdle();
129 void TearDown() override
{
130 sync_worker_
.reset();
131 extension_service_
.reset();
132 base::RunLoop().RunUntilIdle();
135 MockExtensionService
* extension_service() { return extension_service_
.get(); }
136 SyncWorker
* sync_worker() { return sync_worker_
.get(); }
138 void UpdateRegisteredApps() {
139 sync_worker_
->UpdateRegisteredApps();
142 SyncTaskManager
* GetSyncTaskManager() {
143 return sync_worker_
->task_manager_
.get();
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_worker_
->GetCurrentState());
153 MetadataDatabase
* metadata_database() {
154 return sync_worker_
->GetMetadataDatabase();
158 content::TestBrowserThreadBundle browser_threads_
;
159 base::ScopedTempDir profile_dir_
;
160 scoped_ptr
<leveldb::Env
> in_memory_env_
;
162 scoped_ptr
<MockExtensionService
> extension_service_
;
163 scoped_ptr
<SyncWorker
> sync_worker_
;
165 DISALLOW_COPY_AND_ASSIGN(SyncWorkerTest
);
168 TEST_F(SyncWorkerTest
, EnableOrigin
) {
170 SyncStatusCode sync_status
= SYNC_STATUS_UNKNOWN
;
171 GURL origin
= extensions::Extension::GetBaseURLFromExtensionId(kAppID
);
173 sync_worker()->RegisterOrigin(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_APP_ROOT
, tracker
.tracker_kind());
179 sync_worker()->DisableOrigin(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_DISABLED_APP_ROOT
, tracker
.tracker_kind());
185 sync_worker()->EnableOrigin(origin
, CreateResultReceiver(&sync_status
));
186 base::RunLoop().RunUntilIdle();
187 EXPECT_EQ(SYNC_STATUS_OK
, sync_status
);
188 ASSERT_TRUE(metadata_database()->FindAppRootTracker(kAppID
, &tracker
));
189 EXPECT_EQ(TRACKER_KIND_APP_ROOT
, tracker
.tracker_kind());
191 sync_worker()->UninstallOrigin(
193 RemoteFileSyncService::UNINSTALL_AND_KEEP_REMOTE
,
194 CreateResultReceiver(&sync_status
));
195 base::RunLoop().RunUntilIdle();
196 EXPECT_EQ(SYNC_STATUS_OK
, sync_status
);
197 ASSERT_FALSE(metadata_database()->FindAppRootTracker(kAppID
, &tracker
));
200 TEST_F(SyncWorkerTest
, UpdateRegisteredApps
) {
201 SyncStatusCode sync_status
= SYNC_STATUS_UNKNOWN
;
202 for (int i
= 0; i
< 3; i
++) {
203 scoped_refptr
<const extensions::Extension
> extension
=
204 extensions::ExtensionBuilder()
205 .SetManifest(extensions::DictionaryBuilder()
207 .Set("version", "1.0")
208 .Set("manifest_version", 2))
209 .SetID(base::StringPrintf("app_%d", i
))
211 extension_service()->AddExtension(extension
.get());
212 GURL origin
= extensions::Extension::GetBaseURLFromExtensionId(
214 sync_status
= SYNC_STATUS_UNKNOWN
;
215 sync_worker()->RegisterOrigin(origin
, CreateResultReceiver(&sync_status
));
216 base::RunLoop().RunUntilIdle();
217 EXPECT_EQ(SYNC_STATUS_OK
, sync_status
);
222 ASSERT_TRUE(metadata_database()->FindAppRootTracker("app_0", &tracker
));
223 EXPECT_EQ(TRACKER_KIND_APP_ROOT
, tracker
.tracker_kind());
225 ASSERT_TRUE(metadata_database()->FindAppRootTracker("app_1", &tracker
));
226 EXPECT_EQ(TRACKER_KIND_APP_ROOT
, tracker
.tracker_kind());
228 ASSERT_TRUE(metadata_database()->FindAppRootTracker("app_2", &tracker
));
229 EXPECT_EQ(TRACKER_KIND_APP_ROOT
, tracker
.tracker_kind());
231 extension_service()->DisableExtension("app_1");
232 extension_service()->UninstallExtension("app_2");
233 ASSERT_FALSE(extension_service()->GetInstalledExtension("app_2"));
234 UpdateRegisteredApps();
235 base::RunLoop().RunUntilIdle();
237 ASSERT_TRUE(metadata_database()->FindAppRootTracker("app_0", &tracker
));
238 EXPECT_EQ(TRACKER_KIND_APP_ROOT
, tracker
.tracker_kind());
240 ASSERT_TRUE(metadata_database()->FindAppRootTracker("app_1", &tracker
));
241 EXPECT_EQ(TRACKER_KIND_DISABLED_APP_ROOT
, tracker
.tracker_kind());
243 ASSERT_FALSE(metadata_database()->FindAppRootTracker("app_2", &tracker
));
246 TEST_F(SyncWorkerTest
, GetOriginStatusMap
) {
248 SyncStatusCode sync_status
= SYNC_STATUS_UNKNOWN
;
249 GURL origin
= extensions::Extension::GetBaseURLFromExtensionId(kAppID
);
251 sync_worker()->RegisterOrigin(GURL("chrome-extension://app_0"),
252 CreateResultReceiver(&sync_status
));
253 base::RunLoop().RunUntilIdle();
254 EXPECT_EQ(SYNC_STATUS_OK
, sync_status
);
256 sync_worker()->RegisterOrigin(GURL("chrome-extension://app_1"),
257 CreateResultReceiver(&sync_status
));
258 base::RunLoop().RunUntilIdle();
259 EXPECT_EQ(SYNC_STATUS_OK
, sync_status
);
261 scoped_ptr
<RemoteFileSyncService::OriginStatusMap
> status_map
;
262 sync_worker()->GetOriginStatusMap(CreateResultReceiver(&status_map
));
263 base::RunLoop().RunUntilIdle();
264 ASSERT_EQ(2u, status_map
->size());
265 EXPECT_EQ("Enabled", (*status_map
)[GURL("chrome-extension://app_0")]);
266 EXPECT_EQ("Enabled", (*status_map
)[GURL("chrome-extension://app_1")]);
268 sync_worker()->DisableOrigin(GURL("chrome-extension://app_1"),
269 CreateResultReceiver(&sync_status
));
270 base::RunLoop().RunUntilIdle();
271 EXPECT_EQ(SYNC_STATUS_OK
, sync_status
);
273 sync_worker()->GetOriginStatusMap(CreateResultReceiver(&status_map
));
274 base::RunLoop().RunUntilIdle();
275 ASSERT_EQ(2u, status_map
->size());
276 EXPECT_EQ("Enabled", (*status_map
)[GURL("chrome-extension://app_0")]);
277 EXPECT_EQ("Disabled", (*status_map
)[GURL("chrome-extension://app_1")]);
280 TEST_F(SyncWorkerTest
, UpdateServiceState
) {
281 EXPECT_EQ(REMOTE_SERVICE_OK
, sync_worker()->GetCurrentState());
283 GetSyncTaskManager()->ScheduleTask(
285 base::Bind(&EmptyTask
, SYNC_STATUS_AUTHENTICATION_FAILED
),
286 SyncTaskManager::PRIORITY_MED
,
287 base::Bind(&SyncWorkerTest::CheckServiceState
,
289 SYNC_STATUS_AUTHENTICATION_FAILED
,
290 REMOTE_SERVICE_AUTHENTICATION_REQUIRED
));
292 GetSyncTaskManager()->ScheduleTask(
294 base::Bind(&EmptyTask
, SYNC_STATUS_ACCESS_FORBIDDEN
),
295 SyncTaskManager::PRIORITY_MED
,
296 base::Bind(&SyncWorkerTest::CheckServiceState
,
298 SYNC_STATUS_ACCESS_FORBIDDEN
,
299 REMOTE_SERVICE_ACCESS_FORBIDDEN
));
301 GetSyncTaskManager()->ScheduleTask(
303 base::Bind(&EmptyTask
, SYNC_STATUS_SERVICE_TEMPORARILY_UNAVAILABLE
),
304 SyncTaskManager::PRIORITY_MED
,
305 base::Bind(&SyncWorkerTest::CheckServiceState
,
307 SYNC_STATUS_SERVICE_TEMPORARILY_UNAVAILABLE
,
308 REMOTE_SERVICE_TEMPORARY_UNAVAILABLE
));
310 GetSyncTaskManager()->ScheduleTask(
312 base::Bind(&EmptyTask
, SYNC_STATUS_NETWORK_ERROR
),
313 SyncTaskManager::PRIORITY_MED
,
314 base::Bind(&SyncWorkerTest::CheckServiceState
,
316 SYNC_STATUS_NETWORK_ERROR
,
317 REMOTE_SERVICE_TEMPORARY_UNAVAILABLE
));
319 GetSyncTaskManager()->ScheduleTask(
321 base::Bind(&EmptyTask
, SYNC_STATUS_ABORT
),
322 SyncTaskManager::PRIORITY_MED
,
323 base::Bind(&SyncWorkerTest::CheckServiceState
,
326 REMOTE_SERVICE_TEMPORARY_UNAVAILABLE
));
328 GetSyncTaskManager()->ScheduleTask(
330 base::Bind(&EmptyTask
, SYNC_STATUS_FAILED
),
331 SyncTaskManager::PRIORITY_MED
,
332 base::Bind(&SyncWorkerTest::CheckServiceState
,
335 REMOTE_SERVICE_TEMPORARY_UNAVAILABLE
));
337 GetSyncTaskManager()->ScheduleTask(
339 base::Bind(&EmptyTask
, SYNC_DATABASE_ERROR_CORRUPTION
),
340 SyncTaskManager::PRIORITY_MED
,
341 base::Bind(&SyncWorkerTest::CheckServiceState
,
343 SYNC_DATABASE_ERROR_CORRUPTION
,
344 REMOTE_SERVICE_DISABLED
));
346 GetSyncTaskManager()->ScheduleTask(
348 base::Bind(&EmptyTask
, SYNC_DATABASE_ERROR_IO_ERROR
),
349 SyncTaskManager::PRIORITY_MED
,
350 base::Bind(&SyncWorkerTest::CheckServiceState
,
352 SYNC_DATABASE_ERROR_IO_ERROR
,
353 REMOTE_SERVICE_DISABLED
));
355 GetSyncTaskManager()->ScheduleTask(
357 base::Bind(&EmptyTask
, SYNC_DATABASE_ERROR_FAILED
),
358 SyncTaskManager::PRIORITY_MED
,
359 base::Bind(&SyncWorkerTest::CheckServiceState
,
361 SYNC_DATABASE_ERROR_FAILED
,
362 REMOTE_SERVICE_DISABLED
));
364 GetSyncTaskManager()->ScheduleSyncTask(
366 scoped_ptr
<SyncTask
>(new MockSyncTask(false)),
367 SyncTaskManager::PRIORITY_MED
,
368 base::Bind(&SyncWorkerTest::CheckServiceState
,
371 REMOTE_SERVICE_DISABLED
));
373 GetSyncTaskManager()->ScheduleSyncTask(
375 scoped_ptr
<SyncTask
>(new MockSyncTask(true)),
376 SyncTaskManager::PRIORITY_MED
,
377 base::Bind(&SyncWorkerTest::CheckServiceState
,
382 base::RunLoop().RunUntilIdle();
385 } // namespace drive_backend
386 } // namespace sync_file_system