sync_worker_unittest.cc revision 116680a4aac90f2aa7413d9095a592090648e557
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. 4 5#include "chrome/browser/sync_file_system/drive_backend/sync_worker.h" 6 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" 28 29namespace sync_file_system { 30namespace drive_backend { 31 32namespace { 33 34const char kAppID[] = "app_id"; 35 36void EmptyTask(SyncStatusCode status, const SyncStatusCallback& callback) { 37 base::MessageLoop::current()->PostTask( 38 FROM_HERE, base::Bind(callback, status)); 39} 40 41} // namespace 42 43class MockSyncTask : public ExclusiveTask { 44 public: 45 explicit MockSyncTask(bool used_network) { 46 set_used_network(used_network); 47 } 48 virtual ~MockSyncTask() {} 49 50 virtual void RunExclusive(const SyncStatusCallback& callback) OVERRIDE { 51 callback.Run(SYNC_STATUS_OK); 52 } 53 54 private: 55 DISALLOW_COPY_AND_ASSIGN(MockSyncTask); 56}; 57 58class MockExtensionService : public TestExtensionService { 59 public: 60 MockExtensionService() {} 61 virtual ~MockExtensionService() {} 62 63 virtual const extensions::ExtensionSet* extensions() const OVERRIDE { 64 return &extensions_; 65 } 66 67 virtual void AddExtension(const extensions::Extension* extension) OVERRIDE { 68 extensions_.Insert(make_scoped_refptr(extension)); 69 } 70 71 virtual const extensions::Extension* GetInstalledExtension( 72 const std::string& extension_id) const OVERRIDE { 73 return extensions_.GetByID(extension_id); 74 } 75 76 virtual bool IsExtensionEnabled( 77 const std::string& extension_id) const OVERRIDE { 78 return extensions_.Contains(extension_id) && 79 !disabled_extensions_.Contains(extension_id); 80 } 81 82 void UninstallExtension(const std::string& extension_id) { 83 extensions_.Remove(extension_id); 84 disabled_extensions_.Remove(extension_id); 85 } 86 87 void DisableExtension(const std::string& extension_id) { 88 if (!IsExtensionEnabled(extension_id)) 89 return; 90 const extensions::Extension* extension = extensions_.GetByID(extension_id); 91 disabled_extensions_.Insert(make_scoped_refptr(extension)); 92 } 93 94 private: 95 extensions::ExtensionSet extensions_; 96 extensions::ExtensionSet disabled_extensions_; 97 98 DISALLOW_COPY_AND_ASSIGN(MockExtensionService); 99}; 100 101class SyncWorkerTest : public testing::Test, 102 public base::SupportsWeakPtr<SyncWorkerTest> { 103 public: 104 SyncWorkerTest() {} 105 virtual ~SyncWorkerTest() {} 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 scoped_ptr<SyncEngineContext> 116 sync_engine_context(new SyncEngineContext( 117 fake_drive_service.Pass(), 118 scoped_ptr<drive::DriveUploaderInterface>(), 119 NULL /* task_logger */, 120 base::ThreadTaskRunnerHandle::Get() /* ui_task_runner */, 121 base::ThreadTaskRunnerHandle::Get() /* worker_task_runner */, 122 base::ThreadTaskRunnerHandle::Get() /* file_task_runner */)); 123 124 sync_worker_.reset(new SyncWorker( 125 profile_dir_.path(), 126 extension_service_->AsWeakPtr(), 127 in_memory_env_.get())); 128 sync_worker_->Initialize(sync_engine_context.Pass()); 129 130 sync_worker_->SetSyncEnabled(true); 131 base::RunLoop().RunUntilIdle(); 132 } 133 134 virtual void TearDown() OVERRIDE { 135 sync_worker_.reset(); 136 extension_service_.reset(); 137 base::RunLoop().RunUntilIdle(); 138 } 139 140 MockExtensionService* extension_service() { return extension_service_.get(); } 141 SyncWorker* sync_worker() { return sync_worker_.get(); } 142 143 void UpdateRegisteredApps() { 144 sync_worker_->UpdateRegisteredApps(); 145 } 146 147 SyncTaskManager* GetSyncTaskManager() { 148 return sync_worker_->task_manager_.get(); 149 } 150 151 void CheckServiceState(SyncStatusCode expected_sync_status, 152 RemoteServiceState expected_service_status, 153 SyncStatusCode sync_status) { 154 EXPECT_EQ(expected_sync_status, sync_status); 155 EXPECT_EQ(expected_service_status, sync_worker_->GetCurrentState()); 156 } 157 158 MetadataDatabase* metadata_database() { 159 return sync_worker_->GetMetadataDatabase(); 160 } 161 162 void SetHasRefreshToken(bool has_refresh_token) { 163 sync_worker_->has_refresh_token_ = has_refresh_token; 164 } 165 166 private: 167 content::TestBrowserThreadBundle browser_threads_; 168 base::ScopedTempDir profile_dir_; 169 scoped_ptr<leveldb::Env> in_memory_env_; 170 171 scoped_ptr<MockExtensionService> extension_service_; 172 scoped_ptr<SyncWorker> sync_worker_; 173 174 DISALLOW_COPY_AND_ASSIGN(SyncWorkerTest); 175}; 176 177TEST_F(SyncWorkerTest, EnableOrigin) { 178 FileTracker tracker; 179 SyncStatusCode sync_status = SYNC_STATUS_UNKNOWN; 180 GURL origin = extensions::Extension::GetBaseURLFromExtensionId(kAppID); 181 182 sync_worker()->RegisterOrigin(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()); 187 188 sync_worker()->DisableOrigin(origin, CreateResultReceiver(&sync_status)); 189 base::RunLoop().RunUntilIdle(); 190 EXPECT_EQ(SYNC_STATUS_OK, sync_status); 191 ASSERT_TRUE(metadata_database()->FindAppRootTracker(kAppID, &tracker)); 192 EXPECT_EQ(TRACKER_KIND_DISABLED_APP_ROOT, tracker.tracker_kind()); 193 194 sync_worker()->EnableOrigin(origin, CreateResultReceiver(&sync_status)); 195 base::RunLoop().RunUntilIdle(); 196 EXPECT_EQ(SYNC_STATUS_OK, sync_status); 197 ASSERT_TRUE(metadata_database()->FindAppRootTracker(kAppID, &tracker)); 198 EXPECT_EQ(TRACKER_KIND_APP_ROOT, tracker.tracker_kind()); 199 200 sync_worker()->UninstallOrigin( 201 origin, 202 RemoteFileSyncService::UNINSTALL_AND_KEEP_REMOTE, 203 CreateResultReceiver(&sync_status)); 204 base::RunLoop().RunUntilIdle(); 205 EXPECT_EQ(SYNC_STATUS_OK, sync_status); 206 ASSERT_FALSE(metadata_database()->FindAppRootTracker(kAppID, &tracker)); 207} 208 209TEST_F(SyncWorkerTest, UpdateRegisteredApps) { 210 SyncStatusCode sync_status = SYNC_STATUS_UNKNOWN; 211 for (int i = 0; i < 3; i++) { 212 scoped_refptr<const extensions::Extension> extension = 213 extensions::ExtensionBuilder() 214 .SetManifest(extensions::DictionaryBuilder() 215 .Set("name", "foo") 216 .Set("version", "1.0") 217 .Set("manifest_version", 2)) 218 .SetID(base::StringPrintf("app_%d", i)) 219 .Build(); 220 extension_service()->AddExtension(extension.get()); 221 GURL origin = extensions::Extension::GetBaseURLFromExtensionId( 222 extension->id()); 223 sync_status = SYNC_STATUS_UNKNOWN; 224 sync_worker()->RegisterOrigin(origin, CreateResultReceiver(&sync_status)); 225 base::RunLoop().RunUntilIdle(); 226 EXPECT_EQ(SYNC_STATUS_OK, sync_status); 227 } 228 229 FileTracker tracker; 230 231 ASSERT_TRUE(metadata_database()->FindAppRootTracker("app_0", &tracker)); 232 EXPECT_EQ(TRACKER_KIND_APP_ROOT, tracker.tracker_kind()); 233 234 ASSERT_TRUE(metadata_database()->FindAppRootTracker("app_1", &tracker)); 235 EXPECT_EQ(TRACKER_KIND_APP_ROOT, tracker.tracker_kind()); 236 237 ASSERT_TRUE(metadata_database()->FindAppRootTracker("app_2", &tracker)); 238 EXPECT_EQ(TRACKER_KIND_APP_ROOT, tracker.tracker_kind()); 239 240 extension_service()->DisableExtension("app_1"); 241 extension_service()->UninstallExtension("app_2"); 242 ASSERT_FALSE(extension_service()->GetInstalledExtension("app_2")); 243 UpdateRegisteredApps(); 244 base::RunLoop().RunUntilIdle(); 245 246 ASSERT_TRUE(metadata_database()->FindAppRootTracker("app_0", &tracker)); 247 EXPECT_EQ(TRACKER_KIND_APP_ROOT, tracker.tracker_kind()); 248 249 ASSERT_TRUE(metadata_database()->FindAppRootTracker("app_1", &tracker)); 250 EXPECT_EQ(TRACKER_KIND_DISABLED_APP_ROOT, tracker.tracker_kind()); 251 252 ASSERT_FALSE(metadata_database()->FindAppRootTracker("app_2", &tracker)); 253} 254 255TEST_F(SyncWorkerTest, GetOriginStatusMap) { 256 FileTracker tracker; 257 SyncStatusCode sync_status = SYNC_STATUS_UNKNOWN; 258 GURL origin = extensions::Extension::GetBaseURLFromExtensionId(kAppID); 259 260 sync_worker()->RegisterOrigin(GURL("chrome-extension://app_0"), 261 CreateResultReceiver(&sync_status)); 262 base::RunLoop().RunUntilIdle(); 263 EXPECT_EQ(SYNC_STATUS_OK, sync_status); 264 265 sync_worker()->RegisterOrigin(GURL("chrome-extension://app_1"), 266 CreateResultReceiver(&sync_status)); 267 base::RunLoop().RunUntilIdle(); 268 EXPECT_EQ(SYNC_STATUS_OK, sync_status); 269 270 scoped_ptr<RemoteFileSyncService::OriginStatusMap> status_map; 271 sync_worker()->GetOriginStatusMap(CreateResultReceiver(&status_map)); 272 base::RunLoop().RunUntilIdle(); 273 ASSERT_EQ(2u, status_map->size()); 274 EXPECT_EQ("Enabled", (*status_map)[GURL("chrome-extension://app_0")]); 275 EXPECT_EQ("Enabled", (*status_map)[GURL("chrome-extension://app_1")]); 276 277 sync_worker()->DisableOrigin(GURL("chrome-extension://app_1"), 278 CreateResultReceiver(&sync_status)); 279 base::RunLoop().RunUntilIdle(); 280 EXPECT_EQ(SYNC_STATUS_OK, sync_status); 281 282 sync_worker()->GetOriginStatusMap(CreateResultReceiver(&status_map)); 283 base::RunLoop().RunUntilIdle(); 284 ASSERT_EQ(2u, status_map->size()); 285 EXPECT_EQ("Enabled", (*status_map)[GURL("chrome-extension://app_0")]); 286 EXPECT_EQ("Disabled", (*status_map)[GURL("chrome-extension://app_1")]); 287} 288 289TEST_F(SyncWorkerTest, UpdateServiceState) { 290 EXPECT_EQ(REMOTE_SERVICE_OK, sync_worker()->GetCurrentState()); 291 292 // Assume an user is in login state. 293 SetHasRefreshToken(true); 294 295 GetSyncTaskManager()->ScheduleTask( 296 FROM_HERE, 297 base::Bind(&EmptyTask, SYNC_STATUS_AUTHENTICATION_FAILED), 298 SyncTaskManager::PRIORITY_MED, 299 base::Bind(&SyncWorkerTest::CheckServiceState, 300 AsWeakPtr(), 301 SYNC_STATUS_AUTHENTICATION_FAILED, 302 REMOTE_SERVICE_AUTHENTICATION_REQUIRED)); 303 304 GetSyncTaskManager()->ScheduleTask( 305 FROM_HERE, 306 base::Bind(&EmptyTask, SYNC_STATUS_ACCESS_FORBIDDEN), 307 SyncTaskManager::PRIORITY_MED, 308 base::Bind(&SyncWorkerTest::CheckServiceState, 309 AsWeakPtr(), 310 SYNC_STATUS_ACCESS_FORBIDDEN, 311 REMOTE_SERVICE_AUTHENTICATION_REQUIRED)); 312 313 GetSyncTaskManager()->ScheduleTask( 314 FROM_HERE, 315 base::Bind(&EmptyTask, SYNC_STATUS_SERVICE_TEMPORARILY_UNAVAILABLE), 316 SyncTaskManager::PRIORITY_MED, 317 base::Bind(&SyncWorkerTest::CheckServiceState, 318 AsWeakPtr(), 319 SYNC_STATUS_SERVICE_TEMPORARILY_UNAVAILABLE, 320 REMOTE_SERVICE_TEMPORARY_UNAVAILABLE)); 321 322 GetSyncTaskManager()->ScheduleTask( 323 FROM_HERE, 324 base::Bind(&EmptyTask, SYNC_STATUS_NETWORK_ERROR), 325 SyncTaskManager::PRIORITY_MED, 326 base::Bind(&SyncWorkerTest::CheckServiceState, 327 AsWeakPtr(), 328 SYNC_STATUS_NETWORK_ERROR, 329 REMOTE_SERVICE_TEMPORARY_UNAVAILABLE)); 330 331 GetSyncTaskManager()->ScheduleTask( 332 FROM_HERE, 333 base::Bind(&EmptyTask, SYNC_STATUS_ABORT), 334 SyncTaskManager::PRIORITY_MED, 335 base::Bind(&SyncWorkerTest::CheckServiceState, 336 AsWeakPtr(), 337 SYNC_STATUS_ABORT, 338 REMOTE_SERVICE_TEMPORARY_UNAVAILABLE)); 339 340 GetSyncTaskManager()->ScheduleTask( 341 FROM_HERE, 342 base::Bind(&EmptyTask, SYNC_STATUS_FAILED), 343 SyncTaskManager::PRIORITY_MED, 344 base::Bind(&SyncWorkerTest::CheckServiceState, 345 AsWeakPtr(), 346 SYNC_STATUS_FAILED, 347 REMOTE_SERVICE_TEMPORARY_UNAVAILABLE)); 348 349 GetSyncTaskManager()->ScheduleTask( 350 FROM_HERE, 351 base::Bind(&EmptyTask, SYNC_DATABASE_ERROR_CORRUPTION), 352 SyncTaskManager::PRIORITY_MED, 353 base::Bind(&SyncWorkerTest::CheckServiceState, 354 AsWeakPtr(), 355 SYNC_DATABASE_ERROR_CORRUPTION, 356 REMOTE_SERVICE_DISABLED)); 357 358 GetSyncTaskManager()->ScheduleTask( 359 FROM_HERE, 360 base::Bind(&EmptyTask, SYNC_DATABASE_ERROR_IO_ERROR), 361 SyncTaskManager::PRIORITY_MED, 362 base::Bind(&SyncWorkerTest::CheckServiceState, 363 AsWeakPtr(), 364 SYNC_DATABASE_ERROR_IO_ERROR, 365 REMOTE_SERVICE_DISABLED)); 366 367 GetSyncTaskManager()->ScheduleTask( 368 FROM_HERE, 369 base::Bind(&EmptyTask, SYNC_DATABASE_ERROR_FAILED), 370 SyncTaskManager::PRIORITY_MED, 371 base::Bind(&SyncWorkerTest::CheckServiceState, 372 AsWeakPtr(), 373 SYNC_DATABASE_ERROR_FAILED, 374 REMOTE_SERVICE_DISABLED)); 375 376 GetSyncTaskManager()->ScheduleSyncTask( 377 FROM_HERE, 378 scoped_ptr<SyncTask>(new MockSyncTask(false)), 379 SyncTaskManager::PRIORITY_MED, 380 base::Bind(&SyncWorkerTest::CheckServiceState, 381 AsWeakPtr(), 382 SYNC_STATUS_OK, 383 REMOTE_SERVICE_DISABLED)); 384 385 GetSyncTaskManager()->ScheduleSyncTask( 386 FROM_HERE, 387 scoped_ptr<SyncTask>(new MockSyncTask(true)), 388 SyncTaskManager::PRIORITY_MED, 389 base::Bind(&SyncWorkerTest::CheckServiceState, 390 AsWeakPtr(), 391 SYNC_STATUS_OK, 392 REMOTE_SERVICE_OK)); 393 394 base::RunLoop().RunUntilIdle(); 395} 396 397} // namespace drive_backend 398} // namespace sync_file_system 399