change_list_loader_unittest.cc revision 9ab5563a3196760eb381d102cbb2bc0f7abc6a50
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/chromeos/drive/change_list_loader.h" 6 7#include "base/files/scoped_temp_dir.h" 8#include "base/memory/scoped_ptr.h" 9#include "base/prefs/testing_pref_service.h" 10#include "base/run_loop.h" 11#include "chrome/browser/chromeos/drive/change_list_loader_observer.h" 12#include "chrome/browser/chromeos/drive/file_cache.h" 13#include "chrome/browser/chromeos/drive/file_system_util.h" 14#include "chrome/browser/chromeos/drive/job_scheduler.h" 15#include "chrome/browser/chromeos/drive/resource_metadata.h" 16#include "chrome/browser/chromeos/drive/test_util.h" 17#include "chrome/browser/drive/fake_drive_service.h" 18#include "chrome/browser/google_apis/test_util.h" 19#include "content/public/test/test_browser_thread_bundle.h" 20#include "testing/gtest/include/gtest/gtest.h" 21 22namespace drive { 23namespace internal { 24 25class TestChangeListLoaderObserver : public ChangeListLoaderObserver { 26 public: 27 explicit TestChangeListLoaderObserver(ChangeListLoader* loader) 28 : loader_(loader), 29 load_from_server_complete_count_(0), 30 initial_load_complete_count_(0) { 31 loader_->AddObserver(this); 32 } 33 34 virtual ~TestChangeListLoaderObserver() { 35 loader_->RemoveObserver(this); 36 } 37 38 const std::set<base::FilePath>& changed_directories() const { 39 return changed_directories_; 40 } 41 int load_from_server_complete_count() const { 42 return load_from_server_complete_count_; 43 } 44 int initial_load_complete_count() const { 45 return initial_load_complete_count_; 46 } 47 48 // ChageListObserver overrides: 49 virtual void OnDirectoryChanged( 50 const base::FilePath& directory_path) OVERRIDE { 51 changed_directories_.insert(directory_path); 52 } 53 virtual void OnLoadFromServerComplete() OVERRIDE { 54 ++load_from_server_complete_count_; 55 } 56 virtual void OnInitialLoadComplete() OVERRIDE { 57 ++initial_load_complete_count_; 58 } 59 60 private: 61 ChangeListLoader* loader_; 62 std::set<base::FilePath> changed_directories_; 63 int load_from_server_complete_count_; 64 int initial_load_complete_count_; 65 66 DISALLOW_COPY_AND_ASSIGN(TestChangeListLoaderObserver); 67}; 68 69class ChangeListLoaderTest : public testing::Test { 70 protected: 71 virtual void SetUp() OVERRIDE { 72 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 73 pref_service_.reset(new TestingPrefServiceSimple); 74 test_util::RegisterDrivePrefs(pref_service_->registry()); 75 76 drive_service_.reset(new FakeDriveService); 77 ASSERT_TRUE(drive_service_->LoadResourceListForWapi( 78 "gdata/root_feed.json")); 79 ASSERT_TRUE(drive_service_->LoadAccountMetadataForWapi( 80 "gdata/account_metadata.json")); 81 82 scheduler_.reset(new JobScheduler(pref_service_.get(), 83 drive_service_.get(), 84 base::MessageLoopProxy::current().get())); 85 metadata_storage_.reset(new ResourceMetadataStorage( 86 temp_dir_.path(), base::MessageLoopProxy::current().get())); 87 ASSERT_TRUE(metadata_storage_->Initialize()); 88 89 metadata_.reset(new ResourceMetadata( 90 metadata_storage_.get(), base::MessageLoopProxy::current().get())); 91 ASSERT_EQ(FILE_ERROR_OK, metadata_->Initialize()); 92 93 cache_.reset(new FileCache(metadata_storage_.get(), 94 temp_dir_.path(), 95 base::MessageLoopProxy::current().get(), 96 NULL /* free_disk_space_getter */)); 97 ASSERT_TRUE(cache_->Initialize()); 98 99 change_list_loader_.reset( 100 new ChangeListLoader(base::MessageLoopProxy::current().get(), 101 metadata_.get(), 102 scheduler_.get())); 103 } 104 105 // Adds a new file to the root directory of the service. 106 scoped_ptr<google_apis::ResourceEntry> AddNewFile(const std::string& title) { 107 google_apis::GDataErrorCode error = google_apis::GDATA_FILE_ERROR; 108 scoped_ptr<google_apis::ResourceEntry> entry; 109 drive_service_->AddNewFile( 110 "text/plain", 111 "content text", 112 drive_service_->GetRootResourceId(), 113 title, 114 false, // shared_with_me 115 google_apis::test_util::CreateCopyResultCallback(&error, &entry)); 116 base::RunLoop().RunUntilIdle(); 117 EXPECT_EQ(google_apis::HTTP_CREATED, error); 118 return entry.Pass(); 119 } 120 121 content::TestBrowserThreadBundle thread_bundle_; 122 base::ScopedTempDir temp_dir_; 123 scoped_ptr<TestingPrefServiceSimple> pref_service_; 124 scoped_ptr<FakeDriveService> drive_service_; 125 scoped_ptr<JobScheduler> scheduler_; 126 scoped_ptr<ResourceMetadataStorage, 127 test_util::DestroyHelperForTests> metadata_storage_; 128 scoped_ptr<ResourceMetadata, test_util::DestroyHelperForTests> metadata_; 129 scoped_ptr<FileCache, test_util::DestroyHelperForTests> cache_; 130 scoped_ptr<ChangeListLoader> change_list_loader_; 131}; 132 133TEST_F(ChangeListLoaderTest, LoadIfNeeded) { 134 EXPECT_FALSE(change_list_loader_->IsRefreshing()); 135 136 // Start initial load. 137 TestChangeListLoaderObserver observer(change_list_loader_.get()); 138 139 FileError error = FILE_ERROR_FAILED; 140 change_list_loader_->LoadIfNeeded( 141 DirectoryFetchInfo(), 142 google_apis::test_util::CreateCopyResultCallback(&error)); 143 EXPECT_TRUE(change_list_loader_->IsRefreshing()); 144 base::RunLoop().RunUntilIdle(); 145 EXPECT_EQ(FILE_ERROR_OK, error); 146 147 EXPECT_FALSE(change_list_loader_->IsRefreshing()); 148 EXPECT_LT(0, metadata_->GetLargestChangestamp()); 149 EXPECT_EQ(1, drive_service_->resource_list_load_count()); 150 EXPECT_EQ(1, observer.initial_load_complete_count()); 151 EXPECT_EQ(1, observer.load_from_server_complete_count()); 152 EXPECT_TRUE(observer.changed_directories().empty()); 153 154 base::FilePath file_path = 155 util::GetDriveMyDriveRootPath().AppendASCII("File 1.txt"); 156 ResourceEntry entry; 157 EXPECT_EQ(FILE_ERROR_OK, 158 metadata_->GetResourceEntryByPath(file_path, &entry)); 159 160 // Reload. This should result in no-op. 161 int64 previous_changestamp = metadata_->GetLargestChangestamp(); 162 int previous_resource_list_load_count = 163 drive_service_->resource_list_load_count(); 164 change_list_loader_->LoadIfNeeded( 165 DirectoryFetchInfo(), 166 google_apis::test_util::CreateCopyResultCallback(&error)); 167 EXPECT_FALSE(change_list_loader_->IsRefreshing()); 168 base::RunLoop().RunUntilIdle(); 169 EXPECT_EQ(FILE_ERROR_OK, error); 170 171 EXPECT_FALSE(change_list_loader_->IsRefreshing()); 172 EXPECT_EQ(previous_changestamp, metadata_->GetLargestChangestamp()); 173 EXPECT_EQ(previous_resource_list_load_count, 174 drive_service_->resource_list_load_count()); 175} 176 177TEST_F(ChangeListLoaderTest, LoadIfNeeded_LocalMetadataAvailable) { 178 // Prepare metadata. 179 FileError error = FILE_ERROR_FAILED; 180 change_list_loader_->LoadIfNeeded( 181 DirectoryFetchInfo(), 182 google_apis::test_util::CreateCopyResultCallback(&error)); 183 base::RunLoop().RunUntilIdle(); 184 EXPECT_EQ(FILE_ERROR_OK, error); 185 186 // Reset loader. 187 change_list_loader_.reset( 188 new ChangeListLoader(base::MessageLoopProxy::current().get(), 189 metadata_.get(), 190 scheduler_.get())); 191 192 // Add a file to the service. 193 scoped_ptr<google_apis::ResourceEntry> gdata_entry = AddNewFile("New File"); 194 ASSERT_TRUE(gdata_entry); 195 196 // Start loading. Because local metadata is available, the load results in 197 // returning FILE_ERROR_OK without fetching full list of resources. 198 const int previous_resource_list_load_count = 199 drive_service_->resource_list_load_count(); 200 TestChangeListLoaderObserver observer(change_list_loader_.get()); 201 202 change_list_loader_->LoadIfNeeded( 203 DirectoryFetchInfo(), 204 google_apis::test_util::CreateCopyResultCallback(&error)); 205 EXPECT_TRUE(change_list_loader_->IsRefreshing()); 206 base::RunLoop().RunUntilIdle(); 207 EXPECT_EQ(FILE_ERROR_OK, error); 208 EXPECT_EQ(previous_resource_list_load_count, 209 drive_service_->resource_list_load_count()); 210 EXPECT_EQ(1, observer.initial_load_complete_count()); 211 212 // Update should be checked by LoadIfNeeded(). 213 EXPECT_EQ(drive_service_->largest_changestamp(), 214 metadata_->GetLargestChangestamp()); 215 EXPECT_EQ(1, drive_service_->change_list_load_count()); 216 EXPECT_EQ(1, observer.load_from_server_complete_count()); 217 EXPECT_EQ(1U, observer.changed_directories().count( 218 util::GetDriveMyDriveRootPath())); 219 220 base::FilePath file_path = 221 util::GetDriveMyDriveRootPath().AppendASCII(gdata_entry->title()); 222 ResourceEntry entry; 223 EXPECT_EQ(FILE_ERROR_OK, 224 metadata_->GetResourceEntryByPath(file_path, &entry)); 225} 226 227TEST_F(ChangeListLoaderTest, CheckForUpdates) { 228 // CheckForUpdates() results in no-op before load. 229 FileError check_for_updates_error = FILE_ERROR_FAILED; 230 change_list_loader_->CheckForUpdates( 231 google_apis::test_util::CreateCopyResultCallback( 232 &check_for_updates_error)); 233 EXPECT_FALSE(change_list_loader_->IsRefreshing()); 234 base::RunLoop().RunUntilIdle(); 235 EXPECT_EQ(FILE_ERROR_FAILED, 236 check_for_updates_error); // Callback was not run. 237 EXPECT_EQ(0, metadata_->GetLargestChangestamp()); 238 EXPECT_EQ(0, drive_service_->resource_list_load_count()); 239 240 // Start initial load. 241 FileError load_error = FILE_ERROR_FAILED; 242 change_list_loader_->LoadIfNeeded( 243 DirectoryFetchInfo(), 244 google_apis::test_util::CreateCopyResultCallback(&load_error)); 245 EXPECT_TRUE(change_list_loader_->IsRefreshing()); 246 247 // CheckForUpdates() while loading. 248 change_list_loader_->CheckForUpdates( 249 google_apis::test_util::CreateCopyResultCallback( 250 &check_for_updates_error)); 251 252 base::RunLoop().RunUntilIdle(); 253 EXPECT_FALSE(change_list_loader_->IsRefreshing()); 254 EXPECT_EQ(FILE_ERROR_OK, load_error); 255 EXPECT_EQ(FILE_ERROR_OK, check_for_updates_error); 256 EXPECT_LT(0, metadata_->GetLargestChangestamp()); 257 EXPECT_EQ(1, drive_service_->resource_list_load_count()); 258 259 int64 previous_changestamp = metadata_->GetLargestChangestamp(); 260 // CheckForUpdates() results in no update. 261 change_list_loader_->CheckForUpdates( 262 google_apis::test_util::CreateCopyResultCallback( 263 &check_for_updates_error)); 264 EXPECT_TRUE(change_list_loader_->IsRefreshing()); 265 base::RunLoop().RunUntilIdle(); 266 EXPECT_FALSE(change_list_loader_->IsRefreshing()); 267 EXPECT_EQ(previous_changestamp, metadata_->GetLargestChangestamp()); 268 269 // Add a file to the service. 270 scoped_ptr<google_apis::ResourceEntry> gdata_entry = AddNewFile("New File"); 271 ASSERT_TRUE(gdata_entry); 272 273 // CheckForUpdates() results in update. 274 TestChangeListLoaderObserver observer(change_list_loader_.get()); 275 change_list_loader_->CheckForUpdates( 276 google_apis::test_util::CreateCopyResultCallback( 277 &check_for_updates_error)); 278 EXPECT_TRUE(change_list_loader_->IsRefreshing()); 279 base::RunLoop().RunUntilIdle(); 280 EXPECT_FALSE(change_list_loader_->IsRefreshing()); 281 EXPECT_LT(previous_changestamp, metadata_->GetLargestChangestamp()); 282 EXPECT_EQ(1, observer.load_from_server_complete_count()); 283 EXPECT_EQ(1U, observer.changed_directories().count( 284 util::GetDriveMyDriveRootPath())); 285 286 // The new file is found in the local metadata. 287 base::FilePath new_file_path = 288 util::GetDriveMyDriveRootPath().AppendASCII(gdata_entry->title()); 289 ResourceEntry entry; 290 EXPECT_EQ(FILE_ERROR_OK, 291 metadata_->GetResourceEntryByPath(new_file_path, &entry)); 292} 293 294} // namespace internal 295} // namespace drive 296