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 "chrome/browser/chromeos/drive/resource_metadata.h"
11 #include "base/files/scoped_temp_dir.h"
12 #include "base/strings/stringprintf.h"
13 #include "chrome/browser/chromeos/drive/drive.pb.h"
14 #include "chrome/browser/chromeos/drive/file_system_util.h"
15 #include "chrome/browser/chromeos/drive/test_util.h"
16 #include "content/public/test/test_browser_thread_bundle.h"
17 #include "testing/gtest/include/gtest/gtest.h"
23 // The changestamp of the resource metadata used in
24 // ResourceMetadataTest.
25 const int64 kTestChangestamp = 100;
27 // Returns the sorted base names from |entries|.
28 std::vector<std::string> GetSortedBaseNames(
29 const ResourceEntryVector& entries) {
30 std::vector<std::string> base_names;
31 for (size_t i = 0; i < entries.size(); ++i)
32 base_names.push_back(entries[i].base_name());
33 std::sort(base_names.begin(), base_names.end());
38 // Creates a ResourceEntry for a directory with explicitly set resource_id.
39 ResourceEntry CreateDirectoryEntryWithResourceId(
40 const std::string& title,
41 const std::string& resource_id,
42 const std::string& parent_local_id) {
44 entry.set_title(title);
45 entry.set_resource_id(resource_id);
46 entry.set_parent_local_id(parent_local_id);
47 entry.mutable_file_info()->set_is_directory(true);
48 entry.mutable_directory_specific_info()->set_changestamp(kTestChangestamp);
52 // Creates a ResourceEntry for a directory.
53 ResourceEntry CreateDirectoryEntry(const std::string& title,
54 const std::string& parent_local_id) {
55 return CreateDirectoryEntryWithResourceId(
56 title, "id:" + title, parent_local_id);
59 // Creates a ResourceEntry for a file with explicitly set resource_id.
60 ResourceEntry CreateFileEntryWithResourceId(
61 const std::string& title,
62 const std::string& resource_id,
63 const std::string& parent_local_id) {
65 entry.set_title(title);
66 entry.set_resource_id(resource_id);
67 entry.set_parent_local_id(parent_local_id);
68 entry.mutable_file_info()->set_is_directory(false);
69 entry.mutable_file_info()->set_size(1024);
70 entry.mutable_file_specific_info()->set_md5("md5:" + title);
74 // Creates a ResourceEntry for a file.
75 ResourceEntry CreateFileEntry(const std::string& title,
76 const std::string& parent_local_id) {
77 return CreateFileEntryWithResourceId(title, "id:" + title, parent_local_id);
80 // Creates the following files/directories
83 // drive/root/dir1/dir3/
84 // drive/root/dir1/file4
85 // drive/root/dir1/file5
86 // drive/root/dir2/file6
87 // drive/root/dir2/file7
88 // drive/root/dir2/file8
89 // drive/root/dir1/dir3/file9
90 // drive/root/dir1/dir3/file10
91 void SetUpEntries(ResourceMetadata* resource_metadata) {
93 ASSERT_EQ(FILE_ERROR_OK, resource_metadata->GetIdByPath(
94 util::GetDriveMyDriveRootPath(), &local_id));
95 const std::string root_local_id = local_id;
97 ASSERT_EQ(FILE_ERROR_OK, resource_metadata->AddEntry(
98 CreateDirectoryEntry("dir1", root_local_id), &local_id));
99 const std::string local_id_dir1 = local_id;
101 ASSERT_EQ(FILE_ERROR_OK, resource_metadata->AddEntry(
102 CreateDirectoryEntry("dir2", root_local_id), &local_id));
103 const std::string local_id_dir2 = local_id;
105 ASSERT_EQ(FILE_ERROR_OK, resource_metadata->AddEntry(
106 CreateDirectoryEntry("dir3", local_id_dir1), &local_id));
107 const std::string local_id_dir3 = local_id;
109 ASSERT_EQ(FILE_ERROR_OK, resource_metadata->AddEntry(
110 CreateFileEntry("file4", local_id_dir1), &local_id));
111 ASSERT_EQ(FILE_ERROR_OK, resource_metadata->AddEntry(
112 CreateFileEntry("file5", local_id_dir1), &local_id));
114 ASSERT_EQ(FILE_ERROR_OK, resource_metadata->AddEntry(
115 CreateFileEntry("file6", local_id_dir2), &local_id));
116 ASSERT_EQ(FILE_ERROR_OK, resource_metadata->AddEntry(
117 CreateFileEntry("file7", local_id_dir2), &local_id));
118 ASSERT_EQ(FILE_ERROR_OK, resource_metadata->AddEntry(
119 CreateFileEntry("file8", local_id_dir2), &local_id));
121 ASSERT_EQ(FILE_ERROR_OK, resource_metadata->AddEntry(
122 CreateFileEntry("file9", local_id_dir3), &local_id));
123 ASSERT_EQ(FILE_ERROR_OK, resource_metadata->AddEntry(
124 CreateFileEntry("file10", local_id_dir3), &local_id));
126 ASSERT_EQ(FILE_ERROR_OK,
127 resource_metadata->SetLargestChangestamp(kTestChangestamp));
132 // Tests for methods running on the blocking task runner.
133 class ResourceMetadataTest : public testing::Test {
135 virtual void SetUp() OVERRIDE {
136 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
138 metadata_storage_.reset(new ResourceMetadataStorage(
139 temp_dir_.path(), base::MessageLoopProxy::current().get()));
140 ASSERT_TRUE(metadata_storage_->Initialize());
142 resource_metadata_.reset(new ResourceMetadata(
143 metadata_storage_.get(), base::MessageLoopProxy::current()));
145 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->Initialize());
147 SetUpEntries(resource_metadata_.get());
150 base::ScopedTempDir temp_dir_;
151 content::TestBrowserThreadBundle thread_bundle_;
152 scoped_ptr<ResourceMetadataStorage, test_util::DestroyHelperForTests>
154 scoped_ptr<ResourceMetadata, test_util::DestroyHelperForTests>
158 TEST_F(ResourceMetadataTest, LargestChangestamp) {
159 const int64 kChangestamp = 123456;
160 EXPECT_EQ(FILE_ERROR_OK,
161 resource_metadata_->SetLargestChangestamp(kChangestamp));
162 EXPECT_EQ(kChangestamp, resource_metadata_->GetLargestChangestamp());
165 TEST_F(ResourceMetadataTest, GetResourceEntryByPath) {
166 // Confirm that an existing file is found.
168 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryByPath(
169 base::FilePath::FromUTF8Unsafe("drive/root/dir1/file4"), &entry));
170 EXPECT_EQ("file4", entry.base_name());
172 // Confirm that a non existing file is not found.
173 EXPECT_EQ(FILE_ERROR_NOT_FOUND, resource_metadata_->GetResourceEntryByPath(
174 base::FilePath::FromUTF8Unsafe("drive/root/dir1/non_existing"), &entry));
176 // Confirm that the root is found.
177 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryByPath(
178 base::FilePath::FromUTF8Unsafe("drive"), &entry));
180 // Confirm that a non existing file is not found at the root level.
181 EXPECT_EQ(FILE_ERROR_NOT_FOUND, resource_metadata_->GetResourceEntryByPath(
182 base::FilePath::FromUTF8Unsafe("non_existing"), &entry));
184 // Confirm that an entry is not found with a wrong root.
185 EXPECT_EQ(FILE_ERROR_NOT_FOUND, resource_metadata_->GetResourceEntryByPath(
186 base::FilePath::FromUTF8Unsafe("non_existing/root"), &entry));
189 TEST_F(ResourceMetadataTest, ReadDirectoryByPath) {
190 // Confirm that an existing directory is found.
191 ResourceEntryVector entries;
192 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->ReadDirectoryByPath(
193 base::FilePath::FromUTF8Unsafe("drive/root/dir1"), &entries));
194 ASSERT_EQ(3U, entries.size());
195 // The order is not guaranteed so we should sort the base names.
196 std::vector<std::string> base_names = GetSortedBaseNames(entries);
197 EXPECT_EQ("dir3", base_names[0]);
198 EXPECT_EQ("file4", base_names[1]);
199 EXPECT_EQ("file5", base_names[2]);
201 // Confirm that a non existing directory is not found.
202 EXPECT_EQ(FILE_ERROR_NOT_FOUND, resource_metadata_->ReadDirectoryByPath(
203 base::FilePath::FromUTF8Unsafe("drive/root/non_existing"), &entries));
205 // Confirm that reading a file results in FILE_ERROR_NOT_A_DIRECTORY.
206 EXPECT_EQ(FILE_ERROR_NOT_A_DIRECTORY, resource_metadata_->ReadDirectoryByPath(
207 base::FilePath::FromUTF8Unsafe("drive/root/dir1/file4"), &entries));
210 TEST_F(ResourceMetadataTest, RefreshEntry) {
211 base::FilePath drive_file_path;
216 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath(
217 base::FilePath::FromUTF8Unsafe("drive/root/dir1/dir3/file9"), &file_id));
218 EXPECT_EQ(FILE_ERROR_OK,
219 resource_metadata_->GetResourceEntryById(file_id, &entry));
220 EXPECT_EQ("file9", entry.base_name());
221 EXPECT_TRUE(!entry.file_info().is_directory());
222 EXPECT_EQ("md5:file9", entry.file_specific_info().md5());
225 ResourceEntry file_entry(entry);
226 file_entry.set_title("file100");
227 EXPECT_EQ(FILE_ERROR_OK,
228 resource_metadata_->RefreshEntry(file_entry));
230 EXPECT_EQ("drive/root/dir1/dir3/file100",
231 resource_metadata_->GetFilePath(file_id).AsUTF8Unsafe());
233 EXPECT_EQ(FILE_ERROR_OK,
234 resource_metadata_->GetResourceEntryById(file_id, &entry));
235 EXPECT_EQ("file100", entry.base_name());
236 EXPECT_TRUE(!entry.file_info().is_directory());
237 EXPECT_EQ("md5:file9", entry.file_specific_info().md5());
239 // Update the file md5.
240 const std::string updated_md5("md5:updated");
242 file_entry.mutable_file_specific_info()->set_md5(updated_md5);
243 EXPECT_EQ(FILE_ERROR_OK,
244 resource_metadata_->RefreshEntry(file_entry));
246 EXPECT_EQ("drive/root/dir1/dir3/file100",
247 resource_metadata_->GetFilePath(file_id).AsUTF8Unsafe());
249 EXPECT_EQ(FILE_ERROR_OK,
250 resource_metadata_->GetResourceEntryById(file_id, &entry));
251 EXPECT_EQ("file100", entry.base_name());
252 EXPECT_TRUE(!entry.file_info().is_directory());
253 EXPECT_EQ(updated_md5, entry.file_specific_info().md5());
255 // Make sure we get the same thing from GetResourceEntryByPath.
257 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryByPath(
258 base::FilePath::FromUTF8Unsafe("drive/root/dir1/dir3/file100"), &entry));
259 EXPECT_EQ("file100", entry.base_name());
260 ASSERT_TRUE(!entry.file_info().is_directory());
261 EXPECT_EQ(updated_md5, entry.file_specific_info().md5());
266 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath(
267 base::FilePath::FromUTF8Unsafe("drive/root/dir2"), &dir_id));
268 EXPECT_EQ(FILE_ERROR_OK,
269 resource_metadata_->GetResourceEntryById(dir_id, &entry));
270 EXPECT_EQ("dir2", entry.base_name());
271 ASSERT_TRUE(entry.file_info().is_directory());
275 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath(
276 base::FilePath::FromUTF8Unsafe("drive/root/dir1/dir3"), &dir3_id));
278 // Change the name to dir100 and change the parent to drive/dir1/dir3.
279 ResourceEntry dir_entry(entry);
280 dir_entry.set_title("dir100");
281 dir_entry.set_parent_local_id(dir3_id);
282 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->RefreshEntry(dir_entry));
284 EXPECT_EQ("drive/root/dir1/dir3/dir100",
285 resource_metadata_->GetFilePath(dir_id).AsUTF8Unsafe());
287 EXPECT_EQ(FILE_ERROR_OK,
288 resource_metadata_->GetResourceEntryById(dir_id, &entry));
289 EXPECT_EQ("dir100", entry.base_name());
290 EXPECT_TRUE(entry.file_info().is_directory());
291 EXPECT_EQ("id:dir2", entry.resource_id());
293 // Make sure the children have moved over. Test file6.
295 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryByPath(
296 base::FilePath::FromUTF8Unsafe("drive/root/dir1/dir3/dir100/file6"),
298 EXPECT_EQ("file6", entry.base_name());
300 // Make sure dir2 no longer exists.
301 EXPECT_EQ(FILE_ERROR_NOT_FOUND, resource_metadata_->GetResourceEntryByPath(
302 base::FilePath::FromUTF8Unsafe("drive/root/dir2"), &entry));
304 // Make sure that directory cannot move under a file.
305 dir_entry.set_parent_local_id(file_id);
306 EXPECT_EQ(FILE_ERROR_NOT_A_DIRECTORY,
307 resource_metadata_->RefreshEntry(dir_entry));
309 // Cannot refresh root.
311 dir_entry.set_local_id(util::kDriveGrandRootLocalId);
312 dir_entry.set_title("new-root-name");
313 dir_entry.set_parent_local_id(dir3_id);
314 EXPECT_EQ(FILE_ERROR_INVALID_OPERATION,
315 resource_metadata_->RefreshEntry(dir_entry));
318 TEST_F(ResourceMetadataTest, RefreshEntry_ResourceIDCheck) {
319 // Get an entry with a non-empty resource ID.
321 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryByPath(
322 base::FilePath::FromUTF8Unsafe("drive/root/dir1"), &entry));
323 EXPECT_FALSE(entry.resource_id().empty());
325 // Add a new entry with an empty resource ID.
326 ResourceEntry new_entry;
327 new_entry.set_parent_local_id(entry.local_id());
328 new_entry.set_title("new entry");
329 std::string local_id;
330 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(new_entry, &local_id));
332 // Try to refresh the new entry with a used resource ID.
333 new_entry.set_local_id(local_id);
334 new_entry.set_resource_id(entry.resource_id());
335 EXPECT_EQ(FILE_ERROR_INVALID_OPERATION,
336 resource_metadata_->RefreshEntry(new_entry));
339 TEST_F(ResourceMetadataTest, GetSubDirectoriesRecursively) {
340 std::set<base::FilePath> sub_directories;
342 // file9: not a directory, so no children.
343 std::string local_id;
344 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath(
345 base::FilePath::FromUTF8Unsafe("drive/root/dir1/dir3/file9"), &local_id));
346 resource_metadata_->GetSubDirectoriesRecursively(local_id, &sub_directories);
347 EXPECT_TRUE(sub_directories.empty());
349 // dir2: no child directories.
350 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath(
351 base::FilePath::FromUTF8Unsafe("drive/root/dir2"), &local_id));
352 resource_metadata_->GetSubDirectoriesRecursively(local_id, &sub_directories);
353 EXPECT_TRUE(sub_directories.empty());
354 const std::string dir2_id = local_id;
356 // dir1: dir3 is the only child
357 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath(
358 base::FilePath::FromUTF8Unsafe("drive/root/dir1"), &local_id));
359 resource_metadata_->GetSubDirectoriesRecursively(local_id, &sub_directories);
360 EXPECT_EQ(1u, sub_directories.size());
361 EXPECT_EQ(1u, sub_directories.count(
362 base::FilePath::FromUTF8Unsafe("drive/root/dir1/dir3")));
363 sub_directories.clear();
365 // Add a few more directories to make sure deeper nesting works.
368 // dir2/dir101/dir102
369 // dir2/dir101/dir103
370 // dir2/dir101/dir104
371 // dir2/dir101/dir104/dir105
372 // dir2/dir101/dir104/dir105/dir106
373 // dir2/dir101/dir104/dir105/dir106/dir107
374 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
375 CreateDirectoryEntry("dir100", dir2_id), &local_id));
376 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
377 CreateDirectoryEntry("dir101", dir2_id), &local_id));
378 const std::string dir101_id = local_id;
379 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
380 CreateDirectoryEntry("dir102", dir101_id), &local_id));
381 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
382 CreateDirectoryEntry("dir103", dir101_id), &local_id));
383 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
384 CreateDirectoryEntry("dir104", dir101_id), &local_id));
385 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
386 CreateDirectoryEntry("dir105", local_id), &local_id));
387 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
388 CreateDirectoryEntry("dir106", local_id), &local_id));
389 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
390 CreateDirectoryEntry("dir107", local_id), &local_id));
392 resource_metadata_->GetSubDirectoriesRecursively(dir2_id, &sub_directories);
393 EXPECT_EQ(8u, sub_directories.size());
394 EXPECT_EQ(1u, sub_directories.count(base::FilePath::FromUTF8Unsafe(
395 "drive/root/dir2/dir101")));
396 EXPECT_EQ(1u, sub_directories.count(base::FilePath::FromUTF8Unsafe(
397 "drive/root/dir2/dir101/dir104")));
398 EXPECT_EQ(1u, sub_directories.count(base::FilePath::FromUTF8Unsafe(
399 "drive/root/dir2/dir101/dir104/dir105/dir106/dir107")));
402 TEST_F(ResourceMetadataTest, AddEntry) {
403 base::FilePath drive_file_path;
405 // Add a file to dir3.
406 std::string local_id;
407 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath(
408 base::FilePath::FromUTF8Unsafe("drive/root/dir1/dir3"), &local_id));
409 ResourceEntry file_entry = CreateFileEntry("file100", local_id);
410 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(file_entry, &local_id));
411 EXPECT_EQ("drive/root/dir1/dir3/file100",
412 resource_metadata_->GetFilePath(local_id).AsUTF8Unsafe());
415 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath(
416 base::FilePath::FromUTF8Unsafe("drive/root/dir1"), &local_id));
417 ResourceEntry dir_entry = CreateDirectoryEntry("dir101", local_id);
418 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(dir_entry, &local_id));
419 EXPECT_EQ("drive/root/dir1/dir101",
420 resource_metadata_->GetFilePath(local_id).AsUTF8Unsafe());
422 // Add to an invalid parent.
423 ResourceEntry file_entry3 = CreateFileEntry("file103", "id:invalid");
424 EXPECT_EQ(FILE_ERROR_NOT_FOUND,
425 resource_metadata_->AddEntry(file_entry3, &local_id));
427 // Add an existing file.
428 EXPECT_EQ(FILE_ERROR_EXISTS,
429 resource_metadata_->AddEntry(file_entry, &local_id));
432 TEST_F(ResourceMetadataTest, RemoveEntry) {
433 // Make sure file9 is found.
434 std::string file9_local_id;
435 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath(
436 base::FilePath::FromUTF8Unsafe("drive/root/dir1/dir3/file9"),
439 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryById(
440 file9_local_id, &entry));
441 EXPECT_EQ("file9", entry.base_name());
444 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->RemoveEntry(file9_local_id));
446 // file9 should no longer exist.
447 EXPECT_EQ(FILE_ERROR_NOT_FOUND, resource_metadata_->GetResourceEntryById(
448 file9_local_id, &entry));
451 std::string dir3_local_id;
452 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath(
453 base::FilePath::FromUTF8Unsafe("drive/root/dir1/dir3"), &dir3_local_id));
454 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryById(
455 dir3_local_id, &entry));
456 EXPECT_EQ("dir3", entry.base_name());
459 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->RemoveEntry(dir3_local_id));
461 // dir3 should no longer exist.
462 EXPECT_EQ(FILE_ERROR_NOT_FOUND, resource_metadata_->GetResourceEntryById(
463 dir3_local_id, &entry));
465 // Remove unknown local_id using RemoveEntry.
466 EXPECT_EQ(FILE_ERROR_NOT_FOUND, resource_metadata_->RemoveEntry("foo"));
468 // Try removing root. This should fail.
469 EXPECT_EQ(FILE_ERROR_ACCESS_DENIED, resource_metadata_->RemoveEntry(
470 util::kDriveGrandRootLocalId));
473 TEST_F(ResourceMetadataTest, GetResourceEntryById_RootDirectory) {
474 // Look up the root directory by its ID.
476 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryById(
477 util::kDriveGrandRootLocalId, &entry));
478 EXPECT_EQ("drive", entry.base_name());
481 TEST_F(ResourceMetadataTest, GetResourceEntryById) {
482 // Get file4 by path.
483 std::string local_id;
484 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath(
485 base::FilePath::FromUTF8Unsafe("drive/root/dir1/file4"), &local_id));
487 // Confirm that an existing file is found.
489 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryById(
491 EXPECT_EQ("file4", entry.base_name());
493 // Confirm that a non existing file is not found.
494 EXPECT_EQ(FILE_ERROR_NOT_FOUND, resource_metadata_->GetResourceEntryById(
495 "file:non_existing", &entry));
498 TEST_F(ResourceMetadataTest, Iterate) {
499 scoped_ptr<ResourceMetadata::Iterator> it = resource_metadata_->GetIterator();
502 int file_count = 0, directory_count = 0;
503 for (; !it->IsAtEnd(); it->Advance()) {
504 if (!it->GetValue().file_info().is_directory())
510 EXPECT_EQ(7, file_count);
511 EXPECT_EQ(7, directory_count);
514 TEST_F(ResourceMetadataTest, DuplicatedNames) {
515 std::string root_local_id;
516 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath(
517 base::FilePath::FromUTF8Unsafe("drive/root"), &root_local_id));
521 // When multiple entries with the same title are added in a single directory,
522 // their base_names are de-duped.
524 // - drive/root/foo (1)
525 std::string dir_id_0;
526 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
527 CreateDirectoryEntryWithResourceId(
528 "foo", "foo0", root_local_id), &dir_id_0));
529 std::string dir_id_1;
530 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
531 CreateDirectoryEntryWithResourceId(
532 "foo", "foo1", root_local_id), &dir_id_1));
534 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryById(
536 EXPECT_EQ("foo", entry.base_name());
537 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryById(
539 EXPECT_EQ("foo (1)", entry.base_name());
541 // - drive/root/foo/bar.txt
542 // - drive/root/foo/bar (1).txt
543 // - drive/root/foo/bar (2).txt
545 // - drive/root/foo/bar (99).txt
546 std::vector<std::string> file_ids(100);
547 for (size_t i = 0; i < file_ids.size(); ++i) {
548 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
549 CreateFileEntryWithResourceId(
550 "bar.txt", base::StringPrintf("bar%d", static_cast<int>(i)),
551 dir_id_0), &file_ids[i]));
554 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryById(
555 file_ids[0], &entry));
556 EXPECT_EQ("bar.txt", entry.base_name());
557 for (size_t i = 1; i < file_ids.size(); ++i) {
558 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryById(
559 file_ids[i], &entry)) << i;
560 EXPECT_EQ(base::StringPrintf("bar (%d).txt", static_cast<int>(i)),
564 // Same name but different parent. No renaming.
565 // - drive/root/foo (1)/bar.txt
566 std::string file_id_3;
567 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
568 CreateFileEntryWithResourceId(
569 "bar.txt", "bar_different_parent", dir_id_1), &file_id_3));
571 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryById(
573 EXPECT_EQ("bar.txt", entry.base_name());
575 // Checks that the entries can be looked up by the de-duped paths.
576 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryByPath(
577 base::FilePath::FromUTF8Unsafe("drive/root/foo/bar (2).txt"), &entry));
578 EXPECT_EQ("bar2", entry.resource_id());
579 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryByPath(
580 base::FilePath::FromUTF8Unsafe("drive/root/foo (1)/bar.txt"), &entry));
581 EXPECT_EQ("bar_different_parent", entry.resource_id());
584 TEST_F(ResourceMetadataTest, EncodedNames) {
585 std::string root_local_id;
586 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath(
587 base::FilePath::FromUTF8Unsafe("drive/root"), &root_local_id));
592 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
593 CreateDirectoryEntry("\\(^o^)/", root_local_id), &dir_id));
594 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryById(
596 EXPECT_EQ("\\(^o^)_", entry.base_name());
599 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
600 CreateFileEntryWithResourceId("Slash /.txt", "myfile", dir_id),
602 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryById(
604 EXPECT_EQ("Slash _.txt", entry.base_name());
606 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryByPath(
607 base::FilePath::FromUTF8Unsafe(
608 "drive/root/\\(^o^)_/Slash _.txt"),
610 EXPECT_EQ("myfile", entry.resource_id());
613 TEST_F(ResourceMetadataTest, Reset) {
614 // The grand root has "root" which is not empty.
615 std::vector<ResourceEntry> entries;
616 ASSERT_EQ(FILE_ERROR_OK,
617 resource_metadata_->ReadDirectoryByPath(
618 base::FilePath::FromUTF8Unsafe("drive/root"), &entries));
619 ASSERT_FALSE(entries.empty());
622 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->Reset());
624 // change stamp should be reset.
625 EXPECT_EQ(0, resource_metadata_->GetLargestChangestamp());
627 // root should continue to exist.
629 ASSERT_EQ(FILE_ERROR_OK,
630 resource_metadata_->GetResourceEntryByPath(
631 base::FilePath::FromUTF8Unsafe("drive"), &entry));
632 EXPECT_EQ("drive", entry.base_name());
633 ASSERT_TRUE(entry.file_info().is_directory());
634 EXPECT_EQ(util::kDriveGrandRootLocalId, entry.local_id());
636 // There are "other", "trash" and "root" under "drive".
637 ASSERT_EQ(FILE_ERROR_OK,
638 resource_metadata_->ReadDirectoryByPath(
639 base::FilePath::FromUTF8Unsafe("drive"), &entries));
640 EXPECT_EQ(3U, entries.size());
642 // The "other" directory should be empty.
643 ASSERT_EQ(FILE_ERROR_OK,
644 resource_metadata_->ReadDirectoryByPath(
645 base::FilePath::FromUTF8Unsafe("drive/other"), &entries));
646 EXPECT_TRUE(entries.empty());
648 // The "trash" directory should be empty.
649 ASSERT_EQ(FILE_ERROR_OK,
650 resource_metadata_->ReadDirectoryByPath(
651 base::FilePath::FromUTF8Unsafe("drive/trash"), &entries));
652 EXPECT_TRUE(entries.empty());
655 } // namespace internal