- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / chromeos / drive / change_list_loader_unittest.cc
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/change_list_processor.h"
13 #include "chrome/browser/chromeos/drive/file_cache.h"
14 #include "chrome/browser/chromeos/drive/file_system_util.h"
15 #include "chrome/browser/chromeos/drive/job_scheduler.h"
16 #include "chrome/browser/chromeos/drive/resource_metadata.h"
17 #include "chrome/browser/chromeos/drive/test_util.h"
18 #include "chrome/browser/drive/fake_drive_service.h"
19 #include "chrome/browser/google_apis/test_util.h"
20 #include "content/public/test/test_browser_thread_bundle.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22
23 namespace drive {
24 namespace internal {
25
26 class TestChangeListLoaderObserver : public ChangeListLoaderObserver {
27  public:
28   explicit TestChangeListLoaderObserver(ChangeListLoader* loader)
29       : loader_(loader),
30         load_from_server_complete_count_(0),
31         initial_load_complete_count_(0) {
32     loader_->AddObserver(this);
33   }
34
35   virtual ~TestChangeListLoaderObserver() {
36     loader_->RemoveObserver(this);
37   }
38
39   const std::set<base::FilePath>& changed_directories() const {
40     return changed_directories_;
41   }
42   void clear_changed_directories() { changed_directories_.clear(); }
43
44   int load_from_server_complete_count() const {
45     return load_from_server_complete_count_;
46   }
47   int initial_load_complete_count() const {
48     return initial_load_complete_count_;
49   }
50
51   // ChageListObserver overrides:
52   virtual void OnDirectoryChanged(
53       const base::FilePath& directory_path) OVERRIDE {
54     changed_directories_.insert(directory_path);
55   }
56   virtual void OnLoadFromServerComplete() OVERRIDE {
57     ++load_from_server_complete_count_;
58   }
59   virtual void OnInitialLoadComplete() OVERRIDE {
60     ++initial_load_complete_count_;
61   }
62
63  private:
64   ChangeListLoader* loader_;
65   std::set<base::FilePath> changed_directories_;
66   int load_from_server_complete_count_;
67   int initial_load_complete_count_;
68
69   DISALLOW_COPY_AND_ASSIGN(TestChangeListLoaderObserver);
70 };
71
72 class ChangeListLoaderTest : public testing::Test {
73  protected:
74   virtual void SetUp() OVERRIDE {
75     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
76     pref_service_.reset(new TestingPrefServiceSimple);
77     test_util::RegisterDrivePrefs(pref_service_->registry());
78
79     drive_service_.reset(new FakeDriveService);
80     ASSERT_TRUE(drive_service_->LoadResourceListForWapi(
81         "gdata/root_feed.json"));
82     ASSERT_TRUE(drive_service_->LoadAccountMetadataForWapi(
83         "gdata/account_metadata.json"));
84
85     scheduler_.reset(new JobScheduler(pref_service_.get(),
86                                       drive_service_.get(),
87                                       base::MessageLoopProxy::current().get()));
88     metadata_storage_.reset(new ResourceMetadataStorage(
89         temp_dir_.path(), base::MessageLoopProxy::current().get()));
90     ASSERT_TRUE(metadata_storage_->Initialize());
91
92     metadata_.reset(new ResourceMetadata(
93         metadata_storage_.get(), base::MessageLoopProxy::current().get()));
94     ASSERT_EQ(FILE_ERROR_OK, metadata_->Initialize());
95
96     cache_.reset(new FileCache(metadata_storage_.get(),
97                                temp_dir_.path(),
98                                base::MessageLoopProxy::current().get(),
99                                NULL /* free_disk_space_getter */));
100     ASSERT_TRUE(cache_->Initialize());
101
102     change_list_loader_.reset(
103         new ChangeListLoader(base::MessageLoopProxy::current().get(),
104                              metadata_.get(),
105                              scheduler_.get(),
106                              drive_service_.get()));
107   }
108
109   // Adds a new file to the root directory of the service.
110   scoped_ptr<google_apis::ResourceEntry> AddNewFile(const std::string& title) {
111     google_apis::GDataErrorCode error = google_apis::GDATA_FILE_ERROR;
112     scoped_ptr<google_apis::ResourceEntry> entry;
113     drive_service_->AddNewFile(
114         "text/plain",
115         "content text",
116         drive_service_->GetRootResourceId(),
117         title,
118         false,  // shared_with_me
119         google_apis::test_util::CreateCopyResultCallback(&error, &entry));
120     base::RunLoop().RunUntilIdle();
121     EXPECT_EQ(google_apis::HTTP_CREATED, error);
122     return entry.Pass();
123   }
124
125   content::TestBrowserThreadBundle thread_bundle_;
126   base::ScopedTempDir temp_dir_;
127   scoped_ptr<TestingPrefServiceSimple> pref_service_;
128   scoped_ptr<FakeDriveService> drive_service_;
129   scoped_ptr<JobScheduler> scheduler_;
130   scoped_ptr<ResourceMetadataStorage,
131              test_util::DestroyHelperForTests> metadata_storage_;
132   scoped_ptr<ResourceMetadata, test_util::DestroyHelperForTests> metadata_;
133   scoped_ptr<FileCache, test_util::DestroyHelperForTests> cache_;
134   scoped_ptr<ChangeListLoader> change_list_loader_;
135 };
136
137 TEST_F(ChangeListLoaderTest, LoadIfNeeded) {
138   EXPECT_FALSE(change_list_loader_->IsRefreshing());
139
140   // Start initial load.
141   TestChangeListLoaderObserver observer(change_list_loader_.get());
142
143   FileError error = FILE_ERROR_FAILED;
144   change_list_loader_->LoadIfNeeded(
145       DirectoryFetchInfo(),
146       google_apis::test_util::CreateCopyResultCallback(&error));
147   EXPECT_TRUE(change_list_loader_->IsRefreshing());
148   base::RunLoop().RunUntilIdle();
149   EXPECT_EQ(FILE_ERROR_OK, error);
150
151   EXPECT_FALSE(change_list_loader_->IsRefreshing());
152   EXPECT_LT(0, metadata_->GetLargestChangestamp());
153   EXPECT_EQ(1, drive_service_->resource_list_load_count());
154   EXPECT_EQ(1, observer.initial_load_complete_count());
155   EXPECT_EQ(1, observer.load_from_server_complete_count());
156   EXPECT_TRUE(observer.changed_directories().empty());
157
158   base::FilePath file_path =
159       util::GetDriveMyDriveRootPath().AppendASCII("File 1.txt");
160   ResourceEntry entry;
161   EXPECT_EQ(FILE_ERROR_OK,
162             metadata_->GetResourceEntryByPath(file_path, &entry));
163
164   // Reload. This should result in no-op.
165   int64 previous_changestamp = metadata_->GetLargestChangestamp();
166   int previous_resource_list_load_count =
167       drive_service_->resource_list_load_count();
168   change_list_loader_->LoadIfNeeded(
169       DirectoryFetchInfo(),
170       google_apis::test_util::CreateCopyResultCallback(&error));
171   EXPECT_FALSE(change_list_loader_->IsRefreshing());
172   base::RunLoop().RunUntilIdle();
173   EXPECT_EQ(FILE_ERROR_OK, error);
174
175   EXPECT_FALSE(change_list_loader_->IsRefreshing());
176   EXPECT_EQ(previous_changestamp, metadata_->GetLargestChangestamp());
177   EXPECT_EQ(previous_resource_list_load_count,
178             drive_service_->resource_list_load_count());
179 }
180
181 TEST_F(ChangeListLoaderTest, LoadIfNeeded_LocalMetadataAvailable) {
182   // Prepare metadata.
183   FileError error = FILE_ERROR_FAILED;
184   change_list_loader_->LoadIfNeeded(
185       DirectoryFetchInfo(),
186       google_apis::test_util::CreateCopyResultCallback(&error));
187   base::RunLoop().RunUntilIdle();
188   EXPECT_EQ(FILE_ERROR_OK, error);
189
190   // Reset loader.
191   change_list_loader_.reset(
192       new ChangeListLoader(base::MessageLoopProxy::current().get(),
193                            metadata_.get(),
194                            scheduler_.get(),
195                            drive_service_.get()));
196
197   // Add a file to the service.
198   scoped_ptr<google_apis::ResourceEntry> gdata_entry = AddNewFile("New File");
199   ASSERT_TRUE(gdata_entry);
200
201   // Start loading. Because local metadata is available, the load results in
202   // returning FILE_ERROR_OK without fetching full list of resources.
203   const int previous_resource_list_load_count =
204       drive_service_->resource_list_load_count();
205   TestChangeListLoaderObserver observer(change_list_loader_.get());
206
207   change_list_loader_->LoadIfNeeded(
208       DirectoryFetchInfo(),
209       google_apis::test_util::CreateCopyResultCallback(&error));
210   EXPECT_TRUE(change_list_loader_->IsRefreshing());
211   base::RunLoop().RunUntilIdle();
212   EXPECT_EQ(FILE_ERROR_OK, error);
213   EXPECT_EQ(previous_resource_list_load_count,
214             drive_service_->resource_list_load_count());
215   EXPECT_EQ(1, observer.initial_load_complete_count());
216
217   // Update should be checked by LoadIfNeeded().
218   EXPECT_EQ(drive_service_->largest_changestamp(),
219             metadata_->GetLargestChangestamp());
220   EXPECT_EQ(1, drive_service_->change_list_load_count());
221   EXPECT_EQ(1, observer.load_from_server_complete_count());
222   EXPECT_EQ(1U, observer.changed_directories().count(
223       util::GetDriveMyDriveRootPath()));
224
225   base::FilePath file_path =
226       util::GetDriveMyDriveRootPath().AppendASCII(gdata_entry->title());
227   ResourceEntry entry;
228   EXPECT_EQ(FILE_ERROR_OK,
229             metadata_->GetResourceEntryByPath(file_path, &entry));
230 }
231
232 TEST_F(ChangeListLoaderTest, LoadIfNeeded_MyDrive) {
233   TestChangeListLoaderObserver observer(change_list_loader_.get());
234
235   // Emulate the slowness of GetAllResourceList().
236   drive_service_->set_never_return_all_resource_list(true);
237
238   // Load grand root.
239   FileError error = FILE_ERROR_FAILED;
240   change_list_loader_->LoadIfNeeded(
241       DirectoryFetchInfo(util::kDriveGrandRootSpecialResourceId, 0),
242       google_apis::test_util::CreateCopyResultCallback(&error));
243   base::RunLoop().RunUntilIdle();
244   EXPECT_EQ(FILE_ERROR_OK, error);
245   EXPECT_EQ(1U, observer.changed_directories().count(
246       util::GetDriveGrandRootPath()));
247   observer.clear_changed_directories();
248
249   // GetAllResourceList() was called.
250   EXPECT_EQ(1, drive_service_->blocked_resource_list_load_count());
251
252   // My Drive is present in the local metadata, but its child is not.
253   ResourceEntry entry;
254   EXPECT_EQ(FILE_ERROR_OK,
255             metadata_->GetResourceEntryByPath(util::GetDriveMyDriveRootPath(),
256                                               &entry));
257   const int64 mydrive_changestamp =
258       entry.directory_specific_info().changestamp();
259
260   base::FilePath file_path =
261       util::GetDriveMyDriveRootPath().AppendASCII("File 1.txt");
262   EXPECT_EQ(FILE_ERROR_NOT_FOUND,
263             metadata_->GetResourceEntryByPath(file_path, &entry));
264
265   // Load My Drive.
266   change_list_loader_->LoadIfNeeded(
267       DirectoryFetchInfo(drive_service_->GetRootResourceId(),
268                          mydrive_changestamp),
269       google_apis::test_util::CreateCopyResultCallback(&error));
270   base::RunLoop().RunUntilIdle();
271   EXPECT_EQ(FILE_ERROR_OK, error);
272   EXPECT_EQ(1U, observer.changed_directories().count(
273       util::GetDriveMyDriveRootPath()));
274
275   // Now the file is present.
276   EXPECT_EQ(FILE_ERROR_OK,
277             metadata_->GetResourceEntryByPath(file_path, &entry));
278 }
279
280 TEST_F(ChangeListLoaderTest, LoadIfNeeded_NewDirectories) {
281   // Make local metadata up to date.
282   FileError error = FILE_ERROR_FAILED;
283   change_list_loader_->LoadIfNeeded(
284       DirectoryFetchInfo(),
285       google_apis::test_util::CreateCopyResultCallback(&error));
286   base::RunLoop().RunUntilIdle();
287   EXPECT_EQ(FILE_ERROR_OK, error);
288
289   // Add a new file.
290   scoped_ptr<google_apis::ResourceEntry> file = AddNewFile("New File");
291   ASSERT_TRUE(file);
292
293   // Emulate the slowness of GetAllResourceList().
294   drive_service_->set_never_return_all_resource_list(true);
295
296   // Enter refreshing state.
297   FileError check_for_updates_error = FILE_ERROR_FAILED;
298   change_list_loader_->CheckForUpdates(
299       google_apis::test_util::CreateCopyResultCallback(
300           &check_for_updates_error));
301   EXPECT_TRUE(change_list_loader_->IsRefreshing());
302
303   // Load My Drive.
304   TestChangeListLoaderObserver observer(change_list_loader_.get());
305   change_list_loader_->LoadIfNeeded(
306       DirectoryFetchInfo(drive_service_->GetRootResourceId(),
307                          metadata_->GetLargestChangestamp()),
308       google_apis::test_util::CreateCopyResultCallback(&error));
309   base::RunLoop().RunUntilIdle();
310   EXPECT_EQ(FILE_ERROR_OK, error);
311   EXPECT_EQ(1U, observer.changed_directories().count(
312       util::GetDriveMyDriveRootPath()));
313
314   // The new file is present in the local metadata.
315   base::FilePath file_path =
316       util::GetDriveMyDriveRootPath().AppendASCII(file->title());
317   ResourceEntry entry;
318   EXPECT_EQ(FILE_ERROR_OK,
319             metadata_->GetResourceEntryByPath(file_path, &entry));
320 }
321
322 TEST_F(ChangeListLoaderTest, LoadIfNeeded_MultipleCalls) {
323   TestChangeListLoaderObserver observer(change_list_loader_.get());
324
325   // Load grand root.
326   FileError error = FILE_ERROR_FAILED;
327   change_list_loader_->LoadIfNeeded(
328       DirectoryFetchInfo(util::kDriveGrandRootSpecialResourceId, 0),
329       google_apis::test_util::CreateCopyResultCallback(&error));
330
331   // Load grand root again without waiting for the result.
332   FileError error2 = FILE_ERROR_FAILED;
333   change_list_loader_->LoadIfNeeded(
334       DirectoryFetchInfo(util::kDriveGrandRootSpecialResourceId, 0),
335       google_apis::test_util::CreateCopyResultCallback(&error2));
336   base::RunLoop().RunUntilIdle();
337
338   // Callback is called for each method call.
339   EXPECT_EQ(FILE_ERROR_OK, error);
340   EXPECT_EQ(FILE_ERROR_OK, error2);
341
342   // No duplicated resource list load and observer events.
343   EXPECT_EQ(1, drive_service_->resource_list_load_count());
344   EXPECT_EQ(1, observer.initial_load_complete_count());
345   EXPECT_EQ(1, observer.load_from_server_complete_count());
346 }
347
348 TEST_F(ChangeListLoaderTest, CheckForUpdates) {
349   // CheckForUpdates() results in no-op before load.
350   FileError check_for_updates_error = FILE_ERROR_FAILED;
351   change_list_loader_->CheckForUpdates(
352       google_apis::test_util::CreateCopyResultCallback(
353           &check_for_updates_error));
354   EXPECT_FALSE(change_list_loader_->IsRefreshing());
355   base::RunLoop().RunUntilIdle();
356   EXPECT_EQ(FILE_ERROR_FAILED,
357             check_for_updates_error);  // Callback was not run.
358   EXPECT_EQ(0, metadata_->GetLargestChangestamp());
359   EXPECT_EQ(0, drive_service_->resource_list_load_count());
360
361   // Start initial load.
362   FileError load_error = FILE_ERROR_FAILED;
363   change_list_loader_->LoadIfNeeded(
364       DirectoryFetchInfo(),
365       google_apis::test_util::CreateCopyResultCallback(&load_error));
366   EXPECT_TRUE(change_list_loader_->IsRefreshing());
367
368   // CheckForUpdates() while loading.
369   change_list_loader_->CheckForUpdates(
370       google_apis::test_util::CreateCopyResultCallback(
371           &check_for_updates_error));
372
373   base::RunLoop().RunUntilIdle();
374   EXPECT_FALSE(change_list_loader_->IsRefreshing());
375   EXPECT_EQ(FILE_ERROR_OK, load_error);
376   EXPECT_EQ(FILE_ERROR_OK, check_for_updates_error);
377   EXPECT_LT(0, metadata_->GetLargestChangestamp());
378   EXPECT_EQ(1, drive_service_->resource_list_load_count());
379
380   int64 previous_changestamp = metadata_->GetLargestChangestamp();
381   // CheckForUpdates() results in no update.
382   change_list_loader_->CheckForUpdates(
383       google_apis::test_util::CreateCopyResultCallback(
384           &check_for_updates_error));
385   EXPECT_TRUE(change_list_loader_->IsRefreshing());
386   base::RunLoop().RunUntilIdle();
387   EXPECT_FALSE(change_list_loader_->IsRefreshing());
388   EXPECT_EQ(previous_changestamp, metadata_->GetLargestChangestamp());
389
390   // Add a file to the service.
391   scoped_ptr<google_apis::ResourceEntry> gdata_entry = AddNewFile("New File");
392   ASSERT_TRUE(gdata_entry);
393
394   // CheckForUpdates() results in update.
395   TestChangeListLoaderObserver observer(change_list_loader_.get());
396   change_list_loader_->CheckForUpdates(
397       google_apis::test_util::CreateCopyResultCallback(
398           &check_for_updates_error));
399   EXPECT_TRUE(change_list_loader_->IsRefreshing());
400   base::RunLoop().RunUntilIdle();
401   EXPECT_FALSE(change_list_loader_->IsRefreshing());
402   EXPECT_LT(previous_changestamp, metadata_->GetLargestChangestamp());
403   EXPECT_EQ(1, observer.load_from_server_complete_count());
404   EXPECT_EQ(1U, observer.changed_directories().count(
405       util::GetDriveMyDriveRootPath()));
406
407   // The new file is found in the local metadata.
408   base::FilePath new_file_path =
409       util::GetDriveMyDriveRootPath().AppendASCII(gdata_entry->title());
410   ResourceEntry entry;
411   EXPECT_EQ(FILE_ERROR_OK,
412             metadata_->GetResourceEntryByPath(new_file_path, &entry));
413 }
414
415 }  // namespace internal
416 }  // namespace drive