OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "chrome/browser/chromeos/drive/resource_metadata.h" | |
6 | |
7 #include <algorithm> | |
8 #include <string> | |
9 #include <vector> | |
10 | |
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 "chrome/browser/chromeos/drive/fake_free_disk_space_getter.h" | |
16 #include "chrome/browser/chromeos/drive/file_cache.h" | |
17 #include "chrome/browser/chromeos/drive/file_system_core_util.h" | |
18 #include "components/drive/drive.pb.h" | |
19 #include "components/drive/drive_test_util.h" | |
20 #include "content/public/test/test_browser_thread_bundle.h" | |
21 #include "testing/gtest/include/gtest/gtest.h" | |
22 | |
23 namespace drive { | |
24 namespace internal { | |
25 namespace { | |
26 | |
27 // The changestamp of the resource metadata used in | |
28 // ResourceMetadataTest. | |
29 const int64 kTestChangestamp = 100; | |
30 | |
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()); | |
38 | |
39 return base_names; | |
40 } | |
41 | |
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; | |
54 } | |
55 | |
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); | |
61 } | |
62 | |
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; | |
76 } | |
77 | |
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); | |
82 } | |
83 | |
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; | |
100 | |
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; | |
104 | |
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; | |
108 | |
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; | |
112 | |
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)); | |
117 | |
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)); | |
124 | |
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)); | |
129 | |
130 ASSERT_EQ(FILE_ERROR_OK, | |
131 resource_metadata->SetLargestChangestamp(kTestChangestamp)); | |
132 } | |
133 | |
134 } // namespace | |
135 | |
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()); | |
141 | |
142 metadata_storage_.reset(new ResourceMetadataStorage( | |
143 temp_dir_.path(), base::ThreadTaskRunnerHandle::Get().get())); | |
144 ASSERT_TRUE(metadata_storage_->Initialize()); | |
145 | |
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()); | |
152 | |
153 resource_metadata_.reset(new ResourceMetadata( | |
154 metadata_storage_.get(), cache_.get(), | |
155 base::ThreadTaskRunnerHandle::Get())); | |
156 | |
157 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->Initialize()); | |
158 | |
159 SetUpEntries(resource_metadata_.get()); | |
160 } | |
161 | |
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_; | |
170 }; | |
171 | |
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); | |
180 } | |
181 | |
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()); | |
188 | |
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)); | |
192 | |
193 // Confirm that the root is found. | |
194 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryByPath( | |
195 base::FilePath::FromUTF8Unsafe("drive"), &entry)); | |
196 | |
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)); | |
200 | |
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)); | |
204 } | |
205 | |
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]); | |
217 | |
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)); | |
221 | |
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)); | |
225 } | |
226 | |
227 TEST_F(ResourceMetadataTest, RefreshEntry) { | |
228 base::FilePath drive_file_path; | |
229 ResourceEntry entry; | |
230 | |
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()); | |
240 | |
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)); | |
246 | |
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()); | |
256 | |
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)); | |
263 | |
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()); | |
272 | |
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()); | |
280 | |
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()); | |
290 | |
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)); | |
295 | |
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)); | |
301 | |
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()); | |
310 | |
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()); | |
317 | |
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)); | |
321 | |
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)); | |
326 | |
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)); | |
334 } | |
335 | |
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()); | |
342 | |
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)); | |
349 | |
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)); | |
355 } | |
356 | |
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)); | |
361 | |
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)); | |
365 | |
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()); | |
370 | |
371 // Pin the file. | |
372 EXPECT_EQ(FILE_ERROR_OK, cache_->Pin(entry.local_id())); | |
373 | |
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)); | |
379 | |
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()); | |
384 } | |
385 | |
386 TEST_F(ResourceMetadataTest, GetSubDirectoriesRecursively) { | |
387 std::set<base::FilePath> sub_directories; | |
388 | |
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()); | |
396 | |
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; | |
404 | |
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(); | |
414 | |
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)); | |
441 | |
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"))); | |
451 } | |
452 | |
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()); | |
463 | |
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()); | |
471 | |
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)); | |
476 | |
477 // Add an existing file. | |
478 EXPECT_EQ(FILE_ERROR_EXISTS, | |
479 resource_metadata_->AddEntry(file_entry, &local_id)); | |
480 } | |
481 | |
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()); | |
492 | |
493 // Remove file9. | |
494 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->RemoveEntry(file9_local_id)); | |
495 | |
496 // file9 should no longer exist. | |
497 EXPECT_EQ(FILE_ERROR_NOT_FOUND, resource_metadata_->GetResourceEntryById( | |
498 file9_local_id, &entry)); | |
499 | |
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()); | |
507 | |
508 // Remove dir3. | |
509 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->RemoveEntry(dir3_local_id)); | |
510 | |
511 // dir3 should no longer exist. | |
512 EXPECT_EQ(FILE_ERROR_NOT_FOUND, resource_metadata_->GetResourceEntryById( | |
513 dir3_local_id, &entry)); | |
514 | |
515 // Remove unknown local_id using RemoveEntry. | |
516 EXPECT_EQ(FILE_ERROR_NOT_FOUND, resource_metadata_->RemoveEntry("foo")); | |
517 | |
518 // Try removing root. This should fail. | |
519 EXPECT_EQ(FILE_ERROR_ACCESS_DENIED, resource_metadata_->RemoveEntry( | |
520 util::kDriveGrandRootLocalId)); | |
521 } | |
522 | |
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()); | |
529 } | |
530 | |
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)); | |
536 | |
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()); | |
542 | |
543 // Confirm that a non existing file is not found. | |
544 EXPECT_EQ(FILE_ERROR_NOT_FOUND, resource_metadata_->GetResourceEntryById( | |
545 "non_existing", &entry)); | |
546 } | |
547 | |
548 TEST_F(ResourceMetadataTest, Iterate) { | |
549 scoped_ptr<ResourceMetadata::Iterator> it = resource_metadata_->GetIterator(); | |
550 ASSERT_TRUE(it); | |
551 | |
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; | |
558 } | |
559 | |
560 EXPECT_EQ(7, file_count); | |
561 EXPECT_EQ(7, directory_count); | |
562 } | |
563 | |
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)); | |
568 | |
569 ResourceEntry entry; | |
570 | |
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)); | |
583 | |
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()); | |
590 | |
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])); | |
602 } | |
603 | |
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()); | |
612 } | |
613 | |
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)); | |
620 | |
621 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryById( | |
622 file_id_3, &entry)); | |
623 EXPECT_EQ("bar.txt", entry.base_name()); | |
624 | |
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()); | |
632 } | |
633 | |
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)); | |
638 | |
639 ResourceEntry entry; | |
640 | |
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()); | |
647 | |
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()); | |
655 | |
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()); | |
661 } | |
662 | |
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()); | |
670 | |
671 // Reset. | |
672 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->Reset()); | |
673 | |
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); | |
679 | |
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()); | |
688 | |
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()); | |
694 | |
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()); | |
700 | |
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()); | |
706 } | |
707 | |
708 } // namespace internal | |
709 } // namespace drive | |
OLD | NEW |