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/macros.h" 9 #include "base/run_loop.h" 10 #include "chrome/browser/drive/drive_uploader.h" 11 #include "chrome/browser/drive/fake_drive_service.h" 12 #include "chrome/browser/sync_file_system/drive_backend/callback_helper.h" 13 #include "chrome/browser/sync_file_system/drive_backend/fake_sync_worker.h" 14 #include "chrome/browser/sync_file_system/drive_backend/sync_worker_interface.h" 15 #include "chrome/browser/sync_file_system/remote_file_sync_service.h" 16 #include "chrome/browser/sync_file_system/sync_file_system_test_util.h" 17 #include "content/public/browser/browser_thread.h" 18 #include "content/public/test/test_browser_thread_bundle.h" 19 #include "testing/gtest/include/gtest/gtest.h" 20 21 namespace sync_file_system { 22 namespace drive_backend { 23 24 class SyncEngineTest : public testing::Test, 25 public base::SupportsWeakPtr<SyncEngineTest> { 26 public: 27 typedef RemoteFileSyncService::OriginStatusMap RemoteOriginStatusMap; 28 29 SyncEngineTest() {} 30 virtual ~SyncEngineTest() {} 31 32 virtual void SetUp() OVERRIDE { 33 ASSERT_TRUE(profile_dir_.CreateUniqueTempDir()); 34 35 scoped_ptr<drive::DriveServiceInterface> 36 fake_drive_service(new drive::FakeDriveService); 37 38 worker_pool_ = new base::SequencedWorkerPool(1, "Worker"); 39 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner = 40 base::MessageLoopProxy::current(); 41 worker_task_runner_ = 42 worker_pool_->GetSequencedTaskRunnerWithShutdownBehavior( 43 worker_pool_->GetSequenceToken(), 44 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); 45 46 sync_engine_.reset(new drive_backend::SyncEngine( 47 ui_task_runner, 48 worker_task_runner_, 49 NULL /* file_task_runner */, 50 NULL /* drive_task_runner */, 51 profile_dir_.path(), 52 NULL /* task_logger */, 53 NULL /* notification_manager */, 54 NULL /* extension_service */, 55 NULL /* signin_manager */, 56 NULL /* token_service */, 57 NULL /* request_context */, 58 NULL /* in_memory_env */)); 59 60 sync_engine_->InitializeForTesting( 61 fake_drive_service.Pass(), 62 scoped_ptr<drive::DriveUploaderInterface>(), 63 scoped_ptr<SyncWorkerInterface>(new FakeSyncWorker)); 64 sync_engine_->SetSyncEnabled(true); 65 66 WaitForWorkerTaskRunner(); 67 } 68 69 virtual void TearDown() OVERRIDE { 70 sync_engine_.reset(); 71 WaitForWorkerTaskRunner(); 72 worker_pool_->Shutdown(); 73 base::RunLoop().RunUntilIdle(); 74 } 75 76 bool FindOriginStatus(const GURL& origin, std::string* status) { 77 scoped_ptr<RemoteOriginStatusMap> status_map; 78 sync_engine()->GetOriginStatusMap(CreateResultReceiver(&status_map)); 79 WaitForWorkerTaskRunner(); 80 81 RemoteOriginStatusMap::const_iterator itr = status_map->find(origin); 82 if (itr == status_map->end()) 83 return false; 84 85 *status = itr->second; 86 // If an origin is uninstalled, it should not be found actually. 87 if (*status == "Uninstalled") 88 return false; 89 return true; 90 } 91 92 void PostUpdateServiceState(RemoteServiceState state, 93 const std::string& description) { 94 worker_task_runner_->PostTask( 95 FROM_HERE, 96 base::Bind(&FakeSyncWorker::UpdateServiceState, 97 base::Unretained(fake_sync_worker()), 98 state, 99 description)); 100 WaitForWorkerTaskRunner(); 101 } 102 103 void WaitForWorkerTaskRunner() { 104 DCHECK(worker_task_runner_); 105 106 base::RunLoop run_loop; 107 worker_task_runner_->PostTask( 108 FROM_HERE, 109 RelayCallbackToCurrentThread( 110 FROM_HERE, run_loop.QuitClosure())); 111 run_loop.Run(); 112 } 113 114 // Accessors 115 SyncEngine* sync_engine() { return sync_engine_.get(); } 116 117 FakeSyncWorker* fake_sync_worker() { 118 return static_cast<FakeSyncWorker*>(sync_engine_->sync_worker_.get()); 119 } 120 121 private: 122 content::TestBrowserThreadBundle browser_threads_; 123 base::ScopedTempDir profile_dir_; 124 scoped_ptr<drive_backend::SyncEngine> sync_engine_; 125 126 scoped_refptr<base::SequencedWorkerPool> worker_pool_; 127 scoped_refptr<base::SequencedTaskRunner> worker_task_runner_; 128 129 DISALLOW_COPY_AND_ASSIGN(SyncEngineTest); 130 }; 131 132 TEST_F(SyncEngineTest, OriginTest) { 133 GURL origin("chrome-extension://app_0"); 134 135 SyncStatusCode sync_status; 136 std::string status; 137 138 sync_engine()->RegisterOrigin( 139 origin, 140 CreateResultReceiver(&sync_status)); 141 WaitForWorkerTaskRunner(); 142 EXPECT_EQ(SYNC_STATUS_OK, sync_status); 143 ASSERT_TRUE(FindOriginStatus(origin, &status)); 144 EXPECT_EQ("Registered", status); 145 146 sync_engine()->DisableOrigin( 147 origin, 148 CreateResultReceiver(&sync_status)); 149 WaitForWorkerTaskRunner(); 150 EXPECT_EQ(SYNC_STATUS_OK, sync_status); 151 ASSERT_TRUE(FindOriginStatus(origin, &status)); 152 EXPECT_EQ("Disabled", status); 153 154 sync_engine()->EnableOrigin( 155 origin, 156 CreateResultReceiver(&sync_status)); 157 WaitForWorkerTaskRunner(); 158 EXPECT_EQ(SYNC_STATUS_OK, sync_status); 159 ASSERT_TRUE(FindOriginStatus(origin, &status)); 160 EXPECT_EQ("Enabled", status); 161 162 sync_engine()->UninstallOrigin( 163 origin, 164 RemoteFileSyncService::UNINSTALL_AND_KEEP_REMOTE, 165 CreateResultReceiver(&sync_status)); 166 WaitForWorkerTaskRunner(); 167 EXPECT_EQ(SYNC_STATUS_OK, sync_status); 168 EXPECT_FALSE(FindOriginStatus(origin, &status)); 169 EXPECT_EQ("Uninstalled", status); 170 } 171 172 TEST_F(SyncEngineTest, GetOriginStatusMap) { 173 SyncStatusCode sync_status = SYNC_STATUS_UNKNOWN; 174 175 sync_engine()->RegisterOrigin(GURL("chrome-extension://app_0"), 176 CreateResultReceiver(&sync_status)); 177 WaitForWorkerTaskRunner(); 178 EXPECT_EQ(SYNC_STATUS_OK, sync_status); 179 180 sync_engine()->RegisterOrigin(GURL("chrome-extension://app_1"), 181 CreateResultReceiver(&sync_status)); 182 WaitForWorkerTaskRunner(); 183 EXPECT_EQ(SYNC_STATUS_OK, sync_status); 184 185 scoped_ptr<RemoteOriginStatusMap> status_map; 186 sync_engine()->GetOriginStatusMap(CreateResultReceiver(&status_map)); 187 WaitForWorkerTaskRunner(); 188 ASSERT_EQ(2u, status_map->size()); 189 EXPECT_EQ("Registered", (*status_map)[GURL("chrome-extension://app_0")]); 190 EXPECT_EQ("Registered", (*status_map)[GURL("chrome-extension://app_1")]); 191 192 sync_engine()->DisableOrigin(GURL("chrome-extension://app_1"), 193 CreateResultReceiver(&sync_status)); 194 WaitForWorkerTaskRunner(); 195 EXPECT_EQ(SYNC_STATUS_OK, sync_status); 196 197 sync_engine()->GetOriginStatusMap(CreateResultReceiver(&status_map)); 198 WaitForWorkerTaskRunner(); 199 ASSERT_EQ(2u, status_map->size()); 200 EXPECT_EQ("Registered", (*status_map)[GURL("chrome-extension://app_0")]); 201 EXPECT_EQ("Disabled", (*status_map)[GURL("chrome-extension://app_1")]); 202 } 203 204 TEST_F(SyncEngineTest, UpdateServiceState) { 205 struct { 206 RemoteServiceState state; 207 const char* description; 208 } test_data[] = { 209 {REMOTE_SERVICE_OK, "OK"}, 210 {REMOTE_SERVICE_TEMPORARY_UNAVAILABLE, "TEMPORARY_UNAVAILABLE"}, 211 {REMOTE_SERVICE_AUTHENTICATION_REQUIRED, "AUTHENTICATION_REQUIRED"}, 212 {REMOTE_SERVICE_DISABLED, "DISABLED"}, 213 }; 214 215 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) { 216 PostUpdateServiceState(test_data[i].state, test_data[i].description); 217 EXPECT_EQ(test_data[i].state, sync_engine()->GetCurrentState()) 218 << "Expected state: REMOTE_SERVICE_" << test_data[i].description; 219 } 220 } 221 222 TEST_F(SyncEngineTest, ProcessRemoteChange) { 223 SyncStatusCode sync_status; 224 fileapi::FileSystemURL url; 225 sync_engine()->ProcessRemoteChange(CreateResultReceiver(&sync_status, &url)); 226 WaitForWorkerTaskRunner(); 227 EXPECT_EQ(SYNC_STATUS_OK, sync_status); 228 } 229 230 } // namespace drive_backend 231 } // namespace sync_file_system 232