sync_engine_unittest.cc revision 010d83a9304c5a91596085d917d248abff47903a
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 base::MessageLoopProxy::current(), 123 in_memory_env_.get()); 124 sync_engine_->SetSyncEnabled(true); 125 base::RunLoop().RunUntilIdle(); 126 } 127 128 virtual void TearDown() OVERRIDE { 129 sync_engine_.reset(); 130 extension_service_.reset(); 131 base::RunLoop().RunUntilIdle(); 132 } 133 134 MockExtensionService* extension_service() { return extension_service_.get(); } 135 SyncEngine* sync_engine() { return sync_engine_.get(); } 136 137 void UpdateRegisteredApps() { 138 sync_engine_->UpdateRegisteredApps(); 139 } 140 141 SyncTaskManager* GetSyncEngineTaskManager() { 142 return sync_engine_->GetSyncTaskManagerForTesting(); 143 } 144 145 void CheckServiceState(SyncStatusCode expected_sync_status, 146 RemoteServiceState expected_service_status, 147 SyncStatusCode sync_status) { 148 EXPECT_EQ(expected_sync_status, sync_status); 149 EXPECT_EQ(expected_service_status, sync_engine_->GetCurrentState()); 150 } 151 152 private: 153 content::TestBrowserThreadBundle browser_threads_; 154 base::ScopedTempDir profile_dir_; 155 scoped_ptr<leveldb::Env> in_memory_env_; 156 157 scoped_ptr<MockExtensionService> extension_service_; 158 scoped_ptr<drive_backend::SyncEngine> sync_engine_; 159 160 DISALLOW_COPY_AND_ASSIGN(SyncEngineTest); 161}; 162 163TEST_F(SyncEngineTest, EnableOrigin) { 164 FileTracker tracker; 165 SyncStatusCode sync_status = SYNC_STATUS_UNKNOWN; 166 MetadataDatabase* metadata_database = sync_engine()->GetMetadataDatabase(); 167 GURL origin = extensions::Extension::GetBaseURLFromExtensionId(kAppID); 168 169 sync_engine()->RegisterOrigin(origin, CreateResultReceiver(&sync_status)); 170 base::RunLoop().RunUntilIdle(); 171 EXPECT_EQ(SYNC_STATUS_OK, sync_status); 172 ASSERT_TRUE(metadata_database->FindAppRootTracker(kAppID, &tracker)); 173 EXPECT_EQ(TRACKER_KIND_APP_ROOT, tracker.tracker_kind()); 174 175 sync_engine()->DisableOrigin(origin, CreateResultReceiver(&sync_status)); 176 base::RunLoop().RunUntilIdle(); 177 EXPECT_EQ(SYNC_STATUS_OK, sync_status); 178 ASSERT_TRUE(metadata_database->FindAppRootTracker(kAppID, &tracker)); 179 EXPECT_EQ(TRACKER_KIND_DISABLED_APP_ROOT, tracker.tracker_kind()); 180 181 sync_engine()->EnableOrigin(origin, CreateResultReceiver(&sync_status)); 182 base::RunLoop().RunUntilIdle(); 183 EXPECT_EQ(SYNC_STATUS_OK, sync_status); 184 ASSERT_TRUE(metadata_database->FindAppRootTracker(kAppID, &tracker)); 185 EXPECT_EQ(TRACKER_KIND_APP_ROOT, tracker.tracker_kind()); 186 187 sync_engine()->UninstallOrigin( 188 origin, 189 RemoteFileSyncService::UNINSTALL_AND_KEEP_REMOTE, 190 CreateResultReceiver(&sync_status)); 191 base::RunLoop().RunUntilIdle(); 192 EXPECT_EQ(SYNC_STATUS_OK, sync_status); 193 ASSERT_FALSE(metadata_database->FindAppRootTracker(kAppID, &tracker)); 194} 195 196TEST_F(SyncEngineTest, UpdateRegisteredApps) { 197 SyncStatusCode sync_status = SYNC_STATUS_UNKNOWN; 198 for (int i = 0; i < 3; i++) { 199 scoped_refptr<const extensions::Extension> extension = 200 extensions::ExtensionBuilder() 201 .SetManifest(extensions::DictionaryBuilder() 202 .Set("name", "foo") 203 .Set("version", "1.0") 204 .Set("manifest_version", 2)) 205 .SetID(base::StringPrintf("app_%d", i)) 206 .Build(); 207 extension_service()->AddExtension(extension.get()); 208 GURL origin = extensions::Extension::GetBaseURLFromExtensionId( 209 extension->id()); 210 sync_status = SYNC_STATUS_UNKNOWN; 211 sync_engine()->RegisterOrigin(origin, CreateResultReceiver(&sync_status)); 212 base::RunLoop().RunUntilIdle(); 213 EXPECT_EQ(SYNC_STATUS_OK, sync_status); 214 } 215 216 MetadataDatabase* metadata_database = sync_engine()->GetMetadataDatabase(); 217 FileTracker tracker; 218 219 ASSERT_TRUE(metadata_database->FindAppRootTracker("app_0", &tracker)); 220 EXPECT_EQ(TRACKER_KIND_APP_ROOT, tracker.tracker_kind()); 221 222 ASSERT_TRUE(metadata_database->FindAppRootTracker("app_1", &tracker)); 223 EXPECT_EQ(TRACKER_KIND_APP_ROOT, tracker.tracker_kind()); 224 225 ASSERT_TRUE(metadata_database->FindAppRootTracker("app_2", &tracker)); 226 EXPECT_EQ(TRACKER_KIND_APP_ROOT, tracker.tracker_kind()); 227 228 extension_service()->DisableExtension("app_1"); 229 extension_service()->UninstallExtension("app_2"); 230 ASSERT_FALSE(extension_service()->GetInstalledExtension("app_2")); 231 UpdateRegisteredApps(); 232 base::RunLoop().RunUntilIdle(); 233 234 ASSERT_TRUE(metadata_database->FindAppRootTracker("app_0", &tracker)); 235 EXPECT_EQ(TRACKER_KIND_APP_ROOT, tracker.tracker_kind()); 236 237 ASSERT_TRUE(metadata_database->FindAppRootTracker("app_1", &tracker)); 238 EXPECT_EQ(TRACKER_KIND_DISABLED_APP_ROOT, tracker.tracker_kind()); 239 240 ASSERT_FALSE(metadata_database->FindAppRootTracker("app_2", &tracker)); 241} 242 243TEST_F(SyncEngineTest, GetOriginStatusMap) { 244 FileTracker tracker; 245 SyncStatusCode sync_status = SYNC_STATUS_UNKNOWN; 246 GURL origin = extensions::Extension::GetBaseURLFromExtensionId(kAppID); 247 248 sync_engine()->RegisterOrigin(GURL("chrome-extension://app_0"), 249 CreateResultReceiver(&sync_status)); 250 base::RunLoop().RunUntilIdle(); 251 EXPECT_EQ(SYNC_STATUS_OK, sync_status); 252 253 sync_engine()->RegisterOrigin(GURL("chrome-extension://app_1"), 254 CreateResultReceiver(&sync_status)); 255 base::RunLoop().RunUntilIdle(); 256 EXPECT_EQ(SYNC_STATUS_OK, sync_status); 257 258 RemoteFileSyncService::OriginStatusMap status_map; 259 sync_engine()->GetOriginStatusMap(&status_map); 260 ASSERT_EQ(2u, status_map.size()); 261 EXPECT_EQ("Enabled", status_map[GURL("chrome-extension://app_0")]); 262 EXPECT_EQ("Enabled", status_map[GURL("chrome-extension://app_1")]); 263 264 sync_engine()->DisableOrigin(GURL("chrome-extension://app_1"), 265 CreateResultReceiver(&sync_status)); 266 base::RunLoop().RunUntilIdle(); 267 EXPECT_EQ(SYNC_STATUS_OK, sync_status); 268 269 sync_engine()->GetOriginStatusMap(&status_map); 270 ASSERT_EQ(2u, status_map.size()); 271 EXPECT_EQ("Enabled", status_map[GURL("chrome-extension://app_0")]); 272 EXPECT_EQ("Disabled", status_map[GURL("chrome-extension://app_1")]); 273} 274 275TEST_F(SyncEngineTest, UpdateServiceState) { 276 EXPECT_EQ(REMOTE_SERVICE_OK, sync_engine()->GetCurrentState()); 277 278 GetSyncEngineTaskManager()->ScheduleTask( 279 FROM_HERE, 280 base::Bind(&EmptyTask, SYNC_STATUS_AUTHENTICATION_FAILED), 281 SyncTaskManager::PRIORITY_MED, 282 base::Bind(&SyncEngineTest::CheckServiceState, 283 AsWeakPtr(), 284 SYNC_STATUS_AUTHENTICATION_FAILED, 285 REMOTE_SERVICE_AUTHENTICATION_REQUIRED)); 286 287 GetSyncEngineTaskManager()->ScheduleTask( 288 FROM_HERE, 289 base::Bind(&EmptyTask, SYNC_STATUS_ACCESS_FORBIDDEN), 290 SyncTaskManager::PRIORITY_MED, 291 base::Bind(&SyncEngineTest::CheckServiceState, 292 AsWeakPtr(), 293 SYNC_STATUS_ACCESS_FORBIDDEN, 294 REMOTE_SERVICE_AUTHENTICATION_REQUIRED)); 295 296 GetSyncEngineTaskManager()->ScheduleTask( 297 FROM_HERE, 298 base::Bind(&EmptyTask, SYNC_STATUS_SERVICE_TEMPORARILY_UNAVAILABLE), 299 SyncTaskManager::PRIORITY_MED, 300 base::Bind(&SyncEngineTest::CheckServiceState, 301 AsWeakPtr(), 302 SYNC_STATUS_SERVICE_TEMPORARILY_UNAVAILABLE, 303 REMOTE_SERVICE_TEMPORARY_UNAVAILABLE)); 304 305 GetSyncEngineTaskManager()->ScheduleTask( 306 FROM_HERE, 307 base::Bind(&EmptyTask, SYNC_STATUS_NETWORK_ERROR), 308 SyncTaskManager::PRIORITY_MED, 309 base::Bind(&SyncEngineTest::CheckServiceState, 310 AsWeakPtr(), 311 SYNC_STATUS_NETWORK_ERROR, 312 REMOTE_SERVICE_TEMPORARY_UNAVAILABLE)); 313 314 GetSyncEngineTaskManager()->ScheduleTask( 315 FROM_HERE, 316 base::Bind(&EmptyTask, SYNC_STATUS_ABORT), 317 SyncTaskManager::PRIORITY_MED, 318 base::Bind(&SyncEngineTest::CheckServiceState, 319 AsWeakPtr(), 320 SYNC_STATUS_ABORT, 321 REMOTE_SERVICE_TEMPORARY_UNAVAILABLE)); 322 323 GetSyncEngineTaskManager()->ScheduleTask( 324 FROM_HERE, 325 base::Bind(&EmptyTask, SYNC_STATUS_FAILED), 326 SyncTaskManager::PRIORITY_MED, 327 base::Bind(&SyncEngineTest::CheckServiceState, 328 AsWeakPtr(), 329 SYNC_STATUS_FAILED, 330 REMOTE_SERVICE_TEMPORARY_UNAVAILABLE)); 331 332 GetSyncEngineTaskManager()->ScheduleTask( 333 FROM_HERE, 334 base::Bind(&EmptyTask, SYNC_DATABASE_ERROR_CORRUPTION), 335 SyncTaskManager::PRIORITY_MED, 336 base::Bind(&SyncEngineTest::CheckServiceState, 337 AsWeakPtr(), 338 SYNC_DATABASE_ERROR_CORRUPTION, 339 REMOTE_SERVICE_DISABLED)); 340 341 GetSyncEngineTaskManager()->ScheduleTask( 342 FROM_HERE, 343 base::Bind(&EmptyTask, SYNC_DATABASE_ERROR_IO_ERROR), 344 SyncTaskManager::PRIORITY_MED, 345 base::Bind(&SyncEngineTest::CheckServiceState, 346 AsWeakPtr(), 347 SYNC_DATABASE_ERROR_IO_ERROR, 348 REMOTE_SERVICE_DISABLED)); 349 350 GetSyncEngineTaskManager()->ScheduleTask( 351 FROM_HERE, 352 base::Bind(&EmptyTask, SYNC_DATABASE_ERROR_FAILED), 353 SyncTaskManager::PRIORITY_MED, 354 base::Bind(&SyncEngineTest::CheckServiceState, 355 AsWeakPtr(), 356 SYNC_DATABASE_ERROR_FAILED, 357 REMOTE_SERVICE_DISABLED)); 358 359 GetSyncEngineTaskManager()->ScheduleSyncTask( 360 FROM_HERE, 361 scoped_ptr<SyncTask>(new MockSyncTask(false)), 362 SyncTaskManager::PRIORITY_MED, 363 base::Bind(&SyncEngineTest::CheckServiceState, 364 AsWeakPtr(), 365 SYNC_STATUS_OK, 366 REMOTE_SERVICE_DISABLED)); 367 368 GetSyncEngineTaskManager()->ScheduleSyncTask( 369 FROM_HERE, 370 scoped_ptr<SyncTask>(new MockSyncTask(true)), 371 SyncTaskManager::PRIORITY_MED, 372 base::Bind(&SyncEngineTest::CheckServiceState, 373 AsWeakPtr(), 374 SYNC_STATUS_OK, 375 REMOTE_SERVICE_OK)); 376 377 base::RunLoop().RunUntilIdle(); 378} 379 380} // namespace drive_backend 381} // namespace sync_file_system 382