Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / chromeos / drive / file_system / update_operation_unittest.cc
blob8a3b42851cf88e2fd46bae13dffd49a48921413c
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/callback_helpers.h"
8 #include "base/file_util.h"
9 #include "base/md5.h"
10 #include "base/task_runner_util.h"
11 #include "chrome/browser/chromeos/drive/file_cache.h"
12 #include "chrome/browser/chromeos/drive/file_system/operation_test_base.h"
13 #include "chrome/browser/chromeos/drive/file_system_interface.h"
14 #include "chrome/browser/drive/fake_drive_service.h"
15 #include "google_apis/drive/gdata_wapi_parser.h"
16 #include "google_apis/drive/test_util.h"
17 #include "testing/gtest/include/gtest/gtest.h"
19 namespace drive {
20 namespace file_system {
22 class UpdateOperationTest : public OperationTestBase {
23 protected:
24 virtual void SetUp() OVERRIDE {
25 OperationTestBase::SetUp();
26 operation_.reset(new UpdateOperation(blocking_task_runner(),
27 observer(),
28 scheduler(),
29 metadata(),
30 cache()));
33 // Stores |content| to the cache and mark it as dirty.
34 FileError StoreAndMarkDirty(const std::string& local_id,
35 const std::string& content) {
36 base::FilePath path;
37 if (!base::CreateTemporaryFileInDir(temp_dir(), &path) ||
38 !google_apis::test_util::WriteStringToFile(path, content))
39 return FILE_ERROR_FAILED;
41 // Store the file to cache.
42 FileError error = FILE_ERROR_FAILED;
43 base::PostTaskAndReplyWithResult(
44 blocking_task_runner(),
45 FROM_HERE,
46 base::Bind(&internal::FileCache::Store,
47 base::Unretained(cache()),
48 local_id, base::MD5String(content), path,
49 internal::FileCache::FILE_OPERATION_COPY),
50 google_apis::test_util::CreateCopyResultCallback(&error));
51 test_util::RunBlockingPoolTask();
52 if (error != FILE_ERROR_OK)
53 return error;
55 // Add the dirty bit.
56 error = FILE_ERROR_FAILED;
57 scoped_ptr<base::ScopedClosureRunner> file_closer;
58 base::PostTaskAndReplyWithResult(
59 blocking_task_runner(),
60 FROM_HERE,
61 base::Bind(&internal::FileCache::OpenForWrite,
62 base::Unretained(cache()),
63 local_id,
64 &file_closer),
65 google_apis::test_util::CreateCopyResultCallback(&error));
66 test_util::RunBlockingPoolTask();
67 return error;
70 scoped_ptr<UpdateOperation> operation_;
73 TEST_F(UpdateOperationTest, UpdateFileByLocalId) {
74 const base::FilePath kFilePath(FILE_PATH_LITERAL("drive/root/File 1.txt"));
75 const std::string kResourceId("file:2_file_resource_id");
77 const std::string local_id = GetLocalId(kFilePath);
78 EXPECT_FALSE(local_id.empty());
80 const std::string kTestFileContent = "I'm being uploaded! Yay!";
81 EXPECT_EQ(FILE_ERROR_OK, StoreAndMarkDirty(local_id, kTestFileContent));
83 int64 original_changestamp = fake_service()->largest_changestamp();
85 // The callback will be called upon completion of UpdateFileByLocalId().
86 FileError error = FILE_ERROR_FAILED;
87 operation_->UpdateFileByLocalId(
88 local_id,
89 ClientContext(USER_INITIATED),
90 UpdateOperation::RUN_CONTENT_CHECK,
91 google_apis::test_util::CreateCopyResultCallback(&error));
92 test_util::RunBlockingPoolTask();
93 EXPECT_EQ(FILE_ERROR_OK, error);
95 // Check that the server has received an update.
96 EXPECT_LT(original_changestamp, fake_service()->largest_changestamp());
98 // Check that the file size is updated to that of the updated content.
99 google_apis::GDataErrorCode gdata_error = google_apis::GDATA_OTHER_ERROR;
100 scoped_ptr<google_apis::ResourceEntry> server_entry;
101 fake_service()->GetResourceEntry(
102 kResourceId,
103 google_apis::test_util::CreateCopyResultCallback(&gdata_error,
104 &server_entry));
105 test_util::RunBlockingPoolTask();
106 EXPECT_EQ(google_apis::HTTP_SUCCESS, gdata_error);
107 EXPECT_EQ(static_cast<int64>(kTestFileContent.size()),
108 server_entry->file_size());
110 // Make sure that the cache is no longer dirty.
111 bool success = false;
112 FileCacheEntry cache_entry;
113 base::PostTaskAndReplyWithResult(
114 blocking_task_runner(),
115 FROM_HERE,
116 base::Bind(&internal::FileCache::GetCacheEntry,
117 base::Unretained(cache()),
118 local_id,
119 &cache_entry),
120 google_apis::test_util::CreateCopyResultCallback(&success));
121 test_util::RunBlockingPoolTask();
122 ASSERT_TRUE(success);
123 EXPECT_FALSE(cache_entry.is_dirty());
126 TEST_F(UpdateOperationTest, UpdateFileByLocalId_NonexistentFile) {
127 FileError error = FILE_ERROR_OK;
128 operation_->UpdateFileByLocalId(
129 "nonexistent_local_id",
130 ClientContext(USER_INITIATED),
131 UpdateOperation::RUN_CONTENT_CHECK,
132 google_apis::test_util::CreateCopyResultCallback(&error));
133 test_util::RunBlockingPoolTask();
134 EXPECT_EQ(FILE_ERROR_NOT_FOUND, error);
137 TEST_F(UpdateOperationTest, UpdateFileByLocalId_Md5) {
138 const base::FilePath kFilePath(FILE_PATH_LITERAL("drive/root/File 1.txt"));
139 const std::string kResourceId("file:2_file_resource_id");
141 const std::string local_id = GetLocalId(kFilePath);
142 EXPECT_FALSE(local_id.empty());
144 const std::string kTestFileContent = "I'm being uploaded! Yay!";
145 EXPECT_EQ(FILE_ERROR_OK, StoreAndMarkDirty(local_id, kTestFileContent));
147 int64 original_changestamp = fake_service()->largest_changestamp();
149 // The callback will be called upon completion of UpdateFileByLocalId().
150 FileError error = FILE_ERROR_FAILED;
151 operation_->UpdateFileByLocalId(
152 local_id,
153 ClientContext(USER_INITIATED),
154 UpdateOperation::RUN_CONTENT_CHECK,
155 google_apis::test_util::CreateCopyResultCallback(&error));
156 test_util::RunBlockingPoolTask();
157 EXPECT_EQ(FILE_ERROR_OK, error);
159 // Check that the server has received an update.
160 EXPECT_LT(original_changestamp, fake_service()->largest_changestamp());
162 // Check that the file size is updated to that of the updated content.
163 google_apis::GDataErrorCode gdata_error = google_apis::GDATA_OTHER_ERROR;
164 scoped_ptr<google_apis::ResourceEntry> server_entry;
165 fake_service()->GetResourceEntry(
166 kResourceId,
167 google_apis::test_util::CreateCopyResultCallback(&gdata_error,
168 &server_entry));
169 test_util::RunBlockingPoolTask();
170 EXPECT_EQ(google_apis::HTTP_SUCCESS, gdata_error);
171 EXPECT_EQ(static_cast<int64>(kTestFileContent.size()),
172 server_entry->file_size());
174 // Make sure that the cache is no longer dirty.
175 bool success = false;
176 FileCacheEntry cache_entry;
177 base::PostTaskAndReplyWithResult(
178 blocking_task_runner(),
179 FROM_HERE,
180 base::Bind(&internal::FileCache::GetCacheEntry,
181 base::Unretained(cache()),
182 local_id,
183 &cache_entry),
184 google_apis::test_util::CreateCopyResultCallback(&success));
185 test_util::RunBlockingPoolTask();
186 ASSERT_TRUE(success);
187 EXPECT_FALSE(cache_entry.is_dirty());
189 // Again mark the cache file dirty.
190 scoped_ptr<base::ScopedClosureRunner> file_closer;
191 error = FILE_ERROR_FAILED;
192 base::PostTaskAndReplyWithResult(
193 blocking_task_runner(),
194 FROM_HERE,
195 base::Bind(&internal::FileCache::OpenForWrite,
196 base::Unretained(cache()),
197 local_id,
198 &file_closer),
199 google_apis::test_util::CreateCopyResultCallback(&error));
200 test_util::RunBlockingPoolTask();
201 EXPECT_EQ(FILE_ERROR_OK, error);
203 // And call UpdateFileByLocalId again.
204 // In this case, although the file is marked as dirty, but the content
205 // hasn't been changed. Thus, the actual uploading should be skipped.
206 original_changestamp = fake_service()->largest_changestamp();
207 error = FILE_ERROR_FAILED;
208 operation_->UpdateFileByLocalId(
209 local_id,
210 ClientContext(USER_INITIATED),
211 UpdateOperation::RUN_CONTENT_CHECK,
212 google_apis::test_util::CreateCopyResultCallback(&error));
213 test_util::RunBlockingPoolTask();
214 EXPECT_EQ(FILE_ERROR_OK, error);
216 EXPECT_EQ(original_changestamp, fake_service()->largest_changestamp());
218 // Make sure that the cache is no longer dirty.
219 success = false;
220 base::PostTaskAndReplyWithResult(
221 blocking_task_runner(),
222 FROM_HERE,
223 base::Bind(&internal::FileCache::GetCacheEntry,
224 base::Unretained(cache()),
225 local_id,
226 &cache_entry),
227 google_apis::test_util::CreateCopyResultCallback(&success));
228 test_util::RunBlockingPoolTask();
229 ASSERT_TRUE(success);
230 EXPECT_FALSE(cache_entry.is_dirty());
232 // Once again mark the cache file dirty.
233 error = FILE_ERROR_FAILED;
234 base::PostTaskAndReplyWithResult(
235 blocking_task_runner(),
236 FROM_HERE,
237 base::Bind(&internal::FileCache::OpenForWrite,
238 base::Unretained(cache()),
239 local_id,
240 &file_closer),
241 google_apis::test_util::CreateCopyResultCallback(&error));
242 test_util::RunBlockingPoolTask();
243 EXPECT_EQ(FILE_ERROR_OK, error);
245 // And call UpdateFileByLocalId again.
246 // In this case, NO_CONTENT_CHECK is set, so the actual uploading should run
247 // no matter the content is changed or not.
248 original_changestamp = fake_service()->largest_changestamp();
249 error = FILE_ERROR_FAILED;
250 operation_->UpdateFileByLocalId(
251 local_id,
252 ClientContext(USER_INITIATED),
253 UpdateOperation::NO_CONTENT_CHECK,
254 google_apis::test_util::CreateCopyResultCallback(&error));
255 test_util::RunBlockingPoolTask();
256 EXPECT_EQ(FILE_ERROR_OK, error);
258 // Make sure that the server is receiving a change.
259 EXPECT_LE(original_changestamp, fake_service()->largest_changestamp());
262 TEST_F(UpdateOperationTest, UpdateFileByLocalId_OpenedForWrite) {
263 const base::FilePath kFilePath(FILE_PATH_LITERAL("drive/root/File 1.txt"));
264 const std::string kResourceId("file:2_file_resource_id");
266 const std::string local_id = GetLocalId(kFilePath);
267 EXPECT_FALSE(local_id.empty());
269 const std::string kTestFileContent = "I'm being uploaded! Yay!";
270 EXPECT_EQ(FILE_ERROR_OK, StoreAndMarkDirty(local_id, kTestFileContent));
272 // Emulate a situation where someone is writing to the file.
273 scoped_ptr<base::ScopedClosureRunner> file_closer;
274 FileError error = FILE_ERROR_FAILED;
275 base::PostTaskAndReplyWithResult(
276 blocking_task_runner(),
277 FROM_HERE,
278 base::Bind(&internal::FileCache::OpenForWrite,
279 base::Unretained(cache()),
280 local_id,
281 &file_closer),
282 google_apis::test_util::CreateCopyResultCallback(&error));
283 test_util::RunBlockingPoolTask();
284 EXPECT_EQ(FILE_ERROR_OK, error);
286 // Update. This should not clear the dirty bit.
287 error = FILE_ERROR_FAILED;
288 operation_->UpdateFileByLocalId(
289 local_id,
290 ClientContext(USER_INITIATED),
291 UpdateOperation::RUN_CONTENT_CHECK,
292 google_apis::test_util::CreateCopyResultCallback(&error));
293 test_util::RunBlockingPoolTask();
294 EXPECT_EQ(FILE_ERROR_OK, error);
296 // Make sure that the cache is still dirty.
297 bool success = false;
298 FileCacheEntry cache_entry;
299 base::PostTaskAndReplyWithResult(
300 blocking_task_runner(),
301 FROM_HERE,
302 base::Bind(&internal::FileCache::GetCacheEntry,
303 base::Unretained(cache()),
304 local_id,
305 &cache_entry),
306 google_apis::test_util::CreateCopyResultCallback(&success));
307 test_util::RunBlockingPoolTask();
308 EXPECT_TRUE(success);
309 EXPECT_TRUE(cache_entry.is_dirty());
311 // Close the file.
312 file_closer.reset();
314 // Update. This should clear the dirty bit.
315 error = FILE_ERROR_FAILED;
316 operation_->UpdateFileByLocalId(
317 local_id,
318 ClientContext(USER_INITIATED),
319 UpdateOperation::RUN_CONTENT_CHECK,
320 google_apis::test_util::CreateCopyResultCallback(&error));
321 test_util::RunBlockingPoolTask();
322 EXPECT_EQ(FILE_ERROR_OK, error);
324 // Make sure that the cache is no longer dirty.
325 base::PostTaskAndReplyWithResult(
326 blocking_task_runner(),
327 FROM_HERE,
328 base::Bind(&internal::FileCache::GetCacheEntry,
329 base::Unretained(cache()),
330 local_id,
331 &cache_entry),
332 google_apis::test_util::CreateCopyResultCallback(&success));
333 test_util::RunBlockingPoolTask();
334 EXPECT_TRUE(success);
335 EXPECT_FALSE(cache_entry.is_dirty());
338 } // namespace file_system
339 } // namespace drive