blob: 3947fe799ca4cf72d7822145c17c6a7968dbb8ce [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]7a669962012-08-21 06:25:387#include <vector>
8
[email protected]92b84f332012-03-21 20:45:219#include "base/file_util.h"
[email protected]57999812013-02-24 05:40:5210#include "base/files/file_path.h"
[email protected]ea1a3f62012-11-16 20:34:2311#include "base/files/scoped_temp_dir.h"
[email protected]92b84f332012-03-21 20:45:2112#include "base/memory/scoped_ptr.h"
13#include "base/message_loop.h"
[email protected]b83e5202012-06-27 07:50:2414#include "base/test/test_timeouts.h"
[email protected]ddbf2052012-07-13 15:07:0215#include "base/threading/sequenced_worker_pool.h"
[email protected]15de8142012-10-11 06:00:5416#include "chrome/browser/chromeos/drive/drive.pb.h"
[email protected]70e1665c2013-04-19 18:05:0217#include "chrome/browser/chromeos/drive/drive_cache.h"
[email protected]15de8142012-10-11 06:00:5418#include "chrome/browser/chromeos/drive/drive_file_system_util.h"
19#include "chrome/browser/chromeos/drive/drive_test_util.h"
20#include "chrome/browser/chromeos/drive/mock_drive_file_system.h"
[email protected]7601e182013-03-22 09:38:0221#include "chrome/browser/google_apis/test_util.h"
[email protected]e97882f2012-06-04 02:23:1722#include "content/public/test/test_browser_thread.h"
[email protected]92b84f332012-03-21 20:45:2123#include "testing/gmock/include/gmock/gmock.h"
24#include "testing/gtest/include/gtest/gtest.h"
25
[email protected]b83e5202012-06-27 07:50:2426using ::testing::StrictMock;
[email protected]92b84f332012-03-21 20:45:2127using ::testing::_;
28
[email protected]d9d04df2012-10-12 07:06:3529namespace drive {
[email protected]92b84f332012-03-21 20:45:2130
[email protected]80199362012-09-09 23:24:2931namespace {
32
[email protected]aaa70a42012-06-05 22:22:5133// Action used to set mock expectations for GetFileByResourceId().
34ACTION_P4(MockGetFileByResourceId, error, local_path, mime_type, file_type) {
[email protected]192c3cc2013-02-11 22:15:4935 arg2.Run(error, local_path, mime_type, file_type);
[email protected]aaa70a42012-06-05 22:22:5136}
37
[email protected]b83e5202012-06-27 07:50:2438// Action used to set mock expectations for UpdateFileByResourceId().
39ACTION_P(MockUpdateFileByResourceId, error) {
[email protected]192c3cc2013-02-11 22:15:4940 arg2.Run(error);
[email protected]b83e5202012-06-27 07:50:2441}
42
[email protected]85b62192012-06-29 19:56:3843// Action used to set mock expectations for GetFileInfoByResourceId().
44ACTION_P2(MockUpdateFileByResourceId, error, md5) {
[email protected]28a64092012-08-21 10:01:1245 scoped_ptr<DriveEntryProto> entry_proto(new DriveEntryProto);
[email protected]8a4c1d1a2012-07-21 05:12:1746 entry_proto->mutable_file_specific_info()->set_file_md5(md5);
[email protected]650b2d52013-02-10 03:41:4547 arg1.Run(error, base::FilePath(), entry_proto.Pass());
[email protected]85b62192012-06-29 19:56:3848}
49
[email protected]80199362012-09-09 23:24:2950} // namespace
51
[email protected]d876d70b2013-04-23 20:06:1552class SyncClientTest : public testing::Test {
[email protected]ffd60e432012-03-24 20:36:0053 public:
[email protected]d876d70b2013-04-23 20:06:1554 SyncClientTest()
[email protected]92b84f332012-03-21 20:45:2155 : ui_thread_(content::BrowserThread::UI, &message_loop_),
[email protected]80199362012-09-09 23:24:2956 mock_file_system_(new StrictMock<MockDriveFileSystem>) {
[email protected]92b84f332012-03-21 20:45:2157 }
58
59 virtual void SetUp() OVERRIDE {
[email protected]92b84f332012-03-21 20:45:2160 // Create a temporary directory.
61 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
62
[email protected]e63bdc972012-11-22 12:10:4863 // Initialize the cache.
[email protected]ddbf2052012-07-13 15:07:0264 scoped_refptr<base::SequencedWorkerPool> pool =
65 content::BrowserThread::GetBlockingPool();
[email protected]c0a3b8e82013-03-18 21:07:4566 cache_.reset(new DriveCache(
[email protected]e0529fc2012-06-12 11:07:5867 temp_dir_.path(),
[email protected]f6fd98a2012-12-14 00:04:0268 pool->GetSequencedTaskRunner(pool->GetSequenceToken()),
[email protected]c0a3b8e82013-03-18 21:07:4569 NULL /* free_disk_space_getter */));
[email protected]e76fd272013-03-25 13:37:1470 bool success = false;
[email protected]e63bdc972012-11-22 12:10:4871 cache_->RequestInitialize(
[email protected]e76fd272013-03-25 13:37:1472 google_apis::test_util::CreateCopyResultCallback(&success));
[email protected]e63bdc972012-11-22 12:10:4873 google_apis::test_util::RunBlockingPoolTask();
[email protected]e76fd272013-03-25 13:37:1474 ASSERT_TRUE(success);
[email protected]e63bdc972012-11-22 12:10:4875 SetUpCache();
76
77 // Initialize the sync client.
[email protected]70e1665c2013-04-19 18:05:0278 EXPECT_CALL(*mock_file_system_, AddObserver(_)).Times(1);
79 EXPECT_CALL(*mock_file_system_, RemoveObserver(_)).Times(1);
[email protected]d876d70b2013-04-23 20:06:1580 sync_client_.reset(new SyncClient(mock_file_system_.get(), cache_.get()));
[email protected]e0529fc2012-06-12 11:07:5881
[email protected]b83e5202012-06-27 07:50:2482 // Disable delaying so that DoSyncLoop() starts immediately.
83 sync_client_->set_delay_for_testing(base::TimeDelta::FromSeconds(0));
[email protected]92b84f332012-03-21 20:45:2184 }
85
[email protected]a5381772012-04-05 02:20:0486 virtual void TearDown() OVERRIDE {
[email protected]2416a2e2012-05-07 20:58:4987 sync_client_.reset();
[email protected]c0a3b8e82013-03-18 21:07:4588 cache_.reset();
[email protected]a5381772012-04-05 02:20:0489 }
90
[email protected]e63bdc972012-11-22 12:10:4891 // Sets up cache for tests.
92 void SetUpCache() {
93 // Prepare a temp file.
[email protected]650b2d52013-02-10 03:41:4594 base::FilePath temp_file;
[email protected]e63bdc972012-11-22 12:10:4895 EXPECT_TRUE(file_util::CreateTemporaryFileInDir(temp_dir_.path(),
96 &temp_file));
[email protected]8764a392012-06-20 06:43:0897 const std::string content = "hello";
[email protected]e63bdc972012-11-22 12:10:4898 EXPECT_EQ(static_cast<int>(content.size()),
99 file_util::WriteFile(temp_file, content.data(), content.size()));
[email protected]b83e5202012-06-27 07:50:24100
[email protected]e63bdc972012-11-22 12:10:48101 // Prepare 3 pinned-but-not-present files.
[email protected]78a158b2013-04-23 06:57:49102 FileError error = FILE_ERROR_OK;
[email protected]e63bdc972012-11-22 12:10:48103 cache_->Pin("resource_id_not_fetched_foo", "",
[email protected]7601e182013-03-22 09:38:02104 google_apis::test_util::CreateCopyResultCallback(&error));
[email protected]e63bdc972012-11-22 12:10:48105 google_apis::test_util::RunBlockingPoolTask();
[email protected]78a158b2013-04-23 06:57:49106 EXPECT_EQ(FILE_ERROR_OK, error);
[email protected]e63bdc972012-11-22 12:10:48107
108 cache_->Pin("resource_id_not_fetched_bar", "",
[email protected]7601e182013-03-22 09:38:02109 google_apis::test_util::CreateCopyResultCallback(&error));
[email protected]e63bdc972012-11-22 12:10:48110 google_apis::test_util::RunBlockingPoolTask();
[email protected]78a158b2013-04-23 06:57:49111 EXPECT_EQ(FILE_ERROR_OK, error);
[email protected]e63bdc972012-11-22 12:10:48112
113 cache_->Pin("resource_id_not_fetched_baz", "",
[email protected]7601e182013-03-22 09:38:02114 google_apis::test_util::CreateCopyResultCallback(&error));
[email protected]e63bdc972012-11-22 12:10:48115 google_apis::test_util::RunBlockingPoolTask();
[email protected]78a158b2013-04-23 06:57:49116 EXPECT_EQ(FILE_ERROR_OK, error);
[email protected]e63bdc972012-11-22 12:10:48117
118 // Prepare a pinned-and-fetched file.
119 const std::string resource_id_fetched = "resource_id_fetched";
120 const std::string md5_fetched = "md5";
[email protected]650b2d52013-02-10 03:41:45121 base::FilePath cache_file_path;
[email protected]e63bdc972012-11-22 12:10:48122 cache_->Store(resource_id_fetched, md5_fetched, temp_file,
123 DriveCache::FILE_OPERATION_COPY,
[email protected]7601e182013-03-22 09:38:02124 google_apis::test_util::CreateCopyResultCallback(&error));
[email protected]e63bdc972012-11-22 12:10:48125 google_apis::test_util::RunBlockingPoolTask();
[email protected]78a158b2013-04-23 06:57:49126 EXPECT_EQ(FILE_ERROR_OK, error);
[email protected]e63bdc972012-11-22 12:10:48127 cache_->Pin(resource_id_fetched, md5_fetched,
[email protected]7601e182013-03-22 09:38:02128 google_apis::test_util::CreateCopyResultCallback(&error));
[email protected]e63bdc972012-11-22 12:10:48129 google_apis::test_util::RunBlockingPoolTask();
[email protected]78a158b2013-04-23 06:57:49130 EXPECT_EQ(FILE_ERROR_OK, error);
[email protected]e63bdc972012-11-22 12:10:48131
132 // Prepare a pinned-and-fetched-and-dirty file.
133 const std::string resource_id_dirty = "resource_id_dirty";
134 const std::string md5_dirty = ""; // Don't care.
135 cache_->Store(resource_id_dirty, md5_dirty, temp_file,
136 DriveCache::FILE_OPERATION_COPY,
[email protected]7601e182013-03-22 09:38:02137 google_apis::test_util::CreateCopyResultCallback(&error));
[email protected]e63bdc972012-11-22 12:10:48138 google_apis::test_util::RunBlockingPoolTask();
[email protected]78a158b2013-04-23 06:57:49139 EXPECT_EQ(FILE_ERROR_OK, error);
[email protected]e63bdc972012-11-22 12:10:48140 cache_->Pin(resource_id_dirty, md5_dirty,
[email protected]7601e182013-03-22 09:38:02141 google_apis::test_util::CreateCopyResultCallback(&error));
[email protected]e63bdc972012-11-22 12:10:48142 google_apis::test_util::RunBlockingPoolTask();
[email protected]78a158b2013-04-23 06:57:49143 EXPECT_EQ(FILE_ERROR_OK, error);
[email protected]e63bdc972012-11-22 12:10:48144 cache_->MarkDirty(
145 resource_id_dirty, md5_dirty,
[email protected]7601e182013-03-22 09:38:02146 google_apis::test_util::CreateCopyResultCallback(&error));
[email protected]e63bdc972012-11-22 12:10:48147 google_apis::test_util::RunBlockingPoolTask();
[email protected]78a158b2013-04-23 06:57:49148 EXPECT_EQ(FILE_ERROR_OK, error);
[email protected]e63bdc972012-11-22 12:10:48149 cache_->CommitDirty(
150 resource_id_dirty, md5_dirty,
[email protected]7601e182013-03-22 09:38:02151 google_apis::test_util::CreateCopyResultCallback(&error));
[email protected]e63bdc972012-11-22 12:10:48152 google_apis::test_util::RunBlockingPoolTask();
[email protected]78a158b2013-04-23 06:57:49153 EXPECT_EQ(FILE_ERROR_OK, error);
[email protected]adf84402012-03-25 21:56:38154 }
155
[email protected]7f53dc72012-08-23 19:06:55156 // Sets the expectation for MockDriveFileSystem::GetFileByResourceId(),
[email protected]aaa70a42012-06-05 22:22:51157 // that simulates successful retrieval of a file for the given resource ID.
158 void SetExpectationForGetFileByResourceId(const std::string& resource_id) {
159 EXPECT_CALL(*mock_file_system_,
[email protected]192c3cc2013-02-11 22:15:49160 GetFileByResourceId(resource_id, _, _, _))
[email protected]1e4ff462013-02-26 05:36:36161 .WillOnce(
[email protected]189541ba2012-10-24 11:18:15162 MockGetFileByResourceId(
[email protected]78a158b2013-04-23 06:57:49163 FILE_ERROR_OK,
[email protected]650b2d52013-02-10 03:41:45164 base::FilePath::FromUTF8Unsafe("local_path_does_not_matter"),
[email protected]189541ba2012-10-24 11:18:15165 std::string("mime_type_does_not_matter"),
[email protected]1e4ff462013-02-26 05:36:36166 REGULAR_FILE));
[email protected]189541ba2012-10-24 11:18:15167 }
168
[email protected]7f53dc72012-08-23 19:06:55169 // Sets the expectation for MockDriveFileSystem::UpdateFileByResourceId(),
[email protected]b83e5202012-06-27 07:50:24170 // that simulates successful uploading of a file for the given resource ID.
171 void SetExpectationForUpdateFileByResourceId(
172 const std::string& resource_id) {
173 EXPECT_CALL(*mock_file_system_,
[email protected]192c3cc2013-02-11 22:15:49174 UpdateFileByResourceId(resource_id, _, _))
[email protected]78a158b2013-04-23 06:57:49175 .WillOnce(MockUpdateFileByResourceId(FILE_ERROR_OK));
[email protected]b83e5202012-06-27 07:50:24176 }
177
[email protected]7f53dc72012-08-23 19:06:55178 // Sets the expectation for MockDriveFileSystem::GetFileInfoByResourceId(),
[email protected]85b62192012-06-29 19:56:38179 // that simulates successful retrieval of file info for the given resource
180 // ID.
181 //
182 // This is used for testing StartCheckingExistingPinnedFiles(), hence we
[email protected]28a64092012-08-21 10:01:12183 // are only interested in the MD5 value in DriveEntryProto.
[email protected]85b62192012-06-29 19:56:38184 void SetExpectationForGetFileInfoByResourceId(
185 const std::string& resource_id,
186 const std::string& new_md5) {
[email protected]e07bbd972013-01-23 17:38:42187 EXPECT_CALL(*mock_file_system_,
188 GetEntryInfoByResourceId(resource_id, _))
189 .WillOnce(MockUpdateFileByResourceId(
[email protected]78a158b2013-04-23 06:57:49190 FILE_ERROR_OK,
[email protected]e07bbd972013-01-23 17:38:42191 new_md5));
[email protected]85b62192012-06-29 19:56:38192 }
193
[email protected]b7c5da72012-06-26 05:27:46194 // Returns the resource IDs in the queue to be fetched.
195 std::vector<std::string> GetResourceIdsToBeFetched() {
[email protected]d876d70b2013-04-23 20:06:15196 return sync_client_->GetResourceIdsForTesting(SyncClient::FETCH);
[email protected]b7c5da72012-06-26 05:27:46197 }
198
[email protected]b83e5202012-06-27 07:50:24199 // Returns the resource IDs in the queue to be uploaded.
200 std::vector<std::string> GetResourceIdsToBeUploaded() {
[email protected]d876d70b2013-04-23 20:06:15201 return sync_client_->GetResourceIdsForTesting(SyncClient::UPLOAD);
[email protected]b83e5202012-06-27 07:50:24202 }
203
[email protected]b7c5da72012-06-26 05:27:46204 // Adds a resource ID of a file to fetch.
205 void AddResourceIdToFetch(const std::string& resource_id) {
[email protected]d876d70b2013-04-23 20:06:15206 sync_client_->AddResourceIdForTesting(SyncClient::FETCH, resource_id);
[email protected]b7c5da72012-06-26 05:27:46207 }
208
[email protected]b83e5202012-06-27 07:50:24209 // Adds a resource ID of a file to upload.
210 void AddResourceIdToUpload(const std::string& resource_id) {
[email protected]d876d70b2013-04-23 20:06:15211 sync_client_->AddResourceIdForTesting(SyncClient::UPLOAD, resource_id);
[email protected]b83e5202012-06-27 07:50:24212 }
213
[email protected]ffd60e432012-03-24 20:36:00214 protected:
[email protected]92b84f332012-03-21 20:45:21215 MessageLoopForUI message_loop_;
216 content::TestBrowserThread ui_thread_;
[email protected]ea1a3f62012-11-16 20:34:23217 base::ScopedTempDir temp_dir_;
[email protected]7f53dc72012-08-23 19:06:55218 scoped_ptr<StrictMock<MockDriveFileSystem> > mock_file_system_;
[email protected]c0a3b8e82013-03-18 21:07:45219 scoped_ptr<DriveCache, test_util::DestroyHelperForTests> cache_;
[email protected]d876d70b2013-04-23 20:06:15220 scoped_ptr<SyncClient> sync_client_;
[email protected]92b84f332012-03-21 20:45:21221};
222
[email protected]d876d70b2013-04-23 20:06:15223TEST_F(SyncClientTest, StartInitialScan) {
[email protected]b83e5202012-06-27 07:50:24224 // Start processing the files in the backlog. This will collect the
[email protected]8764a392012-06-20 06:43:08225 // resource IDs of these files.
[email protected]b83e5202012-06-27 07:50:24226 sync_client_->StartProcessingBacklog();
[email protected]92b84f332012-03-21 20:45:21227
[email protected]b83e5202012-06-27 07:50:24228 // Check the contents of the queue for fetching.
[email protected]e07bbd972013-01-23 17:38:42229 SetExpectationForGetFileByResourceId("resource_id_not_fetched_bar");
230 SetExpectationForGetFileByResourceId("resource_id_not_fetched_baz");
231 SetExpectationForGetFileByResourceId("resource_id_not_fetched_foo");
[email protected]b83e5202012-06-27 07:50:24232
233 // Check the contents of the queue for uploading.
[email protected]b83e5202012-06-27 07:50:24234 SetExpectationForUpdateFileByResourceId("resource_id_dirty");
[email protected]adf84402012-03-25 21:56:38235
[email protected]e07bbd972013-01-23 17:38:42236 google_apis::test_util::RunBlockingPoolTask();
[email protected]a5381772012-04-05 02:20:04237}
238
[email protected]d876d70b2013-04-23 20:06:15239TEST_F(SyncClientTest, OnCachePinned) {
[email protected]b83e5202012-06-27 07:50:24240 // This file will be fetched by GetFileByResourceId() as OnCachePinned()
[email protected]b7c5da72012-06-26 05:27:46241 // will kick off the sync loop.
[email protected]b83e5202012-06-27 07:50:24242 SetExpectationForGetFileByResourceId("resource_id_not_fetched_foo");
[email protected]adf84402012-03-25 21:56:38243
[email protected]73f9c742012-06-15 07:37:13244 sync_client_->OnCachePinned("resource_id_not_fetched_foo", "md5");
[email protected]e07bbd972013-01-23 17:38:42245
246 google_apis::test_util::RunBlockingPoolTask();
[email protected]adf84402012-03-25 21:56:38247}
248
[email protected]d876d70b2013-04-23 20:06:15249TEST_F(SyncClientTest, OnCacheUnpinned) {
[email protected]b7c5da72012-06-26 05:27:46250 AddResourceIdToFetch("resource_id_not_fetched_foo");
251 AddResourceIdToFetch("resource_id_not_fetched_bar");
252 AddResourceIdToFetch("resource_id_not_fetched_baz");
253 ASSERT_EQ(3U, GetResourceIdsToBeFetched().size());
[email protected]adf84402012-03-25 21:56:38254
[email protected]73f9c742012-06-15 07:37:13255 sync_client_->OnCacheUnpinned("resource_id_not_fetched_foo", "md5");
[email protected]73f9c742012-06-15 07:37:13256 sync_client_->OnCacheUnpinned("resource_id_not_fetched_baz", "md5");
[email protected]e07bbd972013-01-23 17:38:42257
258 // Only resource_id_not_fetched_foo should be fetched.
259 SetExpectationForGetFileByResourceId("resource_id_not_fetched_bar");
260
261 google_apis::test_util::RunBlockingPoolTask();
[email protected]adf84402012-03-25 21:56:38262}
263
[email protected]d876d70b2013-04-23 20:06:15264TEST_F(SyncClientTest, Deduplication) {
[email protected]b83e5202012-06-27 07:50:24265 AddResourceIdToFetch("resource_id_not_fetched_foo");
266
267 // Set the delay so that DoSyncLoop() is delayed.
268 sync_client_->set_delay_for_testing(TestTimeouts::action_max_timeout());
269 // Raise OnCachePinned() event. This shouldn't result in adding the second
270 // task, as tasks are de-duplicated.
271 sync_client_->OnCachePinned("resource_id_not_fetched_foo", "md5");
272
273 ASSERT_EQ(1U, GetResourceIdsToBeFetched().size());
274}
275
[email protected]d876d70b2013-04-23 20:06:15276TEST_F(SyncClientTest, ExistingPinnedFiles) {
[email protected]7f53dc72012-08-23 19:06:55277 // Set the expectation so that the MockDriveFileSystem returns "new_md5"
[email protected]85b62192012-06-29 19:56:38278 // for "resource_id_fetched". This simulates that the file is updated on
279 // the server side, and the new MD5 is obtained from the server (i.e. the
[email protected]fba59542012-12-18 06:05:38280 // local cache file is stale).
[email protected]85b62192012-06-29 19:56:38281 SetExpectationForGetFileInfoByResourceId("resource_id_fetched",
282 "new_md5");
[email protected]7f53dc72012-08-23 19:06:55283 // Set the expectation so that the MockDriveFileSystem returns "some_md5"
[email protected]85b62192012-06-29 19:56:38284 // for "resource_id_dirty". The MD5 on the server is always different from
285 // the MD5 of a dirty file, which is set to "local". We should not collect
286 // this by StartCheckingExistingPinnedFiles().
287 SetExpectationForGetFileInfoByResourceId("resource_id_dirty",
288 "some_md5");
289
290 // Start checking the existing pinned files. This will collect the resource
291 // IDs of pinned files, with stale local cache files.
292 sync_client_->StartCheckingExistingPinnedFiles();
[email protected]e07bbd972013-01-23 17:38:42293
294 SetExpectationForGetFileByResourceId("resource_id_fetched");
295
[email protected]fb0fc202012-10-22 09:30:28296 google_apis::test_util::RunBlockingPoolTask();
[email protected]189541ba2012-10-24 11:18:15297}
298
[email protected]d9d04df2012-10-12 07:06:35299} // namespace drive