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