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