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