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