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/list_changes_task.h" 6 7 #include <string> 8 9 #include "base/files/scoped_temp_dir.h" 10 #include "base/format_macros.h" 11 #include "base/run_loop.h" 12 #include "base/thread_task_runner_handle.h" 13 #include "chrome/browser/sync_file_system/drive_backend/drive_backend_constants.h" 14 #include "chrome/browser/sync_file_system/drive_backend/fake_drive_service_helper.h" 15 #include "chrome/browser/sync_file_system/drive_backend/metadata_database.h" 16 #include "chrome/browser/sync_file_system/drive_backend/register_app_task.h" 17 #include "chrome/browser/sync_file_system/drive_backend/sync_engine_context.h" 18 #include "chrome/browser/sync_file_system/drive_backend/sync_engine_initializer.h" 19 #include "chrome/browser/sync_file_system/drive_backend/sync_task_manager.h" 20 #include "chrome/browser/sync_file_system/sync_file_system_test_util.h" 21 #include "content/public/test/test_browser_thread_bundle.h" 22 #include "google_apis/drive/drive_api_parser.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 27 namespace sync_file_system { 28 namespace drive_backend { 29 30 namespace { 31 32 const char kAppID[] = "app_id"; 33 const char kUnregisteredAppID[] = "app_id unregistered"; 34 35 } // namespace 36 37 class ListChangesTaskTest : public testing::Test { 38 public: 39 ListChangesTaskTest() {} 40 virtual ~ListChangesTaskTest() {} 41 42 virtual void SetUp() OVERRIDE { 43 ASSERT_TRUE(database_dir_.CreateUniqueTempDir()); 44 in_memory_env_.reset(leveldb::NewMemEnv(leveldb::Env::Default())); 45 46 scoped_ptr<drive::FakeDriveService> 47 fake_drive_service(new drive::FakeDriveService); 48 49 scoped_ptr<drive::DriveUploaderInterface> 50 drive_uploader(new drive::DriveUploader( 51 fake_drive_service.get(), 52 base::ThreadTaskRunnerHandle::Get())); 53 54 fake_drive_service_helper_.reset( 55 new FakeDriveServiceHelper(fake_drive_service.get(), 56 drive_uploader.get(), 57 kSyncRootFolderTitle)); 58 59 sync_task_manager_.reset(new SyncTaskManager( 60 base::WeakPtr<SyncTaskManager::Client>(), 61 10 /* maximum_background_task */, 62 base::ThreadTaskRunnerHandle::Get())); 63 sync_task_manager_->Initialize(SYNC_STATUS_OK); 64 65 context_.reset(new SyncEngineContext( 66 fake_drive_service.PassAs<drive::DriveServiceInterface>(), 67 drive_uploader.Pass(), 68 NULL, 69 base::ThreadTaskRunnerHandle::Get(), 70 base::ThreadTaskRunnerHandle::Get())); 71 72 SetUpRemoteFolders(); 73 74 InitializeMetadataDatabase(); 75 RegisterApp(kAppID); 76 } 77 78 virtual void TearDown() OVERRIDE { 79 sync_task_manager_.reset(); 80 context_.reset(); 81 base::RunLoop().RunUntilIdle(); 82 } 83 84 protected: 85 SyncStatusCode RunTask(scoped_ptr<SyncTask> sync_task) { 86 SyncStatusCode status = SYNC_STATUS_UNKNOWN; 87 sync_task_manager_->ScheduleSyncTask( 88 FROM_HERE, sync_task.Pass(), 89 SyncTaskManager::PRIORITY_MED, 90 CreateResultReceiver(&status)); 91 base::RunLoop().RunUntilIdle(); 92 return status; 93 } 94 95 size_t CountDirtyTracker() { 96 return context_->GetMetadataDatabase()->CountDirtyTracker(); 97 } 98 99 FakeDriveServiceHelper* fake_drive_service_helper() { 100 return fake_drive_service_helper_.get(); 101 } 102 103 void SetUpChangesInFolder(const std::string& folder_id) { 104 std::string new_file_id; 105 ASSERT_EQ(google_apis::HTTP_SUCCESS, 106 fake_drive_service_helper()->AddFile( 107 folder_id, "new file", "file contents", &new_file_id)); 108 std::string same_name_file_id; 109 ASSERT_EQ(google_apis::HTTP_SUCCESS, 110 fake_drive_service_helper()->AddFile( 111 folder_id, "new file", "file contents", 112 &same_name_file_id)); 113 114 std::string new_folder_id; 115 ASSERT_EQ(google_apis::HTTP_CREATED, 116 fake_drive_service_helper()->AddFolder( 117 folder_id, "new folder", &new_folder_id)); 118 119 std::string modified_file_id; 120 ASSERT_EQ(google_apis::HTTP_SUCCESS, 121 fake_drive_service_helper()->AddFile( 122 folder_id, "modified file", "file content", 123 &modified_file_id)); 124 ASSERT_EQ(google_apis::HTTP_SUCCESS, 125 fake_drive_service_helper()->UpdateFile( 126 modified_file_id, "modified file content")); 127 128 129 std::string deleted_file_id; 130 ASSERT_EQ(google_apis::HTTP_SUCCESS, 131 fake_drive_service_helper()->AddFile( 132 folder_id, "trashed file", "file content", 133 &deleted_file_id)); 134 ASSERT_EQ(google_apis::HTTP_NO_CONTENT, 135 fake_drive_service_helper()->DeleteResource(deleted_file_id)); 136 } 137 138 std::string root_resource_id() { 139 return context_->GetDriveService()->GetRootResourceId(); 140 } 141 142 std::string app_root_folder_id() { 143 return app_root_folder_id_; 144 } 145 146 std::string unregistered_app_root_folder_id() { 147 return unregistered_app_root_folder_id_; 148 } 149 150 SyncEngineContext* GetSyncEngineContext() { 151 return context_.get(); 152 } 153 154 private: 155 void SetUpRemoteFolders() { 156 ASSERT_EQ(google_apis::HTTP_CREATED, 157 fake_drive_service_helper_->AddOrphanedFolder( 158 kSyncRootFolderTitle, &sync_root_folder_id_)); 159 ASSERT_EQ(google_apis::HTTP_CREATED, 160 fake_drive_service_helper_->AddFolder( 161 sync_root_folder_id_, kAppID, &app_root_folder_id_)); 162 ASSERT_EQ(google_apis::HTTP_CREATED, 163 fake_drive_service_helper_->AddFolder( 164 sync_root_folder_id_, kUnregisteredAppID, 165 &unregistered_app_root_folder_id_)); 166 } 167 168 void InitializeMetadataDatabase() { 169 SyncStatusCode status = SYNC_STATUS_UNKNOWN; 170 SyncEngineInitializer* initializer = 171 new SyncEngineInitializer(context_.get(), 172 database_dir_.path(), 173 in_memory_env_.get()); 174 175 sync_task_manager_->ScheduleSyncTask( 176 FROM_HERE, scoped_ptr<SyncTask>(initializer), 177 SyncTaskManager::PRIORITY_MED, 178 base::Bind(&ListChangesTaskTest::DidInitializeMetadataDatabase, 179 base::Unretained(this), initializer, &status)); 180 181 base::RunLoop().RunUntilIdle(); 182 183 EXPECT_EQ(SYNC_STATUS_OK, status); 184 } 185 186 void DidInitializeMetadataDatabase(SyncEngineInitializer* initializer, 187 SyncStatusCode* status_out, 188 SyncStatusCode status) { 189 context_->SetMetadataDatabase(initializer->PassMetadataDatabase()); 190 *status_out = status; 191 } 192 193 void RegisterApp(const std::string& app_id) { 194 EXPECT_EQ(SYNC_STATUS_OK, RunTask(scoped_ptr<SyncTask>( 195 new RegisterAppTask(context_.get(), app_id)))); 196 } 197 198 scoped_ptr<leveldb::Env> in_memory_env_; 199 200 std::string sync_root_folder_id_; 201 std::string app_root_folder_id_; 202 std::string unregistered_app_root_folder_id_; 203 204 content::TestBrowserThreadBundle browser_threads_; 205 base::ScopedTempDir database_dir_; 206 207 scoped_ptr<SyncEngineContext> context_; 208 scoped_ptr<FakeDriveServiceHelper> fake_drive_service_helper_; 209 210 scoped_ptr<SyncTaskManager> sync_task_manager_; 211 212 DISALLOW_COPY_AND_ASSIGN(ListChangesTaskTest); 213 }; 214 215 TEST_F(ListChangesTaskTest, NoChange) { 216 size_t num_dirty_trackers = CountDirtyTracker(); 217 218 EXPECT_EQ(SYNC_STATUS_NO_CHANGE_TO_SYNC, RunTask( 219 scoped_ptr<SyncTask>(new ListChangesTask(GetSyncEngineContext())))); 220 221 EXPECT_EQ(num_dirty_trackers, CountDirtyTracker()); 222 } 223 224 TEST_F(ListChangesTaskTest, UnrelatedChange) { 225 size_t num_dirty_trackers = CountDirtyTracker(); 226 227 SetUpChangesInFolder(root_resource_id()); 228 SetUpChangesInFolder(unregistered_app_root_folder_id()); 229 230 EXPECT_EQ(SYNC_STATUS_OK, RunTask( 231 scoped_ptr<SyncTask>(new ListChangesTask(GetSyncEngineContext())))); 232 233 EXPECT_EQ(num_dirty_trackers, CountDirtyTracker()); 234 } 235 236 TEST_F(ListChangesTaskTest, UnderTrackedFolder) { 237 size_t num_dirty_trackers = CountDirtyTracker(); 238 239 SetUpChangesInFolder(app_root_folder_id()); 240 241 EXPECT_EQ(SYNC_STATUS_OK, RunTask( 242 scoped_ptr<SyncTask>(new ListChangesTask(GetSyncEngineContext())))); 243 244 EXPECT_EQ(num_dirty_trackers + 4, CountDirtyTracker()); 245 } 246 247 } // namespace drive_backend 248 } // namespace sync_file_system 249