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