| OLD | NEW |
| (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 AreEquivalentProtobufs(const Value& left, const Value& right) { |
| 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 void DatabaseCreateResultCallback(SyncStatusCode* status_out, |
| 41 scoped_ptr<MetadataDatabase>* database_out, |
| 42 SyncStatusCode status, |
| 43 scoped_ptr<MetadataDatabase> database) { |
| 44 EXPECT_EQ(SYNC_STATUS_UNKNOWN, *status_out); |
| 45 *status_out = status; |
| 46 *database_out = database.Pass(); |
| 47 } |
| 48 |
| 49 } // namespace |
| 50 |
| 51 class MetadataDatabaseTest : public testing::Test { |
| 52 public: |
| 53 MetadataDatabaseTest() : next_file_id_number_(1) {} |
| 54 |
| 55 virtual ~MetadataDatabaseTest() {} |
| 56 |
| 57 virtual void SetUp() OVERRIDE { |
| 58 ASSERT_TRUE(database_dir_.CreateUniqueTempDir()); |
| 59 } |
| 60 |
| 61 virtual void TearDown() OVERRIDE { DropDatabase(); } |
| 62 |
| 63 protected: |
| 64 std::string GenerateFileID() { |
| 65 return "file_id_" + base::Int64ToString(next_file_id_number_++); |
| 66 } |
| 67 |
| 68 SyncStatusCode InitializeDatabase() { |
| 69 SyncStatusCode status = SYNC_STATUS_UNKNOWN; |
| 70 MetadataDatabase::Create(base::MessageLoopProxy::current(), |
| 71 database_dir_.path(), |
| 72 base::Bind(&DatabaseCreateResultCallback, |
| 73 &status, &metadata_database_)); |
| 74 message_loop_.RunUntilIdle(); |
| 75 return status; |
| 76 } |
| 77 |
| 78 void DropDatabase() { |
| 79 metadata_database_.reset(); |
| 80 message_loop_.RunUntilIdle(); |
| 81 } |
| 82 |
| 83 MetadataDatabase* metadata_database() { return metadata_database_.get(); } |
| 84 |
| 85 leveldb::DB* db() { |
| 86 if (!metadata_database_) |
| 87 return NULL; |
| 88 return metadata_database_->db_.get(); |
| 89 } |
| 90 |
| 91 scoped_ptr<leveldb::DB> OpenDB() { |
| 92 leveldb::DB* db = NULL; |
| 93 leveldb::Options options; |
| 94 options.create_if_missing = true; |
| 95 leveldb::Status status = |
| 96 leveldb::DB::Open(options, database_dir_.path().AsUTF8Unsafe(), &db); |
| 97 EXPECT_TRUE(status.ok()); |
| 98 return make_scoped_ptr(db); |
| 99 } |
| 100 |
| 101 void SetUpServiceMetadata(leveldb::DB* db) { |
| 102 ServiceMetadata service_metadata; |
| 103 service_metadata.set_largest_change_id(kInitialChangeID); |
| 104 service_metadata.set_sync_root_folder_id(kSyncRootFolderID); |
| 105 std::string value; |
| 106 ASSERT_TRUE(service_metadata.SerializeToString(&value)); |
| 107 db->Put(leveldb::WriteOptions(), "SERVICE", value); |
| 108 } |
| 109 |
| 110 DriveFileMetadata CreateSyncRoot() { |
| 111 DriveFileMetadata metadata; |
| 112 metadata.set_file_id(kSyncRootFolderID); |
| 113 metadata.set_parent_folder_id(std::string()); |
| 114 metadata.mutable_synced_details()->set_title("Chrome Syncable FileSystem"); |
| 115 metadata.mutable_synced_details()->set_kind(KIND_FOLDER); |
| 116 metadata.set_active(true); |
| 117 metadata.set_dirty(false); |
| 118 return metadata; |
| 119 } |
| 120 |
| 121 DriveFileMetadata CreateUnknownFile(const std::string& app_id, |
| 122 const std::string& parent_folder_id) { |
| 123 DriveFileMetadata metadata; |
| 124 metadata.set_file_id(GenerateFileID()); |
| 125 metadata.set_parent_folder_id(parent_folder_id); |
| 126 metadata.set_app_id(app_id); |
| 127 metadata.set_is_app_root(parent_folder_id == kSyncRootFolderID); |
| 128 return metadata; |
| 129 } |
| 130 |
| 131 DriveFileMetadata CreateFile(const std::string& app_id, |
| 132 const std::string& parent_folder_id, |
| 133 const std::string& title) { |
| 134 DriveFileMetadata file(CreateUnknownFile(app_id, parent_folder_id)); |
| 135 file.mutable_synced_details()->add_parent_folder_id(parent_folder_id); |
| 136 file.mutable_synced_details()->set_title(title); |
| 137 file.mutable_synced_details()->set_kind(KIND_FILE); |
| 138 file.set_active(true); |
| 139 file.set_dirty(false); |
| 140 return file; |
| 141 } |
| 142 |
| 143 DriveFileMetadata CreateFolder(const std::string& app_id, |
| 144 const std::string& parent_folder_id, |
| 145 const std::string& title) { |
| 146 DriveFileMetadata folder(CreateUnknownFile(app_id, parent_folder_id)); |
| 147 folder.mutable_synced_details()->add_parent_folder_id(parent_folder_id); |
| 148 folder.mutable_synced_details()->set_title(title); |
| 149 folder.mutable_synced_details()->set_kind(KIND_FOLDER); |
| 150 folder.set_active(true); |
| 151 folder.set_dirty(false); |
| 152 return folder; |
| 153 } |
| 154 |
| 155 leveldb::Status PutFileToDB(leveldb::DB* db, const DriveFileMetadata& file) { |
| 156 std::string key = "FILE: " + file.file_id(); |
| 157 std::string value; |
| 158 file.SerializeToString(&value); |
| 159 return db->Put(leveldb::WriteOptions(), key, value); |
| 160 } |
| 161 |
| 162 void VerifyMetadataExists(const DriveFileMetadata& file) { |
| 163 DriveFileMetadata file_in_metadata_db; |
| 164 ASSERT_TRUE(metadata_database()->FindFileByFileID( |
| 165 file.file_id(), &file_in_metadata_db)); |
| 166 EXPECT_TRUE(AreEquivalentProtobufs(file, file_in_metadata_db)); |
| 167 } |
| 168 |
| 169 private: |
| 170 base::ScopedTempDir database_dir_; |
| 171 base::MessageLoop message_loop_; |
| 172 |
| 173 scoped_ptr<MetadataDatabase> metadata_database_; |
| 174 |
| 175 int64 next_file_id_number_; |
| 176 |
| 177 DISALLOW_COPY_AND_ASSIGN(MetadataDatabaseTest); |
| 178 }; |
| 179 |
| 180 TEST_F(MetadataDatabaseTest, InitializationTest_Empty) { |
| 181 EXPECT_EQ(SYNC_STATUS_OK, InitializeDatabase()); |
| 182 DropDatabase(); |
| 183 EXPECT_EQ(SYNC_STATUS_OK, InitializeDatabase()); |
| 184 } |
| 185 |
| 186 TEST_F(MetadataDatabaseTest, InitializationTest_SimpleTree) { |
| 187 std::string app_id = "app_id"; |
| 188 DriveFileMetadata sync_root(CreateSyncRoot()); |
| 189 DriveFileMetadata app_root(CreateFolder(app_id, kSyncRootFolderID, app_id)); |
| 190 DriveFileMetadata file(CreateFile(app_id, app_root.file_id(), "file")); |
| 191 DriveFileMetadata folder(CreateFolder(app_id, app_root.file_id(), "folder")); |
| 192 DriveFileMetadata file_in_folder( |
| 193 CreateFile(app_id, folder.file_id(), "file_in_folder")); |
| 194 DriveFileMetadata orphaned(CreateUnknownFile(std::string(), "root")); |
| 195 |
| 196 { |
| 197 scoped_ptr<leveldb::DB> db = OpenDB(); |
| 198 ASSERT_TRUE(db); |
| 199 db->Put(leveldb::WriteOptions(), "VERSION", base::Int64ToString(3)); |
| 200 SetUpServiceMetadata(db.get()); |
| 201 |
| 202 EXPECT_TRUE(PutFileToDB(db.get(), sync_root).ok()); |
| 203 EXPECT_TRUE(PutFileToDB(db.get(), app_root).ok()); |
| 204 EXPECT_TRUE(PutFileToDB(db.get(), file).ok()); |
| 205 EXPECT_TRUE(PutFileToDB(db.get(), folder).ok()); |
| 206 EXPECT_TRUE(PutFileToDB(db.get(), file_in_folder).ok()); |
| 207 EXPECT_TRUE(PutFileToDB(db.get(), orphaned).ok()); |
| 208 } |
| 209 |
| 210 EXPECT_EQ(SYNC_STATUS_OK, InitializeDatabase()); |
| 211 |
| 212 VerifyMetadataExists(sync_root); |
| 213 VerifyMetadataExists(app_root); |
| 214 VerifyMetadataExists(file); |
| 215 VerifyMetadataExists(folder); |
| 216 VerifyMetadataExists(file_in_folder); |
| 217 EXPECT_FALSE(metadata_database()->FindFileByFileID(orphaned.file_id(), NULL)); |
| 218 } |
| 219 |
| 220 } // namespace drive_backend |
| 221 } // namespace sync_file_system |
| OLD | NEW |