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.
5 #include "chrome/browser/sync_file_system/drive_backend/sync_engine.h"
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/extension_set.h"
20 #include "extensions/common/value_builder.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22 #include "third_party/leveldatabase/src/helpers/memenv/memenv.h"
23 #include "third_party/leveldatabase/src/include/leveldb/env.h"
25 namespace sync_file_system {
26 namespace drive_backend {
30 const char kAppID[] = "app_id";
32 void EmptyTask(SyncStatusCode status, const SyncStatusCallback& callback) {
33 base::MessageLoop::current()->PostTask(
34 FROM_HERE, base::Bind(callback, status));
39 class MockSyncTask : public SyncTask {
41 explicit MockSyncTask(bool used_network) {
42 set_used_network(used_network);
44 virtual ~MockSyncTask() {}
46 virtual void Run(const SyncStatusCallback& callback) OVERRIDE {
47 callback.Run(SYNC_STATUS_OK);
51 DISALLOW_COPY_AND_ASSIGN(MockSyncTask);
54 class MockExtensionService : public TestExtensionService {
56 MockExtensionService() {}
57 virtual ~MockExtensionService() {}
59 virtual const extensions::ExtensionSet* extensions() const OVERRIDE {
63 virtual void AddExtension(const extensions::Extension* extension) OVERRIDE {
64 extensions_.Insert(make_scoped_refptr(extension));
67 virtual const extensions::Extension* GetInstalledExtension(
68 const std::string& extension_id) const OVERRIDE {
69 return extensions_.GetByID(extension_id);
72 virtual bool IsExtensionEnabled(
73 const std::string& extension_id) const OVERRIDE {
74 return extensions_.Contains(extension_id) &&
75 !disabled_extensions_.Contains(extension_id);
78 void UninstallExtension(const std::string& extension_id) {
79 extensions_.Remove(extension_id);
80 disabled_extensions_.Remove(extension_id);
83 void DisableExtension(const std::string& extension_id) {
84 if (!IsExtensionEnabled(extension_id))
86 const extensions::Extension* extension = extensions_.GetByID(extension_id);
87 disabled_extensions_.Insert(make_scoped_refptr(extension));
91 extensions::ExtensionSet extensions_;
92 extensions::ExtensionSet disabled_extensions_;
94 DISALLOW_COPY_AND_ASSIGN(MockExtensionService);
98 : public testing::Test,
99 public base::SupportsWeakPtr<SyncEngineTest> {
102 virtual ~SyncEngineTest() {}
104 virtual 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::FakeDriveService> fake_drive_service(
110 new drive::FakeDriveService);
112 ASSERT_TRUE(fake_drive_service->LoadAccountMetadataForWapi(
113 "sync_file_system/account_metadata.json"));
114 ASSERT_TRUE(fake_drive_service->LoadResourceListForWapi(
115 "gdata/empty_feed.json"));
116 sync_engine_.reset(new drive_backend::SyncEngine(
118 base::MessageLoopProxy::current(),
119 fake_drive_service.PassAs<drive::DriveServiceInterface>(),
120 scoped_ptr<drive::DriveUploaderInterface>(),
121 NULL /* notification_manager */,
122 extension_service_.get(),
123 NULL /* auth_token_service */,
124 in_memory_env_.get()));
125 sync_engine_->Initialize();
126 base::RunLoop().RunUntilIdle();
129 virtual void TearDown() OVERRIDE {
130 sync_engine_.reset();
131 extension_service_.reset();
132 base::RunLoop().RunUntilIdle();
135 MockExtensionService* extension_service() { return extension_service_.get(); }
136 SyncEngine* sync_engine() { return sync_engine_.get(); }
138 void UpdateRegisteredApps() {
139 sync_engine_->UpdateRegisteredApps();
142 SyncTaskManager* GetSyncEngineTaskManager() {
143 return sync_engine_->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_engine_->GetCurrentState());
154 content::TestBrowserThreadBundle browser_threads_;
155 base::ScopedTempDir profile_dir_;
156 scoped_ptr<leveldb::Env> in_memory_env_;
158 scoped_ptr<MockExtensionService> extension_service_;
159 scoped_ptr<drive_backend::SyncEngine> sync_engine_;
161 DISALLOW_COPY_AND_ASSIGN(SyncEngineTest);
164 TEST_F(SyncEngineTest, EnableOrigin) {
166 SyncStatusCode sync_status = SYNC_STATUS_UNKNOWN;
167 MetadataDatabase* metadata_database = sync_engine()->GetMetadataDatabase();
168 GURL origin = extensions::Extension::GetBaseURLFromExtensionId(kAppID);
170 sync_engine()->RegisterOrigin(origin, CreateResultReceiver(&sync_status));
171 base::RunLoop().RunUntilIdle();
172 EXPECT_EQ(SYNC_STATUS_OK, sync_status);
173 ASSERT_TRUE(metadata_database->FindAppRootTracker(kAppID, &tracker));
174 EXPECT_EQ(TRACKER_KIND_APP_ROOT, tracker.tracker_kind());
176 sync_engine()->DisableOrigin(origin, CreateResultReceiver(&sync_status));
177 base::RunLoop().RunUntilIdle();
178 EXPECT_EQ(SYNC_STATUS_OK, sync_status);
179 ASSERT_TRUE(metadata_database->FindAppRootTracker(kAppID, &tracker));
180 EXPECT_EQ(TRACKER_KIND_DISABLED_APP_ROOT, tracker.tracker_kind());
182 sync_engine()->EnableOrigin(origin, CreateResultReceiver(&sync_status));
183 base::RunLoop().RunUntilIdle();
184 EXPECT_EQ(SYNC_STATUS_OK, sync_status);
185 ASSERT_TRUE(metadata_database->FindAppRootTracker(kAppID, &tracker));
186 EXPECT_EQ(TRACKER_KIND_APP_ROOT, tracker.tracker_kind());
188 sync_engine()->UninstallOrigin(
190 RemoteFileSyncService::UNINSTALL_AND_KEEP_REMOTE,
191 CreateResultReceiver(&sync_status));
192 base::RunLoop().RunUntilIdle();
193 EXPECT_EQ(SYNC_STATUS_OK, sync_status);
194 ASSERT_FALSE(metadata_database->FindAppRootTracker(kAppID, &tracker));
197 TEST_F(SyncEngineTest, UpdateRegisteredApps) {
198 SyncStatusCode sync_status = SYNC_STATUS_UNKNOWN;
199 for (int i = 0; i < 3; i++) {
200 scoped_refptr<const extensions::Extension> extension =
201 extensions::ExtensionBuilder()
202 .SetManifest(extensions::DictionaryBuilder()
204 .Set("version", "1.0")
205 .Set("manifest_version", 2))
206 .SetID(base::StringPrintf("app_%d", i))
208 extension_service()->AddExtension(extension.get());
209 GURL origin = extensions::Extension::GetBaseURLFromExtensionId(
211 sync_status = SYNC_STATUS_UNKNOWN;
212 sync_engine()->RegisterOrigin(origin, CreateResultReceiver(&sync_status));
213 base::RunLoop().RunUntilIdle();
214 EXPECT_EQ(SYNC_STATUS_OK, sync_status);
217 MetadataDatabase* metadata_database = sync_engine()->GetMetadataDatabase();
220 ASSERT_TRUE(metadata_database->FindAppRootTracker("app_0", &tracker));
221 EXPECT_EQ(TRACKER_KIND_APP_ROOT, tracker.tracker_kind());
223 ASSERT_TRUE(metadata_database->FindAppRootTracker("app_1", &tracker));
224 EXPECT_EQ(TRACKER_KIND_APP_ROOT, tracker.tracker_kind());
226 ASSERT_TRUE(metadata_database->FindAppRootTracker("app_2", &tracker));
227 EXPECT_EQ(TRACKER_KIND_APP_ROOT, tracker.tracker_kind());
229 extension_service()->DisableExtension("app_1");
230 extension_service()->UninstallExtension("app_2");
231 ASSERT_FALSE(extension_service()->GetInstalledExtension("app_2"));
232 UpdateRegisteredApps();
233 base::RunLoop().RunUntilIdle();
235 ASSERT_TRUE(metadata_database->FindAppRootTracker("app_0", &tracker));
236 EXPECT_EQ(TRACKER_KIND_APP_ROOT, tracker.tracker_kind());
238 ASSERT_TRUE(metadata_database->FindAppRootTracker("app_1", &tracker));
239 EXPECT_EQ(TRACKER_KIND_DISABLED_APP_ROOT, tracker.tracker_kind());
241 ASSERT_FALSE(metadata_database->FindAppRootTracker("app_2", &tracker));
244 TEST_F(SyncEngineTest, GetOriginStatusMap) {
246 SyncStatusCode sync_status = SYNC_STATUS_UNKNOWN;
247 GURL origin = extensions::Extension::GetBaseURLFromExtensionId(kAppID);
249 sync_engine()->RegisterOrigin(GURL("chrome-extension://app_0"),
250 CreateResultReceiver(&sync_status));
251 base::RunLoop().RunUntilIdle();
252 EXPECT_EQ(SYNC_STATUS_OK, sync_status);
254 sync_engine()->RegisterOrigin(GURL("chrome-extension://app_1"),
255 CreateResultReceiver(&sync_status));
256 base::RunLoop().RunUntilIdle();
257 EXPECT_EQ(SYNC_STATUS_OK, sync_status);
259 RemoteFileSyncService::OriginStatusMap status_map;
260 sync_engine()->GetOriginStatusMap(&status_map);
261 ASSERT_EQ(2u, status_map.size());
262 EXPECT_EQ("Enabled", status_map[GURL("chrome-extension://app_0")]);
263 EXPECT_EQ("Enabled", status_map[GURL("chrome-extension://app_1")]);
265 sync_engine()->DisableOrigin(GURL("chrome-extension://app_1"),
266 CreateResultReceiver(&sync_status));
267 base::RunLoop().RunUntilIdle();
268 EXPECT_EQ(SYNC_STATUS_OK, sync_status);
270 sync_engine()->GetOriginStatusMap(&status_map);
271 ASSERT_EQ(2u, status_map.size());
272 EXPECT_EQ("Enabled", status_map[GURL("chrome-extension://app_0")]);
273 EXPECT_EQ("Disabled", status_map[GURL("chrome-extension://app_1")]);
276 TEST_F(SyncEngineTest, UpdateServiceState) {
277 EXPECT_EQ(REMOTE_SERVICE_OK, sync_engine()->GetCurrentState());
279 GetSyncEngineTaskManager()->ScheduleTask(
280 base::Bind(&EmptyTask, SYNC_STATUS_AUTHENTICATION_FAILED),
281 base::Bind(&SyncEngineTest::CheckServiceState,
283 SYNC_STATUS_AUTHENTICATION_FAILED,
284 REMOTE_SERVICE_AUTHENTICATION_REQUIRED));
286 GetSyncEngineTaskManager()->ScheduleTask(
287 base::Bind(&EmptyTask, SYNC_STATUS_ACCESS_FORBIDDEN),
288 base::Bind(&SyncEngineTest::CheckServiceState,
290 SYNC_STATUS_ACCESS_FORBIDDEN,
291 REMOTE_SERVICE_AUTHENTICATION_REQUIRED));
293 GetSyncEngineTaskManager()->ScheduleTask(
294 base::Bind(&EmptyTask, SYNC_STATUS_SERVICE_TEMPORARILY_UNAVAILABLE),
295 base::Bind(&SyncEngineTest::CheckServiceState,
297 SYNC_STATUS_SERVICE_TEMPORARILY_UNAVAILABLE,
298 REMOTE_SERVICE_TEMPORARY_UNAVAILABLE));
300 GetSyncEngineTaskManager()->ScheduleTask(
301 base::Bind(&EmptyTask, SYNC_STATUS_NETWORK_ERROR),
302 base::Bind(&SyncEngineTest::CheckServiceState,
304 SYNC_STATUS_NETWORK_ERROR,
305 REMOTE_SERVICE_TEMPORARY_UNAVAILABLE));
307 GetSyncEngineTaskManager()->ScheduleTask(
308 base::Bind(&EmptyTask, SYNC_STATUS_ABORT),
309 base::Bind(&SyncEngineTest::CheckServiceState,
312 REMOTE_SERVICE_TEMPORARY_UNAVAILABLE));
314 GetSyncEngineTaskManager()->ScheduleTask(
315 base::Bind(&EmptyTask, SYNC_STATUS_FAILED),
316 base::Bind(&SyncEngineTest::CheckServiceState,
319 REMOTE_SERVICE_TEMPORARY_UNAVAILABLE));
321 GetSyncEngineTaskManager()->ScheduleTask(
322 base::Bind(&EmptyTask, SYNC_DATABASE_ERROR_CORRUPTION),
323 base::Bind(&SyncEngineTest::CheckServiceState,
325 SYNC_DATABASE_ERROR_CORRUPTION,
326 REMOTE_SERVICE_DISABLED));
328 GetSyncEngineTaskManager()->ScheduleTask(
329 base::Bind(&EmptyTask, SYNC_DATABASE_ERROR_IO_ERROR),
330 base::Bind(&SyncEngineTest::CheckServiceState,
332 SYNC_DATABASE_ERROR_IO_ERROR,
333 REMOTE_SERVICE_DISABLED));
335 GetSyncEngineTaskManager()->ScheduleTask(
336 base::Bind(&EmptyTask, SYNC_DATABASE_ERROR_FAILED),
337 base::Bind(&SyncEngineTest::CheckServiceState,
339 SYNC_DATABASE_ERROR_FAILED,
340 REMOTE_SERVICE_DISABLED));
342 GetSyncEngineTaskManager()->ScheduleSyncTask(
343 scoped_ptr<SyncTask>(new MockSyncTask(false)),
344 base::Bind(&SyncEngineTest::CheckServiceState,
347 REMOTE_SERVICE_DISABLED));
349 GetSyncEngineTaskManager()->ScheduleSyncTask(
350 scoped_ptr<SyncTask>(new MockSyncTask(true)),
351 base::Bind(&SyncEngineTest::CheckServiceState,
356 base::RunLoop().RunUntilIdle();
359 } // namespace drive_backend
360 } // namespace sync_file_system