Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / chromeos / drive / file_system / download_operation_unittest.cc
blob5aaedfcb9249f3499747a35319b07dc801733917
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/download_operation.h"
7 #include "base/callback_helpers.h"
8 #include "base/file_util.h"
9 #include "base/task_runner_util.h"
10 #include "chrome/browser/chromeos/drive/fake_free_disk_space_getter.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_util.h"
14 #include "chrome/browser/drive/fake_drive_service.h"
15 #include "google_apis/drive/test_util.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17 #include "third_party/cros_system_api/constants/cryptohome.h"
19 namespace drive {
20 namespace file_system {
22 class DownloadOperationTest : public OperationTestBase {
23 protected:
24 virtual void SetUp() OVERRIDE {
25 OperationTestBase::SetUp();
27 operation_.reset(new DownloadOperation(
28 blocking_task_runner(), observer(), scheduler(), metadata(), cache(),
29 temp_dir()));
32 scoped_ptr<DownloadOperation> operation_;
35 TEST_F(DownloadOperationTest,
36 EnsureFileDownloadedByPath_FromServer_EnoughSpace) {
37 base::FilePath file_in_root(FILE_PATH_LITERAL("drive/root/File 1.txt"));
38 ResourceEntry src_entry;
39 ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(file_in_root, &src_entry));
40 const int64 file_size = src_entry.file_info().size();
42 // Pretend we have enough space.
43 fake_free_disk_space_getter()->set_default_value(
44 file_size + cryptohome::kMinFreeSpaceInBytes);
46 FileError error = FILE_ERROR_FAILED;
47 base::FilePath file_path;
48 scoped_ptr<ResourceEntry> entry;
49 operation_->EnsureFileDownloadedByPath(
50 file_in_root,
51 ClientContext(USER_INITIATED),
52 GetFileContentInitializedCallback(),
53 google_apis::GetContentCallback(),
54 google_apis::test_util::CreateCopyResultCallback(
55 &error, &file_path, &entry));
56 test_util::RunBlockingPoolTask();
58 EXPECT_EQ(FILE_ERROR_OK, error);
59 ASSERT_TRUE(entry);
60 EXPECT_FALSE(entry->file_specific_info().is_hosted_document());
62 // The transfered file is cached and the change of "offline available"
63 // attribute is notified.
64 EXPECT_EQ(1U, observer()->get_changed_paths().size());
65 EXPECT_EQ(1U, observer()->get_changed_paths().count(file_in_root.DirName()));
67 // Verify that readable permission is set.
68 int permission = 0;
69 EXPECT_TRUE(base::GetPosixFilePermissions(file_path, &permission));
70 EXPECT_EQ(base::FILE_PERMISSION_READ_BY_USER |
71 base::FILE_PERMISSION_WRITE_BY_USER |
72 base::FILE_PERMISSION_READ_BY_GROUP |
73 base::FILE_PERMISSION_READ_BY_OTHERS, permission);
76 TEST_F(DownloadOperationTest,
77 EnsureFileDownloadedByPath_FromServer_NoSpaceAtAll) {
78 base::FilePath file_in_root(FILE_PATH_LITERAL("drive/root/File 1.txt"));
80 // Pretend we have no space at all.
81 fake_free_disk_space_getter()->set_default_value(0);
83 FileError error = FILE_ERROR_OK;
84 base::FilePath file_path;
85 scoped_ptr<ResourceEntry> entry;
86 operation_->EnsureFileDownloadedByPath(
87 file_in_root,
88 ClientContext(USER_INITIATED),
89 GetFileContentInitializedCallback(),
90 google_apis::GetContentCallback(),
91 google_apis::test_util::CreateCopyResultCallback(
92 &error, &file_path, &entry));
93 test_util::RunBlockingPoolTask();
95 EXPECT_EQ(FILE_ERROR_NO_LOCAL_SPACE, error);
98 TEST_F(DownloadOperationTest,
99 EnsureFileDownloadedByPath_FromServer_NoEnoughSpaceButCanFreeUp) {
100 base::FilePath file_in_root(FILE_PATH_LITERAL("drive/root/File 1.txt"));
101 ResourceEntry src_entry;
102 ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(file_in_root, &src_entry));
103 const int64 file_size = src_entry.file_info().size();
105 // Pretend we have no space first (checked before downloading a file),
106 // but then start reporting we have space. This is to emulate that
107 // the disk space was freed up by removing temporary files.
108 fake_free_disk_space_getter()->PushFakeValue(
109 file_size + cryptohome::kMinFreeSpaceInBytes);
110 fake_free_disk_space_getter()->PushFakeValue(0);
111 fake_free_disk_space_getter()->set_default_value(
112 file_size + cryptohome::kMinFreeSpaceInBytes);
114 // Store something of the file size in the temporary cache directory.
115 const std::string content(file_size, 'x');
116 base::ScopedTempDir temp_dir;
117 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
118 const base::FilePath tmp_file =
119 temp_dir.path().AppendASCII("something.txt");
120 ASSERT_TRUE(google_apis::test_util::WriteStringToFile(tmp_file, content));
122 FileError error = FILE_ERROR_FAILED;
123 base::PostTaskAndReplyWithResult(
124 blocking_task_runner(),
125 FROM_HERE,
126 base::Bind(&internal::FileCache::Store,
127 base::Unretained(cache()),
128 "<id>", "<md5>", tmp_file,
129 internal::FileCache::FILE_OPERATION_COPY),
130 google_apis::test_util::CreateCopyResultCallback(&error));
131 test_util::RunBlockingPoolTask();
132 EXPECT_EQ(FILE_ERROR_OK, error);
134 base::FilePath file_path;
135 scoped_ptr<ResourceEntry> entry;
136 operation_->EnsureFileDownloadedByPath(
137 file_in_root,
138 ClientContext(USER_INITIATED),
139 GetFileContentInitializedCallback(),
140 google_apis::GetContentCallback(),
141 google_apis::test_util::CreateCopyResultCallback(
142 &error, &file_path, &entry));
143 test_util::RunBlockingPoolTask();
145 EXPECT_EQ(FILE_ERROR_OK, error);
146 ASSERT_TRUE(entry);
147 EXPECT_FALSE(entry->file_specific_info().is_hosted_document());
149 // The transfered file is cached and the change of "offline available"
150 // attribute is notified.
151 EXPECT_EQ(1U, observer()->get_changed_paths().size());
152 EXPECT_EQ(1U, observer()->get_changed_paths().count(file_in_root.DirName()));
154 // The cache entry should be removed in order to free up space.
155 FileCacheEntry cache_entry;
156 bool result = true;
157 base::PostTaskAndReplyWithResult(
158 blocking_task_runner(),
159 FROM_HERE,
160 base::Bind(&internal::FileCache::GetCacheEntry,
161 base::Unretained(cache()),
162 "<id>",
163 &cache_entry),
164 google_apis::test_util::CreateCopyResultCallback(&result));
165 test_util::RunBlockingPoolTask();
166 ASSERT_FALSE(result);
169 TEST_F(DownloadOperationTest,
170 EnsureFileDownloadedByPath_FromServer_EnoughSpaceButBecomeFull) {
171 base::FilePath file_in_root(FILE_PATH_LITERAL("drive/root/File 1.txt"));
172 ResourceEntry src_entry;
173 ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(file_in_root, &src_entry));
174 const int64 file_size = src_entry.file_info().size();
176 // Pretend we have enough space first (checked before downloading a file),
177 // but then start reporting we have not enough space. This is to emulate that
178 // the disk space becomes full after the file is downloaded for some reason
179 // (ex. the actual file was larger than the expected size).
180 fake_free_disk_space_getter()->PushFakeValue(
181 file_size + cryptohome::kMinFreeSpaceInBytes);
182 fake_free_disk_space_getter()->set_default_value(
183 cryptohome::kMinFreeSpaceInBytes - 1);
185 FileError error = FILE_ERROR_OK;
186 base::FilePath file_path;
187 scoped_ptr<ResourceEntry> entry;
188 operation_->EnsureFileDownloadedByPath(
189 file_in_root,
190 ClientContext(USER_INITIATED),
191 GetFileContentInitializedCallback(),
192 google_apis::GetContentCallback(),
193 google_apis::test_util::CreateCopyResultCallback(
194 &error, &file_path, &entry));
195 test_util::RunBlockingPoolTask();
197 EXPECT_EQ(FILE_ERROR_NO_LOCAL_SPACE, error);
200 TEST_F(DownloadOperationTest, EnsureFileDownloadedByPath_FromCache) {
201 base::FilePath temp_file;
202 ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir(), &temp_file));
204 base::FilePath file_in_root(FILE_PATH_LITERAL("drive/root/File 1.txt"));
205 ResourceEntry src_entry;
206 ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(file_in_root, &src_entry));
208 // Store something as cached version of this file.
209 FileError error = FILE_ERROR_OK;
210 base::PostTaskAndReplyWithResult(
211 blocking_task_runner(),
212 FROM_HERE,
213 base::Bind(&internal::FileCache::Store,
214 base::Unretained(cache()),
215 GetLocalId(file_in_root),
216 src_entry.file_specific_info().md5(),
217 temp_file,
218 internal::FileCache::FILE_OPERATION_COPY),
219 google_apis::test_util::CreateCopyResultCallback(&error));
220 test_util::RunBlockingPoolTask();
221 EXPECT_EQ(FILE_ERROR_OK, error);
223 base::FilePath file_path;
224 scoped_ptr<ResourceEntry> entry;
225 operation_->EnsureFileDownloadedByPath(
226 file_in_root,
227 ClientContext(USER_INITIATED),
228 GetFileContentInitializedCallback(),
229 google_apis::GetContentCallback(),
230 google_apis::test_util::CreateCopyResultCallback(
231 &error, &file_path, &entry));
232 test_util::RunBlockingPoolTask();
234 EXPECT_EQ(FILE_ERROR_OK, error);
235 ASSERT_TRUE(entry);
236 EXPECT_FALSE(entry->file_specific_info().is_hosted_document());
239 TEST_F(DownloadOperationTest, EnsureFileDownloadedByPath_HostedDocument) {
240 base::FilePath file_in_root(FILE_PATH_LITERAL(
241 "drive/root/Document 1 excludeDir-test.gdoc"));
243 FileError error = FILE_ERROR_FAILED;
244 base::FilePath file_path;
245 scoped_ptr<ResourceEntry> entry;
246 operation_->EnsureFileDownloadedByPath(
247 file_in_root,
248 ClientContext(USER_INITIATED),
249 GetFileContentInitializedCallback(),
250 google_apis::GetContentCallback(),
251 google_apis::test_util::CreateCopyResultCallback(
252 &error, &file_path, &entry));
253 test_util::RunBlockingPoolTask();
255 EXPECT_EQ(FILE_ERROR_OK, error);
256 ASSERT_TRUE(entry);
257 EXPECT_TRUE(entry->file_specific_info().is_hosted_document());
258 EXPECT_FALSE(file_path.empty());
260 EXPECT_EQ(GURL(entry->file_specific_info().alternate_url()),
261 util::ReadUrlFromGDocFile(file_path));
262 EXPECT_EQ(entry->resource_id(), util::ReadResourceIdFromGDocFile(file_path));
265 TEST_F(DownloadOperationTest, EnsureFileDownloadedByLocalId) {
266 base::FilePath file_in_root(FILE_PATH_LITERAL("drive/root/File 1.txt"));
267 ResourceEntry src_entry;
268 ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(file_in_root, &src_entry));
270 FileError error = FILE_ERROR_OK;
271 base::FilePath file_path;
272 scoped_ptr<ResourceEntry> entry;
273 operation_->EnsureFileDownloadedByLocalId(
274 GetLocalId(file_in_root),
275 ClientContext(USER_INITIATED),
276 GetFileContentInitializedCallback(),
277 google_apis::GetContentCallback(),
278 google_apis::test_util::CreateCopyResultCallback(
279 &error, &file_path, &entry));
280 test_util::RunBlockingPoolTask();
282 EXPECT_EQ(FILE_ERROR_OK, error);
283 ASSERT_TRUE(entry);
284 EXPECT_FALSE(entry->file_specific_info().is_hosted_document());
286 // The transfered file is cached and the change of "offline available"
287 // attribute is notified.
288 EXPECT_EQ(1U, observer()->get_changed_paths().size());
289 EXPECT_EQ(1U, observer()->get_changed_paths().count(file_in_root.DirName()));
292 TEST_F(DownloadOperationTest,
293 EnsureFileDownloadedByPath_WithGetContentCallback) {
294 base::FilePath file_in_root(FILE_PATH_LITERAL("drive/root/File 1.txt"));
297 FileError initialized_error = FILE_ERROR_FAILED;
298 scoped_ptr<ResourceEntry> entry, entry_dontcare;
299 base::FilePath local_path, local_path_dontcare;
300 base::Closure cancel_download;
301 google_apis::test_util::TestGetContentCallback get_content_callback;
303 FileError completion_error = FILE_ERROR_FAILED;
305 operation_->EnsureFileDownloadedByPath(
306 file_in_root,
307 ClientContext(USER_INITIATED),
308 google_apis::test_util::CreateCopyResultCallback(
309 &initialized_error, &entry, &local_path, &cancel_download),
310 get_content_callback.callback(),
311 google_apis::test_util::CreateCopyResultCallback(
312 &completion_error, &local_path_dontcare, &entry_dontcare));
313 test_util::RunBlockingPoolTask();
315 // For the first time, file is downloaded from the remote server.
316 // In this case, |local_path| is empty while |cancel_download| is not.
317 EXPECT_EQ(FILE_ERROR_OK, initialized_error);
318 ASSERT_TRUE(entry);
319 ASSERT_TRUE(local_path.empty());
320 EXPECT_TRUE(!cancel_download.is_null());
321 // Content is available through the second callback argument.
322 EXPECT_EQ(static_cast<size_t>(entry->file_info().size()),
323 get_content_callback.GetConcatenatedData().size());
324 EXPECT_EQ(FILE_ERROR_OK, completion_error);
326 // The transfered file is cached and the change of "offline available"
327 // attribute is notified.
328 EXPECT_EQ(1U, observer()->get_changed_paths().size());
329 EXPECT_EQ(1U,
330 observer()->get_changed_paths().count(file_in_root.DirName()));
334 FileError initialized_error = FILE_ERROR_FAILED;
335 scoped_ptr<ResourceEntry> entry, entry_dontcare;
336 base::FilePath local_path, local_path_dontcare;
337 base::Closure cancel_download;
338 google_apis::test_util::TestGetContentCallback get_content_callback;
340 FileError completion_error = FILE_ERROR_FAILED;
342 operation_->EnsureFileDownloadedByPath(
343 file_in_root,
344 ClientContext(USER_INITIATED),
345 google_apis::test_util::CreateCopyResultCallback(
346 &initialized_error, &entry, &local_path, &cancel_download),
347 get_content_callback.callback(),
348 google_apis::test_util::CreateCopyResultCallback(
349 &completion_error, &local_path_dontcare, &entry_dontcare));
350 test_util::RunBlockingPoolTask();
352 // Try second download. In this case, the file should be cached, so
353 // |local_path| should not be empty while |cancel_download| is empty.
354 EXPECT_EQ(FILE_ERROR_OK, initialized_error);
355 ASSERT_TRUE(entry);
356 ASSERT_TRUE(!local_path.empty());
357 EXPECT_TRUE(cancel_download.is_null());
358 // The content is available from the cache file.
359 EXPECT_TRUE(get_content_callback.data().empty());
360 int64 local_file_size = 0;
361 base::GetFileSize(local_path, &local_file_size);
362 EXPECT_EQ(entry->file_info().size(), local_file_size);
363 EXPECT_EQ(FILE_ERROR_OK, completion_error);
367 TEST_F(DownloadOperationTest, EnsureFileDownloadedByLocalId_FromCache) {
368 base::FilePath temp_file;
369 ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir(), &temp_file));
371 base::FilePath file_in_root(FILE_PATH_LITERAL("drive/root/File 1.txt"));
372 ResourceEntry src_entry;
373 ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(file_in_root, &src_entry));
375 // Store something as cached version of this file.
376 FileError error = FILE_ERROR_FAILED;
377 base::PostTaskAndReplyWithResult(
378 blocking_task_runner(),
379 FROM_HERE,
380 base::Bind(&internal::FileCache::Store,
381 base::Unretained(cache()),
382 GetLocalId(file_in_root),
383 src_entry.file_specific_info().md5(),
384 temp_file,
385 internal::FileCache::FILE_OPERATION_COPY),
386 google_apis::test_util::CreateCopyResultCallback(&error));
387 test_util::RunBlockingPoolTask();
388 EXPECT_EQ(FILE_ERROR_OK, error);
390 // The file is obtained from the cache.
391 // Hence the downloading should work even if the drive service is offline.
392 fake_service()->set_offline(true);
394 base::FilePath file_path;
395 scoped_ptr<ResourceEntry> entry;
396 operation_->EnsureFileDownloadedByLocalId(
397 GetLocalId(file_in_root),
398 ClientContext(USER_INITIATED),
399 GetFileContentInitializedCallback(),
400 google_apis::GetContentCallback(),
401 google_apis::test_util::CreateCopyResultCallback(
402 &error, &file_path, &entry));
403 test_util::RunBlockingPoolTask();
405 EXPECT_EQ(FILE_ERROR_OK, error);
406 ASSERT_TRUE(entry);
407 EXPECT_FALSE(entry->file_specific_info().is_hosted_document());
410 TEST_F(DownloadOperationTest, EnsureFileDownloadedByPath_DirtyCache) {
411 base::FilePath file_in_root(FILE_PATH_LITERAL("drive/root/File 1.txt"));
412 ResourceEntry src_entry;
413 ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(file_in_root, &src_entry));
415 // Prepare a dirty file to store to cache that has a different size than
416 // stored in resource metadata.
417 base::FilePath dirty_file = temp_dir().AppendASCII("dirty.txt");
418 size_t dirty_size = src_entry.file_info().size() + 10;
419 google_apis::test_util::WriteStringToFile(dirty_file,
420 std::string(dirty_size, 'x'));
422 // Store the file as a cache, marking it to be dirty.
423 FileError error = FILE_ERROR_FAILED;
424 base::PostTaskAndReplyWithResult(
425 blocking_task_runner(),
426 FROM_HERE,
427 base::Bind(&internal::FileCache::Store,
428 base::Unretained(cache()),
429 GetLocalId(file_in_root),
430 src_entry.file_specific_info().md5(),
431 dirty_file,
432 internal::FileCache::FILE_OPERATION_COPY),
433 google_apis::test_util::CreateCopyResultCallback(&error));
434 test_util::RunBlockingPoolTask();
435 EXPECT_EQ(FILE_ERROR_OK, error);
436 scoped_ptr<base::ScopedClosureRunner> file_closer;
437 base::PostTaskAndReplyWithResult(
438 blocking_task_runner(),
439 FROM_HERE,
440 base::Bind(&internal::FileCache::OpenForWrite,
441 base::Unretained(cache()),
442 GetLocalId(file_in_root),
443 &file_closer),
444 google_apis::test_util::CreateCopyResultCallback(&error));
445 test_util::RunBlockingPoolTask();
446 EXPECT_EQ(FILE_ERROR_OK, error);
448 // Record values passed to GetFileContentInitializedCallback().
449 FileError init_error;
450 base::FilePath init_path;
451 scoped_ptr<ResourceEntry> init_entry;
452 base::Closure cancel_callback;
454 base::FilePath file_path;
455 scoped_ptr<ResourceEntry> entry;
456 operation_->EnsureFileDownloadedByPath(
457 file_in_root,
458 ClientContext(USER_INITIATED),
459 google_apis::test_util::CreateCopyResultCallback(
460 &init_error, &init_entry, &init_path, &cancel_callback),
461 google_apis::GetContentCallback(),
462 google_apis::test_util::CreateCopyResultCallback(
463 &error, &file_path, &entry));
464 test_util::RunBlockingPoolTask();
466 EXPECT_EQ(FILE_ERROR_OK, error);
467 // Check that the result of local modification is propagated.
468 EXPECT_EQ(static_cast<int64>(dirty_size), init_entry->file_info().size());
469 EXPECT_EQ(static_cast<int64>(dirty_size), entry->file_info().size());
472 } // namespace file_system
473 } // namespace drive