Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(98)

Side by Side Diff: content/browser/fileapi/dragged_file_util_unittest.cc

Issue 2368913003: Populate storage_unittests target. (Closed)
Patch Set: Removed unnecessary include from storage/browser/blob/blob_storage_context_unittest.cc. Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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.
4
5 #include <stddef.h>
6
7 #include <map>
8 #include <memory>
9 #include <queue>
10 #include <set>
11 #include <string>
12 #include <vector>
13
14 #include "base/files/file_enumerator.h"
15 #include "base/files/file_util.h"
16 #include "base/files/scoped_temp_dir.h"
17 #include "base/logging.h"
18 #include "base/macros.h"
19 #include "base/memory/ptr_util.h"
20 #include "base/message_loop/message_loop.h"
21 #include "base/time/time.h"
22 #include "build/build_config.h"
23 #include "content/public/test/async_file_test_helper.h"
24 #include "content/public/test/test_file_system_context.h"
25 #include "content/test/fileapi_test_file_set.h"
26 #include "storage/browser/fileapi/dragged_file_util.h"
27 #include "storage/browser/fileapi/file_system_context.h"
28 #include "storage/browser/fileapi/file_system_operation_context.h"
29 #include "storage/browser/fileapi/isolated_context.h"
30 #include "storage/browser/fileapi/local_file_util.h"
31 #include "storage/browser/fileapi/native_file_util.h"
32 #include "testing/gtest/include/gtest/gtest.h"
33
34 using content::AsyncFileTestHelper;
35 using storage::FileSystemContext;
36 using storage::FileSystemOperationContext;
37 using storage::FileSystemType;
38 using storage::FileSystemURL;
39
40 namespace content {
41
42 namespace {
43
44 typedef AsyncFileTestHelper::FileEntryList FileEntryList;
45
46 // Used in DraggedFileUtilTest::SimulateDropFiles().
47 // Random root paths in which we create each file/directory of the
48 // RegularTestCases (so that we can simulate a drop with files/directories
49 // from multiple directories).
50 static const base::FilePath::CharType* kRootPaths[] = {
51 FILE_PATH_LITERAL("a"),
52 FILE_PATH_LITERAL("b/c"),
53 FILE_PATH_LITERAL("etc"),
54 };
55
56 base::FilePath GetTopLevelPath(const base::FilePath& path) {
57 std::vector<base::FilePath::StringType> components;
58 path.GetComponents(&components);
59 return base::FilePath(components[0]);
60 }
61
62 bool IsDirectoryEmpty(FileSystemContext* context, const FileSystemURL& url) {
63 FileEntryList entries;
64 EXPECT_EQ(base::File::FILE_OK,
65 AsyncFileTestHelper::ReadDirectory(context, url, &entries));
66 return entries.empty();
67 }
68
69 FileSystemURL GetEntryURL(FileSystemContext* file_system_context,
70 const FileSystemURL& dir,
71 const base::FilePath::StringType& name) {
72 return file_system_context->CreateCrackedFileSystemURL(
73 dir.origin(),
74 dir.mount_type(),
75 dir.virtual_path().Append(name));
76 }
77
78 base::FilePath GetRelativeVirtualPath(const FileSystemURL& root,
79 const FileSystemURL& url) {
80 if (root.virtual_path().empty())
81 return url.virtual_path();
82 base::FilePath relative;
83 const bool success = root.virtual_path().AppendRelativePath(
84 url.virtual_path(), &relative);
85 DCHECK(success);
86 return relative;
87 }
88
89 FileSystemURL GetOtherURL(FileSystemContext* file_system_context,
90 const FileSystemURL& root,
91 const FileSystemURL& other_root,
92 const FileSystemURL& url) {
93 return file_system_context->CreateCrackedFileSystemURL(
94 other_root.origin(),
95 other_root.mount_type(),
96 other_root.virtual_path().Append(GetRelativeVirtualPath(root, url)));
97 }
98
99 } // namespace
100
101 class DraggedFileUtilTest : public testing::Test {
102 public:
103 DraggedFileUtilTest() {}
104
105 void SetUp() override {
106 ASSERT_TRUE(data_dir_.CreateUniqueTempDir());
107 ASSERT_TRUE(partition_dir_.CreateUniqueTempDir());
108 file_util_.reset(new storage::DraggedFileUtil());
109
110 // Register the files/directories of RegularTestCases (with random
111 // root paths) as dropped files.
112 SimulateDropFiles();
113
114 file_system_context_ = CreateFileSystemContextForTesting(
115 NULL /* quota_manager */, partition_dir_.GetPath());
116
117 isolated_context()->AddReference(filesystem_id_);
118 }
119
120 void TearDown() override {
121 isolated_context()->RemoveReference(filesystem_id_);
122 }
123
124 protected:
125 storage::IsolatedContext* isolated_context() const {
126 return storage::IsolatedContext::GetInstance();
127 }
128 const base::FilePath& root_path() const { return data_dir_.GetPath(); }
129 FileSystemContext* file_system_context() const {
130 return file_system_context_.get();
131 }
132 storage::FileSystemFileUtil* file_util() const { return file_util_.get(); }
133 std::string filesystem_id() const { return filesystem_id_; }
134
135 base::FilePath GetTestCasePlatformPath(
136 const base::FilePath::StringType& path) {
137 return toplevel_root_map_[GetTopLevelPath(base::FilePath(path))]
138 .Append(path).NormalizePathSeparators();
139 }
140
141 base::FilePath GetTestCaseLocalPath(const base::FilePath& path) {
142 base::FilePath relative;
143 if (data_dir_.GetPath().AppendRelativePath(path, &relative))
144 return relative;
145 return path;
146 }
147
148 FileSystemURL GetFileSystemURL(const base::FilePath& path) const {
149 base::FilePath virtual_path = isolated_context()->CreateVirtualRootPath(
150 filesystem_id()).Append(path);
151 return file_system_context_->CreateCrackedFileSystemURL(
152 GURL("http://example.com"),
153 storage::kFileSystemTypeIsolated,
154 virtual_path);
155 }
156
157 FileSystemURL GetOtherFileSystemURL(const base::FilePath& path) const {
158 return file_system_context()->CreateCrackedFileSystemURL(
159 GURL("http://example.com"),
160 storage::kFileSystemTypeTemporary,
161 base::FilePath().AppendASCII("dest").Append(path));
162 }
163
164 void VerifyFilesHaveSameContent(const FileSystemURL& url1,
165 const FileSystemURL& url2) {
166 // Get the file info and the platform path for url1.
167 base::File::Info info1;
168 ASSERT_EQ(base::File::FILE_OK,
169 AsyncFileTestHelper::GetMetadata(
170 file_system_context(), url1, &info1));
171 base::FilePath platform_path1;
172 ASSERT_EQ(base::File::FILE_OK,
173 AsyncFileTestHelper::GetPlatformPath(
174 file_system_context(), url1, &platform_path1));
175
176 // Get the file info and the platform path for url2.
177 base::File::Info info2;
178 ASSERT_EQ(base::File::FILE_OK,
179 AsyncFileTestHelper::GetMetadata(
180 file_system_context(), url2, &info2));
181 base::FilePath platform_path2;
182 ASSERT_EQ(base::File::FILE_OK,
183 AsyncFileTestHelper::GetPlatformPath(
184 file_system_context(), url2, &platform_path2));
185
186 // See if file info matches with the other one.
187 EXPECT_EQ(info1.is_directory, info2.is_directory);
188 EXPECT_EQ(info1.size, info2.size);
189 EXPECT_EQ(info1.is_symbolic_link, info2.is_symbolic_link);
190 EXPECT_NE(platform_path1, platform_path2);
191
192 std::string content1, content2;
193 EXPECT_TRUE(base::ReadFileToString(platform_path1, &content1));
194 EXPECT_TRUE(base::ReadFileToString(platform_path2, &content2));
195 EXPECT_EQ(content1, content2);
196 }
197
198 void VerifyDirectoriesHaveSameContent(const FileSystemURL& root1,
199 const FileSystemURL& root2) {
200 base::FilePath root_path1 = root1.path();
201 base::FilePath root_path2 = root2.path();
202
203 FileEntryList entries;
204 std::queue<FileSystemURL> directories;
205
206 directories.push(root1);
207 std::set<base::FilePath> file_set1;
208 while (!directories.empty()) {
209 FileSystemURL dir = directories.front();
210 directories.pop();
211
212 ASSERT_EQ(base::File::FILE_OK,
213 AsyncFileTestHelper::ReadDirectory(
214 file_system_context(), dir, &entries));
215 for (size_t i = 0; i < entries.size(); ++i) {
216 FileSystemURL url = GetEntryURL(file_system_context(),
217 dir, entries[i].name);
218 if (entries[i].is_directory) {
219 directories.push(url);
220 continue;
221 }
222 file_set1.insert(GetRelativeVirtualPath(root1, url));
223 }
224 }
225
226 directories.push(root2);
227 while (!directories.empty()) {
228 FileSystemURL dir = directories.front();
229 directories.pop();
230
231 ASSERT_EQ(base::File::FILE_OK,
232 AsyncFileTestHelper::ReadDirectory(
233 file_system_context(), dir, &entries));
234 for (size_t i = 0; i < entries.size(); ++i) {
235 FileSystemURL url2 = GetEntryURL(file_system_context(),
236 dir, entries[i].name);
237 FileSystemURL url1 = GetOtherURL(file_system_context(),
238 root2, root1, url2);
239 if (entries[i].is_directory) {
240 directories.push(url2);
241 EXPECT_EQ(IsDirectoryEmpty(file_system_context(), url1),
242 IsDirectoryEmpty(file_system_context(), url2));
243 continue;
244 }
245 base::FilePath relative = GetRelativeVirtualPath(root2, url2);
246 EXPECT_TRUE(file_set1.find(relative) != file_set1.end());
247 VerifyFilesHaveSameContent(url1, url2);
248 }
249 }
250 }
251
252 std::unique_ptr<storage::FileSystemOperationContext> GetOperationContext() {
253 return base::MakeUnique<storage::FileSystemOperationContext>(
254 file_system_context());
255 }
256
257
258 private:
259 void SimulateDropFiles() {
260 size_t root_path_index = 0;
261
262 storage::IsolatedContext::FileInfoSet toplevels;
263 for (size_t i = 0; i < kRegularFileSystemTestCaseSize; ++i) {
264 const FileSystemTestCaseRecord& test_case =
265 kRegularFileSystemTestCases[i];
266 base::FilePath path(test_case.path);
267 base::FilePath toplevel = GetTopLevelPath(path);
268
269 // We create the test case files under one of the kRootPaths
270 // to simulate a drop with multiple directories.
271 if (toplevel_root_map_.find(toplevel) == toplevel_root_map_.end()) {
272 base::FilePath root = root_path().Append(
273 kRootPaths[(root_path_index++) % arraysize(kRootPaths)]);
274 toplevel_root_map_[toplevel] = root;
275 toplevels.AddPath(root.Append(path), NULL);
276 }
277
278 SetUpOneFileSystemTestCase(toplevel_root_map_[toplevel], test_case);
279 }
280
281 // Register the toplevel entries.
282 filesystem_id_ = isolated_context()->RegisterDraggedFileSystem(toplevels);
283 }
284
285 base::ScopedTempDir data_dir_;
286 base::ScopedTempDir partition_dir_;
287 base::MessageLoopForIO message_loop_;
288 std::string filesystem_id_;
289 scoped_refptr<FileSystemContext> file_system_context_;
290 std::map<base::FilePath, base::FilePath> toplevel_root_map_;
291 std::unique_ptr<storage::DraggedFileUtil> file_util_;
292 DISALLOW_COPY_AND_ASSIGN(DraggedFileUtilTest);
293 };
294
295 TEST_F(DraggedFileUtilTest, BasicTest) {
296 for (size_t i = 0; i < kRegularFileSystemTestCaseSize; ++i) {
297 SCOPED_TRACE(testing::Message() << "Testing RegularTestCases " << i);
298 const FileSystemTestCaseRecord& test_case =
299 kRegularFileSystemTestCases[i];
300
301 FileSystemURL url = GetFileSystemURL(base::FilePath(test_case.path));
302
303 // See if we can query the file info via the isolated FileUtil.
304 // (This should succeed since we have registered all the top-level
305 // entries of the test cases in SetUp())
306 base::File::Info info;
307 base::FilePath platform_path;
308 FileSystemOperationContext context(file_system_context());
309 ASSERT_EQ(base::File::FILE_OK,
310 file_util()->GetFileInfo(&context, url, &info, &platform_path));
311
312 // See if the obtained file info is correct.
313 if (!test_case.is_directory)
314 ASSERT_EQ(test_case.data_file_size, info.size);
315 ASSERT_EQ(test_case.is_directory, info.is_directory);
316 ASSERT_EQ(GetTestCasePlatformPath(test_case.path),
317 platform_path.NormalizePathSeparators());
318 }
319 }
320
321 TEST_F(DraggedFileUtilTest, UnregisteredPathsTest) {
322 static const FileSystemTestCaseRecord kUnregisteredCases[] = {
323 {true, FILE_PATH_LITERAL("nonexistent"), 0},
324 {true, FILE_PATH_LITERAL("nonexistent/dir foo"), 0},
325 {false, FILE_PATH_LITERAL("nonexistent/false"), 0},
326 {false, FILE_PATH_LITERAL("foo"), 30},
327 {false, FILE_PATH_LITERAL("bar"), 20},
328 };
329
330 for (size_t i = 0; i < arraysize(kUnregisteredCases); ++i) {
331 SCOPED_TRACE(testing::Message() << "Creating kUnregisteredCases " << i);
332 const FileSystemTestCaseRecord& test_case = kUnregisteredCases[i];
333
334 // Prepare the test file/directory.
335 SetUpOneFileSystemTestCase(root_path(), test_case);
336
337 // Make sure regular GetFileInfo succeeds.
338 base::File::Info info;
339 ASSERT_TRUE(base::GetFileInfo(root_path().Append(test_case.path), &info));
340 if (!test_case.is_directory)
341 ASSERT_EQ(test_case.data_file_size, info.size);
342 ASSERT_EQ(test_case.is_directory, info.is_directory);
343 }
344
345 for (size_t i = 0; i < arraysize(kUnregisteredCases); ++i) {
346 SCOPED_TRACE(testing::Message() << "Creating kUnregisteredCases " << i);
347 const FileSystemTestCaseRecord& test_case = kUnregisteredCases[i];
348 FileSystemURL url = GetFileSystemURL(base::FilePath(test_case.path));
349
350 // We should not be able to get the valid URL for unregistered files.
351 ASSERT_FALSE(url.is_valid());
352 }
353 }
354
355 TEST_F(DraggedFileUtilTest, ReadDirectoryTest) {
356 for (size_t i = 0; i < kRegularFileSystemTestCaseSize; ++i) {
357 const FileSystemTestCaseRecord& test_case =
358 kRegularFileSystemTestCases[i];
359 if (!test_case.is_directory)
360 continue;
361
362 SCOPED_TRACE(testing::Message() << "Testing RegularTestCases " << i
363 << ": " << test_case.path);
364
365 // Read entries in the directory to construct the expected results map.
366 typedef std::map<base::FilePath::StringType, storage::DirectoryEntry>
367 EntryMap;
368 EntryMap expected_entry_map;
369
370 base::FilePath dir_path = GetTestCasePlatformPath(test_case.path);
371 base::FileEnumerator file_enum(
372 dir_path, false /* not recursive */,
373 base::FileEnumerator::FILES | base::FileEnumerator::DIRECTORIES);
374 base::FilePath current;
375 while (!(current = file_enum.Next()).empty()) {
376 base::FileEnumerator::FileInfo file_info = file_enum.GetInfo();
377 storage::DirectoryEntry entry;
378 entry.is_directory = file_info.IsDirectory();
379 entry.name = current.BaseName().value();
380 expected_entry_map[entry.name] = entry;
381
382 #if defined(OS_POSIX)
383 // Creates a symlink for each file/directory.
384 // They should be ignored by ReadDirectory, so we don't add them
385 // to expected_entry_map.
386 base::CreateSymbolicLink(
387 current,
388 dir_path.Append(current.BaseName().AddExtension(
389 FILE_PATH_LITERAL("link"))));
390 #endif
391 }
392
393 // Perform ReadDirectory in the isolated filesystem.
394 FileSystemURL url = GetFileSystemURL(base::FilePath(test_case.path));
395 FileEntryList entries;
396 ASSERT_EQ(base::File::FILE_OK,
397 AsyncFileTestHelper::ReadDirectory(
398 file_system_context(), url, &entries));
399
400 EXPECT_EQ(expected_entry_map.size(), entries.size());
401 for (size_t i = 0; i < entries.size(); ++i) {
402 const storage::DirectoryEntry& entry = entries[i];
403 EntryMap::iterator found = expected_entry_map.find(entry.name);
404 EXPECT_TRUE(found != expected_entry_map.end());
405 EXPECT_EQ(found->second.name, entry.name);
406 EXPECT_EQ(found->second.is_directory, entry.is_directory);
407 }
408 }
409 }
410
411 TEST_F(DraggedFileUtilTest, GetLocalFilePathTest) {
412 for (size_t i = 0; i < kRegularFileSystemTestCaseSize; ++i) {
413 const FileSystemTestCaseRecord& test_case =
414 kRegularFileSystemTestCases[i];
415 FileSystemURL url = GetFileSystemURL(base::FilePath(test_case.path));
416
417 FileSystemOperationContext context(file_system_context());
418
419 base::FilePath local_file_path;
420 EXPECT_EQ(base::File::FILE_OK,
421 file_util()->GetLocalFilePath(&context, url, &local_file_path));
422 EXPECT_EQ(GetTestCasePlatformPath(test_case.path).value(),
423 local_file_path.value());
424 }
425 }
426
427 TEST_F(DraggedFileUtilTest, CopyOutFileTest) {
428 FileSystemURL src_root = GetFileSystemURL(base::FilePath());
429 FileSystemURL dest_root = GetOtherFileSystemURL(base::FilePath());
430
431 FileEntryList entries;
432 std::queue<FileSystemURL> directories;
433 directories.push(src_root);
434
435 ASSERT_EQ(base::File::FILE_OK,
436 AsyncFileTestHelper::CreateDirectory(file_system_context(),
437 dest_root));
438
439 while (!directories.empty()) {
440 FileSystemURL dir = directories.front();
441 directories.pop();
442 ASSERT_EQ(base::File::FILE_OK,
443 AsyncFileTestHelper::ReadDirectory(file_system_context(),
444 dir, &entries));
445 for (size_t i = 0; i < entries.size(); ++i) {
446 FileSystemURL src_url = GetEntryURL(file_system_context(),
447 dir, entries[i].name);
448 FileSystemURL dest_url = GetOtherURL(file_system_context(),
449 src_root, dest_root, src_url);
450
451 if (entries[i].is_directory) {
452 ASSERT_EQ(base::File::FILE_OK,
453 AsyncFileTestHelper::CreateDirectory(file_system_context(),
454 dest_url));
455 directories.push(src_url);
456 continue;
457 }
458 SCOPED_TRACE(testing::Message() << "Testing file copy "
459 << src_url.path().value());
460 ASSERT_EQ(base::File::FILE_OK,
461 AsyncFileTestHelper::Copy(file_system_context(),
462 src_url, dest_url));
463 VerifyFilesHaveSameContent(src_url, dest_url);
464 }
465 }
466 }
467
468 TEST_F(DraggedFileUtilTest, CopyOutDirectoryTest) {
469 FileSystemURL src_root = GetFileSystemURL(base::FilePath());
470 FileSystemURL dest_root = GetOtherFileSystemURL(base::FilePath());
471
472 ASSERT_EQ(base::File::FILE_OK,
473 AsyncFileTestHelper::CreateDirectory(file_system_context(),
474 dest_root));
475
476 FileEntryList entries;
477 ASSERT_EQ(base::File::FILE_OK,
478 AsyncFileTestHelper::ReadDirectory(file_system_context(),
479 src_root, &entries));
480 for (size_t i = 0; i < entries.size(); ++i) {
481 if (!entries[i].is_directory)
482 continue;
483 FileSystemURL src_url = GetEntryURL(file_system_context(),
484 src_root, entries[i].name);
485 FileSystemURL dest_url = GetOtherURL(file_system_context(),
486 src_root, dest_root, src_url);
487 SCOPED_TRACE(testing::Message() << "Testing file copy "
488 << src_url.path().value());
489 ASSERT_EQ(base::File::FILE_OK,
490 AsyncFileTestHelper::Copy(file_system_context(),
491 src_url, dest_url));
492 VerifyDirectoriesHaveSameContent(src_url, dest_url);
493 }
494 }
495
496 TEST_F(DraggedFileUtilTest, TouchTest) {
497 for (size_t i = 0; i < kRegularFileSystemTestCaseSize; ++i) {
498 const FileSystemTestCaseRecord& test_case =
499 kRegularFileSystemTestCases[i];
500 if (test_case.is_directory)
501 continue;
502 SCOPED_TRACE(testing::Message() << test_case.path);
503 FileSystemURL url = GetFileSystemURL(base::FilePath(test_case.path));
504
505 base::Time last_access_time = base::Time::FromTimeT(1000);
506 base::Time last_modified_time = base::Time::FromTimeT(2000);
507
508 EXPECT_EQ(base::File::FILE_OK,
509 file_util()->Touch(GetOperationContext().get(), url,
510 last_access_time,
511 last_modified_time));
512
513 // Verification.
514 base::File::Info info;
515 base::FilePath platform_path;
516 ASSERT_EQ(base::File::FILE_OK,
517 file_util()->GetFileInfo(GetOperationContext().get(), url,
518 &info, &platform_path));
519 EXPECT_EQ(last_access_time.ToTimeT(), info.last_accessed.ToTimeT());
520 EXPECT_EQ(last_modified_time.ToTimeT(), info.last_modified.ToTimeT());
521 }
522 }
523
524 TEST_F(DraggedFileUtilTest, TruncateTest) {
525 for (size_t i = 0; i < kRegularFileSystemTestCaseSize; ++i) {
526 const FileSystemTestCaseRecord& test_case =
527 kRegularFileSystemTestCases[i];
528 if (test_case.is_directory)
529 continue;
530
531 SCOPED_TRACE(testing::Message() << test_case.path);
532 FileSystemURL url = GetFileSystemURL(base::FilePath(test_case.path));
533
534 // Truncate to 0.
535 base::File::Info info;
536 base::FilePath platform_path;
537 EXPECT_EQ(base::File::FILE_OK,
538 file_util()->Truncate(GetOperationContext().get(), url, 0));
539 ASSERT_EQ(base::File::FILE_OK,
540 file_util()->GetFileInfo(GetOperationContext().get(), url,
541 &info, &platform_path));
542 EXPECT_EQ(0, info.size);
543
544 // Truncate (extend) to 999.
545 EXPECT_EQ(base::File::FILE_OK,
546 file_util()->Truncate(GetOperationContext().get(), url, 999));
547 ASSERT_EQ(base::File::FILE_OK,
548 file_util()->GetFileInfo(GetOperationContext().get(), url,
549 &info, &platform_path));
550 EXPECT_EQ(999, info.size);
551 }
552 }
553
554 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698