cygprofile: increase timeouts to allow showing web contents
[chromium-blink-merge.git] / components / drive / resource_metadata_unittest.cc
blob15beb4d5284802d24fe5154f18f6c6b18d77d9e3
1 // 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.
5 #include "components/drive/resource_metadata.h"
7 #include <algorithm>
8 #include <string>
9 #include <vector>
11 #include "base/files/scoped_temp_dir.h"
12 #include "base/single_thread_task_runner.h"
13 #include "base/strings/stringprintf.h"
14 #include "base/thread_task_runner_handle.h"
15 #include "components/drive/drive.pb.h"
16 #include "components/drive/drive_test_util.h"
17 #include "components/drive/fake_free_disk_space_getter.h"
18 #include "components/drive/file_cache.h"
19 #include "components/drive/file_system_core_util.h"
20 #include "content/public/test/test_browser_thread_bundle.h"
21 #include "testing/gtest/include/gtest/gtest.h"
23 namespace drive {
24 namespace internal {
25 namespace {
27 // The changestamp of the resource metadata used in
28 // ResourceMetadataTest.
29 const int64 kTestChangestamp = 100;
31 // Returns the sorted base names from |entries|.
32 std::vector<std::string> GetSortedBaseNames(
33 const ResourceEntryVector& entries) {
34 std::vector<std::string> base_names;
35 for (size_t i = 0; i < entries.size(); ++i)
36 base_names.push_back(entries[i].base_name());
37 std::sort(base_names.begin(), base_names.end());
39 return base_names;
42 // Creates a ResourceEntry for a directory with explicitly set resource_id.
43 ResourceEntry CreateDirectoryEntryWithResourceId(
44 const std::string& title,
45 const std::string& resource_id,
46 const std::string& parent_local_id) {
47 ResourceEntry entry;
48 entry.set_title(title);
49 entry.set_resource_id(resource_id);
50 entry.set_parent_local_id(parent_local_id);
51 entry.mutable_file_info()->set_is_directory(true);
52 entry.mutable_directory_specific_info()->set_changestamp(kTestChangestamp);
53 return entry;
56 // Creates a ResourceEntry for a directory.
57 ResourceEntry CreateDirectoryEntry(const std::string& title,
58 const std::string& parent_local_id) {
59 return CreateDirectoryEntryWithResourceId(
60 title, "id:" + title, parent_local_id);
63 // Creates a ResourceEntry for a file with explicitly set resource_id.
64 ResourceEntry CreateFileEntryWithResourceId(
65 const std::string& title,
66 const std::string& resource_id,
67 const std::string& parent_local_id) {
68 ResourceEntry entry;
69 entry.set_title(title);
70 entry.set_resource_id(resource_id);
71 entry.set_parent_local_id(parent_local_id);
72 entry.mutable_file_info()->set_is_directory(false);
73 entry.mutable_file_info()->set_size(1024);
74 entry.mutable_file_specific_info()->set_md5("md5:" + title);
75 return entry;
78 // Creates a ResourceEntry for a file.
79 ResourceEntry CreateFileEntry(const std::string& title,
80 const std::string& parent_local_id) {
81 return CreateFileEntryWithResourceId(title, "id:" + title, parent_local_id);
84 // Creates the following files/directories
85 // drive/root/dir1/
86 // drive/root/dir2/
87 // drive/root/dir1/dir3/
88 // drive/root/dir1/file4
89 // drive/root/dir1/file5
90 // drive/root/dir2/file6
91 // drive/root/dir2/file7
92 // drive/root/dir2/file8
93 // drive/root/dir1/dir3/file9
94 // drive/root/dir1/dir3/file10
95 void SetUpEntries(ResourceMetadata* resource_metadata) {
96 std::string local_id;
97 ASSERT_EQ(FILE_ERROR_OK, resource_metadata->GetIdByPath(
98 util::GetDriveMyDriveRootPath(), &local_id));
99 const std::string root_local_id = local_id;
101 ASSERT_EQ(FILE_ERROR_OK, resource_metadata->AddEntry(
102 CreateDirectoryEntry("dir1", root_local_id), &local_id));
103 const std::string local_id_dir1 = local_id;
105 ASSERT_EQ(FILE_ERROR_OK, resource_metadata->AddEntry(
106 CreateDirectoryEntry("dir2", root_local_id), &local_id));
107 const std::string local_id_dir2 = local_id;
109 ASSERT_EQ(FILE_ERROR_OK, resource_metadata->AddEntry(
110 CreateDirectoryEntry("dir3", local_id_dir1), &local_id));
111 const std::string local_id_dir3 = local_id;
113 ASSERT_EQ(FILE_ERROR_OK, resource_metadata->AddEntry(
114 CreateFileEntry("file4", local_id_dir1), &local_id));
115 ASSERT_EQ(FILE_ERROR_OK, resource_metadata->AddEntry(
116 CreateFileEntry("file5", local_id_dir1), &local_id));
118 ASSERT_EQ(FILE_ERROR_OK, resource_metadata->AddEntry(
119 CreateFileEntry("file6", local_id_dir2), &local_id));
120 ASSERT_EQ(FILE_ERROR_OK, resource_metadata->AddEntry(
121 CreateFileEntry("file7", local_id_dir2), &local_id));
122 ASSERT_EQ(FILE_ERROR_OK, resource_metadata->AddEntry(
123 CreateFileEntry("file8", local_id_dir2), &local_id));
125 ASSERT_EQ(FILE_ERROR_OK, resource_metadata->AddEntry(
126 CreateFileEntry("file9", local_id_dir3), &local_id));
127 ASSERT_EQ(FILE_ERROR_OK, resource_metadata->AddEntry(
128 CreateFileEntry("file10", local_id_dir3), &local_id));
130 ASSERT_EQ(FILE_ERROR_OK,
131 resource_metadata->SetLargestChangestamp(kTestChangestamp));
134 } // namespace
136 // Tests for methods running on the blocking task runner.
137 class ResourceMetadataTest : public testing::Test {
138 protected:
139 void SetUp() override {
140 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
142 metadata_storage_.reset(new ResourceMetadataStorage(
143 temp_dir_.path(), base::ThreadTaskRunnerHandle::Get().get()));
144 ASSERT_TRUE(metadata_storage_->Initialize());
146 fake_free_disk_space_getter_.reset(new FakeFreeDiskSpaceGetter);
147 cache_.reset(new FileCache(metadata_storage_.get(),
148 temp_dir_.path(),
149 base::ThreadTaskRunnerHandle::Get().get(),
150 fake_free_disk_space_getter_.get()));
151 ASSERT_TRUE(cache_->Initialize());
153 resource_metadata_.reset(new ResourceMetadata(
154 metadata_storage_.get(), cache_.get(),
155 base::ThreadTaskRunnerHandle::Get()));
157 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->Initialize());
159 SetUpEntries(resource_metadata_.get());
162 base::ScopedTempDir temp_dir_;
163 content::TestBrowserThreadBundle thread_bundle_;
164 scoped_ptr<ResourceMetadataStorage, test_util::DestroyHelperForTests>
165 metadata_storage_;
166 scoped_ptr<FakeFreeDiskSpaceGetter> fake_free_disk_space_getter_;
167 scoped_ptr<FileCache, test_util::DestroyHelperForTests> cache_;
168 scoped_ptr<ResourceMetadata, test_util::DestroyHelperForTests>
169 resource_metadata_;
172 TEST_F(ResourceMetadataTest, LargestChangestamp) {
173 const int64 kChangestamp = 123456;
174 EXPECT_EQ(FILE_ERROR_OK,
175 resource_metadata_->SetLargestChangestamp(kChangestamp));
176 int64 changestamp = 0;
177 EXPECT_EQ(FILE_ERROR_OK,
178 resource_metadata_->GetLargestChangestamp(&changestamp));
179 EXPECT_EQ(kChangestamp, changestamp);
182 TEST_F(ResourceMetadataTest, GetResourceEntryByPath) {
183 // Confirm that an existing file is found.
184 ResourceEntry entry;
185 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryByPath(
186 base::FilePath::FromUTF8Unsafe("drive/root/dir1/file4"), &entry));
187 EXPECT_EQ("file4", entry.base_name());
189 // Confirm that a non existing file is not found.
190 EXPECT_EQ(FILE_ERROR_NOT_FOUND, resource_metadata_->GetResourceEntryByPath(
191 base::FilePath::FromUTF8Unsafe("drive/root/dir1/non_existing"), &entry));
193 // Confirm that the root is found.
194 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryByPath(
195 base::FilePath::FromUTF8Unsafe("drive"), &entry));
197 // Confirm that a non existing file is not found at the root level.
198 EXPECT_EQ(FILE_ERROR_NOT_FOUND, resource_metadata_->GetResourceEntryByPath(
199 base::FilePath::FromUTF8Unsafe("non_existing"), &entry));
201 // Confirm that an entry is not found with a wrong root.
202 EXPECT_EQ(FILE_ERROR_NOT_FOUND, resource_metadata_->GetResourceEntryByPath(
203 base::FilePath::FromUTF8Unsafe("non_existing/root"), &entry));
206 TEST_F(ResourceMetadataTest, ReadDirectoryByPath) {
207 // Confirm that an existing directory is found.
208 ResourceEntryVector entries;
209 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->ReadDirectoryByPath(
210 base::FilePath::FromUTF8Unsafe("drive/root/dir1"), &entries));
211 ASSERT_EQ(3U, entries.size());
212 // The order is not guaranteed so we should sort the base names.
213 std::vector<std::string> base_names = GetSortedBaseNames(entries);
214 EXPECT_EQ("dir3", base_names[0]);
215 EXPECT_EQ("file4", base_names[1]);
216 EXPECT_EQ("file5", base_names[2]);
218 // Confirm that a non existing directory is not found.
219 EXPECT_EQ(FILE_ERROR_NOT_FOUND, resource_metadata_->ReadDirectoryByPath(
220 base::FilePath::FromUTF8Unsafe("drive/root/non_existing"), &entries));
222 // Confirm that reading a file results in FILE_ERROR_NOT_A_DIRECTORY.
223 EXPECT_EQ(FILE_ERROR_NOT_A_DIRECTORY, resource_metadata_->ReadDirectoryByPath(
224 base::FilePath::FromUTF8Unsafe("drive/root/dir1/file4"), &entries));
227 TEST_F(ResourceMetadataTest, RefreshEntry) {
228 base::FilePath drive_file_path;
229 ResourceEntry entry;
231 // Get file9.
232 std::string file_id;
233 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath(
234 base::FilePath::FromUTF8Unsafe("drive/root/dir1/dir3/file9"), &file_id));
235 EXPECT_EQ(FILE_ERROR_OK,
236 resource_metadata_->GetResourceEntryById(file_id, &entry));
237 EXPECT_EQ("file9", entry.base_name());
238 EXPECT_TRUE(!entry.file_info().is_directory());
239 EXPECT_EQ("md5:file9", entry.file_specific_info().md5());
241 // Rename it.
242 ResourceEntry file_entry(entry);
243 file_entry.set_title("file100");
244 EXPECT_EQ(FILE_ERROR_OK,
245 resource_metadata_->RefreshEntry(file_entry));
247 base::FilePath path;
248 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetFilePath(file_id, &path));
249 EXPECT_EQ("drive/root/dir1/dir3/file100", path.AsUTF8Unsafe());
250 entry.Clear();
251 EXPECT_EQ(FILE_ERROR_OK,
252 resource_metadata_->GetResourceEntryById(file_id, &entry));
253 EXPECT_EQ("file100", entry.base_name());
254 EXPECT_TRUE(!entry.file_info().is_directory());
255 EXPECT_EQ("md5:file9", entry.file_specific_info().md5());
257 // Update the file md5.
258 const std::string updated_md5("md5:updated");
259 file_entry = entry;
260 file_entry.mutable_file_specific_info()->set_md5(updated_md5);
261 EXPECT_EQ(FILE_ERROR_OK,
262 resource_metadata_->RefreshEntry(file_entry));
264 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetFilePath(file_id, &path));
265 EXPECT_EQ("drive/root/dir1/dir3/file100", path.AsUTF8Unsafe());
266 entry.Clear();
267 EXPECT_EQ(FILE_ERROR_OK,
268 resource_metadata_->GetResourceEntryById(file_id, &entry));
269 EXPECT_EQ("file100", entry.base_name());
270 EXPECT_TRUE(!entry.file_info().is_directory());
271 EXPECT_EQ(updated_md5, entry.file_specific_info().md5());
273 // Make sure we get the same thing from GetResourceEntryByPath.
274 entry.Clear();
275 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryByPath(
276 base::FilePath::FromUTF8Unsafe("drive/root/dir1/dir3/file100"), &entry));
277 EXPECT_EQ("file100", entry.base_name());
278 ASSERT_TRUE(!entry.file_info().is_directory());
279 EXPECT_EQ(updated_md5, entry.file_specific_info().md5());
281 // Get dir2.
282 entry.Clear();
283 std::string dir_id;
284 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath(
285 base::FilePath::FromUTF8Unsafe("drive/root/dir2"), &dir_id));
286 EXPECT_EQ(FILE_ERROR_OK,
287 resource_metadata_->GetResourceEntryById(dir_id, &entry));
288 EXPECT_EQ("dir2", entry.base_name());
289 ASSERT_TRUE(entry.file_info().is_directory());
291 // Get dir3's ID.
292 std::string dir3_id;
293 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath(
294 base::FilePath::FromUTF8Unsafe("drive/root/dir1/dir3"), &dir3_id));
296 // Change the name to dir100 and change the parent to drive/dir1/dir3.
297 ResourceEntry dir_entry(entry);
298 dir_entry.set_title("dir100");
299 dir_entry.set_parent_local_id(dir3_id);
300 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->RefreshEntry(dir_entry));
302 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetFilePath(dir_id, &path));
303 EXPECT_EQ("drive/root/dir1/dir3/dir100", path.AsUTF8Unsafe());
304 entry.Clear();
305 EXPECT_EQ(FILE_ERROR_OK,
306 resource_metadata_->GetResourceEntryById(dir_id, &entry));
307 EXPECT_EQ("dir100", entry.base_name());
308 EXPECT_TRUE(entry.file_info().is_directory());
309 EXPECT_EQ("id:dir2", entry.resource_id());
311 // Make sure the children have moved over. Test file6.
312 entry.Clear();
313 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryByPath(
314 base::FilePath::FromUTF8Unsafe("drive/root/dir1/dir3/dir100/file6"),
315 &entry));
316 EXPECT_EQ("file6", entry.base_name());
318 // Make sure dir2 no longer exists.
319 EXPECT_EQ(FILE_ERROR_NOT_FOUND, resource_metadata_->GetResourceEntryByPath(
320 base::FilePath::FromUTF8Unsafe("drive/root/dir2"), &entry));
322 // Make sure that directory cannot move under a file.
323 dir_entry.set_parent_local_id(file_id);
324 EXPECT_EQ(FILE_ERROR_NOT_A_DIRECTORY,
325 resource_metadata_->RefreshEntry(dir_entry));
327 // Cannot refresh root.
328 dir_entry.Clear();
329 dir_entry.set_local_id(util::kDriveGrandRootLocalId);
330 dir_entry.set_title("new-root-name");
331 dir_entry.set_parent_local_id(dir3_id);
332 EXPECT_EQ(FILE_ERROR_INVALID_OPERATION,
333 resource_metadata_->RefreshEntry(dir_entry));
336 TEST_F(ResourceMetadataTest, RefreshEntry_ResourceIDCheck) {
337 // Get an entry with a non-empty resource ID.
338 ResourceEntry entry;
339 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryByPath(
340 base::FilePath::FromUTF8Unsafe("drive/root/dir1"), &entry));
341 EXPECT_FALSE(entry.resource_id().empty());
343 // Add a new entry with an empty resource ID.
344 ResourceEntry new_entry;
345 new_entry.set_parent_local_id(entry.local_id());
346 new_entry.set_title("new entry");
347 std::string local_id;
348 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(new_entry, &local_id));
350 // Try to refresh the new entry with a used resource ID.
351 new_entry.set_local_id(local_id);
352 new_entry.set_resource_id(entry.resource_id());
353 EXPECT_EQ(FILE_ERROR_INVALID_OPERATION,
354 resource_metadata_->RefreshEntry(new_entry));
357 TEST_F(ResourceMetadataTest, RefreshEntry_DoNotOverwriteCacheState) {
358 ResourceEntry entry;
359 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryByPath(
360 base::FilePath::FromUTF8Unsafe("drive/root/dir1/file4"), &entry));
362 // Try to set MD5 with RefreshEntry.
363 entry.mutable_file_specific_info()->mutable_cache_state()->set_md5("md5");
364 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->RefreshEntry(entry));
366 // Cache state is unchanged.
367 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryByPath(
368 base::FilePath::FromUTF8Unsafe("drive/root/dir1/file4"), &entry));
369 EXPECT_TRUE(entry.file_specific_info().cache_state().md5().empty());
371 // Pin the file.
372 EXPECT_EQ(FILE_ERROR_OK, cache_->Pin(entry.local_id()));
374 // Try to clear the cache state with RefreshEntry.
375 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryByPath(
376 base::FilePath::FromUTF8Unsafe("drive/root/dir1/file4"), &entry));
377 entry.mutable_file_specific_info()->clear_cache_state();
378 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->RefreshEntry(entry));
380 // Cache state is not cleared.
381 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryByPath(
382 base::FilePath::FromUTF8Unsafe("drive/root/dir1/file4"), &entry));
383 EXPECT_TRUE(entry.file_specific_info().cache_state().is_pinned());
386 TEST_F(ResourceMetadataTest, GetSubDirectoriesRecursively) {
387 std::set<base::FilePath> sub_directories;
389 // file9: not a directory, so no children.
390 std::string local_id;
391 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath(
392 base::FilePath::FromUTF8Unsafe("drive/root/dir1/dir3/file9"), &local_id));
393 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetSubDirectoriesRecursively(
394 local_id, &sub_directories));
395 EXPECT_TRUE(sub_directories.empty());
397 // dir2: no child directories.
398 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath(
399 base::FilePath::FromUTF8Unsafe("drive/root/dir2"), &local_id));
400 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetSubDirectoriesRecursively(
401 local_id, &sub_directories));
402 EXPECT_TRUE(sub_directories.empty());
403 const std::string dir2_id = local_id;
405 // dir1: dir3 is the only child
406 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath(
407 base::FilePath::FromUTF8Unsafe("drive/root/dir1"), &local_id));
408 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetSubDirectoriesRecursively(
409 local_id, &sub_directories));
410 EXPECT_EQ(1u, sub_directories.size());
411 EXPECT_EQ(1u, sub_directories.count(
412 base::FilePath::FromUTF8Unsafe("drive/root/dir1/dir3")));
413 sub_directories.clear();
415 // Add a few more directories to make sure deeper nesting works.
416 // dir2/dir100
417 // dir2/dir101
418 // dir2/dir101/dir102
419 // dir2/dir101/dir103
420 // dir2/dir101/dir104
421 // dir2/dir101/dir104/dir105
422 // dir2/dir101/dir104/dir105/dir106
423 // dir2/dir101/dir104/dir105/dir106/dir107
424 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
425 CreateDirectoryEntry("dir100", dir2_id), &local_id));
426 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
427 CreateDirectoryEntry("dir101", dir2_id), &local_id));
428 const std::string dir101_id = local_id;
429 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
430 CreateDirectoryEntry("dir102", dir101_id), &local_id));
431 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
432 CreateDirectoryEntry("dir103", dir101_id), &local_id));
433 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
434 CreateDirectoryEntry("dir104", dir101_id), &local_id));
435 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
436 CreateDirectoryEntry("dir105", local_id), &local_id));
437 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
438 CreateDirectoryEntry("dir106", local_id), &local_id));
439 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
440 CreateDirectoryEntry("dir107", local_id), &local_id));
442 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetSubDirectoriesRecursively(
443 dir2_id, &sub_directories));
444 EXPECT_EQ(8u, sub_directories.size());
445 EXPECT_EQ(1u, sub_directories.count(base::FilePath::FromUTF8Unsafe(
446 "drive/root/dir2/dir101")));
447 EXPECT_EQ(1u, sub_directories.count(base::FilePath::FromUTF8Unsafe(
448 "drive/root/dir2/dir101/dir104")));
449 EXPECT_EQ(1u, sub_directories.count(base::FilePath::FromUTF8Unsafe(
450 "drive/root/dir2/dir101/dir104/dir105/dir106/dir107")));
453 TEST_F(ResourceMetadataTest, AddEntry) {
454 // Add a file to dir3.
455 std::string local_id;
456 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath(
457 base::FilePath::FromUTF8Unsafe("drive/root/dir1/dir3"), &local_id));
458 ResourceEntry file_entry = CreateFileEntry("file100", local_id);
459 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(file_entry, &local_id));
460 base::FilePath path;
461 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetFilePath(local_id, &path));
462 EXPECT_EQ("drive/root/dir1/dir3/file100", path.AsUTF8Unsafe());
464 // Add a directory.
465 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath(
466 base::FilePath::FromUTF8Unsafe("drive/root/dir1"), &local_id));
467 ResourceEntry dir_entry = CreateDirectoryEntry("dir101", local_id);
468 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(dir_entry, &local_id));
469 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetFilePath(local_id, &path));
470 EXPECT_EQ("drive/root/dir1/dir101", path.AsUTF8Unsafe());
472 // Add to an invalid parent.
473 ResourceEntry file_entry3 = CreateFileEntry("file103", "id:invalid");
474 EXPECT_EQ(FILE_ERROR_NOT_FOUND,
475 resource_metadata_->AddEntry(file_entry3, &local_id));
477 // Add an existing file.
478 EXPECT_EQ(FILE_ERROR_EXISTS,
479 resource_metadata_->AddEntry(file_entry, &local_id));
482 TEST_F(ResourceMetadataTest, RemoveEntry) {
483 // Make sure file9 is found.
484 std::string file9_local_id;
485 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath(
486 base::FilePath::FromUTF8Unsafe("drive/root/dir1/dir3/file9"),
487 &file9_local_id));
488 ResourceEntry entry;
489 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryById(
490 file9_local_id, &entry));
491 EXPECT_EQ("file9", entry.base_name());
493 // Remove file9.
494 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->RemoveEntry(file9_local_id));
496 // file9 should no longer exist.
497 EXPECT_EQ(FILE_ERROR_NOT_FOUND, resource_metadata_->GetResourceEntryById(
498 file9_local_id, &entry));
500 // Look for dir3.
501 std::string dir3_local_id;
502 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath(
503 base::FilePath::FromUTF8Unsafe("drive/root/dir1/dir3"), &dir3_local_id));
504 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryById(
505 dir3_local_id, &entry));
506 EXPECT_EQ("dir3", entry.base_name());
508 // Remove dir3.
509 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->RemoveEntry(dir3_local_id));
511 // dir3 should no longer exist.
512 EXPECT_EQ(FILE_ERROR_NOT_FOUND, resource_metadata_->GetResourceEntryById(
513 dir3_local_id, &entry));
515 // Remove unknown local_id using RemoveEntry.
516 EXPECT_EQ(FILE_ERROR_NOT_FOUND, resource_metadata_->RemoveEntry("foo"));
518 // Try removing root. This should fail.
519 EXPECT_EQ(FILE_ERROR_ACCESS_DENIED, resource_metadata_->RemoveEntry(
520 util::kDriveGrandRootLocalId));
523 TEST_F(ResourceMetadataTest, GetResourceEntryById_RootDirectory) {
524 // Look up the root directory by its ID.
525 ResourceEntry entry;
526 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryById(
527 util::kDriveGrandRootLocalId, &entry));
528 EXPECT_EQ("drive", entry.base_name());
531 TEST_F(ResourceMetadataTest, GetResourceEntryById) {
532 // Get file4 by path.
533 std::string local_id;
534 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath(
535 base::FilePath::FromUTF8Unsafe("drive/root/dir1/file4"), &local_id));
537 // Confirm that an existing file is found.
538 ResourceEntry entry;
539 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryById(
540 local_id, &entry));
541 EXPECT_EQ("file4", entry.base_name());
543 // Confirm that a non existing file is not found.
544 EXPECT_EQ(FILE_ERROR_NOT_FOUND, resource_metadata_->GetResourceEntryById(
545 "non_existing", &entry));
548 TEST_F(ResourceMetadataTest, Iterate) {
549 scoped_ptr<ResourceMetadata::Iterator> it = resource_metadata_->GetIterator();
550 ASSERT_TRUE(it);
552 int file_count = 0, directory_count = 0;
553 for (; !it->IsAtEnd(); it->Advance()) {
554 if (!it->GetValue().file_info().is_directory())
555 ++file_count;
556 else
557 ++directory_count;
560 EXPECT_EQ(7, file_count);
561 EXPECT_EQ(7, directory_count);
564 TEST_F(ResourceMetadataTest, DuplicatedNames) {
565 std::string root_local_id;
566 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath(
567 base::FilePath::FromUTF8Unsafe("drive/root"), &root_local_id));
569 ResourceEntry entry;
571 // When multiple entries with the same title are added in a single directory,
572 // their base_names are de-duped.
573 // - drive/root/foo
574 // - drive/root/foo (1)
575 std::string dir_id_0;
576 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
577 CreateDirectoryEntryWithResourceId(
578 "foo", "foo0", root_local_id), &dir_id_0));
579 std::string dir_id_1;
580 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
581 CreateDirectoryEntryWithResourceId(
582 "foo", "foo1", root_local_id), &dir_id_1));
584 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryById(
585 dir_id_0, &entry));
586 EXPECT_EQ("foo", entry.base_name());
587 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryById(
588 dir_id_1, &entry));
589 EXPECT_EQ("foo (1)", entry.base_name());
591 // - drive/root/foo/bar.txt
592 // - drive/root/foo/bar (1).txt
593 // - drive/root/foo/bar (2).txt
594 // ...
595 // - drive/root/foo/bar (99).txt
596 std::vector<std::string> file_ids(100);
597 for (size_t i = 0; i < file_ids.size(); ++i) {
598 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
599 CreateFileEntryWithResourceId(
600 "bar.txt", base::StringPrintf("bar%d", static_cast<int>(i)),
601 dir_id_0), &file_ids[i]));
604 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryById(
605 file_ids[0], &entry));
606 EXPECT_EQ("bar.txt", entry.base_name());
607 for (size_t i = 1; i < file_ids.size(); ++i) {
608 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryById(
609 file_ids[i], &entry)) << i;
610 EXPECT_EQ(base::StringPrintf("bar (%d).txt", static_cast<int>(i)),
611 entry.base_name());
614 // Same name but different parent. No renaming.
615 // - drive/root/foo (1)/bar.txt
616 std::string file_id_3;
617 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
618 CreateFileEntryWithResourceId(
619 "bar.txt", "bar_different_parent", dir_id_1), &file_id_3));
621 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryById(
622 file_id_3, &entry));
623 EXPECT_EQ("bar.txt", entry.base_name());
625 // Checks that the entries can be looked up by the de-duped paths.
626 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryByPath(
627 base::FilePath::FromUTF8Unsafe("drive/root/foo/bar (2).txt"), &entry));
628 EXPECT_EQ("bar2", entry.resource_id());
629 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryByPath(
630 base::FilePath::FromUTF8Unsafe("drive/root/foo (1)/bar.txt"), &entry));
631 EXPECT_EQ("bar_different_parent", entry.resource_id());
634 TEST_F(ResourceMetadataTest, EncodedNames) {
635 std::string root_local_id;
636 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath(
637 base::FilePath::FromUTF8Unsafe("drive/root"), &root_local_id));
639 ResourceEntry entry;
641 std::string dir_id;
642 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
643 CreateDirectoryEntry("\\(^o^)/", root_local_id), &dir_id));
644 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryById(
645 dir_id, &entry));
646 EXPECT_EQ("\\(^o^)_", entry.base_name());
648 std::string file_id;
649 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
650 CreateFileEntryWithResourceId("Slash /.txt", "myfile", dir_id),
651 &file_id));
652 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryById(
653 file_id, &entry));
654 EXPECT_EQ("Slash _.txt", entry.base_name());
656 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryByPath(
657 base::FilePath::FromUTF8Unsafe(
658 "drive/root/\\(^o^)_/Slash _.txt"),
659 &entry));
660 EXPECT_EQ("myfile", entry.resource_id());
663 TEST_F(ResourceMetadataTest, Reset) {
664 // The grand root has "root" which is not empty.
665 std::vector<ResourceEntry> entries;
666 ASSERT_EQ(FILE_ERROR_OK,
667 resource_metadata_->ReadDirectoryByPath(
668 base::FilePath::FromUTF8Unsafe("drive/root"), &entries));
669 ASSERT_FALSE(entries.empty());
671 // Reset.
672 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->Reset());
674 // change stamp should be reset.
675 int64 changestamp = 0;
676 EXPECT_EQ(FILE_ERROR_OK,
677 resource_metadata_->GetLargestChangestamp(&changestamp));
678 EXPECT_EQ(0, changestamp);
680 // root should continue to exist.
681 ResourceEntry entry;
682 ASSERT_EQ(FILE_ERROR_OK,
683 resource_metadata_->GetResourceEntryByPath(
684 base::FilePath::FromUTF8Unsafe("drive"), &entry));
685 EXPECT_EQ("drive", entry.base_name());
686 ASSERT_TRUE(entry.file_info().is_directory());
687 EXPECT_EQ(util::kDriveGrandRootLocalId, entry.local_id());
689 // There are "other", "trash" and "root" under "drive".
690 ASSERT_EQ(FILE_ERROR_OK,
691 resource_metadata_->ReadDirectoryByPath(
692 base::FilePath::FromUTF8Unsafe("drive"), &entries));
693 EXPECT_EQ(3U, entries.size());
695 // The "other" directory should be empty.
696 ASSERT_EQ(FILE_ERROR_OK,
697 resource_metadata_->ReadDirectoryByPath(
698 base::FilePath::FromUTF8Unsafe("drive/other"), &entries));
699 EXPECT_TRUE(entries.empty());
701 // The "trash" directory should be empty.
702 ASSERT_EQ(FILE_ERROR_OK,
703 resource_metadata_->ReadDirectoryByPath(
704 base::FilePath::FromUTF8Unsafe("drive/trash"), &entries));
705 EXPECT_TRUE(entries.empty());
708 } // namespace internal
709 } // namespace drive