Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(175)

Side by Side Diff: chrome/browser/sync_file_system/drive_backend/metadata_database_unittest.cc

Issue 18591004: [SyncFS] Implement MetadataDatabase initialization (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: +test verification Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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
5 #include "chrome/browser/sync_file_system/drive_backend/metadata_database.h"
6
7 #include "base/bind.h"
8 #include "base/files/scoped_temp_dir.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/message_loop/message_loop_proxy.h"
11 #include "base/strings/string_number_conversions.h"
12 #include "chrome/browser/sync_file_system/drive_backend/metadata_database.pb.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14 #include "third_party/leveldatabase/src/include/leveldb/db.h"
15 #include "third_party/leveldatabase/src/include/leveldb/write_batch.h"
16
17 namespace sync_file_system {
18 namespace drive_backend {
19
20 namespace {
21
22 const int64 kInitialChangeID = 1234;
23 const char kSyncRootFolderID[] = "sync_root_folder_id";
24
25 template <typename Value>
26 bool AreEquivalentProtobuf(const Value& left, const Value& right) {
kinuko 2013/07/04 15:59:11 AreEquivalentProtobuf's' (for all AreEquivalentFoo
tzik 2013/07/05 07:42:28 Done.
27 std::string serialized_left;
28 std::string serialized_right;
29 left.SerializeToString(&serialized_left);
30 right.SerializeToString(&serialized_right);
31 return serialized_left == serialized_right;
32 }
33
34 void SyncStatusResultCallback(SyncStatusCode* status_out,
35 SyncStatusCode status) {
36 EXPECT_EQ(SYNC_STATUS_UNKNOWN, *status_out);
37 *status_out = status;
38 }
39
40 // Returns true if given two std::map<Key, protobuf*> is equivalent under '=='.
41 template <typename Container>
42 bool AreEquivalentPtrMap(const Container& left, const Container& right) {
43 if (left.size() != right.size())
44 return false;
45
46 typedef typename Container::const_iterator const_iterator;
47 const_iterator left_itr = left.begin();
48 const_iterator right_itr = right.begin();
49
50 while (left_itr != left.end()) {
51 if (left_itr->first != right_itr->first)
52 return false;
53 if (!AreEquivalentProtobuf(*left_itr->second, *right_itr->second))
54 return false;
55
56 ++left_itr;
57 ++right_itr;
58 }
59 return true;
60 }
61
62 // Returns true if given two std::set<protobuf*> is equivalent under '=='.
63 template <typename Container>
64 bool AreEquivalentPtrSet(const Container& left, const Container& right) {
65 if (left.size() != right.size())
66 return false;
67
68 typedef typename Container::const_iterator const_iterator;
69 const_iterator left_itr = left.begin();
70 const_iterator right_itr = right.begin();
71 while (left_itr != left.end()) {
72 if (!AreEquivalentProtobuf(**left_itr, **right_itr))
73 return false;
74 ++left_itr;
75 ++right_itr;
76 }
77 return true;
78 }
79
80 // Returns true if given two std::map<Key, std::set<Value*> > is equivalent
81 // under '=='.
82 template <typename Container>
83 bool AreEquivalentPtrSetMap(const Container& left, const Container& right) {
84 if (left.size() != right.size())
85 return false;
86
87 typedef typename Container::const_iterator const_iterator;
88 const_iterator left_itr = left.begin();
89 const_iterator right_itr = right.begin();
90
91 while (left_itr != left.end()) {
92 if (left_itr->first != right_itr->first)
93 return false;
94 if (!AreEquivalentPtrSet(left_itr->second, right_itr->second))
95 return false;
96 ++left_itr;
97 ++right_itr;
98 }
99 return true;
100 }
101
102 } // namespace
103
104 class SyncFS_MetadataDatabaseTest : public testing::Test {
kinuko 2013/07/04 15:59:11 I'm slightly not sure about this naming. Does thi
tzik 2013/07/05 07:42:28 It doesn't conflict, but I feel a bit uneasy to pu
kinuko 2013/07/08 04:18:56 We're already adding generic test names, if we rea
105 public:
106 SyncFS_MetadataDatabaseTest()
107 : next_file_id_number_(1) {
108 }
109
110 virtual ~SyncFS_MetadataDatabaseTest() {
111 }
112
113 virtual void SetUp() OVERRIDE {
114 ASSERT_TRUE(database_dir_.CreateUniqueTempDir());
115 }
116
117 virtual void TearDown() OVERRIDE {
118 DropDatabase();
119 }
120
121 protected:
122 std::string GenerateFileID() {
123 return "file_id_" + base::Int64ToString(next_file_id_number_++);
124 }
125
126 SyncStatusCode InitializeDatabase() {
127 SyncStatusCode status = SYNC_STATUS_UNKNOWN;
128 metadata_database_.reset(new MetadataDatabase(
129 base::MessageLoopProxy::current()));
130 metadata_database_->Initialize(
131 database_dir_.path(),
132 base::Bind(&SyncStatusResultCallback, &status));
133 message_loop_.RunUntilIdle();
134 return status;
135 }
136
137 void DropDatabase() {
138 metadata_database_.reset();
139 message_loop_.RunUntilIdle();
140 }
141
142 MetadataDatabase* metadata_database() {
143 return metadata_database_.get();
144 }
145
146 leveldb::DB* db() {
147 if (!metadata_database_)
148 return NULL;
149 return metadata_database_->db_.get();
150 }
151
152 scoped_ptr<leveldb::DB> OpenDB() {
153 bool created = false;
154 SyncStatusCode status = SYNC_STATUS_UNKNOWN;
155 scoped_ptr<leveldb::DB> db = MetadataDatabase::OpenDatabase(
156 database_dir_.path(), &status, &created);
157 EXPECT_EQ(status, SYNC_STATUS_OK);
158 return db.Pass();
159 }
160
161 void SetUpServiceMetadata(leveldb::DB* db) {
162 ServiceMetadata service_metadata;
163 service_metadata.set_largest_change_id(kInitialChangeID);
164 service_metadata.set_sync_root_folder_id(kSyncRootFolderID);
165 std::string value;
166 ASSERT_TRUE(service_metadata.SerializeToString(&value));
167 db->Put(leveldb::WriteOptions(), "SERVICE", value);
168 }
169
170 DriveFileMetadata CreateSyncRoot() {
171 DriveFileMetadata metadata;
172 metadata.set_file_id(kSyncRootFolderID);
173 metadata.set_parent_folder_id(std::string());
174 metadata.mutable_synced_details()->set_title("Chrome Syncable FileSystem");
175 metadata.mutable_synced_details()->set_kind(KIND_FOLDER);
176 metadata.set_active(true);
177 return metadata;
178 }
179
180 DriveFileMetadata CreateUnknownFile(const std::string& app_id,
181 const std::string& parent_folder_id) {
182 DriveFileMetadata metadata;
183 metadata.set_file_id(GenerateFileID());
184 metadata.set_parent_folder_id(parent_folder_id);
185 metadata.set_app_id(app_id);
186 metadata.set_is_app_root(parent_folder_id == kSyncRootFolderID);
187 return metadata;
188 }
189
190 DriveFileMetadata CreateFile(const std::string& app_id,
191 const std::string& parent_folder_id,
192 const std::string& title) {
193 DriveFileMetadata file(CreateUnknownFile(app_id, parent_folder_id));
194 file.mutable_synced_details()->add_parent_folder_id(parent_folder_id);
195 file.mutable_synced_details()->set_title(title);
196 file.mutable_synced_details()->set_kind(KIND_FILE);
197 file.set_active(true);
198 file.set_dirty(false);
199 return file;
200 }
201
202 DriveFileMetadata CreateFolder(const std::string& app_id,
203 const std::string& parent_folder_id,
204 const std::string& title) {
205 DriveFileMetadata folder(CreateUnknownFile(app_id, parent_folder_id));
206 folder.mutable_synced_details()->add_parent_folder_id(parent_folder_id);
207 folder.mutable_synced_details()->set_title(title);
208 folder.mutable_synced_details()->set_kind(KIND_FOLDER);
209 folder.set_active(true);
210 folder.set_dirty(false);
211 return folder;
212 }
213
214 DriveFileMetadata CreateUnsupportedFile(const std::string& app_id,
215 const std::string& parent_folder_id,
216 const std::string& title) {
217 DriveFileMetadata file(CreateUnknownFile(app_id, parent_folder_id));
218 file.mutable_synced_details()->add_parent_folder_id(parent_folder_id);
219 file.mutable_synced_details()->set_title(title);
220 file.mutable_synced_details()->set_kind(KIND_UNSUPPORTED);
221 file.set_active(false);
222 file.set_dirty(false);
223 return file;
224 }
225
226 leveldb::Status PutFileToDB(leveldb::DB* db, const DriveFileMetadata& file) {
227 std::string key = "FILE: " + file.file_id();
228 std::string value;
229 file.SerializeToString(&value);
230 return db->Put(leveldb::WriteOptions(), key, value);
231 }
232
233 void VerifyReloadConsistency() {
kinuko 2013/07/04 15:59:11 Is it same if we save all internal maps of metadat
234 MetadataDatabase::InitializeInfo info;
235
236 ASSERT_EQ(SYNC_STATUS_OK,
237 MetadataDatabase::ReadDatabaseContents(
238 metadata_database_->db_.get(), &info));
239
240 leveldb::WriteBatch batch;
241 ASSERT_EQ(SYNC_STATUS_OK,
242 MetadataDatabase::ConstructDataStructure(&info, &batch));
243
244 EXPECT_TRUE(AreEquivalentPtrMap(info.file_by_file_id,
245 metadata_database_->file_by_file_id_));
246 EXPECT_TRUE(AreEquivalentPtrSetMap(info.files_by_parent,
247 metadata_database_->files_by_parent_));
248 EXPECT_TRUE(AreEquivalentPtrMap(info.app_root_by_app_id,
249 metadata_database_->app_root_by_app_id_));
250 EXPECT_TRUE(AreEquivalentPtrMap(
251 info.active_file_by_parent_and_title,
252 metadata_database_->active_file_by_parent_and_title_));
253 }
254
255 void VerifyMetadataExists(const DriveFileMetadata& file) {
256 DriveFileMetadata file_in_metadata_db;
257 ASSERT_TRUE(metadata_database()->FindFileByFileID(
258 file.file_id(), &file_in_metadata_db));
259 EXPECT_TRUE(AreEquivalentProtobuf(file, file_in_metadata_db));
260 }
261
262 private:
263 base::ScopedTempDir database_dir_;
264 base::MessageLoop message_loop_;
265
266 scoped_ptr<MetadataDatabase> metadata_database_;
267
268 int64 next_file_id_number_;
269
270 DISALLOW_COPY_AND_ASSIGN(SyncFS_MetadataDatabaseTest);
271 };
272
273 TEST_F(SyncFS_MetadataDatabaseTest, InitializationTest_Empty) {
274 EXPECT_EQ(SYNC_STATUS_OK, InitializeDatabase());
275 VerifyReloadConsistency();
276 DropDatabase();
277 EXPECT_EQ(SYNC_STATUS_OK, InitializeDatabase());
278 }
279
280 TEST_F(SyncFS_MetadataDatabaseTest, InitializationTest_SimpleTree) {
281 std::string app_id = "app_id";
282 DriveFileMetadata sync_root(CreateSyncRoot());
283 DriveFileMetadata app_root(CreateFolder(app_id, kSyncRootFolderID, app_id));
284 DriveFileMetadata file(CreateFile(app_id, app_root.file_id(), "file"));
285 DriveFileMetadata folder(CreateFolder(app_id, app_root.file_id(), "folder"));
286 DriveFileMetadata file_in_folder(
287 CreateFile(app_id, folder.file_id(), "file_in_folder"));
288 DriveFileMetadata orphaned(CreateUnknownFile(std::string(), "root"));
289
290 {
291 scoped_ptr<leveldb::DB> db = OpenDB();
292 ASSERT_TRUE(db);
293 db->Put(leveldb::WriteOptions(), "VERSION", base::Int64ToString(3));
294 SetUpServiceMetadata(db.get());
295
296 EXPECT_TRUE(PutFileToDB(db.get(), sync_root).ok());
297 EXPECT_TRUE(PutFileToDB(db.get(), app_root).ok());
298 EXPECT_TRUE(PutFileToDB(db.get(), file).ok());
299 EXPECT_TRUE(PutFileToDB(db.get(), folder).ok());
300 EXPECT_TRUE(PutFileToDB(db.get(), file_in_folder).ok());
301 EXPECT_TRUE(PutFileToDB(db.get(), orphaned).ok());
302 }
303
304 EXPECT_EQ(SYNC_STATUS_OK, InitializeDatabase());
305 VerifyReloadConsistency();
306
307 VerifyMetadataExists(sync_root);
308 VerifyMetadataExists(app_root);
309 VerifyMetadataExists(file);
310 VerifyMetadataExists(folder);
311 VerifyMetadataExists(file_in_folder);
312 EXPECT_FALSE(metadata_database()->FindFileByFileID(orphaned.file_id(), NULL));
313 }
314
315 } // namespace drive_backend
316 } // namespace sync_file_system
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698