blob: 37ec8e2a91ddc13e18457dd3d66b582077af5caa [file] [log] [blame]
[email protected]92b84f332012-03-21 20:45:211// Copyright (c) 2012 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
[email protected]d876d70b2013-04-23 20:06:155#include "chrome/browser/chromeos/drive/sync_client.h"
[email protected]92b84f332012-03-21 20:45:216
[email protected]92b84f332012-03-21 20:45:217#include "base/file_util.h"
[email protected]57999812013-02-24 05:40:528#include "base/files/file_path.h"
[email protected]ea1a3f62012-11-16 20:34:239#include "base/files/scoped_temp_dir.h"
[email protected]92b84f332012-03-21 20:45:2110#include "base/memory/scoped_ptr.h"
[email protected]b568b882013-06-10 04:38:0711#include "base/run_loop.h"
[email protected]b83e5202012-06-27 07:50:2412#include "base/test/test_timeouts.h"
[email protected]b568b882013-06-10 04:38:0713#include "chrome/browser/chromeos/drive/change_list_loader.h"
[email protected]15de8142012-10-11 06:00:5414#include "chrome/browser/chromeos/drive/drive.pb.h"
[email protected]eca3fc92013-05-01 03:53:4015#include "chrome/browser/chromeos/drive/file_cache.h"
[email protected]b568b882013-06-10 04:38:0716#include "chrome/browser/chromeos/drive/file_system/operation_observer.h"
17#include "chrome/browser/chromeos/drive/job_scheduler.h"
18#include "chrome/browser/chromeos/drive/resource_entry_conversion.h"
19#include "chrome/browser/chromeos/drive/resource_metadata.h"
[email protected]92931d72013-04-24 05:16:1520#include "chrome/browser/chromeos/drive/test_util.h"
[email protected]0390b812013-06-19 00:27:5021#include "chrome/browser/drive/fake_drive_service.h"
[email protected]7601e182013-03-22 09:38:0222#include "chrome/browser/google_apis/test_util.h"
[email protected]b568b882013-06-10 04:38:0723#include "chrome/test/base/testing_profile.h"
24#include "content/public/test/test_browser_thread_bundle.h"
[email protected]92b84f332012-03-21 20:45:2125#include "testing/gtest/include/gtest/gtest.h"
26
[email protected]d9d04df2012-10-12 07:06:3527namespace drive {
[email protected]4e87c4862013-05-20 04:06:3228namespace internal {
[email protected]92b84f332012-03-21 20:45:2129
[email protected]80199362012-09-09 23:24:2930namespace {
31
[email protected]b568b882013-06-10 04:38:0732// The content of files iniitally stored in the cache.
33const char kLocalContent[] = "Hello!";
[email protected]61a41c12013-06-06 06:23:3634
[email protected]b568b882013-06-10 04:38:0735// The content of files stored in the service.
36const char kRemoteContent[] = "World!";
37
38// SyncClientTestDriveService will return GDATA_CANCELLED when a request is
39// made with the specified resource ID.
40class SyncClientTestDriveService : public google_apis::FakeDriveService {
[email protected]67e264a2013-06-03 05:39:0141 public:
[email protected]b568b882013-06-10 04:38:0742 // FakeDriveService override:
[email protected]cef0f062013-06-14 16:13:0743 virtual google_apis::CancelCallback GetResourceEntry(
[email protected]67e264a2013-06-03 05:39:0144 const std::string& resource_id,
[email protected]b568b882013-06-10 04:38:0745 const google_apis::GetResourceEntryCallback& callback) OVERRIDE {
46 if (resource_id == resource_id_to_be_cancelled_) {
47 scoped_ptr<google_apis::ResourceEntry> null;
48 base::MessageLoopProxy::current()->PostTask(
49 FROM_HERE,
50 base::Bind(callback,
51 google_apis::GDATA_CANCELLED,
52 base::Passed(&null)));
[email protected]cef0f062013-06-14 16:13:0753 return google_apis::CancelCallback();
[email protected]61a41c12013-06-06 06:23:3654 }
[email protected]cef0f062013-06-14 16:13:0755 return FakeDriveService::GetResourceEntry(resource_id, callback);
[email protected]67e264a2013-06-03 05:39:0156 }
[email protected]aaa70a42012-06-05 22:22:5157
[email protected]b568b882013-06-10 04:38:0758 void set_resource_id_to_be_cancelled(const std::string& resource_id) {
59 resource_id_to_be_cancelled_ = resource_id;
[email protected]67e264a2013-06-03 05:39:0160 }
[email protected]b83e5202012-06-27 07:50:2461
[email protected]67e264a2013-06-03 05:39:0162 private:
[email protected]b568b882013-06-10 04:38:0763 std::string resource_id_to_be_cancelled_;
64};
65
66class DummyOperationObserver : public file_system::OperationObserver {
[email protected]6bf581142013-06-11 17:13:0667 // OperationObserver override:
[email protected]b568b882013-06-10 04:38:0768 virtual void OnDirectoryChangedByOperation(
69 const base::FilePath& path) OVERRIDE {}
[email protected]6bf581142013-06-11 17:13:0670 virtual void OnCacheFileUploadNeededByOperation(
71 const std::string& resource_id) OVERRIDE {}
[email protected]67e264a2013-06-03 05:39:0172};
[email protected]85b62192012-06-29 19:56:3873
[email protected]80199362012-09-09 23:24:2974} // namespace
75
[email protected]d876d70b2013-04-23 20:06:1576class SyncClientTest : public testing::Test {
[email protected]ffd60e432012-03-24 20:36:0077 public:
[email protected]92b84f332012-03-21 20:45:2178 virtual void SetUp() OVERRIDE {
[email protected]92b84f332012-03-21 20:45:2179 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
80
[email protected]b568b882013-06-10 04:38:0781 profile_.reset(new TestingProfile);
82
83 drive_service_.reset(new SyncClientTestDriveService);
84 drive_service_->LoadResourceListForWapi("chromeos/gdata/empty_feed.json");
85 drive_service_->LoadAccountMetadataForWapi(
86 "chromeos/gdata/account_metadata.json");
87
88 scheduler_.reset(new JobScheduler(profile_.get(), drive_service_.get()));
89 metadata_.reset(new internal::ResourceMetadata(
90 temp_dir_.path(), base::MessageLoopProxy::current()));
[email protected]34a1bbf32013-06-17 07:24:0291 ASSERT_EQ(FILE_ERROR_OK, metadata_->Initialize());
[email protected]b568b882013-06-10 04:38:0792
93 cache_.reset(new FileCache(temp_dir_.path(),
94 base::MessageLoopProxy::current(),
95 NULL /* free_disk_space_getter */));
[email protected]34a1bbf32013-06-17 07:24:0296 ASSERT_TRUE(cache_->Initialize());
[email protected]e63bdc972012-11-22 12:10:4897
[email protected]b568b882013-06-10 04:38:0798 ASSERT_NO_FATAL_FAILURE(SetUpTestData());
99
100 sync_client_.reset(new SyncClient(base::MessageLoopProxy::current(),
101 &observer_,
102 scheduler_.get(),
103 metadata_.get(),
104 cache_.get()));
[email protected]e0529fc2012-06-12 11:07:58105
[email protected]b83e5202012-06-27 07:50:24106 // Disable delaying so that DoSyncLoop() starts immediately.
107 sync_client_->set_delay_for_testing(base::TimeDelta::FromSeconds(0));
[email protected]92b84f332012-03-21 20:45:21108 }
109
[email protected]a5381772012-04-05 02:20:04110 virtual void TearDown() OVERRIDE {
[email protected]2416a2e2012-05-07 20:58:49111 sync_client_.reset();
[email protected]c0a3b8e82013-03-18 21:07:45112 cache_.reset();
[email protected]b568b882013-06-10 04:38:07113 metadata_.reset();
[email protected]a5381772012-04-05 02:20:04114 }
115
[email protected]b568b882013-06-10 04:38:07116 // Adds a file to the service root and |resource_ids_|.
117 void AddFileEntry(const std::string& title) {
118 google_apis::GDataErrorCode error = google_apis::GDATA_FILE_ERROR;
119 scoped_ptr<google_apis::ResourceEntry> entry;
120 drive_service_->AddNewFile(
121 "text/plain",
122 kRemoteContent,
123 drive_service_->GetRootResourceId(),
124 title,
125 false, // shared_with_me
126 google_apis::test_util::CreateCopyResultCallback(&error, &entry));
127 base::RunLoop().RunUntilIdle();
128 ASSERT_EQ(google_apis::HTTP_CREATED, error);
129 ASSERT_TRUE(entry);
130 resource_ids_[title] = entry->resource_id();
131 }
132
133 // Sets up data for tests.
134 void SetUpTestData() {
[email protected]e63bdc972012-11-22 12:10:48135 // Prepare a temp file.
[email protected]650b2d52013-02-10 03:41:45136 base::FilePath temp_file;
[email protected]e63bdc972012-11-22 12:10:48137 EXPECT_TRUE(file_util::CreateTemporaryFileInDir(temp_dir_.path(),
138 &temp_file));
[email protected]b568b882013-06-10 04:38:07139 ASSERT_TRUE(google_apis::test_util::WriteStringToFile(temp_file,
140 kLocalContent));
[email protected]b83e5202012-06-27 07:50:24141
[email protected]e63bdc972012-11-22 12:10:48142 // Prepare 3 pinned-but-not-present files.
[email protected]b568b882013-06-10 04:38:07143 ASSERT_NO_FATAL_FAILURE(AddFileEntry("foo"));
[email protected]ebc70e22013-06-18 04:09:46144 EXPECT_EQ(FILE_ERROR_OK, cache_->Pin(resource_ids_["foo"]));
[email protected]e63bdc972012-11-22 12:10:48145
[email protected]b568b882013-06-10 04:38:07146 ASSERT_NO_FATAL_FAILURE(AddFileEntry("bar"));
[email protected]ebc70e22013-06-18 04:09:46147 EXPECT_EQ(FILE_ERROR_OK, cache_->Pin(resource_ids_["bar"]));
[email protected]e63bdc972012-11-22 12:10:48148
[email protected]b568b882013-06-10 04:38:07149 ASSERT_NO_FATAL_FAILURE(AddFileEntry("baz"));
[email protected]ebc70e22013-06-18 04:09:46150 EXPECT_EQ(FILE_ERROR_OK, cache_->Pin(resource_ids_["baz"]));
[email protected]e63bdc972012-11-22 12:10:48151
152 // Prepare a pinned-and-fetched file.
[email protected]e63bdc972012-11-22 12:10:48153 const std::string md5_fetched = "md5";
[email protected]b568b882013-06-10 04:38:07154 ASSERT_NO_FATAL_FAILURE(AddFileEntry("fetched"));
155 EXPECT_EQ(FILE_ERROR_OK,
156 cache_->Store(resource_ids_["fetched"], md5_fetched,
157 temp_file, FileCache::FILE_OPERATION_COPY));
[email protected]ebc70e22013-06-18 04:09:46158 EXPECT_EQ(FILE_ERROR_OK, cache_->Pin(resource_ids_["fetched"]));
[email protected]e63bdc972012-11-22 12:10:48159
160 // Prepare a pinned-and-fetched-and-dirty file.
[email protected]e63bdc972012-11-22 12:10:48161 const std::string md5_dirty = ""; // Don't care.
[email protected]b568b882013-06-10 04:38:07162 ASSERT_NO_FATAL_FAILURE(AddFileEntry("dirty"));
163 EXPECT_EQ(FILE_ERROR_OK,
164 cache_->Store(resource_ids_["dirty"], md5_dirty,
165 temp_file, FileCache::FILE_OPERATION_COPY));
[email protected]ebc70e22013-06-18 04:09:46166 EXPECT_EQ(FILE_ERROR_OK, cache_->Pin(resource_ids_["dirty"]));
[email protected]b568b882013-06-10 04:38:07167 EXPECT_EQ(FILE_ERROR_OK,
168 cache_->MarkDirty(resource_ids_["dirty"], md5_dirty));
[email protected]adf84402012-03-25 21:56:38169
[email protected]b568b882013-06-10 04:38:07170 // Load data from the service to the metadata.
171 FileError error = FILE_ERROR_FAILED;
172 internal::ChangeListLoader change_list_loader(
173 base::MessageLoopProxy::current(), metadata_.get(), scheduler_.get());
174 change_list_loader.LoadIfNeeded(
175 DirectoryFetchInfo(),
176 google_apis::test_util::CreateCopyResultCallback(&error));
177 base::RunLoop().RunUntilIdle();
178 EXPECT_EQ(FILE_ERROR_OK, error);
[email protected]b83e5202012-06-27 07:50:24179 }
180
[email protected]ffd60e432012-03-24 20:36:00181 protected:
[email protected]b568b882013-06-10 04:38:07182 content::TestBrowserThreadBundle thread_bundle_;
[email protected]ea1a3f62012-11-16 20:34:23183 base::ScopedTempDir temp_dir_;
[email protected]b568b882013-06-10 04:38:07184 scoped_ptr<TestingProfile> profile_;
185 scoped_ptr<SyncClientTestDriveService> drive_service_;
186 DummyOperationObserver observer_;
187 scoped_ptr<JobScheduler> scheduler_;
188 scoped_ptr<internal::ResourceMetadata, test_util::DestroyHelperForTests>
189 metadata_;
[email protected]4e87c4862013-05-20 04:06:32190 scoped_ptr<FileCache, test_util::DestroyHelperForTests> cache_;
[email protected]d876d70b2013-04-23 20:06:15191 scoped_ptr<SyncClient> sync_client_;
[email protected]b568b882013-06-10 04:38:07192
193 std::map<std::string, std::string> resource_ids_; // Name-to-id map.
[email protected]92b84f332012-03-21 20:45:21194};
195
[email protected]b568b882013-06-10 04:38:07196TEST_F(SyncClientTest, StartProcessingBacklog) {
[email protected]b83e5202012-06-27 07:50:24197 sync_client_->StartProcessingBacklog();
[email protected]b568b882013-06-10 04:38:07198 base::RunLoop().RunUntilIdle();
[email protected]92b84f332012-03-21 20:45:21199
[email protected]b568b882013-06-10 04:38:07200 FileCacheEntry cache_entry;
201 // Pinned files get downloaded.
202 EXPECT_TRUE(cache_->GetCacheEntry(resource_ids_["foo"], std::string(),
203 &cache_entry));
204 EXPECT_TRUE(cache_entry.is_present());
[email protected]b83e5202012-06-27 07:50:24205
[email protected]b568b882013-06-10 04:38:07206 EXPECT_TRUE(cache_->GetCacheEntry(resource_ids_["bar"], std::string(),
207 &cache_entry));
208 EXPECT_TRUE(cache_entry.is_present());
209
210 EXPECT_TRUE(cache_->GetCacheEntry(resource_ids_["baz"], std::string(),
211 &cache_entry));
212 EXPECT_TRUE(cache_entry.is_present());
213
214 // Dirty file gets uploaded.
215 EXPECT_TRUE(cache_->GetCacheEntry(resource_ids_["dirty"], std::string(),
216 &cache_entry));
217 EXPECT_FALSE(cache_entry.is_dirty());
[email protected]a5381772012-04-05 02:20:04218}
219
[email protected]bd2254d2013-06-12 16:00:47220TEST_F(SyncClientTest, AddFetchTask) {
221 sync_client_->AddFetchTask(resource_ids_["foo"]);
[email protected]b568b882013-06-10 04:38:07222 base::RunLoop().RunUntilIdle();
[email protected]67e264a2013-06-03 05:39:01223
[email protected]b568b882013-06-10 04:38:07224 FileCacheEntry cache_entry;
225 EXPECT_TRUE(cache_->GetCacheEntry(resource_ids_["foo"], std::string(),
226 &cache_entry));
227 EXPECT_TRUE(cache_entry.is_present());
[email protected]adf84402012-03-25 21:56:38228}
229
[email protected]bd2254d2013-06-12 16:00:47230TEST_F(SyncClientTest, AddFetchTaskAndCancelled) {
[email protected]61a41c12013-06-06 06:23:36231 // Trigger fetching of a file which results in cancellation.
[email protected]bd2254d2013-06-12 16:00:47232 drive_service_->set_resource_id_to_be_cancelled(resource_ids_["foo"]);
233 sync_client_->AddFetchTask(resource_ids_["foo"]);
[email protected]b568b882013-06-10 04:38:07234 base::RunLoop().RunUntilIdle();
[email protected]61a41c12013-06-06 06:23:36235
236 // The file should be unpinned if the user wants the download to be cancelled.
[email protected]61a41c12013-06-06 06:23:36237 FileCacheEntry cache_entry;
[email protected]b568b882013-06-10 04:38:07238 EXPECT_FALSE(cache_->GetCacheEntry(resource_ids_["foo"], std::string(),
239 &cache_entry));
[email protected]61a41c12013-06-06 06:23:36240}
241
[email protected]bd2254d2013-06-12 16:00:47242TEST_F(SyncClientTest, RemoveFetchTask) {
[email protected]6bf581142013-06-11 17:13:06243 sync_client_->AddFetchTask(resource_ids_["foo"]);
244 sync_client_->AddFetchTask(resource_ids_["bar"]);
245 sync_client_->AddFetchTask(resource_ids_["baz"]);
[email protected]adf84402012-03-25 21:56:38246
[email protected]bd2254d2013-06-12 16:00:47247 sync_client_->RemoveFetchTask(resource_ids_["foo"]);
248 sync_client_->RemoveFetchTask(resource_ids_["baz"]);
[email protected]b568b882013-06-10 04:38:07249 base::RunLoop().RunUntilIdle();
[email protected]e07bbd972013-01-23 17:38:42250
[email protected]b568b882013-06-10 04:38:07251 // Only "bar" should be fetched.
252 FileCacheEntry cache_entry;
253 EXPECT_TRUE(cache_->GetCacheEntry(resource_ids_["foo"], std::string(),
254 &cache_entry));
255 EXPECT_FALSE(cache_entry.is_present());
256
257 EXPECT_TRUE(cache_->GetCacheEntry(resource_ids_["bar"], std::string(),
258 &cache_entry));
259 EXPECT_TRUE(cache_entry.is_present());
260
261 EXPECT_TRUE(cache_->GetCacheEntry(resource_ids_["baz"], std::string(),
262 &cache_entry));
263 EXPECT_FALSE(cache_entry.is_present());
264
[email protected]adf84402012-03-25 21:56:38265}
266
[email protected]d876d70b2013-04-23 20:06:15267TEST_F(SyncClientTest, ExistingPinnedFiles) {
[email protected]85b62192012-06-29 19:56:38268 // Start checking the existing pinned files. This will collect the resource
269 // IDs of pinned files, with stale local cache files.
270 sync_client_->StartCheckingExistingPinnedFiles();
[email protected]b568b882013-06-10 04:38:07271 base::RunLoop().RunUntilIdle();
[email protected]67e264a2013-06-03 05:39:01272
[email protected]b568b882013-06-10 04:38:07273 // "fetched" and "dirty" are the existing pinned files.
274 // The non-dirty one should be synced, but the dirty one should not.
275 base::FilePath cache_file;
276 std::string content;
277 EXPECT_EQ(FILE_ERROR_OK, cache_->GetFile(resource_ids_["fetched"],
278 std::string(), &cache_file));
279 EXPECT_TRUE(file_util::ReadFileToString(cache_file, &content));
280 EXPECT_EQ(kRemoteContent, content);
281 content.clear();
282
283 EXPECT_EQ(FILE_ERROR_OK, cache_->GetFile(resource_ids_["dirty"],
284 std::string(), &cache_file));
285 EXPECT_TRUE(file_util::ReadFileToString(cache_file, &content));
286 EXPECT_EQ(kLocalContent, content);
[email protected]189541ba2012-10-24 11:18:15287}
288
[email protected]4e87c4862013-05-20 04:06:32289} // namespace internal
[email protected]d9d04df2012-10-12 07:06:35290} // namespace drive