sync_engine_unittest.cc revision cedac228d2dd51db4b79ea1e72c7f249408ee061
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::DriveServiceInterface> 112 fake_drive_service(new drive::FakeDriveService); 113 114 sync_engine_.reset(new drive_backend::SyncEngine( 115 fake_drive_service.Pass(), 116 scoped_ptr<drive::DriveUploaderInterface>(), 117 base::MessageLoopProxy::current(), 118 NULL /* notification_manager */, 119 extension_service_.get(), 120 NULL /* signin_manager */)); 121 sync_engine_->Initialize(profile_dir_.path(), 122 NULL, 123 base::MessageLoopProxy::current(), 124 in_memory_env_.get()); 125 sync_engine_->SetSyncEnabled(true); 126 base::RunLoop().RunUntilIdle(); 127 } 128 129 virtual void TearDown() OVERRIDE { 130 sync_engine_.reset(); 131 extension_service_.reset(); 132 base::RunLoop().RunUntilIdle(); 133 } 134 135 MockExtensionService* extension_service() { return extension_service_.get(); } 136 SyncEngine* sync_engine() { return sync_engine_.get(); } 137 138 void UpdateRegisteredApps() { 139 sync_engine_->UpdateRegisteredApps(); 140 } 141 142 SyncTaskManager* GetSyncEngineTaskManager() { 143 return sync_engine_->GetSyncTaskManagerForTesting(); 144 } 145 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()); 151 } 152 153 private: 154 content::TestBrowserThreadBundle browser_threads_; 155 base::ScopedTempDir profile_dir_; 156 scoped_ptr<leveldb::Env> in_memory_env_; 157 158 scoped_ptr<MockExtensionService> extension_service_; 159 scoped_ptr<drive_backend::SyncEngine> sync_engine_; 160 161 DISALLOW_COPY_AND_ASSIGN(SyncEngineTest); 162}; 163 164TEST_F(SyncEngineTest, EnableOrigin) { 165 FileTracker tracker; 166 SyncStatusCode sync_status = SYNC_STATUS_UNKNOWN; 167 MetadataDatabase* metadata_database = sync_engine()->GetMetadataDatabase(); 168 GURL origin = extensions::Extension::GetBaseURLFromExtensionId(kAppID); 169 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()); 175 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()); 181 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()); 187 188 sync_engine()->UninstallOrigin( 189 origin, 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)); 195} 196 197TEST_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() 203 .Set("name", "foo") 204 .Set("version", "1.0") 205 .Set("manifest_version", 2)) 206 .SetID(base::StringPrintf("app_%d", i)) 207 .Build(); 208 extension_service()->AddExtension(extension.get()); 209 GURL origin = extensions::Extension::GetBaseURLFromExtensionId( 210 extension->id()); 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); 215 } 216 217 MetadataDatabase* metadata_database = sync_engine()->GetMetadataDatabase(); 218 FileTracker tracker; 219 220 ASSERT_TRUE(metadata_database->FindAppRootTracker("app_0", &tracker)); 221 EXPECT_EQ(TRACKER_KIND_APP_ROOT, tracker.tracker_kind()); 222 223 ASSERT_TRUE(metadata_database->FindAppRootTracker("app_1", &tracker)); 224 EXPECT_EQ(TRACKER_KIND_APP_ROOT, tracker.tracker_kind()); 225 226 ASSERT_TRUE(metadata_database->FindAppRootTracker("app_2", &tracker)); 227 EXPECT_EQ(TRACKER_KIND_APP_ROOT, tracker.tracker_kind()); 228 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(); 234 235 ASSERT_TRUE(metadata_database->FindAppRootTracker("app_0", &tracker)); 236 EXPECT_EQ(TRACKER_KIND_APP_ROOT, tracker.tracker_kind()); 237 238 ASSERT_TRUE(metadata_database->FindAppRootTracker("app_1", &tracker)); 239 EXPECT_EQ(TRACKER_KIND_DISABLED_APP_ROOT, tracker.tracker_kind()); 240 241 ASSERT_FALSE(metadata_database->FindAppRootTracker("app_2", &tracker)); 242} 243 244TEST_F(SyncEngineTest, GetOriginStatusMap) { 245 FileTracker tracker; 246 SyncStatusCode sync_status = SYNC_STATUS_UNKNOWN; 247 GURL origin = extensions::Extension::GetBaseURLFromExtensionId(kAppID); 248 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); 253 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); 258 259 scoped_ptr<RemoteFileSyncService::OriginStatusMap> status_map; 260 sync_engine()->GetOriginStatusMap(CreateResultReceiver(&status_map)); 261 base::RunLoop().RunUntilIdle(); 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(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("Disabled", (*status_map)[GURL("chrome-extension://app_1")]); 276} 277 278TEST_F(SyncEngineTest, UpdateServiceState) { 279 EXPECT_EQ(REMOTE_SERVICE_OK, sync_engine()->GetCurrentState()); 280 281 GetSyncEngineTaskManager()->ScheduleTask( 282 FROM_HERE, 283 base::Bind(&EmptyTask, SYNC_STATUS_AUTHENTICATION_FAILED), 284 SyncTaskManager::PRIORITY_MED, 285 base::Bind(&SyncEngineTest::CheckServiceState, 286 AsWeakPtr(), 287 SYNC_STATUS_AUTHENTICATION_FAILED, 288 REMOTE_SERVICE_AUTHENTICATION_REQUIRED)); 289 290 GetSyncEngineTaskManager()->ScheduleTask( 291 FROM_HERE, 292 base::Bind(&EmptyTask, SYNC_STATUS_ACCESS_FORBIDDEN), 293 SyncTaskManager::PRIORITY_MED, 294 base::Bind(&SyncEngineTest::CheckServiceState, 295 AsWeakPtr(), 296 SYNC_STATUS_ACCESS_FORBIDDEN, 297 REMOTE_SERVICE_AUTHENTICATION_REQUIRED)); 298 299 GetSyncEngineTaskManager()->ScheduleTask( 300 FROM_HERE, 301 base::Bind(&EmptyTask, SYNC_STATUS_SERVICE_TEMPORARILY_UNAVAILABLE), 302 SyncTaskManager::PRIORITY_MED, 303 base::Bind(&SyncEngineTest::CheckServiceState, 304 AsWeakPtr(), 305 SYNC_STATUS_SERVICE_TEMPORARILY_UNAVAILABLE, 306 REMOTE_SERVICE_TEMPORARY_UNAVAILABLE)); 307 308 GetSyncEngineTaskManager()->ScheduleTask( 309 FROM_HERE, 310 base::Bind(&EmptyTask, SYNC_STATUS_NETWORK_ERROR), 311 SyncTaskManager::PRIORITY_MED, 312 base::Bind(&SyncEngineTest::CheckServiceState, 313 AsWeakPtr(), 314 SYNC_STATUS_NETWORK_ERROR, 315 REMOTE_SERVICE_TEMPORARY_UNAVAILABLE)); 316 317 GetSyncEngineTaskManager()->ScheduleTask( 318 FROM_HERE, 319 base::Bind(&EmptyTask, SYNC_STATUS_ABORT), 320 SyncTaskManager::PRIORITY_MED, 321 base::Bind(&SyncEngineTest::CheckServiceState, 322 AsWeakPtr(), 323 SYNC_STATUS_ABORT, 324 REMOTE_SERVICE_TEMPORARY_UNAVAILABLE)); 325 326 GetSyncEngineTaskManager()->ScheduleTask( 327 FROM_HERE, 328 base::Bind(&EmptyTask, SYNC_STATUS_FAILED), 329 SyncTaskManager::PRIORITY_MED, 330 base::Bind(&SyncEngineTest::CheckServiceState, 331 AsWeakPtr(), 332 SYNC_STATUS_FAILED, 333 REMOTE_SERVICE_TEMPORARY_UNAVAILABLE)); 334 335 GetSyncEngineTaskManager()->ScheduleTask( 336 FROM_HERE, 337 base::Bind(&EmptyTask, SYNC_DATABASE_ERROR_CORRUPTION), 338 SyncTaskManager::PRIORITY_MED, 339 base::Bind(&SyncEngineTest::CheckServiceState, 340 AsWeakPtr(), 341 SYNC_DATABASE_ERROR_CORRUPTION, 342 REMOTE_SERVICE_DISABLED)); 343 344 GetSyncEngineTaskManager()->ScheduleTask( 345 FROM_HERE, 346 base::Bind(&EmptyTask, SYNC_DATABASE_ERROR_IO_ERROR), 347 SyncTaskManager::PRIORITY_MED, 348 base::Bind(&SyncEngineTest::CheckServiceState, 349 AsWeakPtr(), 350 SYNC_DATABASE_ERROR_IO_ERROR, 351 REMOTE_SERVICE_DISABLED)); 352 353 GetSyncEngineTaskManager()->ScheduleTask( 354 FROM_HERE, 355 base::Bind(&EmptyTask, SYNC_DATABASE_ERROR_FAILED), 356 SyncTaskManager::PRIORITY_MED, 357 base::Bind(&SyncEngineTest::CheckServiceState, 358 AsWeakPtr(), 359 SYNC_DATABASE_ERROR_FAILED, 360 REMOTE_SERVICE_DISABLED)); 361 362 GetSyncEngineTaskManager()->ScheduleSyncTask( 363 FROM_HERE, 364 scoped_ptr<SyncTask>(new MockSyncTask(false)), 365 SyncTaskManager::PRIORITY_MED, 366 base::Bind(&SyncEngineTest::CheckServiceState, 367 AsWeakPtr(), 368 SYNC_STATUS_OK, 369 REMOTE_SERVICE_DISABLED)); 370 371 GetSyncEngineTaskManager()->ScheduleSyncTask( 372 FROM_HERE, 373 scoped_ptr<SyncTask>(new MockSyncTask(true)), 374 SyncTaskManager::PRIORITY_MED, 375 base::Bind(&SyncEngineTest::CheckServiceState, 376 AsWeakPtr(), 377 SYNC_STATUS_OK, 378 REMOTE_SERVICE_OK)); 379 380 base::RunLoop().RunUntilIdle(); 381} 382 383} // namespace drive_backend 384} // namespace sync_file_system 385