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.
5 #include "chrome/browser/chromeos/drive/file_system/update_operation.h"
7 #include "base/task_runner_util.h"
8 #include "chrome/browser/chromeos/drive/file_system/operation_test_base.h"
9 #include "chrome/browser/chromeos/drive/file_system_interface.h"
10 #include "chrome/browser/drive/fake_drive_service.h"
11 #include "chrome/browser/google_apis/gdata_wapi_parser.h"
12 #include "chrome/browser/google_apis/test_util.h"
13 #include "testing/gtest/include/gtest/gtest.h"
16 namespace file_system {
18 class UpdateOperationTest : public OperationTestBase {
20 virtual void SetUp() OVERRIDE {
21 OperationTestBase::SetUp();
22 operation_.reset(new UpdateOperation(blocking_task_runner(),
29 scoped_ptr<UpdateOperation> operation_;
32 TEST_F(UpdateOperationTest, UpdateFileByLocalId_PersistentFile) {
33 const base::FilePath kFilePath(FILE_PATH_LITERAL("drive/root/File 1.txt"));
34 const std::string kResourceId("file:2_file_resource_id");
35 const std::string kMd5("3b4382ebefec6e743578c76bbd0575ce");
37 const base::FilePath kTestFile = temp_dir().Append(FILE_PATH_LITERAL("foo"));
38 const std::string kTestFileContent = "I'm being uploaded! Yay!";
39 google_apis::test_util::WriteStringToFile(kTestFile, kTestFileContent);
41 const std::string local_id = GetLocalId(kFilePath);
42 EXPECT_FALSE(local_id.empty());
44 // Pin the file so it'll be store in "persistent" directory.
45 FileError error = FILE_ERROR_FAILED;
46 cache()->PinOnUIThread(
48 google_apis::test_util::CreateCopyResultCallback(&error));
49 test_util::RunBlockingPoolTask();
50 EXPECT_EQ(FILE_ERROR_OK, error);
52 // First store a file to cache.
53 error = FILE_ERROR_FAILED;
54 base::PostTaskAndReplyWithResult(
55 blocking_task_runner(),
57 base::Bind(&internal::FileCache::Store,
58 base::Unretained(cache()),
59 local_id, kMd5, kTestFile,
60 internal::FileCache::FILE_OPERATION_COPY),
61 google_apis::test_util::CreateCopyResultCallback(&error));
62 test_util::RunBlockingPoolTask();
63 EXPECT_EQ(FILE_ERROR_OK, error);
66 error = FILE_ERROR_FAILED;
67 base::PostTaskAndReplyWithResult(
68 blocking_task_runner(),
70 base::Bind(&internal::FileCache::MarkDirty,
71 base::Unretained(cache()),
73 google_apis::test_util::CreateCopyResultCallback(&error));
74 test_util::RunBlockingPoolTask();
75 EXPECT_EQ(FILE_ERROR_OK, error);
77 int64 original_changestamp = fake_service()->largest_changestamp();
79 // The callback will be called upon completion of UpdateFileByLocalId().
80 error = FILE_ERROR_FAILED;
81 operation_->UpdateFileByLocalId(
83 ClientContext(USER_INITIATED),
84 UpdateOperation::RUN_CONTENT_CHECK,
85 google_apis::test_util::CreateCopyResultCallback(&error));
86 test_util::RunBlockingPoolTask();
87 EXPECT_EQ(FILE_ERROR_OK, error);
89 // Check that the server has received an update.
90 EXPECT_LT(original_changestamp, fake_service()->largest_changestamp());
92 // Check that the file size is updated to that of the updated content.
93 google_apis::GDataErrorCode gdata_error = google_apis::GDATA_OTHER_ERROR;
94 scoped_ptr<google_apis::ResourceEntry> server_entry;
95 fake_service()->GetResourceEntry(
97 google_apis::test_util::CreateCopyResultCallback(&gdata_error,
99 test_util::RunBlockingPoolTask();
100 EXPECT_EQ(google_apis::HTTP_SUCCESS, gdata_error);
101 EXPECT_EQ(static_cast<int64>(kTestFileContent.size()),
102 server_entry->file_size());
104 // Make sure that the cache is no longer dirty.
105 bool success = false;
106 FileCacheEntry cache_entry;
107 base::PostTaskAndReplyWithResult(
108 blocking_task_runner(),
110 base::Bind(&internal::FileCache::GetCacheEntry,
111 base::Unretained(cache()),
114 google_apis::test_util::CreateCopyResultCallback(&success));
115 test_util::RunBlockingPoolTask();
116 ASSERT_TRUE(success);
117 EXPECT_FALSE(cache_entry.is_dirty());
120 TEST_F(UpdateOperationTest, UpdateFileByLocalId_NonexistentFile) {
121 FileError error = FILE_ERROR_OK;
122 operation_->UpdateFileByLocalId(
123 "nonexistent_local_id",
124 ClientContext(USER_INITIATED),
125 UpdateOperation::RUN_CONTENT_CHECK,
126 google_apis::test_util::CreateCopyResultCallback(&error));
127 test_util::RunBlockingPoolTask();
128 EXPECT_EQ(FILE_ERROR_NOT_FOUND, error);
131 TEST_F(UpdateOperationTest, UpdateFileByLocalId_Md5) {
132 const base::FilePath kFilePath(FILE_PATH_LITERAL("drive/root/File 1.txt"));
133 const std::string kResourceId("file:2_file_resource_id");
134 const std::string kMd5("3b4382ebefec6e743578c76bbd0575ce");
136 const base::FilePath kTestFile = temp_dir().Append(FILE_PATH_LITERAL("foo"));
137 const std::string kTestFileContent = "I'm being uploaded! Yay!";
138 google_apis::test_util::WriteStringToFile(kTestFile, kTestFileContent);
140 const std::string local_id = GetLocalId(kFilePath);
141 EXPECT_FALSE(local_id.empty());
143 // First store a file to cache.
144 FileError error = FILE_ERROR_FAILED;
145 base::PostTaskAndReplyWithResult(
146 blocking_task_runner(),
148 base::Bind(&internal::FileCache::Store,
149 base::Unretained(cache()),
150 local_id, kMd5, kTestFile,
151 internal::FileCache::FILE_OPERATION_COPY),
152 google_apis::test_util::CreateCopyResultCallback(&error));
153 test_util::RunBlockingPoolTask();
154 EXPECT_EQ(FILE_ERROR_OK, error);
156 // Add the dirty bit.
157 error = FILE_ERROR_FAILED;
158 base::PostTaskAndReplyWithResult(
159 blocking_task_runner(),
161 base::Bind(&internal::FileCache::MarkDirty,
162 base::Unretained(cache()),
164 google_apis::test_util::CreateCopyResultCallback(&error));
165 test_util::RunBlockingPoolTask();
166 EXPECT_EQ(FILE_ERROR_OK, error);
168 int64 original_changestamp = fake_service()->largest_changestamp();
170 // The callback will be called upon completion of UpdateFileByLocalId().
171 error = FILE_ERROR_FAILED;
172 operation_->UpdateFileByLocalId(
174 ClientContext(USER_INITIATED),
175 UpdateOperation::RUN_CONTENT_CHECK,
176 google_apis::test_util::CreateCopyResultCallback(&error));
177 test_util::RunBlockingPoolTask();
178 EXPECT_EQ(FILE_ERROR_OK, error);
180 // Check that the server has received an update.
181 EXPECT_LT(original_changestamp, fake_service()->largest_changestamp());
183 // Check that the file size is updated to that of the updated content.
184 google_apis::GDataErrorCode gdata_error = google_apis::GDATA_OTHER_ERROR;
185 scoped_ptr<google_apis::ResourceEntry> server_entry;
186 fake_service()->GetResourceEntry(
188 google_apis::test_util::CreateCopyResultCallback(&gdata_error,
190 test_util::RunBlockingPoolTask();
191 EXPECT_EQ(google_apis::HTTP_SUCCESS, gdata_error);
192 EXPECT_EQ(static_cast<int64>(kTestFileContent.size()),
193 server_entry->file_size());
195 // Make sure that the cache is no longer dirty.
196 bool success = false;
197 FileCacheEntry cache_entry;
198 base::PostTaskAndReplyWithResult(
199 blocking_task_runner(),
201 base::Bind(&internal::FileCache::GetCacheEntry,
202 base::Unretained(cache()),
205 google_apis::test_util::CreateCopyResultCallback(&success));
206 test_util::RunBlockingPoolTask();
207 ASSERT_TRUE(success);
208 EXPECT_FALSE(cache_entry.is_dirty());
210 // Again mark the cache file dirty.
211 error = FILE_ERROR_FAILED;
212 base::PostTaskAndReplyWithResult(
213 blocking_task_runner(),
215 base::Bind(&internal::FileCache::MarkDirty,
216 base::Unretained(cache()),
218 google_apis::test_util::CreateCopyResultCallback(&error));
219 test_util::RunBlockingPoolTask();
220 EXPECT_EQ(FILE_ERROR_OK, error);
222 // And call UpdateFileByLocalId again.
223 // In this case, although the file is marked as dirty, but the content
224 // hasn't been changed. Thus, the actual uploading should be skipped.
225 original_changestamp = fake_service()->largest_changestamp();
226 error = FILE_ERROR_FAILED;
227 operation_->UpdateFileByLocalId(
229 ClientContext(USER_INITIATED),
230 UpdateOperation::RUN_CONTENT_CHECK,
231 google_apis::test_util::CreateCopyResultCallback(&error));
232 test_util::RunBlockingPoolTask();
233 EXPECT_EQ(FILE_ERROR_OK, error);
235 EXPECT_EQ(original_changestamp, fake_service()->largest_changestamp());
237 // Make sure that the cache is no longer dirty.
239 base::PostTaskAndReplyWithResult(
240 blocking_task_runner(),
242 base::Bind(&internal::FileCache::GetCacheEntry,
243 base::Unretained(cache()),
246 google_apis::test_util::CreateCopyResultCallback(&success));
247 test_util::RunBlockingPoolTask();
248 ASSERT_TRUE(success);
249 EXPECT_FALSE(cache_entry.is_dirty());
251 // Once again mark the cache file dirty.
252 error = FILE_ERROR_FAILED;
253 base::PostTaskAndReplyWithResult(
254 blocking_task_runner(),
256 base::Bind(&internal::FileCache::MarkDirty,
257 base::Unretained(cache()),
259 google_apis::test_util::CreateCopyResultCallback(&error));
260 test_util::RunBlockingPoolTask();
261 EXPECT_EQ(FILE_ERROR_OK, error);
263 // And call UpdateFileByLocalId again.
264 // In this case, NO_CONTENT_CHECK is set, so the actual uploading should run
265 // no matter the content is changed or not.
266 original_changestamp = fake_service()->largest_changestamp();
267 error = FILE_ERROR_FAILED;
268 operation_->UpdateFileByLocalId(
270 ClientContext(USER_INITIATED),
271 UpdateOperation::NO_CONTENT_CHECK,
272 google_apis::test_util::CreateCopyResultCallback(&error));
273 test_util::RunBlockingPoolTask();
274 EXPECT_EQ(FILE_ERROR_OK, error);
276 // Make sure that the server is receiving a change.
277 EXPECT_LE(original_changestamp, fake_service()->largest_changestamp());
280 } // namespace file_system