[email protected] | df3fef2 | 2013-03-21 12:20:41 | [diff] [blame] | 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 | |
lukasza | 6364a02 | 2015-08-21 01:13:24 | [diff] [blame] | 5 | #include "components/drive/resource_metadata_storage.h" |
[email protected] | df3fef2 | 2013-03-21 12:20:41 | [diff] [blame] | 6 | |
avi | bc5337b | 2015-12-25 23:16:33 | [diff] [blame] | 7 | #include <stddef.h> |
| 8 | #include <stdint.h> |
| 9 | |
[email protected] | df3fef2 | 2013-03-21 12:20:41 | [diff] [blame] | 10 | #include <algorithm> |
Lei Zhang | d359bae | 2017-11-29 18:25:57 | [diff] [blame] | 11 | #include <utility> |
[email protected] | df3fef2 | 2013-03-21 12:20:41 | [diff] [blame] | 12 | |
thestig | 18dfb7a5 | 2014-08-26 10:44:04 | [diff] [blame] | 13 | #include "base/files/file_util.h" |
[email protected] | df3fef2 | 2013-03-21 12:20:41 | [diff] [blame] | 14 | #include "base/files/scoped_temp_dir.h" |
pranay.kumar | 229290b5 | 2015-05-14 05:21:04 | [diff] [blame] | 15 | #include "base/single_thread_task_runner.h" |
Lei Zhang | d359bae | 2017-11-29 18:25:57 | [diff] [blame] | 16 | #include "base/stl_util.h" |
limasdf | 511524f | 2014-09-13 00:48:53 | [diff] [blame] | 17 | #include "base/strings/string_split.h" |
gab | 7966d31 | 2016-05-11 20:35:01 | [diff] [blame] | 18 | #include "base/threading/thread_task_runner_handle.h" |
lukasza | 01b9d55a | 2015-07-21 15:19:25 | [diff] [blame] | 19 | #include "components/drive/drive.pb.h" |
Stuart Langley | 22cca24 | 2018-05-18 05:59:12 | [diff] [blame] | 20 | #include "components/drive/file_system_core_util.h" |
Gabriel Charette | c710874 | 2019-08-23 03:31:40 | [diff] [blame] | 21 | #include "content/public/test/browser_task_environment.h" |
Austin Tankiang | c35b6c6 | 2019-11-08 12:15:12 | [diff] [blame] | 22 | #include "content/public/test/test_utils.h" |
[email protected] | df3fef2 | 2013-03-21 12:20:41 | [diff] [blame] | 23 | #include "testing/gtest/include/gtest/gtest.h" |
[email protected] | c28c952d | 2013-04-24 11:41:57 | [diff] [blame] | 24 | #include "third_party/leveldatabase/src/include/leveldb/db.h" |
[email protected] | 12a024ec | 2013-10-24 04:00:05 | [diff] [blame] | 25 | #include "third_party/leveldatabase/src/include/leveldb/write_batch.h" |
[email protected] | df3fef2 | 2013-03-21 12:20:41 | [diff] [blame] | 26 | |
| 27 | namespace drive { |
[email protected] | be427d7 | 2013-06-21 07:09:27 | [diff] [blame] | 28 | namespace internal { |
[email protected] | df3fef2 | 2013-03-21 12:20:41 | [diff] [blame] | 29 | |
Austin Tankiang | c35b6c6 | 2019-11-08 12:15:12 | [diff] [blame] | 30 | namespace { |
| 31 | |
| 32 | // Helper to destroy objects which needs Destroy() to be called on destruction. |
| 33 | // Note: When using this helper, you should destruct objects before |
| 34 | // BrowserThread. |
| 35 | struct DestroyHelperForTests { |
| 36 | template <typename T> |
| 37 | void operator()(T* object) const { |
| 38 | if (object) { |
| 39 | object->Destroy(); |
| 40 | content::RunAllTasksUntilIdle(); // Finish destruction. |
| 41 | } |
| 42 | } |
| 43 | }; |
| 44 | |
| 45 | } // namespace |
| 46 | |
[email protected] | dd8e7fe | 2013-04-26 05:14:23 | [diff] [blame] | 47 | class ResourceMetadataStorageTest : public testing::Test { |
[email protected] | df3fef2 | 2013-03-21 12:20:41 | [diff] [blame] | 48 | protected: |
Stuart Langley | 1cad122 | 2018-05-29 18:58:44 | [diff] [blame] | 49 | ResourceMetadataStorageTest() = default; |
| 50 | ~ResourceMetadataStorageTest() override = default; |
Lei Zhang | d359bae | 2017-11-29 18:25:57 | [diff] [blame] | 51 | |
dcheng | fe77330 | 2015-01-22 19:45:52 | [diff] [blame] | 52 | void SetUp() override { |
[email protected] | df3fef2 | 2013-03-21 12:20:41 | [diff] [blame] | 53 | ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); |
| 54 | |
[email protected] | be427d7 | 2013-06-21 07:09:27 | [diff] [blame] | 55 | storage_.reset(new ResourceMetadataStorage( |
vabr | 96fd0c0f | 2016-09-13 14:21:31 | [diff] [blame] | 56 | temp_dir_.GetPath(), base::ThreadTaskRunnerHandle::Get().get())); |
[email protected] | df3fef2 | 2013-03-21 12:20:41 | [diff] [blame] | 57 | ASSERT_TRUE(storage_->Initialize()); |
| 58 | } |
| 59 | |
[email protected] | df3fef2 | 2013-03-21 12:20:41 | [diff] [blame] | 60 | // Overwrites |storage_|'s version. |
| 61 | void SetDBVersion(int version) { |
[email protected] | b360d67 | 2013-06-20 08:06:36 | [diff] [blame] | 62 | ResourceMetadataHeader header; |
[email protected] | 99613941 | 2014-05-10 06:19:50 | [diff] [blame] | 63 | ASSERT_EQ(FILE_ERROR_OK, storage_->GetHeader(&header)); |
[email protected] | b360d67 | 2013-06-20 08:06:36 | [diff] [blame] | 64 | header.set_version(version); |
[email protected] | 99613941 | 2014-05-10 06:19:50 | [diff] [blame] | 65 | EXPECT_EQ(FILE_ERROR_OK, storage_->PutHeader(header)); |
[email protected] | df3fef2 | 2013-03-21 12:20:41 | [diff] [blame] | 66 | } |
| 67 | |
[email protected] | 74f678e | 2013-04-17 09:16:46 | [diff] [blame] | 68 | bool CheckValidity() { |
| 69 | return storage_->CheckValidity(); |
| 70 | } |
| 71 | |
[email protected] | 12a024ec | 2013-10-24 04:00:05 | [diff] [blame] | 72 | leveldb::DB* resource_map() { return storage_->resource_map_.get(); } |
| 73 | |
[email protected] | c28c952d | 2013-04-24 11:41:57 | [diff] [blame] | 74 | // Puts a child entry. |
[email protected] | 0731029 | 2013-08-19 10:55:41 | [diff] [blame] | 75 | void PutChild(const std::string& parent_id, |
[email protected] | c28c952d | 2013-04-24 11:41:57 | [diff] [blame] | 76 | const std::string& child_base_name, |
[email protected] | 0731029 | 2013-08-19 10:55:41 | [diff] [blame] | 77 | const std::string& child_id) { |
[email protected] | c28c952d | 2013-04-24 11:41:57 | [diff] [blame] | 78 | storage_->resource_map_->Put( |
| 79 | leveldb::WriteOptions(), |
[email protected] | 0731029 | 2013-08-19 10:55:41 | [diff] [blame] | 80 | ResourceMetadataStorage::GetChildEntryKey(parent_id, child_base_name), |
| 81 | child_id); |
[email protected] | c28c952d | 2013-04-24 11:41:57 | [diff] [blame] | 82 | } |
| 83 | |
| 84 | // Removes a child entry. |
[email protected] | 0731029 | 2013-08-19 10:55:41 | [diff] [blame] | 85 | void RemoveChild(const std::string& parent_id, |
[email protected] | c28c952d | 2013-04-24 11:41:57 | [diff] [blame] | 86 | const std::string& child_base_name) { |
| 87 | storage_->resource_map_->Delete( |
| 88 | leveldb::WriteOptions(), |
[email protected] | 0731029 | 2013-08-19 10:55:41 | [diff] [blame] | 89 | ResourceMetadataStorage::GetChildEntryKey(parent_id, child_base_name)); |
[email protected] | c28c952d | 2013-04-24 11:41:57 | [diff] [blame] | 90 | } |
| 91 | |
Lei Zhang | d359bae | 2017-11-29 18:25:57 | [diff] [blame] | 92 | bool UpgradeOldDB() { |
| 93 | return ResourceMetadataStorage::UpgradeOldDB(temp_dir_.GetPath()); |
| 94 | } |
| 95 | |
Gabriel Charette | 798fde7 | 2019-08-20 22:24:04 | [diff] [blame] | 96 | content::BrowserTaskEnvironment task_environment_; |
[email protected] | df3fef2 | 2013-03-21 12:20:41 | [diff] [blame] | 97 | base::ScopedTempDir temp_dir_; |
Austin Tankiang | c35b6c6 | 2019-11-08 12:15:12 | [diff] [blame] | 98 | std::unique_ptr<ResourceMetadataStorage, DestroyHelperForTests> storage_; |
Lei Zhang | d359bae | 2017-11-29 18:25:57 | [diff] [blame] | 99 | |
| 100 | DISALLOW_COPY_AND_ASSIGN(ResourceMetadataStorageTest); |
[email protected] | df3fef2 | 2013-03-21 12:20:41 | [diff] [blame] | 101 | }; |
| 102 | |
[email protected] | dd8e7fe | 2013-04-26 05:14:23 | [diff] [blame] | 103 | TEST_F(ResourceMetadataStorageTest, LargestChangestamp) { |
avi | bc5337b | 2015-12-25 23:16:33 | [diff] [blame] | 104 | const int64_t kLargestChangestamp = 1234567890; |
[email protected] | 99613941 | 2014-05-10 06:19:50 | [diff] [blame] | 105 | EXPECT_EQ(FILE_ERROR_OK, |
| 106 | storage_->SetLargestChangestamp(kLargestChangestamp)); |
avi | bc5337b | 2015-12-25 23:16:33 | [diff] [blame] | 107 | int64_t value = 0; |
[email protected] | 99613941 | 2014-05-10 06:19:50 | [diff] [blame] | 108 | EXPECT_EQ(FILE_ERROR_OK, storage_->GetLargestChangestamp(&value)); |
| 109 | EXPECT_EQ(kLargestChangestamp, value); |
[email protected] | df3fef2 | 2013-03-21 12:20:41 | [diff] [blame] | 110 | } |
| 111 | |
Stuart Langley | 22cca24 | 2018-05-18 05:59:12 | [diff] [blame] | 112 | TEST_F(ResourceMetadataStorageTest, StartPageToken) { |
| 113 | constexpr char kStartPageToken[] = "123456"; |
| 114 | EXPECT_EQ(FILE_ERROR_OK, storage_->SetStartPageToken(kStartPageToken)); |
| 115 | std::string start_page_token; |
| 116 | EXPECT_EQ(FILE_ERROR_OK, storage_->GetStartPageToken(&start_page_token)); |
| 117 | EXPECT_EQ(kStartPageToken, start_page_token); |
| 118 | } |
| 119 | |
[email protected] | dd8e7fe | 2013-04-26 05:14:23 | [diff] [blame] | 120 | TEST_F(ResourceMetadataStorageTest, PutEntry) { |
[email protected] | df3fef2 | 2013-03-21 12:20:41 | [diff] [blame] | 121 | const std::string key1 = "abcdefg"; |
| 122 | const std::string key2 = "abcd"; |
[email protected] | c28c952d | 2013-04-24 11:41:57 | [diff] [blame] | 123 | const std::string key3 = "efgh"; |
| 124 | const std::string name2 = "ABCD"; |
| 125 | const std::string name3 = "EFGH"; |
[email protected] | df3fef2 | 2013-03-21 12:20:41 | [diff] [blame] | 126 | |
[email protected] | df3fef2 | 2013-03-21 12:20:41 | [diff] [blame] | 127 | // key1 not found. |
[email protected] | fff7277 | 2013-06-19 05:09:41 | [diff] [blame] | 128 | ResourceEntry result; |
[email protected] | 99613941 | 2014-05-10 06:19:50 | [diff] [blame] | 129 | EXPECT_EQ(FILE_ERROR_NOT_FOUND, storage_->GetEntry(key1, &result)); |
[email protected] | df3fef2 | 2013-03-21 12:20:41 | [diff] [blame] | 130 | |
| 131 | // Put entry1. |
[email protected] | d38aa40 | 2013-09-25 09:38:43 | [diff] [blame] | 132 | ResourceEntry entry1; |
| 133 | entry1.set_local_id(key1); |
[email protected] | 99613941 | 2014-05-10 06:19:50 | [diff] [blame] | 134 | EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry1)); |
[email protected] | df3fef2 | 2013-03-21 12:20:41 | [diff] [blame] | 135 | |
| 136 | // key1 found. |
[email protected] | 99613941 | 2014-05-10 06:19:50 | [diff] [blame] | 137 | EXPECT_EQ(FILE_ERROR_OK, storage_->GetEntry(key1, &result)); |
[email protected] | df3fef2 | 2013-03-21 12:20:41 | [diff] [blame] | 138 | |
| 139 | // key2 not found. |
[email protected] | 99613941 | 2014-05-10 06:19:50 | [diff] [blame] | 140 | EXPECT_EQ(FILE_ERROR_NOT_FOUND, storage_->GetEntry(key2, &result)); |
[email protected] | df3fef2 | 2013-03-21 12:20:41 | [diff] [blame] | 141 | |
[email protected] | c28c952d | 2013-04-24 11:41:57 | [diff] [blame] | 142 | // Put entry2 as a child of entry1. |
[email protected] | 67241b83 | 2013-05-02 04:55:52 | [diff] [blame] | 143 | ResourceEntry entry2; |
[email protected] | d38aa40 | 2013-09-25 09:38:43 | [diff] [blame] | 144 | entry2.set_local_id(key2); |
[email protected] | 943cb8b | 2013-08-21 03:17:08 | [diff] [blame] | 145 | entry2.set_parent_local_id(key1); |
[email protected] | c28c952d | 2013-04-24 11:41:57 | [diff] [blame] | 146 | entry2.set_base_name(name2); |
[email protected] | 99613941 | 2014-05-10 06:19:50 | [diff] [blame] | 147 | EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry2)); |
[email protected] | c28c952d | 2013-04-24 11:41:57 | [diff] [blame] | 148 | |
| 149 | // key2 found. |
[email protected] | 99613941 | 2014-05-10 06:19:50 | [diff] [blame] | 150 | std::string child_id; |
| 151 | EXPECT_EQ(FILE_ERROR_OK, storage_->GetEntry(key2, &result)); |
| 152 | EXPECT_EQ(FILE_ERROR_OK, storage_->GetChild(key1, name2, &child_id)); |
| 153 | EXPECT_EQ(key2, child_id); |
[email protected] | c28c952d | 2013-04-24 11:41:57 | [diff] [blame] | 154 | |
| 155 | // Put entry3 as a child of entry2. |
[email protected] | 67241b83 | 2013-05-02 04:55:52 | [diff] [blame] | 156 | ResourceEntry entry3; |
[email protected] | d38aa40 | 2013-09-25 09:38:43 | [diff] [blame] | 157 | entry3.set_local_id(key3); |
[email protected] | 943cb8b | 2013-08-21 03:17:08 | [diff] [blame] | 158 | entry3.set_parent_local_id(key2); |
[email protected] | c28c952d | 2013-04-24 11:41:57 | [diff] [blame] | 159 | entry3.set_base_name(name3); |
[email protected] | 99613941 | 2014-05-10 06:19:50 | [diff] [blame] | 160 | EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry3)); |
[email protected] | c28c952d | 2013-04-24 11:41:57 | [diff] [blame] | 161 | |
| 162 | // key3 found. |
[email protected] | 99613941 | 2014-05-10 06:19:50 | [diff] [blame] | 163 | EXPECT_EQ(FILE_ERROR_OK, storage_->GetEntry(key3, &result)); |
| 164 | EXPECT_EQ(FILE_ERROR_OK, storage_->GetChild(key2, name3, &child_id)); |
| 165 | EXPECT_EQ(key3, child_id); |
[email protected] | c28c952d | 2013-04-24 11:41:57 | [diff] [blame] | 166 | |
| 167 | // Change entry3's parent to entry1. |
[email protected] | 943cb8b | 2013-08-21 03:17:08 | [diff] [blame] | 168 | entry3.set_parent_local_id(key1); |
[email protected] | 99613941 | 2014-05-10 06:19:50 | [diff] [blame] | 169 | EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry3)); |
[email protected] | c28c952d | 2013-04-24 11:41:57 | [diff] [blame] | 170 | |
| 171 | // entry3 is a child of entry1 now. |
[email protected] | 99613941 | 2014-05-10 06:19:50 | [diff] [blame] | 172 | EXPECT_EQ(FILE_ERROR_NOT_FOUND, storage_->GetChild(key2, name3, &child_id)); |
| 173 | EXPECT_EQ(FILE_ERROR_OK, storage_->GetChild(key1, name3, &child_id)); |
| 174 | EXPECT_EQ(key3, child_id); |
[email protected] | c28c952d | 2013-04-24 11:41:57 | [diff] [blame] | 175 | |
| 176 | // Remove entries. |
[email protected] | 99613941 | 2014-05-10 06:19:50 | [diff] [blame] | 177 | EXPECT_EQ(FILE_ERROR_OK, storage_->RemoveEntry(key3)); |
| 178 | EXPECT_EQ(FILE_ERROR_NOT_FOUND, storage_->GetEntry(key3, &result)); |
| 179 | EXPECT_EQ(FILE_ERROR_OK, storage_->RemoveEntry(key2)); |
| 180 | EXPECT_EQ(FILE_ERROR_NOT_FOUND, storage_->GetEntry(key2, &result)); |
| 181 | EXPECT_EQ(FILE_ERROR_OK, storage_->RemoveEntry(key1)); |
| 182 | EXPECT_EQ(FILE_ERROR_NOT_FOUND, storage_->GetEntry(key1, &result)); |
[email protected] | df3fef2 | 2013-03-21 12:20:41 | [diff] [blame] | 183 | } |
| 184 | |
[email protected] | eb391ee | 2013-05-10 06:08:57 | [diff] [blame] | 185 | TEST_F(ResourceMetadataStorageTest, Iterator) { |
[email protected] | 8c191e5 | 2013-04-09 14:05:17 | [diff] [blame] | 186 | // Prepare data. |
[email protected] | 0731029 | 2013-08-19 10:55:41 | [diff] [blame] | 187 | std::vector<std::string> keys; |
[email protected] | 8c191e5 | 2013-04-09 14:05:17 | [diff] [blame] | 188 | |
[email protected] | 0731029 | 2013-08-19 10:55:41 | [diff] [blame] | 189 | keys.push_back("entry1"); |
| 190 | keys.push_back("entry2"); |
| 191 | keys.push_back("entry3"); |
| 192 | keys.push_back("entry4"); |
[email protected] | 8c191e5 | 2013-04-09 14:05:17 | [diff] [blame] | 193 | |
Lei Zhang | d359bae | 2017-11-29 18:25:57 | [diff] [blame] | 194 | for (const std::string& key : keys) { |
[email protected] | d38aa40 | 2013-09-25 09:38:43 | [diff] [blame] | 195 | ResourceEntry entry; |
Lei Zhang | d359bae | 2017-11-29 18:25:57 | [diff] [blame] | 196 | entry.set_local_id(key); |
[email protected] | 99613941 | 2014-05-10 06:19:50 | [diff] [blame] | 197 | EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry)); |
[email protected] | d38aa40 | 2013-09-25 09:38:43 | [diff] [blame] | 198 | } |
[email protected] | 8c191e5 | 2013-04-09 14:05:17 | [diff] [blame] | 199 | |
[email protected] | eb391ee | 2013-05-10 06:08:57 | [diff] [blame] | 200 | // Iterate and check the result. |
[email protected] | 0f86f23 | 2013-07-26 03:25:14 | [diff] [blame] | 201 | std::map<std::string, ResourceEntry> found_entries; |
dcheng | f4275023 | 2016-04-12 04:12:27 | [diff] [blame] | 202 | std::unique_ptr<ResourceMetadataStorage::Iterator> it = |
| 203 | storage_->GetIterator(); |
[email protected] | eb391ee | 2013-05-10 06:08:57 | [diff] [blame] | 204 | ASSERT_TRUE(it); |
| 205 | for (; !it->IsAtEnd(); it->Advance()) { |
[email protected] | 0731029 | 2013-08-19 10:55:41 | [diff] [blame] | 206 | const ResourceEntry& entry = it->GetValue(); |
| 207 | found_entries[it->GetID()] = entry; |
[email protected] | eb391ee | 2013-05-10 06:08:57 | [diff] [blame] | 208 | } |
| 209 | EXPECT_FALSE(it->HasError()); |
[email protected] | 8c191e5 | 2013-04-09 14:05:17 | [diff] [blame] | 210 | |
[email protected] | 0731029 | 2013-08-19 10:55:41 | [diff] [blame] | 211 | EXPECT_EQ(keys.size(), found_entries.size()); |
Lei Zhang | d359bae | 2017-11-29 18:25:57 | [diff] [blame] | 212 | for (const std::string& key : keys) |
Jan Wilken Dörrie | 45d34f4 | 2019-06-08 09:40:54 | [diff] [blame] | 213 | EXPECT_TRUE(base::Contains(found_entries, key)); |
[email protected] | 8c191e5 | 2013-04-09 14:05:17 | [diff] [blame] | 214 | } |
| 215 | |
[email protected] | da56f679 | 2013-10-17 04:01:46 | [diff] [blame] | 216 | TEST_F(ResourceMetadataStorageTest, GetIdByResourceId) { |
| 217 | const std::string local_id = "local_id"; |
| 218 | const std::string resource_id = "resource_id"; |
| 219 | |
| 220 | // Resource ID to local ID mapping is not stored yet. |
| 221 | std::string id; |
[email protected] | 99613941 | 2014-05-10 06:19:50 | [diff] [blame] | 222 | EXPECT_EQ(FILE_ERROR_NOT_FOUND, |
| 223 | storage_->GetIdByResourceId(resource_id, &id)); |
[email protected] | da56f679 | 2013-10-17 04:01:46 | [diff] [blame] | 224 | |
| 225 | // Put an entry with the resource ID. |
| 226 | ResourceEntry entry; |
| 227 | entry.set_local_id(local_id); |
| 228 | entry.set_resource_id(resource_id); |
[email protected] | 99613941 | 2014-05-10 06:19:50 | [diff] [blame] | 229 | EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry)); |
[email protected] | da56f679 | 2013-10-17 04:01:46 | [diff] [blame] | 230 | |
| 231 | // Can get local ID by resource ID. |
[email protected] | 99613941 | 2014-05-10 06:19:50 | [diff] [blame] | 232 | EXPECT_EQ(FILE_ERROR_OK, storage_->GetIdByResourceId(resource_id, &id)); |
[email protected] | da56f679 | 2013-10-17 04:01:46 | [diff] [blame] | 233 | EXPECT_EQ(local_id, id); |
| 234 | |
| 235 | // Resource ID to local ID mapping is removed. |
[email protected] | 99613941 | 2014-05-10 06:19:50 | [diff] [blame] | 236 | EXPECT_EQ(FILE_ERROR_OK, storage_->RemoveEntry(local_id)); |
| 237 | EXPECT_EQ(FILE_ERROR_NOT_FOUND, |
| 238 | storage_->GetIdByResourceId(resource_id, &id)); |
[email protected] | da56f679 | 2013-10-17 04:01:46 | [diff] [blame] | 239 | } |
| 240 | |
[email protected] | dd8e7fe | 2013-04-26 05:14:23 | [diff] [blame] | 241 | TEST_F(ResourceMetadataStorageTest, GetChildren) { |
[email protected] | 595867a | 2013-03-23 19:00:02 | [diff] [blame] | 242 | const std::string parents_id[] = { "mercury", "venus", "mars", "jupiter", |
| 243 | "saturn" }; |
Avi Drissman | 8171db7d | 2018-12-25 23:08:31 | [diff] [blame] | 244 | std::vector<base::StringPairs> children_name_id(base::size(parents_id)); |
[email protected] | 595867a | 2013-03-23 19:00:02 | [diff] [blame] | 245 | // Skip children_name_id[0/1] here because Mercury and Venus have no moon. |
| 246 | children_name_id[2].push_back(std::make_pair("phobos", "mars_i")); |
| 247 | children_name_id[2].push_back(std::make_pair("deimos", "mars_ii")); |
| 248 | children_name_id[3].push_back(std::make_pair("io", "jupiter_i")); |
| 249 | children_name_id[3].push_back(std::make_pair("europa", "jupiter_ii")); |
| 250 | children_name_id[3].push_back(std::make_pair("ganymede", "jupiter_iii")); |
| 251 | children_name_id[3].push_back(std::make_pair("calisto", "jupiter_iv")); |
| 252 | children_name_id[4].push_back(std::make_pair("mimas", "saturn_i")); |
| 253 | children_name_id[4].push_back(std::make_pair("enceladus", "saturn_ii")); |
| 254 | children_name_id[4].push_back(std::make_pair("tethys", "saturn_iii")); |
| 255 | children_name_id[4].push_back(std::make_pair("dione", "saturn_iv")); |
| 256 | children_name_id[4].push_back(std::make_pair("rhea", "saturn_v")); |
| 257 | children_name_id[4].push_back(std::make_pair("titan", "saturn_vi")); |
| 258 | children_name_id[4].push_back(std::make_pair("iapetus", "saturn_vii")); |
| 259 | |
[email protected] | c28c952d | 2013-04-24 11:41:57 | [diff] [blame] | 260 | // Put parents. |
Lei Zhang | d359bae | 2017-11-29 18:25:57 | [diff] [blame] | 261 | for (const std::string& id : parents_id) { |
[email protected] | d38aa40 | 2013-09-25 09:38:43 | [diff] [blame] | 262 | ResourceEntry entry; |
Lei Zhang | d359bae | 2017-11-29 18:25:57 | [diff] [blame] | 263 | entry.set_local_id(id); |
[email protected] | 99613941 | 2014-05-10 06:19:50 | [diff] [blame] | 264 | EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry)); |
[email protected] | d38aa40 | 2013-09-25 09:38:43 | [diff] [blame] | 265 | } |
[email protected] | c28c952d | 2013-04-24 11:41:57 | [diff] [blame] | 266 | |
[email protected] | 47505252 | 2013-06-19 08:30:37 | [diff] [blame] | 267 | // Put children. |
[email protected] | c28c952d | 2013-04-24 11:41:57 | [diff] [blame] | 268 | for (size_t i = 0; i < children_name_id.size(); ++i) { |
Lei Zhang | d359bae | 2017-11-29 18:25:57 | [diff] [blame] | 269 | for (const auto& id : children_name_id[i]) { |
[email protected] | 67241b83 | 2013-05-02 04:55:52 | [diff] [blame] | 270 | ResourceEntry entry; |
Lei Zhang | d359bae | 2017-11-29 18:25:57 | [diff] [blame] | 271 | entry.set_local_id(id.second); |
[email protected] | 943cb8b | 2013-08-21 03:17:08 | [diff] [blame] | 272 | entry.set_parent_local_id(parents_id[i]); |
Lei Zhang | d359bae | 2017-11-29 18:25:57 | [diff] [blame] | 273 | entry.set_base_name(id.first); |
[email protected] | 99613941 | 2014-05-10 06:19:50 | [diff] [blame] | 274 | EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry)); |
[email protected] | 595867a | 2013-03-23 19:00:02 | [diff] [blame] | 275 | } |
| 276 | } |
| 277 | |
| 278 | // Try to get children. |
[email protected] | c28c952d | 2013-04-24 11:41:57 | [diff] [blame] | 279 | for (size_t i = 0; i < children_name_id.size(); ++i) { |
[email protected] | 595867a | 2013-03-23 19:00:02 | [diff] [blame] | 280 | std::vector<std::string> children; |
| 281 | storage_->GetChildren(parents_id[i], &children); |
| 282 | EXPECT_EQ(children_name_id[i].size(), children.size()); |
Lei Zhang | d359bae | 2017-11-29 18:25:57 | [diff] [blame] | 283 | for (const auto& id : children_name_id[i]) { |
| 284 | EXPECT_EQ(1, std::count(children.begin(), children.end(), id.second)); |
[email protected] | 595867a | 2013-03-23 19:00:02 | [diff] [blame] | 285 | } |
| 286 | } |
| 287 | } |
| 288 | |
[email protected] | dd8e7fe | 2013-04-26 05:14:23 | [diff] [blame] | 289 | TEST_F(ResourceMetadataStorageTest, OpenExistingDB) { |
[email protected] | df3fef2 | 2013-03-21 12:20:41 | [diff] [blame] | 290 | const std::string parent_id1 = "abcdefg"; |
| 291 | const std::string child_name1 = "WXYZABC"; |
| 292 | const std::string child_id1 = "qwerty"; |
| 293 | |
[email protected] | 67241b83 | 2013-05-02 04:55:52 | [diff] [blame] | 294 | ResourceEntry entry1; |
[email protected] | d38aa40 | 2013-09-25 09:38:43 | [diff] [blame] | 295 | entry1.set_local_id(parent_id1); |
[email protected] | 67241b83 | 2013-05-02 04:55:52 | [diff] [blame] | 296 | ResourceEntry entry2; |
[email protected] | d38aa40 | 2013-09-25 09:38:43 | [diff] [blame] | 297 | entry2.set_local_id(child_id1); |
[email protected] | 943cb8b | 2013-08-21 03:17:08 | [diff] [blame] | 298 | entry2.set_parent_local_id(parent_id1); |
[email protected] | 74f678e | 2013-04-17 09:16:46 | [diff] [blame] | 299 | entry2.set_base_name(child_name1); |
[email protected] | df3fef2 | 2013-03-21 12:20:41 | [diff] [blame] | 300 | |
| 301 | // Put some data. |
[email protected] | 99613941 | 2014-05-10 06:19:50 | [diff] [blame] | 302 | EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry1)); |
| 303 | EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry2)); |
[email protected] | df3fef2 | 2013-03-21 12:20:41 | [diff] [blame] | 304 | |
| 305 | // Close DB and reopen. |
[email protected] | be427d7 | 2013-06-21 07:09:27 | [diff] [blame] | 306 | storage_.reset(new ResourceMetadataStorage( |
vabr | 96fd0c0f | 2016-09-13 14:21:31 | [diff] [blame] | 307 | temp_dir_.GetPath(), base::ThreadTaskRunnerHandle::Get().get())); |
[email protected] | df3fef2 | 2013-03-21 12:20:41 | [diff] [blame] | 308 | ASSERT_TRUE(storage_->Initialize()); |
| 309 | |
| 310 | // Can read data. |
[email protected] | fff7277 | 2013-06-19 05:09:41 | [diff] [blame] | 311 | ResourceEntry result; |
[email protected] | 99613941 | 2014-05-10 06:19:50 | [diff] [blame] | 312 | EXPECT_EQ(FILE_ERROR_OK, storage_->GetEntry(parent_id1, &result)); |
[email protected] | 74f678e | 2013-04-17 09:16:46 | [diff] [blame] | 313 | |
[email protected] | 99613941 | 2014-05-10 06:19:50 | [diff] [blame] | 314 | EXPECT_EQ(FILE_ERROR_OK, storage_->GetEntry(child_id1, &result)); |
[email protected] | 943cb8b | 2013-08-21 03:17:08 | [diff] [blame] | 315 | EXPECT_EQ(parent_id1, result.parent_local_id()); |
[email protected] | fff7277 | 2013-06-19 05:09:41 | [diff] [blame] | 316 | EXPECT_EQ(child_name1, result.base_name()); |
[email protected] | 74f678e | 2013-04-17 09:16:46 | [diff] [blame] | 317 | |
[email protected] | 99613941 | 2014-05-10 06:19:50 | [diff] [blame] | 318 | std::string child_id; |
| 319 | EXPECT_EQ(FILE_ERROR_OK, |
| 320 | storage_->GetChild(parent_id1, child_name1, &child_id)); |
| 321 | EXPECT_EQ(child_id1, child_id); |
[email protected] | df3fef2 | 2013-03-21 12:20:41 | [diff] [blame] | 322 | } |
| 323 | |
[email protected] | 12a024ec | 2013-10-24 04:00:05 | [diff] [blame] | 324 | TEST_F(ResourceMetadataStorageTest, IncompatibleDB_M29) { |
avi | bc5337b | 2015-12-25 23:16:33 | [diff] [blame] | 325 | const int64_t kLargestChangestamp = 1234567890; |
[email protected] | 3d6a825 | 2014-05-29 20:42:09 | [diff] [blame] | 326 | const std::string title = "title"; |
[email protected] | df3fef2 | 2013-03-21 12:20:41 | [diff] [blame] | 327 | |
[email protected] | 12a024ec | 2013-10-24 04:00:05 | [diff] [blame] | 328 | // Construct M29 version DB. |
| 329 | SetDBVersion(6); |
[email protected] | 99613941 | 2014-05-10 06:19:50 | [diff] [blame] | 330 | EXPECT_EQ(FILE_ERROR_OK, |
| 331 | storage_->SetLargestChangestamp(kLargestChangestamp)); |
[email protected] | df3fef2 | 2013-03-21 12:20:41 | [diff] [blame] | 332 | |
[email protected] | 12a024ec | 2013-10-24 04:00:05 | [diff] [blame] | 333 | leveldb::WriteBatch batch; |
| 334 | |
| 335 | // Put a file entry and its cache entry. |
| 336 | ResourceEntry entry; |
| 337 | std::string serialized_entry; |
[email protected] | 3d6a825 | 2014-05-29 20:42:09 | [diff] [blame] | 338 | entry.set_title(title); |
[email protected] | 12a024ec | 2013-10-24 04:00:05 | [diff] [blame] | 339 | entry.set_resource_id("file:abcd"); |
| 340 | EXPECT_TRUE(entry.SerializeToString(&serialized_entry)); |
| 341 | batch.Put("file:abcd", serialized_entry); |
| 342 | |
| 343 | FileCacheEntry cache_entry; |
| 344 | EXPECT_TRUE(cache_entry.SerializeToString(&serialized_entry)); |
| 345 | batch.Put(std::string("file:abcd") + '\0' + "CACHE", serialized_entry); |
| 346 | |
| 347 | EXPECT_TRUE(resource_map()->Write(leveldb::WriteOptions(), &batch).ok()); |
| 348 | |
| 349 | // Upgrade and reopen. |
| 350 | storage_.reset(); |
Lei Zhang | d359bae | 2017-11-29 18:25:57 | [diff] [blame] | 351 | EXPECT_TRUE(UpgradeOldDB()); |
[email protected] | be427d7 | 2013-06-21 07:09:27 | [diff] [blame] | 352 | storage_.reset(new ResourceMetadataStorage( |
vabr | 96fd0c0f | 2016-09-13 14:21:31 | [diff] [blame] | 353 | temp_dir_.GetPath(), base::ThreadTaskRunnerHandle::Get().get())); |
[email protected] | df3fef2 | 2013-03-21 12:20:41 | [diff] [blame] | 354 | ASSERT_TRUE(storage_->Initialize()); |
| 355 | |
[email protected] | 12a024ec | 2013-10-24 04:00:05 | [diff] [blame] | 356 | // Resource-ID-to-local-ID mapping is added. |
| 357 | std::string id; |
[email protected] | 99613941 | 2014-05-10 06:19:50 | [diff] [blame] | 358 | EXPECT_EQ(FILE_ERROR_OK, |
| 359 | storage_->GetIdByResourceId("abcd", &id)); // "file:" is dropped. |
[email protected] | 12a024ec | 2013-10-24 04:00:05 | [diff] [blame] | 360 | |
| 361 | // Data is erased, except cache entries. |
avi | bc5337b | 2015-12-25 23:16:33 | [diff] [blame] | 362 | int64_t largest_changestamp = 0; |
[email protected] | 99613941 | 2014-05-10 06:19:50 | [diff] [blame] | 363 | EXPECT_EQ(FILE_ERROR_OK, |
| 364 | storage_->GetLargestChangestamp(&largest_changestamp)); |
| 365 | EXPECT_EQ(0, largest_changestamp); |
[email protected] | 3d6a825 | 2014-05-29 20:42:09 | [diff] [blame] | 366 | EXPECT_EQ(FILE_ERROR_OK, storage_->GetEntry(id, &entry)); |
| 367 | EXPECT_TRUE(entry.title().empty()); |
| 368 | EXPECT_TRUE(entry.file_specific_info().has_cache_state()); |
[email protected] | fba850ff | 2013-09-19 08:08:53 | [diff] [blame] | 369 | } |
| 370 | |
[email protected] | b0b3dbd | 2013-12-05 11:09:52 | [diff] [blame] | 371 | TEST_F(ResourceMetadataStorageTest, IncompatibleDB_M32) { |
avi | bc5337b | 2015-12-25 23:16:33 | [diff] [blame] | 372 | const int64_t kLargestChangestamp = 1234567890; |
[email protected] | 3d6a825 | 2014-05-29 20:42:09 | [diff] [blame] | 373 | const std::string title = "title"; |
[email protected] | b0b3dbd | 2013-12-05 11:09:52 | [diff] [blame] | 374 | const std::string resource_id = "abcd"; |
| 375 | const std::string local_id = "local-abcd"; |
| 376 | |
| 377 | // Construct M32 version DB. |
| 378 | SetDBVersion(11); |
[email protected] | 99613941 | 2014-05-10 06:19:50 | [diff] [blame] | 379 | EXPECT_EQ(FILE_ERROR_OK, |
| 380 | storage_->SetLargestChangestamp(kLargestChangestamp)); |
[email protected] | b0b3dbd | 2013-12-05 11:09:52 | [diff] [blame] | 381 | |
| 382 | leveldb::WriteBatch batch; |
| 383 | |
| 384 | // Put a file entry and its cache and id entry. |
| 385 | ResourceEntry entry; |
| 386 | std::string serialized_entry; |
[email protected] | 3d6a825 | 2014-05-29 20:42:09 | [diff] [blame] | 387 | entry.set_title(title); |
| 388 | entry.set_local_id(local_id); |
[email protected] | b0b3dbd | 2013-12-05 11:09:52 | [diff] [blame] | 389 | entry.set_resource_id(resource_id); |
| 390 | EXPECT_TRUE(entry.SerializeToString(&serialized_entry)); |
| 391 | batch.Put(local_id, serialized_entry); |
| 392 | |
| 393 | FileCacheEntry cache_entry; |
| 394 | EXPECT_TRUE(cache_entry.SerializeToString(&serialized_entry)); |
| 395 | batch.Put(local_id + '\0' + "CACHE", serialized_entry); |
| 396 | |
| 397 | batch.Put('\0' + std::string("ID") + '\0' + resource_id, local_id); |
| 398 | |
| 399 | EXPECT_TRUE(resource_map()->Write(leveldb::WriteOptions(), &batch).ok()); |
| 400 | |
| 401 | // Upgrade and reopen. |
| 402 | storage_.reset(); |
Lei Zhang | d359bae | 2017-11-29 18:25:57 | [diff] [blame] | 403 | EXPECT_TRUE(UpgradeOldDB()); |
[email protected] | b0b3dbd | 2013-12-05 11:09:52 | [diff] [blame] | 404 | storage_.reset(new ResourceMetadataStorage( |
vabr | 96fd0c0f | 2016-09-13 14:21:31 | [diff] [blame] | 405 | temp_dir_.GetPath(), base::ThreadTaskRunnerHandle::Get().get())); |
[email protected] | b0b3dbd | 2013-12-05 11:09:52 | [diff] [blame] | 406 | ASSERT_TRUE(storage_->Initialize()); |
| 407 | |
| 408 | // Data is erased, except cache and id mapping entries. |
| 409 | std::string id; |
[email protected] | 99613941 | 2014-05-10 06:19:50 | [diff] [blame] | 410 | EXPECT_EQ(FILE_ERROR_OK, storage_->GetIdByResourceId(resource_id, &id)); |
[email protected] | b0b3dbd | 2013-12-05 11:09:52 | [diff] [blame] | 411 | EXPECT_EQ(local_id, id); |
avi | bc5337b | 2015-12-25 23:16:33 | [diff] [blame] | 412 | int64_t largest_changestamp = 0; |
[email protected] | 99613941 | 2014-05-10 06:19:50 | [diff] [blame] | 413 | EXPECT_EQ(FILE_ERROR_OK, |
| 414 | storage_->GetLargestChangestamp(&largest_changestamp)); |
| 415 | EXPECT_EQ(0, largest_changestamp); |
[email protected] | 3d6a825 | 2014-05-29 20:42:09 | [diff] [blame] | 416 | EXPECT_EQ(FILE_ERROR_OK, storage_->GetEntry(id, &entry)); |
| 417 | EXPECT_TRUE(entry.title().empty()); |
| 418 | EXPECT_TRUE(entry.file_specific_info().has_cache_state()); |
| 419 | } |
| 420 | |
| 421 | TEST_F(ResourceMetadataStorageTest, IncompatibleDB_M33) { |
avi | bc5337b | 2015-12-25 23:16:33 | [diff] [blame] | 422 | const int64_t kLargestChangestamp = 1234567890; |
[email protected] | 3d6a825 | 2014-05-29 20:42:09 | [diff] [blame] | 423 | const std::string title = "title"; |
| 424 | const std::string resource_id = "abcd"; |
| 425 | const std::string local_id = "local-abcd"; |
| 426 | const std::string md5 = "md5"; |
| 427 | const std::string resource_id2 = "efgh"; |
| 428 | const std::string local_id2 = "local-efgh"; |
| 429 | const std::string md5_2 = "md5_2"; |
| 430 | |
| 431 | // Construct M33 version DB. |
| 432 | SetDBVersion(12); |
| 433 | EXPECT_EQ(FILE_ERROR_OK, |
| 434 | storage_->SetLargestChangestamp(kLargestChangestamp)); |
| 435 | |
| 436 | leveldb::WriteBatch batch; |
| 437 | |
| 438 | // Put a file entry and its cache and id entry. |
| 439 | ResourceEntry entry; |
| 440 | std::string serialized_entry; |
| 441 | entry.set_title(title); |
| 442 | entry.set_local_id(local_id); |
| 443 | entry.set_resource_id(resource_id); |
| 444 | EXPECT_TRUE(entry.SerializeToString(&serialized_entry)); |
| 445 | batch.Put(local_id, serialized_entry); |
| 446 | |
| 447 | FileCacheEntry cache_entry; |
| 448 | cache_entry.set_md5(md5); |
| 449 | EXPECT_TRUE(cache_entry.SerializeToString(&serialized_entry)); |
| 450 | batch.Put(local_id + '\0' + "CACHE", serialized_entry); |
| 451 | |
| 452 | batch.Put('\0' + std::string("ID") + '\0' + resource_id, local_id); |
| 453 | |
| 454 | // Put another cache entry which is not accompanied by a ResourceEntry. |
| 455 | cache_entry.set_md5(md5_2); |
| 456 | EXPECT_TRUE(cache_entry.SerializeToString(&serialized_entry)); |
| 457 | batch.Put(local_id2 + '\0' + "CACHE", serialized_entry); |
| 458 | batch.Put('\0' + std::string("ID") + '\0' + resource_id2, local_id2); |
| 459 | |
| 460 | EXPECT_TRUE(resource_map()->Write(leveldb::WriteOptions(), &batch).ok()); |
| 461 | |
| 462 | // Upgrade and reopen. |
| 463 | storage_.reset(); |
Lei Zhang | d359bae | 2017-11-29 18:25:57 | [diff] [blame] | 464 | EXPECT_TRUE(UpgradeOldDB()); |
[email protected] | 3d6a825 | 2014-05-29 20:42:09 | [diff] [blame] | 465 | storage_.reset(new ResourceMetadataStorage( |
vabr | 96fd0c0f | 2016-09-13 14:21:31 | [diff] [blame] | 466 | temp_dir_.GetPath(), base::ThreadTaskRunnerHandle::Get().get())); |
[email protected] | 3d6a825 | 2014-05-29 20:42:09 | [diff] [blame] | 467 | ASSERT_TRUE(storage_->Initialize()); |
| 468 | |
Shuhei Takahashi | 87ce7f5 | 2017-09-05 05:15:41 | [diff] [blame] | 469 | // largest_changestamp is cleared. |
avi | bc5337b | 2015-12-25 23:16:33 | [diff] [blame] | 470 | int64_t largest_changestamp = 0; |
[email protected] | 3d6a825 | 2014-05-29 20:42:09 | [diff] [blame] | 471 | EXPECT_EQ(FILE_ERROR_OK, |
| 472 | storage_->GetLargestChangestamp(&largest_changestamp)); |
Shuhei Takahashi | 87ce7f5 | 2017-09-05 05:15:41 | [diff] [blame] | 473 | EXPECT_EQ(0, largest_changestamp); |
[email protected] | 3d6a825 | 2014-05-29 20:42:09 | [diff] [blame] | 474 | |
Shuhei Takahashi | 87ce7f5 | 2017-09-05 05:15:41 | [diff] [blame] | 475 | // No other data is lost. |
[email protected] | 3d6a825 | 2014-05-29 20:42:09 | [diff] [blame] | 476 | std::string id; |
| 477 | EXPECT_EQ(FILE_ERROR_OK, storage_->GetIdByResourceId(resource_id, &id)); |
| 478 | EXPECT_EQ(local_id, id); |
| 479 | EXPECT_EQ(FILE_ERROR_OK, storage_->GetEntry(id, &entry)); |
| 480 | EXPECT_EQ(title, entry.title()); |
| 481 | EXPECT_EQ(md5, entry.file_specific_info().cache_state().md5()); |
| 482 | |
| 483 | EXPECT_EQ(FILE_ERROR_OK, storage_->GetIdByResourceId(resource_id2, &id)); |
| 484 | EXPECT_EQ(local_id2, id); |
| 485 | EXPECT_EQ(FILE_ERROR_OK, storage_->GetEntry(id, &entry)); |
| 486 | EXPECT_EQ(md5_2, entry.file_specific_info().cache_state().md5()); |
[email protected] | b0b3dbd | 2013-12-05 11:09:52 | [diff] [blame] | 487 | } |
| 488 | |
[email protected] | fba850ff | 2013-09-19 08:08:53 | [diff] [blame] | 489 | TEST_F(ResourceMetadataStorageTest, IncompatibleDB_Unknown) { |
avi | bc5337b | 2015-12-25 23:16:33 | [diff] [blame] | 490 | const int64_t kLargestChangestamp = 1234567890; |
[email protected] | fba850ff | 2013-09-19 08:08:53 | [diff] [blame] | 491 | const std::string key1 = "abcd"; |
| 492 | |
| 493 | // Put some data. |
[email protected] | 99613941 | 2014-05-10 06:19:50 | [diff] [blame] | 494 | EXPECT_EQ(FILE_ERROR_OK, |
| 495 | storage_->SetLargestChangestamp(kLargestChangestamp)); |
[email protected] | fba850ff | 2013-09-19 08:08:53 | [diff] [blame] | 496 | ResourceEntry entry; |
[email protected] | d38aa40 | 2013-09-25 09:38:43 | [diff] [blame] | 497 | entry.set_local_id(key1); |
[email protected] | 99613941 | 2014-05-10 06:19:50 | [diff] [blame] | 498 | EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry)); |
[email protected] | fba850ff | 2013-09-19 08:08:53 | [diff] [blame] | 499 | |
[email protected] | 12a024ec | 2013-10-24 04:00:05 | [diff] [blame] | 500 | // Set newer version, upgrade and reopen DB. |
[email protected] | fba850ff | 2013-09-19 08:08:53 | [diff] [blame] | 501 | SetDBVersion(ResourceMetadataStorage::kDBVersion + 1); |
[email protected] | 12a024ec | 2013-10-24 04:00:05 | [diff] [blame] | 502 | storage_.reset(); |
Lei Zhang | d359bae | 2017-11-29 18:25:57 | [diff] [blame] | 503 | EXPECT_FALSE(UpgradeOldDB()); |
[email protected] | fba850ff | 2013-09-19 08:08:53 | [diff] [blame] | 504 | storage_.reset(new ResourceMetadataStorage( |
vabr | 96fd0c0f | 2016-09-13 14:21:31 | [diff] [blame] | 505 | temp_dir_.GetPath(), base::ThreadTaskRunnerHandle::Get().get())); |
[email protected] | fba850ff | 2013-09-19 08:08:53 | [diff] [blame] | 506 | ASSERT_TRUE(storage_->Initialize()); |
| 507 | |
[email protected] | df3fef2 | 2013-03-21 12:20:41 | [diff] [blame] | 508 | // Data is erased because of the incompatible version. |
avi | bc5337b | 2015-12-25 23:16:33 | [diff] [blame] | 509 | int64_t largest_changestamp = 0; |
[email protected] | 99613941 | 2014-05-10 06:19:50 | [diff] [blame] | 510 | EXPECT_EQ(FILE_ERROR_OK, |
| 511 | storage_->GetLargestChangestamp(&largest_changestamp)); |
| 512 | EXPECT_EQ(0, largest_changestamp); |
| 513 | EXPECT_EQ(FILE_ERROR_NOT_FOUND, storage_->GetEntry(key1, &entry)); |
[email protected] | df3fef2 | 2013-03-21 12:20:41 | [diff] [blame] | 514 | } |
| 515 | |
Shuhei Takahashi | 87ce7f5 | 2017-09-05 05:15:41 | [diff] [blame] | 516 | TEST_F(ResourceMetadataStorageTest, IncompatibleDB_M37) { |
| 517 | const int64_t kLargestChangestamp = 1234567890; |
| 518 | |
| 519 | // Construct v13 DB. It was used from M37 to M62. |
| 520 | SetDBVersion(13); |
| 521 | EXPECT_EQ(FILE_ERROR_OK, |
| 522 | storage_->SetLargestChangestamp(kLargestChangestamp)); |
| 523 | |
[email protected] | 0fd5869 | 2014-05-23 11:40:04 | [diff] [blame] | 524 | leveldb::WriteBatch batch; |
| 525 | |
| 526 | // Put an ID entry with a corresponding ResourceEntry. |
| 527 | ResourceEntry entry; |
| 528 | entry.set_local_id("id1"); |
| 529 | entry.set_resource_id("resource_id1"); |
| 530 | |
| 531 | std::string serialized_entry; |
| 532 | EXPECT_TRUE(entry.SerializeToString(&serialized_entry)); |
| 533 | batch.Put("id1", serialized_entry); |
| 534 | batch.Put('\0' + std::string("ID") + '\0' + "resource_id1", "id1"); |
| 535 | |
[email protected] | 0fd5869 | 2014-05-23 11:40:04 | [diff] [blame] | 536 | // Put an ID entry without any corresponding entries. |
[email protected] | 3d6a825 | 2014-05-29 20:42:09 | [diff] [blame] | 537 | batch.Put('\0' + std::string("ID") + '\0' + "resource_id2", "id3"); |
[email protected] | 0fd5869 | 2014-05-23 11:40:04 | [diff] [blame] | 538 | |
| 539 | EXPECT_TRUE(resource_map()->Write(leveldb::WriteOptions(), &batch).ok()); |
| 540 | |
| 541 | // Upgrade and reopen. |
| 542 | storage_.reset(); |
Lei Zhang | d359bae | 2017-11-29 18:25:57 | [diff] [blame] | 543 | EXPECT_TRUE(UpgradeOldDB()); |
[email protected] | 0fd5869 | 2014-05-23 11:40:04 | [diff] [blame] | 544 | storage_.reset(new ResourceMetadataStorage( |
vabr | 96fd0c0f | 2016-09-13 14:21:31 | [diff] [blame] | 545 | temp_dir_.GetPath(), base::ThreadTaskRunnerHandle::Get().get())); |
[email protected] | 0fd5869 | 2014-05-23 11:40:04 | [diff] [blame] | 546 | ASSERT_TRUE(storage_->Initialize()); |
| 547 | |
| 548 | // Only the unused entry is deleted. |
| 549 | std::string id; |
| 550 | EXPECT_EQ(FILE_ERROR_OK, storage_->GetIdByResourceId("resource_id1", &id)); |
| 551 | EXPECT_EQ("id1", id); |
[email protected] | 0fd5869 | 2014-05-23 11:40:04 | [diff] [blame] | 552 | EXPECT_EQ(FILE_ERROR_NOT_FOUND, |
[email protected] | 3d6a825 | 2014-05-29 20:42:09 | [diff] [blame] | 553 | storage_->GetIdByResourceId("resource_id2", &id)); |
Shuhei Takahashi | 87ce7f5 | 2017-09-05 05:15:41 | [diff] [blame] | 554 | |
| 555 | // largest_changestamp is cleared. |
| 556 | int64_t largest_changestamp = 0; |
| 557 | EXPECT_EQ(FILE_ERROR_OK, |
| 558 | storage_->GetLargestChangestamp(&largest_changestamp)); |
| 559 | EXPECT_EQ(0, largest_changestamp); |
[email protected] | 0fd5869 | 2014-05-23 11:40:04 | [diff] [blame] | 560 | } |
| 561 | |
[email protected] | dd8e7fe | 2013-04-26 05:14:23 | [diff] [blame] | 562 | TEST_F(ResourceMetadataStorageTest, WrongPath) { |
[email protected] | df3fef2 | 2013-03-21 12:20:41 | [diff] [blame] | 563 | // Create a file. |
| 564 | base::FilePath path; |
vabr | 96fd0c0f | 2016-09-13 14:21:31 | [diff] [blame] | 565 | ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.GetPath(), &path)); |
[email protected] | df3fef2 | 2013-03-21 12:20:41 | [diff] [blame] | 566 | |
[email protected] | be427d7 | 2013-06-21 07:09:27 | [diff] [blame] | 567 | storage_.reset(new ResourceMetadataStorage( |
pranay.kumar | 229290b5 | 2015-05-14 05:21:04 | [diff] [blame] | 568 | path, base::ThreadTaskRunnerHandle::Get().get())); |
[email protected] | df3fef2 | 2013-03-21 12:20:41 | [diff] [blame] | 569 | // Cannot initialize DB beacause the path does not point a directory. |
| 570 | ASSERT_FALSE(storage_->Initialize()); |
| 571 | } |
| 572 | |
[email protected] | 760abc3 | 2013-11-01 05:13:01 | [diff] [blame] | 573 | TEST_F(ResourceMetadataStorageTest, RecoverCacheEntriesFromTrashedResourceMap) { |
[email protected] | 760abc3 | 2013-11-01 05:13:01 | [diff] [blame] | 574 | // Put entry with id_foo. |
| 575 | ResourceEntry entry; |
| 576 | entry.set_local_id("id_foo"); |
| 577 | entry.set_base_name("foo"); |
[email protected] | 026d4a52 | 2013-11-05 14:22:18 | [diff] [blame] | 578 | entry.set_title("foo"); |
[email protected] | cd8fd37f | 2014-05-20 15:45:21 | [diff] [blame] | 579 | entry.mutable_file_specific_info()->mutable_cache_state()->set_md5("md5_foo"); |
[email protected] | 99613941 | 2014-05-10 06:19:50 | [diff] [blame] | 580 | EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry)); |
[email protected] | 760abc3 | 2013-11-01 05:13:01 | [diff] [blame] | 581 | |
| 582 | // Put entry with id_bar as a id_foo's child. |
| 583 | entry.set_local_id("id_bar"); |
| 584 | entry.set_parent_local_id("id_foo"); |
| 585 | entry.set_base_name("bar"); |
[email protected] | 026d4a52 | 2013-11-05 14:22:18 | [diff] [blame] | 586 | entry.set_title("bar"); |
[email protected] | cd8fd37f | 2014-05-20 15:45:21 | [diff] [blame] | 587 | entry.mutable_file_specific_info()->mutable_cache_state()->set_md5("md5_bar"); |
| 588 | entry.mutable_file_specific_info()->mutable_cache_state()->set_is_dirty(true); |
[email protected] | 99613941 | 2014-05-10 06:19:50 | [diff] [blame] | 589 | EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry)); |
[email protected] | 760abc3 | 2013-11-01 05:13:01 | [diff] [blame] | 590 | |
| 591 | // Remove parent-child relationship to make the DB invalid. |
| 592 | RemoveChild("id_foo", "bar"); |
| 593 | EXPECT_FALSE(CheckValidity()); |
| 594 | |
| 595 | // Reopen. This should result in trashing the DB. |
| 596 | storage_.reset(new ResourceMetadataStorage( |
vabr | 96fd0c0f | 2016-09-13 14:21:31 | [diff] [blame] | 597 | temp_dir_.GetPath(), base::ThreadTaskRunnerHandle::Get().get())); |
[email protected] | 760abc3 | 2013-11-01 05:13:01 | [diff] [blame] | 598 | ASSERT_TRUE(storage_->Initialize()); |
| 599 | |
| 600 | // Recover cache entries from the trashed DB. |
[email protected] | 026d4a52 | 2013-11-05 14:22:18 | [diff] [blame] | 601 | ResourceMetadataStorage::RecoveredCacheInfoMap recovered_cache_info; |
| 602 | storage_->RecoverCacheInfoFromTrashedResourceMap(&recovered_cache_info); |
| 603 | EXPECT_EQ(2U, recovered_cache_info.size()); |
| 604 | EXPECT_FALSE(recovered_cache_info["id_foo"].is_dirty); |
| 605 | EXPECT_EQ("md5_foo", recovered_cache_info["id_foo"].md5); |
| 606 | EXPECT_EQ("foo", recovered_cache_info["id_foo"].title); |
| 607 | EXPECT_TRUE(recovered_cache_info["id_bar"].is_dirty); |
| 608 | EXPECT_EQ("md5_bar", recovered_cache_info["id_bar"].md5); |
| 609 | EXPECT_EQ("bar", recovered_cache_info["id_bar"].title); |
[email protected] | 760abc3 | 2013-11-01 05:13:01 | [diff] [blame] | 610 | } |
| 611 | |
[email protected] | dd8e7fe | 2013-04-26 05:14:23 | [diff] [blame] | 612 | TEST_F(ResourceMetadataStorageTest, CheckValidity) { |
[email protected] | 74f678e | 2013-04-17 09:16:46 | [diff] [blame] | 613 | const std::string key1 = "foo"; |
| 614 | const std::string name1 = "hoge"; |
| 615 | const std::string key2 = "bar"; |
| 616 | const std::string name2 = "fuga"; |
| 617 | const std::string key3 = "boo"; |
| 618 | const std::string name3 = "piyo"; |
| 619 | |
[email protected] | 5bd7f7a | 2013-04-18 05:52:40 | [diff] [blame] | 620 | // Empty storage is valid. |
| 621 | EXPECT_TRUE(CheckValidity()); |
| 622 | |
[email protected] | 74f678e | 2013-04-17 09:16:46 | [diff] [blame] | 623 | // Put entry with key1. |
[email protected] | 67241b83 | 2013-05-02 04:55:52 | [diff] [blame] | 624 | ResourceEntry entry; |
[email protected] | d38aa40 | 2013-09-25 09:38:43 | [diff] [blame] | 625 | entry.set_local_id(key1); |
[email protected] | 74f678e | 2013-04-17 09:16:46 | [diff] [blame] | 626 | entry.set_base_name(name1); |
[email protected] | 99613941 | 2014-05-10 06:19:50 | [diff] [blame] | 627 | EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry)); |
[email protected] | 74f678e | 2013-04-17 09:16:46 | [diff] [blame] | 628 | EXPECT_TRUE(CheckValidity()); |
| 629 | |
| 630 | // Put entry with key2 under key1. |
[email protected] | d38aa40 | 2013-09-25 09:38:43 | [diff] [blame] | 631 | entry.set_local_id(key2); |
[email protected] | 943cb8b | 2013-08-21 03:17:08 | [diff] [blame] | 632 | entry.set_parent_local_id(key1); |
[email protected] | 74f678e | 2013-04-17 09:16:46 | [diff] [blame] | 633 | entry.set_base_name(name2); |
[email protected] | 99613941 | 2014-05-10 06:19:50 | [diff] [blame] | 634 | EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry)); |
[email protected] | c28c952d | 2013-04-24 11:41:57 | [diff] [blame] | 635 | EXPECT_TRUE(CheckValidity()); |
| 636 | |
| 637 | RemoveChild(key1, name2); |
[email protected] | 74f678e | 2013-04-17 09:16:46 | [diff] [blame] | 638 | EXPECT_FALSE(CheckValidity()); // Missing parent-child relationship. |
| 639 | |
[email protected] | c28c952d | 2013-04-24 11:41:57 | [diff] [blame] | 640 | // Add back parent-child relationship between key1 and key2. |
| 641 | PutChild(key1, name2, key2); |
[email protected] | 74f678e | 2013-04-17 09:16:46 | [diff] [blame] | 642 | EXPECT_TRUE(CheckValidity()); |
| 643 | |
[email protected] | 5bd7f7a | 2013-04-18 05:52:40 | [diff] [blame] | 644 | // Add parent-child relationship between key2 and key3. |
[email protected] | c28c952d | 2013-04-24 11:41:57 | [diff] [blame] | 645 | PutChild(key2, name3, key3); |
[email protected] | 74f678e | 2013-04-17 09:16:46 | [diff] [blame] | 646 | EXPECT_FALSE(CheckValidity()); // key3 is not stored in the storage. |
| 647 | |
[email protected] | 5bd7f7a | 2013-04-18 05:52:40 | [diff] [blame] | 648 | // Put entry with key3 under key2. |
[email protected] | d38aa40 | 2013-09-25 09:38:43 | [diff] [blame] | 649 | entry.set_local_id(key3); |
[email protected] | 943cb8b | 2013-08-21 03:17:08 | [diff] [blame] | 650 | entry.set_parent_local_id(key2); |
[email protected] | 74f678e | 2013-04-17 09:16:46 | [diff] [blame] | 651 | entry.set_base_name(name3); |
[email protected] | 99613941 | 2014-05-10 06:19:50 | [diff] [blame] | 652 | EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry)); |
[email protected] | 74f678e | 2013-04-17 09:16:46 | [diff] [blame] | 653 | EXPECT_TRUE(CheckValidity()); |
| 654 | |
| 655 | // Parent-child relationship with wrong name. |
[email protected] | c28c952d | 2013-04-24 11:41:57 | [diff] [blame] | 656 | RemoveChild(key2, name3); |
[email protected] | 74f678e | 2013-04-17 09:16:46 | [diff] [blame] | 657 | EXPECT_FALSE(CheckValidity()); |
[email protected] | c28c952d | 2013-04-24 11:41:57 | [diff] [blame] | 658 | PutChild(key2, name2, key3); |
[email protected] | 5bd7f7a | 2013-04-18 05:52:40 | [diff] [blame] | 659 | EXPECT_FALSE(CheckValidity()); |
| 660 | |
| 661 | // Fix up the relationship between key2 and key3. |
[email protected] | c28c952d | 2013-04-24 11:41:57 | [diff] [blame] | 662 | RemoveChild(key2, name2); |
[email protected] | 5bd7f7a | 2013-04-18 05:52:40 | [diff] [blame] | 663 | EXPECT_FALSE(CheckValidity()); |
[email protected] | c28c952d | 2013-04-24 11:41:57 | [diff] [blame] | 664 | PutChild(key2, name3, key3); |
[email protected] | 5bd7f7a | 2013-04-18 05:52:40 | [diff] [blame] | 665 | EXPECT_TRUE(CheckValidity()); |
| 666 | |
| 667 | // Remove key2. |
[email protected] | c28c952d | 2013-04-24 11:41:57 | [diff] [blame] | 668 | RemoveChild(key1, name2); |
[email protected] | 5bd7f7a | 2013-04-18 05:52:40 | [diff] [blame] | 669 | EXPECT_FALSE(CheckValidity()); |
[email protected] | 99613941 | 2014-05-10 06:19:50 | [diff] [blame] | 670 | EXPECT_EQ(FILE_ERROR_OK, storage_->RemoveEntry(key2)); |
[email protected] | 5bd7f7a | 2013-04-18 05:52:40 | [diff] [blame] | 671 | EXPECT_FALSE(CheckValidity()); |
| 672 | |
| 673 | // Remove key3. |
[email protected] | c28c952d | 2013-04-24 11:41:57 | [diff] [blame] | 674 | RemoveChild(key2, name3); |
[email protected] | 5bd7f7a | 2013-04-18 05:52:40 | [diff] [blame] | 675 | EXPECT_FALSE(CheckValidity()); |
[email protected] | 99613941 | 2014-05-10 06:19:50 | [diff] [blame] | 676 | EXPECT_EQ(FILE_ERROR_OK, storage_->RemoveEntry(key3)); |
[email protected] | 5bd7f7a | 2013-04-18 05:52:40 | [diff] [blame] | 677 | EXPECT_TRUE(CheckValidity()); |
| 678 | |
| 679 | // Remove key1. |
[email protected] | 99613941 | 2014-05-10 06:19:50 | [diff] [blame] | 680 | EXPECT_EQ(FILE_ERROR_OK, storage_->RemoveEntry(key1)); |
[email protected] | 5bd7f7a | 2013-04-18 05:52:40 | [diff] [blame] | 681 | EXPECT_TRUE(CheckValidity()); |
[email protected] | 74f678e | 2013-04-17 09:16:46 | [diff] [blame] | 682 | } |
| 683 | |
Sasha Morrissey | 7ae517a | 2018-05-18 04:14:22 | [diff] [blame] | 684 | TEST_F(ResourceMetadataStorageTest, UpgradeDBv15) { |
Stuart Langley | 8e3f682 | 2018-05-09 11:18:18 | [diff] [blame] | 685 | constexpr int64_t kLargestChangestamp = 54321; |
| 686 | constexpr char kStartPageToken[] = "54322"; |
| 687 | constexpr int64_t kDirectoryChangestamp = 12345; |
| 688 | constexpr char kDirectoryStartpageToken[] = "12346"; |
| 689 | |
| 690 | // Construct a v15 DB |
| 691 | SetDBVersion(15); |
| 692 | EXPECT_EQ(FILE_ERROR_OK, |
| 693 | storage_->SetLargestChangestamp(kLargestChangestamp)); |
| 694 | |
| 695 | // Add a directory with a changestamp |
| 696 | ResourceEntry entry; |
| 697 | entry.set_local_id("local_id_1"); |
| 698 | entry.set_base_name("resource_id_1"); |
| 699 | entry.mutable_directory_specific_info()->set_changestamp( |
| 700 | kDirectoryChangestamp); |
| 701 | EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry)); |
| 702 | |
| 703 | // Upgrade and reopen |
| 704 | storage_.reset(); |
| 705 | EXPECT_TRUE(UpgradeOldDB()); |
| 706 | storage_.reset(new ResourceMetadataStorage( |
| 707 | temp_dir_.GetPath(), base::ThreadTaskRunnerHandle::Get().get())); |
| 708 | ASSERT_TRUE(storage_->Initialize()); |
| 709 | |
| 710 | int64_t largest_changestamp = 0; |
| 711 | EXPECT_EQ(FILE_ERROR_OK, |
| 712 | storage_->GetLargestChangestamp(&largest_changestamp)); |
| 713 | EXPECT_EQ(kLargestChangestamp, largest_changestamp); |
| 714 | |
| 715 | std::string start_page_token; |
| 716 | EXPECT_EQ(FILE_ERROR_OK, storage_->GetStartPageToken(&start_page_token)); |
| 717 | EXPECT_EQ(kStartPageToken, start_page_token); |
| 718 | |
| 719 | EXPECT_EQ(FILE_ERROR_OK, storage_->GetEntry("local_id_1", &entry)); |
| 720 | EXPECT_EQ(kDirectoryChangestamp, |
| 721 | entry.directory_specific_info().changestamp()); |
| 722 | EXPECT_EQ(kDirectoryStartpageToken, |
| 723 | entry.directory_specific_info().start_page_token()); |
| 724 | } |
| 725 | |
Sasha Morrissey | 7ae517a | 2018-05-18 04:14:22 | [diff] [blame] | 726 | // Test that upgrading from DB version 16 to 17 triggers a full metadata refresh |
| 727 | // (since this changes alternate_url to be set for directories, which need to |
| 728 | // be re-fetched). |
| 729 | TEST_F(ResourceMetadataStorageTest, UpgradeDBv16) { |
| 730 | constexpr int64_t kLargestChangestamp = 54321; |
| 731 | constexpr char kStartPageToken[] = "54322"; |
| 732 | |
| 733 | // Construct a v16 DB. |
| 734 | SetDBVersion(16); |
| 735 | EXPECT_EQ(FILE_ERROR_OK, |
| 736 | storage_->SetLargestChangestamp(kLargestChangestamp)); |
| 737 | EXPECT_EQ(FILE_ERROR_OK, storage_->SetStartPageToken(kStartPageToken)); |
| 738 | |
| 739 | // Add a file. |
| 740 | ResourceEntry entry; |
| 741 | entry.set_local_id("local_id_1"); |
| 742 | entry.set_base_name("resource_id_1"); |
| 743 | EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry)); |
| 744 | |
| 745 | // Upgrade and reopen. |
| 746 | storage_.reset(); |
| 747 | EXPECT_TRUE(UpgradeOldDB()); |
| 748 | storage_.reset(new ResourceMetadataStorage( |
| 749 | temp_dir_.GetPath(), base::ThreadTaskRunnerHandle::Get().get())); |
| 750 | ASSERT_TRUE(storage_->Initialize()); |
| 751 | |
| 752 | // Changestamps are reset. |
| 753 | int64_t largest_changestamp = 0; |
| 754 | EXPECT_EQ(FILE_ERROR_OK, |
| 755 | storage_->GetLargestChangestamp(&largest_changestamp)); |
| 756 | EXPECT_EQ(0, largest_changestamp); |
| 757 | |
| 758 | std::string start_page_token; |
| 759 | EXPECT_EQ(FILE_ERROR_OK, storage_->GetStartPageToken(&start_page_token)); |
| 760 | EXPECT_EQ("", start_page_token); |
| 761 | |
| 762 | // The data is retained. |
| 763 | EXPECT_EQ(FILE_ERROR_OK, storage_->GetEntry("local_id_1", &entry)); |
| 764 | EXPECT_EQ("resource_id_1", entry.base_name()); |
| 765 | } |
| 766 | |
[email protected] | be427d7 | 2013-06-21 07:09:27 | [diff] [blame] | 767 | } // namespace internal |
[email protected] | df3fef2 | 2013-03-21 12:20:41 | [diff] [blame] | 768 | } // namespace drive |