blob: c759a3b80567d84c6a22f08bc74d83c3304ea234 [file] [log] [blame]
[email protected]df3fef22013-03-21 12:20:411// 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
lukasza6364a022015-08-21 01:13:245#include "components/drive/resource_metadata_storage.h"
[email protected]df3fef22013-03-21 12:20:416
avibc5337b2015-12-25 23:16:337#include <stddef.h>
8#include <stdint.h>
9
[email protected]df3fef22013-03-21 12:20:4110#include <algorithm>
Lei Zhangd359bae2017-11-29 18:25:5711#include <utility>
[email protected]df3fef22013-03-21 12:20:4112
thestig18dfb7a52014-08-26 10:44:0413#include "base/files/file_util.h"
[email protected]df3fef22013-03-21 12:20:4114#include "base/files/scoped_temp_dir.h"
pranay.kumar229290b52015-05-14 05:21:0415#include "base/single_thread_task_runner.h"
Lei Zhangd359bae2017-11-29 18:25:5716#include "base/stl_util.h"
limasdf511524f2014-09-13 00:48:5317#include "base/strings/string_split.h"
gab7966d312016-05-11 20:35:0118#include "base/threading/thread_task_runner_handle.h"
lukasza01b9d55a2015-07-21 15:19:2519#include "components/drive/drive.pb.h"
Stuart Langley22cca242018-05-18 05:59:1220#include "components/drive/file_system_core_util.h"
Gabriel Charettec7108742019-08-23 03:31:4021#include "content/public/test/browser_task_environment.h"
Austin Tankiangc35b6c62019-11-08 12:15:1222#include "content/public/test/test_utils.h"
[email protected]df3fef22013-03-21 12:20:4123#include "testing/gtest/include/gtest/gtest.h"
[email protected]c28c952d2013-04-24 11:41:5724#include "third_party/leveldatabase/src/include/leveldb/db.h"
[email protected]12a024ec2013-10-24 04:00:0525#include "third_party/leveldatabase/src/include/leveldb/write_batch.h"
[email protected]df3fef22013-03-21 12:20:4126
27namespace drive {
[email protected]be427d72013-06-21 07:09:2728namespace internal {
[email protected]df3fef22013-03-21 12:20:4129
Austin Tankiangc35b6c62019-11-08 12:15:1230namespace {
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.
35struct 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]dd8e7fe2013-04-26 05:14:2347class ResourceMetadataStorageTest : public testing::Test {
[email protected]df3fef22013-03-21 12:20:4148 protected:
Stuart Langley1cad1222018-05-29 18:58:4449 ResourceMetadataStorageTest() = default;
50 ~ResourceMetadataStorageTest() override = default;
Lei Zhangd359bae2017-11-29 18:25:5751
dchengfe773302015-01-22 19:45:5252 void SetUp() override {
[email protected]df3fef22013-03-21 12:20:4153 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
54
[email protected]be427d72013-06-21 07:09:2755 storage_.reset(new ResourceMetadataStorage(
vabr96fd0c0f2016-09-13 14:21:3156 temp_dir_.GetPath(), base::ThreadTaskRunnerHandle::Get().get()));
[email protected]df3fef22013-03-21 12:20:4157 ASSERT_TRUE(storage_->Initialize());
58 }
59
[email protected]df3fef22013-03-21 12:20:4160 // Overwrites |storage_|'s version.
61 void SetDBVersion(int version) {
[email protected]b360d672013-06-20 08:06:3662 ResourceMetadataHeader header;
[email protected]996139412014-05-10 06:19:5063 ASSERT_EQ(FILE_ERROR_OK, storage_->GetHeader(&header));
[email protected]b360d672013-06-20 08:06:3664 header.set_version(version);
[email protected]996139412014-05-10 06:19:5065 EXPECT_EQ(FILE_ERROR_OK, storage_->PutHeader(header));
[email protected]df3fef22013-03-21 12:20:4166 }
67
[email protected]74f678e2013-04-17 09:16:4668 bool CheckValidity() {
69 return storage_->CheckValidity();
70 }
71
[email protected]12a024ec2013-10-24 04:00:0572 leveldb::DB* resource_map() { return storage_->resource_map_.get(); }
73
[email protected]c28c952d2013-04-24 11:41:5774 // Puts a child entry.
[email protected]07310292013-08-19 10:55:4175 void PutChild(const std::string& parent_id,
[email protected]c28c952d2013-04-24 11:41:5776 const std::string& child_base_name,
[email protected]07310292013-08-19 10:55:4177 const std::string& child_id) {
[email protected]c28c952d2013-04-24 11:41:5778 storage_->resource_map_->Put(
79 leveldb::WriteOptions(),
[email protected]07310292013-08-19 10:55:4180 ResourceMetadataStorage::GetChildEntryKey(parent_id, child_base_name),
81 child_id);
[email protected]c28c952d2013-04-24 11:41:5782 }
83
84 // Removes a child entry.
[email protected]07310292013-08-19 10:55:4185 void RemoveChild(const std::string& parent_id,
[email protected]c28c952d2013-04-24 11:41:5786 const std::string& child_base_name) {
87 storage_->resource_map_->Delete(
88 leveldb::WriteOptions(),
[email protected]07310292013-08-19 10:55:4189 ResourceMetadataStorage::GetChildEntryKey(parent_id, child_base_name));
[email protected]c28c952d2013-04-24 11:41:5790 }
91
Lei Zhangd359bae2017-11-29 18:25:5792 bool UpgradeOldDB() {
93 return ResourceMetadataStorage::UpgradeOldDB(temp_dir_.GetPath());
94 }
95
Gabriel Charette798fde72019-08-20 22:24:0496 content::BrowserTaskEnvironment task_environment_;
[email protected]df3fef22013-03-21 12:20:4197 base::ScopedTempDir temp_dir_;
Austin Tankiangc35b6c62019-11-08 12:15:1298 std::unique_ptr<ResourceMetadataStorage, DestroyHelperForTests> storage_;
Lei Zhangd359bae2017-11-29 18:25:5799
100 DISALLOW_COPY_AND_ASSIGN(ResourceMetadataStorageTest);
[email protected]df3fef22013-03-21 12:20:41101};
102
[email protected]dd8e7fe2013-04-26 05:14:23103TEST_F(ResourceMetadataStorageTest, LargestChangestamp) {
avibc5337b2015-12-25 23:16:33104 const int64_t kLargestChangestamp = 1234567890;
[email protected]996139412014-05-10 06:19:50105 EXPECT_EQ(FILE_ERROR_OK,
106 storage_->SetLargestChangestamp(kLargestChangestamp));
avibc5337b2015-12-25 23:16:33107 int64_t value = 0;
[email protected]996139412014-05-10 06:19:50108 EXPECT_EQ(FILE_ERROR_OK, storage_->GetLargestChangestamp(&value));
109 EXPECT_EQ(kLargestChangestamp, value);
[email protected]df3fef22013-03-21 12:20:41110}
111
Stuart Langley22cca242018-05-18 05:59:12112TEST_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]dd8e7fe2013-04-26 05:14:23120TEST_F(ResourceMetadataStorageTest, PutEntry) {
[email protected]df3fef22013-03-21 12:20:41121 const std::string key1 = "abcdefg";
122 const std::string key2 = "abcd";
[email protected]c28c952d2013-04-24 11:41:57123 const std::string key3 = "efgh";
124 const std::string name2 = "ABCD";
125 const std::string name3 = "EFGH";
[email protected]df3fef22013-03-21 12:20:41126
[email protected]df3fef22013-03-21 12:20:41127 // key1 not found.
[email protected]fff72772013-06-19 05:09:41128 ResourceEntry result;
[email protected]996139412014-05-10 06:19:50129 EXPECT_EQ(FILE_ERROR_NOT_FOUND, storage_->GetEntry(key1, &result));
[email protected]df3fef22013-03-21 12:20:41130
131 // Put entry1.
[email protected]d38aa402013-09-25 09:38:43132 ResourceEntry entry1;
133 entry1.set_local_id(key1);
[email protected]996139412014-05-10 06:19:50134 EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry1));
[email protected]df3fef22013-03-21 12:20:41135
136 // key1 found.
[email protected]996139412014-05-10 06:19:50137 EXPECT_EQ(FILE_ERROR_OK, storage_->GetEntry(key1, &result));
[email protected]df3fef22013-03-21 12:20:41138
139 // key2 not found.
[email protected]996139412014-05-10 06:19:50140 EXPECT_EQ(FILE_ERROR_NOT_FOUND, storage_->GetEntry(key2, &result));
[email protected]df3fef22013-03-21 12:20:41141
[email protected]c28c952d2013-04-24 11:41:57142 // Put entry2 as a child of entry1.
[email protected]67241b832013-05-02 04:55:52143 ResourceEntry entry2;
[email protected]d38aa402013-09-25 09:38:43144 entry2.set_local_id(key2);
[email protected]943cb8b2013-08-21 03:17:08145 entry2.set_parent_local_id(key1);
[email protected]c28c952d2013-04-24 11:41:57146 entry2.set_base_name(name2);
[email protected]996139412014-05-10 06:19:50147 EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry2));
[email protected]c28c952d2013-04-24 11:41:57148
149 // key2 found.
[email protected]996139412014-05-10 06:19:50150 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]c28c952d2013-04-24 11:41:57154
155 // Put entry3 as a child of entry2.
[email protected]67241b832013-05-02 04:55:52156 ResourceEntry entry3;
[email protected]d38aa402013-09-25 09:38:43157 entry3.set_local_id(key3);
[email protected]943cb8b2013-08-21 03:17:08158 entry3.set_parent_local_id(key2);
[email protected]c28c952d2013-04-24 11:41:57159 entry3.set_base_name(name3);
[email protected]996139412014-05-10 06:19:50160 EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry3));
[email protected]c28c952d2013-04-24 11:41:57161
162 // key3 found.
[email protected]996139412014-05-10 06:19:50163 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]c28c952d2013-04-24 11:41:57166
167 // Change entry3's parent to entry1.
[email protected]943cb8b2013-08-21 03:17:08168 entry3.set_parent_local_id(key1);
[email protected]996139412014-05-10 06:19:50169 EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry3));
[email protected]c28c952d2013-04-24 11:41:57170
171 // entry3 is a child of entry1 now.
[email protected]996139412014-05-10 06:19:50172 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]c28c952d2013-04-24 11:41:57175
176 // Remove entries.
[email protected]996139412014-05-10 06:19:50177 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]df3fef22013-03-21 12:20:41183}
184
[email protected]eb391ee2013-05-10 06:08:57185TEST_F(ResourceMetadataStorageTest, Iterator) {
[email protected]8c191e52013-04-09 14:05:17186 // Prepare data.
[email protected]07310292013-08-19 10:55:41187 std::vector<std::string> keys;
[email protected]8c191e52013-04-09 14:05:17188
[email protected]07310292013-08-19 10:55:41189 keys.push_back("entry1");
190 keys.push_back("entry2");
191 keys.push_back("entry3");
192 keys.push_back("entry4");
[email protected]8c191e52013-04-09 14:05:17193
Lei Zhangd359bae2017-11-29 18:25:57194 for (const std::string& key : keys) {
[email protected]d38aa402013-09-25 09:38:43195 ResourceEntry entry;
Lei Zhangd359bae2017-11-29 18:25:57196 entry.set_local_id(key);
[email protected]996139412014-05-10 06:19:50197 EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry));
[email protected]d38aa402013-09-25 09:38:43198 }
[email protected]8c191e52013-04-09 14:05:17199
[email protected]eb391ee2013-05-10 06:08:57200 // Iterate and check the result.
[email protected]0f86f232013-07-26 03:25:14201 std::map<std::string, ResourceEntry> found_entries;
dchengf42750232016-04-12 04:12:27202 std::unique_ptr<ResourceMetadataStorage::Iterator> it =
203 storage_->GetIterator();
[email protected]eb391ee2013-05-10 06:08:57204 ASSERT_TRUE(it);
205 for (; !it->IsAtEnd(); it->Advance()) {
[email protected]07310292013-08-19 10:55:41206 const ResourceEntry& entry = it->GetValue();
207 found_entries[it->GetID()] = entry;
[email protected]eb391ee2013-05-10 06:08:57208 }
209 EXPECT_FALSE(it->HasError());
[email protected]8c191e52013-04-09 14:05:17210
[email protected]07310292013-08-19 10:55:41211 EXPECT_EQ(keys.size(), found_entries.size());
Lei Zhangd359bae2017-11-29 18:25:57212 for (const std::string& key : keys)
Jan Wilken Dörrie45d34f42019-06-08 09:40:54213 EXPECT_TRUE(base::Contains(found_entries, key));
[email protected]8c191e52013-04-09 14:05:17214}
215
[email protected]da56f6792013-10-17 04:01:46216TEST_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]996139412014-05-10 06:19:50222 EXPECT_EQ(FILE_ERROR_NOT_FOUND,
223 storage_->GetIdByResourceId(resource_id, &id));
[email protected]da56f6792013-10-17 04:01:46224
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]996139412014-05-10 06:19:50229 EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry));
[email protected]da56f6792013-10-17 04:01:46230
231 // Can get local ID by resource ID.
[email protected]996139412014-05-10 06:19:50232 EXPECT_EQ(FILE_ERROR_OK, storage_->GetIdByResourceId(resource_id, &id));
[email protected]da56f6792013-10-17 04:01:46233 EXPECT_EQ(local_id, id);
234
235 // Resource ID to local ID mapping is removed.
[email protected]996139412014-05-10 06:19:50236 EXPECT_EQ(FILE_ERROR_OK, storage_->RemoveEntry(local_id));
237 EXPECT_EQ(FILE_ERROR_NOT_FOUND,
238 storage_->GetIdByResourceId(resource_id, &id));
[email protected]da56f6792013-10-17 04:01:46239}
240
[email protected]dd8e7fe2013-04-26 05:14:23241TEST_F(ResourceMetadataStorageTest, GetChildren) {
[email protected]595867a2013-03-23 19:00:02242 const std::string parents_id[] = { "mercury", "venus", "mars", "jupiter",
243 "saturn" };
Avi Drissman8171db7d2018-12-25 23:08:31244 std::vector<base::StringPairs> children_name_id(base::size(parents_id));
[email protected]595867a2013-03-23 19:00:02245 // 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]c28c952d2013-04-24 11:41:57260 // Put parents.
Lei Zhangd359bae2017-11-29 18:25:57261 for (const std::string& id : parents_id) {
[email protected]d38aa402013-09-25 09:38:43262 ResourceEntry entry;
Lei Zhangd359bae2017-11-29 18:25:57263 entry.set_local_id(id);
[email protected]996139412014-05-10 06:19:50264 EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry));
[email protected]d38aa402013-09-25 09:38:43265 }
[email protected]c28c952d2013-04-24 11:41:57266
[email protected]475052522013-06-19 08:30:37267 // Put children.
[email protected]c28c952d2013-04-24 11:41:57268 for (size_t i = 0; i < children_name_id.size(); ++i) {
Lei Zhangd359bae2017-11-29 18:25:57269 for (const auto& id : children_name_id[i]) {
[email protected]67241b832013-05-02 04:55:52270 ResourceEntry entry;
Lei Zhangd359bae2017-11-29 18:25:57271 entry.set_local_id(id.second);
[email protected]943cb8b2013-08-21 03:17:08272 entry.set_parent_local_id(parents_id[i]);
Lei Zhangd359bae2017-11-29 18:25:57273 entry.set_base_name(id.first);
[email protected]996139412014-05-10 06:19:50274 EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry));
[email protected]595867a2013-03-23 19:00:02275 }
276 }
277
278 // Try to get children.
[email protected]c28c952d2013-04-24 11:41:57279 for (size_t i = 0; i < children_name_id.size(); ++i) {
[email protected]595867a2013-03-23 19:00:02280 std::vector<std::string> children;
281 storage_->GetChildren(parents_id[i], &children);
282 EXPECT_EQ(children_name_id[i].size(), children.size());
Lei Zhangd359bae2017-11-29 18:25:57283 for (const auto& id : children_name_id[i]) {
284 EXPECT_EQ(1, std::count(children.begin(), children.end(), id.second));
[email protected]595867a2013-03-23 19:00:02285 }
286 }
287}
288
[email protected]dd8e7fe2013-04-26 05:14:23289TEST_F(ResourceMetadataStorageTest, OpenExistingDB) {
[email protected]df3fef22013-03-21 12:20:41290 const std::string parent_id1 = "abcdefg";
291 const std::string child_name1 = "WXYZABC";
292 const std::string child_id1 = "qwerty";
293
[email protected]67241b832013-05-02 04:55:52294 ResourceEntry entry1;
[email protected]d38aa402013-09-25 09:38:43295 entry1.set_local_id(parent_id1);
[email protected]67241b832013-05-02 04:55:52296 ResourceEntry entry2;
[email protected]d38aa402013-09-25 09:38:43297 entry2.set_local_id(child_id1);
[email protected]943cb8b2013-08-21 03:17:08298 entry2.set_parent_local_id(parent_id1);
[email protected]74f678e2013-04-17 09:16:46299 entry2.set_base_name(child_name1);
[email protected]df3fef22013-03-21 12:20:41300
301 // Put some data.
[email protected]996139412014-05-10 06:19:50302 EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry1));
303 EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry2));
[email protected]df3fef22013-03-21 12:20:41304
305 // Close DB and reopen.
[email protected]be427d72013-06-21 07:09:27306 storage_.reset(new ResourceMetadataStorage(
vabr96fd0c0f2016-09-13 14:21:31307 temp_dir_.GetPath(), base::ThreadTaskRunnerHandle::Get().get()));
[email protected]df3fef22013-03-21 12:20:41308 ASSERT_TRUE(storage_->Initialize());
309
310 // Can read data.
[email protected]fff72772013-06-19 05:09:41311 ResourceEntry result;
[email protected]996139412014-05-10 06:19:50312 EXPECT_EQ(FILE_ERROR_OK, storage_->GetEntry(parent_id1, &result));
[email protected]74f678e2013-04-17 09:16:46313
[email protected]996139412014-05-10 06:19:50314 EXPECT_EQ(FILE_ERROR_OK, storage_->GetEntry(child_id1, &result));
[email protected]943cb8b2013-08-21 03:17:08315 EXPECT_EQ(parent_id1, result.parent_local_id());
[email protected]fff72772013-06-19 05:09:41316 EXPECT_EQ(child_name1, result.base_name());
[email protected]74f678e2013-04-17 09:16:46317
[email protected]996139412014-05-10 06:19:50318 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]df3fef22013-03-21 12:20:41322}
323
[email protected]12a024ec2013-10-24 04:00:05324TEST_F(ResourceMetadataStorageTest, IncompatibleDB_M29) {
avibc5337b2015-12-25 23:16:33325 const int64_t kLargestChangestamp = 1234567890;
[email protected]3d6a8252014-05-29 20:42:09326 const std::string title = "title";
[email protected]df3fef22013-03-21 12:20:41327
[email protected]12a024ec2013-10-24 04:00:05328 // Construct M29 version DB.
329 SetDBVersion(6);
[email protected]996139412014-05-10 06:19:50330 EXPECT_EQ(FILE_ERROR_OK,
331 storage_->SetLargestChangestamp(kLargestChangestamp));
[email protected]df3fef22013-03-21 12:20:41332
[email protected]12a024ec2013-10-24 04:00:05333 leveldb::WriteBatch batch;
334
335 // Put a file entry and its cache entry.
336 ResourceEntry entry;
337 std::string serialized_entry;
[email protected]3d6a8252014-05-29 20:42:09338 entry.set_title(title);
[email protected]12a024ec2013-10-24 04:00:05339 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 Zhangd359bae2017-11-29 18:25:57351 EXPECT_TRUE(UpgradeOldDB());
[email protected]be427d72013-06-21 07:09:27352 storage_.reset(new ResourceMetadataStorage(
vabr96fd0c0f2016-09-13 14:21:31353 temp_dir_.GetPath(), base::ThreadTaskRunnerHandle::Get().get()));
[email protected]df3fef22013-03-21 12:20:41354 ASSERT_TRUE(storage_->Initialize());
355
[email protected]12a024ec2013-10-24 04:00:05356 // Resource-ID-to-local-ID mapping is added.
357 std::string id;
[email protected]996139412014-05-10 06:19:50358 EXPECT_EQ(FILE_ERROR_OK,
359 storage_->GetIdByResourceId("abcd", &id)); // "file:" is dropped.
[email protected]12a024ec2013-10-24 04:00:05360
361 // Data is erased, except cache entries.
avibc5337b2015-12-25 23:16:33362 int64_t largest_changestamp = 0;
[email protected]996139412014-05-10 06:19:50363 EXPECT_EQ(FILE_ERROR_OK,
364 storage_->GetLargestChangestamp(&largest_changestamp));
365 EXPECT_EQ(0, largest_changestamp);
[email protected]3d6a8252014-05-29 20:42:09366 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]fba850ff2013-09-19 08:08:53369}
370
[email protected]b0b3dbd2013-12-05 11:09:52371TEST_F(ResourceMetadataStorageTest, IncompatibleDB_M32) {
avibc5337b2015-12-25 23:16:33372 const int64_t kLargestChangestamp = 1234567890;
[email protected]3d6a8252014-05-29 20:42:09373 const std::string title = "title";
[email protected]b0b3dbd2013-12-05 11:09:52374 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]996139412014-05-10 06:19:50379 EXPECT_EQ(FILE_ERROR_OK,
380 storage_->SetLargestChangestamp(kLargestChangestamp));
[email protected]b0b3dbd2013-12-05 11:09:52381
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]3d6a8252014-05-29 20:42:09387 entry.set_title(title);
388 entry.set_local_id(local_id);
[email protected]b0b3dbd2013-12-05 11:09:52389 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 Zhangd359bae2017-11-29 18:25:57403 EXPECT_TRUE(UpgradeOldDB());
[email protected]b0b3dbd2013-12-05 11:09:52404 storage_.reset(new ResourceMetadataStorage(
vabr96fd0c0f2016-09-13 14:21:31405 temp_dir_.GetPath(), base::ThreadTaskRunnerHandle::Get().get()));
[email protected]b0b3dbd2013-12-05 11:09:52406 ASSERT_TRUE(storage_->Initialize());
407
408 // Data is erased, except cache and id mapping entries.
409 std::string id;
[email protected]996139412014-05-10 06:19:50410 EXPECT_EQ(FILE_ERROR_OK, storage_->GetIdByResourceId(resource_id, &id));
[email protected]b0b3dbd2013-12-05 11:09:52411 EXPECT_EQ(local_id, id);
avibc5337b2015-12-25 23:16:33412 int64_t largest_changestamp = 0;
[email protected]996139412014-05-10 06:19:50413 EXPECT_EQ(FILE_ERROR_OK,
414 storage_->GetLargestChangestamp(&largest_changestamp));
415 EXPECT_EQ(0, largest_changestamp);
[email protected]3d6a8252014-05-29 20:42:09416 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
421TEST_F(ResourceMetadataStorageTest, IncompatibleDB_M33) {
avibc5337b2015-12-25 23:16:33422 const int64_t kLargestChangestamp = 1234567890;
[email protected]3d6a8252014-05-29 20:42:09423 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 Zhangd359bae2017-11-29 18:25:57464 EXPECT_TRUE(UpgradeOldDB());
[email protected]3d6a8252014-05-29 20:42:09465 storage_.reset(new ResourceMetadataStorage(
vabr96fd0c0f2016-09-13 14:21:31466 temp_dir_.GetPath(), base::ThreadTaskRunnerHandle::Get().get()));
[email protected]3d6a8252014-05-29 20:42:09467 ASSERT_TRUE(storage_->Initialize());
468
Shuhei Takahashi87ce7f52017-09-05 05:15:41469 // largest_changestamp is cleared.
avibc5337b2015-12-25 23:16:33470 int64_t largest_changestamp = 0;
[email protected]3d6a8252014-05-29 20:42:09471 EXPECT_EQ(FILE_ERROR_OK,
472 storage_->GetLargestChangestamp(&largest_changestamp));
Shuhei Takahashi87ce7f52017-09-05 05:15:41473 EXPECT_EQ(0, largest_changestamp);
[email protected]3d6a8252014-05-29 20:42:09474
Shuhei Takahashi87ce7f52017-09-05 05:15:41475 // No other data is lost.
[email protected]3d6a8252014-05-29 20:42:09476 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]b0b3dbd2013-12-05 11:09:52487}
488
[email protected]fba850ff2013-09-19 08:08:53489TEST_F(ResourceMetadataStorageTest, IncompatibleDB_Unknown) {
avibc5337b2015-12-25 23:16:33490 const int64_t kLargestChangestamp = 1234567890;
[email protected]fba850ff2013-09-19 08:08:53491 const std::string key1 = "abcd";
492
493 // Put some data.
[email protected]996139412014-05-10 06:19:50494 EXPECT_EQ(FILE_ERROR_OK,
495 storage_->SetLargestChangestamp(kLargestChangestamp));
[email protected]fba850ff2013-09-19 08:08:53496 ResourceEntry entry;
[email protected]d38aa402013-09-25 09:38:43497 entry.set_local_id(key1);
[email protected]996139412014-05-10 06:19:50498 EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry));
[email protected]fba850ff2013-09-19 08:08:53499
[email protected]12a024ec2013-10-24 04:00:05500 // Set newer version, upgrade and reopen DB.
[email protected]fba850ff2013-09-19 08:08:53501 SetDBVersion(ResourceMetadataStorage::kDBVersion + 1);
[email protected]12a024ec2013-10-24 04:00:05502 storage_.reset();
Lei Zhangd359bae2017-11-29 18:25:57503 EXPECT_FALSE(UpgradeOldDB());
[email protected]fba850ff2013-09-19 08:08:53504 storage_.reset(new ResourceMetadataStorage(
vabr96fd0c0f2016-09-13 14:21:31505 temp_dir_.GetPath(), base::ThreadTaskRunnerHandle::Get().get()));
[email protected]fba850ff2013-09-19 08:08:53506 ASSERT_TRUE(storage_->Initialize());
507
[email protected]df3fef22013-03-21 12:20:41508 // Data is erased because of the incompatible version.
avibc5337b2015-12-25 23:16:33509 int64_t largest_changestamp = 0;
[email protected]996139412014-05-10 06:19:50510 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]df3fef22013-03-21 12:20:41514}
515
Shuhei Takahashi87ce7f52017-09-05 05:15:41516TEST_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]0fd58692014-05-23 11:40:04524 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]0fd58692014-05-23 11:40:04536 // Put an ID entry without any corresponding entries.
[email protected]3d6a8252014-05-29 20:42:09537 batch.Put('\0' + std::string("ID") + '\0' + "resource_id2", "id3");
[email protected]0fd58692014-05-23 11:40:04538
539 EXPECT_TRUE(resource_map()->Write(leveldb::WriteOptions(), &batch).ok());
540
541 // Upgrade and reopen.
542 storage_.reset();
Lei Zhangd359bae2017-11-29 18:25:57543 EXPECT_TRUE(UpgradeOldDB());
[email protected]0fd58692014-05-23 11:40:04544 storage_.reset(new ResourceMetadataStorage(
vabr96fd0c0f2016-09-13 14:21:31545 temp_dir_.GetPath(), base::ThreadTaskRunnerHandle::Get().get()));
[email protected]0fd58692014-05-23 11:40:04546 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]0fd58692014-05-23 11:40:04552 EXPECT_EQ(FILE_ERROR_NOT_FOUND,
[email protected]3d6a8252014-05-29 20:42:09553 storage_->GetIdByResourceId("resource_id2", &id));
Shuhei Takahashi87ce7f52017-09-05 05:15:41554
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]0fd58692014-05-23 11:40:04560}
561
[email protected]dd8e7fe2013-04-26 05:14:23562TEST_F(ResourceMetadataStorageTest, WrongPath) {
[email protected]df3fef22013-03-21 12:20:41563 // Create a file.
564 base::FilePath path;
vabr96fd0c0f2016-09-13 14:21:31565 ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.GetPath(), &path));
[email protected]df3fef22013-03-21 12:20:41566
[email protected]be427d72013-06-21 07:09:27567 storage_.reset(new ResourceMetadataStorage(
pranay.kumar229290b52015-05-14 05:21:04568 path, base::ThreadTaskRunnerHandle::Get().get()));
[email protected]df3fef22013-03-21 12:20:41569 // Cannot initialize DB beacause the path does not point a directory.
570 ASSERT_FALSE(storage_->Initialize());
571}
572
[email protected]760abc32013-11-01 05:13:01573TEST_F(ResourceMetadataStorageTest, RecoverCacheEntriesFromTrashedResourceMap) {
[email protected]760abc32013-11-01 05:13:01574 // Put entry with id_foo.
575 ResourceEntry entry;
576 entry.set_local_id("id_foo");
577 entry.set_base_name("foo");
[email protected]026d4a522013-11-05 14:22:18578 entry.set_title("foo");
[email protected]cd8fd37f2014-05-20 15:45:21579 entry.mutable_file_specific_info()->mutable_cache_state()->set_md5("md5_foo");
[email protected]996139412014-05-10 06:19:50580 EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry));
[email protected]760abc32013-11-01 05:13:01581
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]026d4a522013-11-05 14:22:18586 entry.set_title("bar");
[email protected]cd8fd37f2014-05-20 15:45:21587 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]996139412014-05-10 06:19:50589 EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry));
[email protected]760abc32013-11-01 05:13:01590
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(
vabr96fd0c0f2016-09-13 14:21:31597 temp_dir_.GetPath(), base::ThreadTaskRunnerHandle::Get().get()));
[email protected]760abc32013-11-01 05:13:01598 ASSERT_TRUE(storage_->Initialize());
599
600 // Recover cache entries from the trashed DB.
[email protected]026d4a522013-11-05 14:22:18601 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]760abc32013-11-01 05:13:01610}
611
[email protected]dd8e7fe2013-04-26 05:14:23612TEST_F(ResourceMetadataStorageTest, CheckValidity) {
[email protected]74f678e2013-04-17 09:16:46613 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]5bd7f7a2013-04-18 05:52:40620 // Empty storage is valid.
621 EXPECT_TRUE(CheckValidity());
622
[email protected]74f678e2013-04-17 09:16:46623 // Put entry with key1.
[email protected]67241b832013-05-02 04:55:52624 ResourceEntry entry;
[email protected]d38aa402013-09-25 09:38:43625 entry.set_local_id(key1);
[email protected]74f678e2013-04-17 09:16:46626 entry.set_base_name(name1);
[email protected]996139412014-05-10 06:19:50627 EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry));
[email protected]74f678e2013-04-17 09:16:46628 EXPECT_TRUE(CheckValidity());
629
630 // Put entry with key2 under key1.
[email protected]d38aa402013-09-25 09:38:43631 entry.set_local_id(key2);
[email protected]943cb8b2013-08-21 03:17:08632 entry.set_parent_local_id(key1);
[email protected]74f678e2013-04-17 09:16:46633 entry.set_base_name(name2);
[email protected]996139412014-05-10 06:19:50634 EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry));
[email protected]c28c952d2013-04-24 11:41:57635 EXPECT_TRUE(CheckValidity());
636
637 RemoveChild(key1, name2);
[email protected]74f678e2013-04-17 09:16:46638 EXPECT_FALSE(CheckValidity()); // Missing parent-child relationship.
639
[email protected]c28c952d2013-04-24 11:41:57640 // Add back parent-child relationship between key1 and key2.
641 PutChild(key1, name2, key2);
[email protected]74f678e2013-04-17 09:16:46642 EXPECT_TRUE(CheckValidity());
643
[email protected]5bd7f7a2013-04-18 05:52:40644 // Add parent-child relationship between key2 and key3.
[email protected]c28c952d2013-04-24 11:41:57645 PutChild(key2, name3, key3);
[email protected]74f678e2013-04-17 09:16:46646 EXPECT_FALSE(CheckValidity()); // key3 is not stored in the storage.
647
[email protected]5bd7f7a2013-04-18 05:52:40648 // Put entry with key3 under key2.
[email protected]d38aa402013-09-25 09:38:43649 entry.set_local_id(key3);
[email protected]943cb8b2013-08-21 03:17:08650 entry.set_parent_local_id(key2);
[email protected]74f678e2013-04-17 09:16:46651 entry.set_base_name(name3);
[email protected]996139412014-05-10 06:19:50652 EXPECT_EQ(FILE_ERROR_OK, storage_->PutEntry(entry));
[email protected]74f678e2013-04-17 09:16:46653 EXPECT_TRUE(CheckValidity());
654
655 // Parent-child relationship with wrong name.
[email protected]c28c952d2013-04-24 11:41:57656 RemoveChild(key2, name3);
[email protected]74f678e2013-04-17 09:16:46657 EXPECT_FALSE(CheckValidity());
[email protected]c28c952d2013-04-24 11:41:57658 PutChild(key2, name2, key3);
[email protected]5bd7f7a2013-04-18 05:52:40659 EXPECT_FALSE(CheckValidity());
660
661 // Fix up the relationship between key2 and key3.
[email protected]c28c952d2013-04-24 11:41:57662 RemoveChild(key2, name2);
[email protected]5bd7f7a2013-04-18 05:52:40663 EXPECT_FALSE(CheckValidity());
[email protected]c28c952d2013-04-24 11:41:57664 PutChild(key2, name3, key3);
[email protected]5bd7f7a2013-04-18 05:52:40665 EXPECT_TRUE(CheckValidity());
666
667 // Remove key2.
[email protected]c28c952d2013-04-24 11:41:57668 RemoveChild(key1, name2);
[email protected]5bd7f7a2013-04-18 05:52:40669 EXPECT_FALSE(CheckValidity());
[email protected]996139412014-05-10 06:19:50670 EXPECT_EQ(FILE_ERROR_OK, storage_->RemoveEntry(key2));
[email protected]5bd7f7a2013-04-18 05:52:40671 EXPECT_FALSE(CheckValidity());
672
673 // Remove key3.
[email protected]c28c952d2013-04-24 11:41:57674 RemoveChild(key2, name3);
[email protected]5bd7f7a2013-04-18 05:52:40675 EXPECT_FALSE(CheckValidity());
[email protected]996139412014-05-10 06:19:50676 EXPECT_EQ(FILE_ERROR_OK, storage_->RemoveEntry(key3));
[email protected]5bd7f7a2013-04-18 05:52:40677 EXPECT_TRUE(CheckValidity());
678
679 // Remove key1.
[email protected]996139412014-05-10 06:19:50680 EXPECT_EQ(FILE_ERROR_OK, storage_->RemoveEntry(key1));
[email protected]5bd7f7a2013-04-18 05:52:40681 EXPECT_TRUE(CheckValidity());
[email protected]74f678e2013-04-17 09:16:46682}
683
Sasha Morrissey7ae517a2018-05-18 04:14:22684TEST_F(ResourceMetadataStorageTest, UpgradeDBv15) {
Stuart Langley8e3f6822018-05-09 11:18:18685 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 Morrissey7ae517a2018-05-18 04:14:22726// 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).
729TEST_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]be427d72013-06-21 07:09:27767} // namespace internal
[email protected]df3fef22013-03-21 12:20:41768} // namespace drive