metadata_db_migration_util_unittest.cc revision eb525c5499e34cc9c4b825d6d9e75bb07cc06ace
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_db_migration_util.h" 6 7#include "base/files/scoped_temp_dir.h" 8#include "base/strings/string_number_conversions.h" 9#include "base/strings/string_util.h" 10#include "chrome/browser/sync_file_system/drive_metadata_store.h" 11#include "testing/gtest/include/gtest/gtest.h" 12#include "third_party/leveldatabase/src/include/leveldb/db.h" 13#include "third_party/leveldatabase/src/include/leveldb/write_batch.h" 14#include "url/gurl.h" 15#include "webkit/browser/fileapi/external_mount_points.h" 16#include "webkit/browser/fileapi/syncable/syncable_file_system_util.h" 17#include "webkit/common/fileapi/file_system_util.h" 18 19#define FPL FILE_PATH_LITERAL 20 21namespace sync_file_system { 22namespace drive_backend { 23 24namespace { 25 26const char kV0ServiceName[] = "drive"; 27 28bool CreateV0SerializedSyncableFileSystemURL( 29 const GURL& origin, 30 const base::FilePath& path, 31 std::string* serialized_url) { 32 fileapi::ScopedExternalFileSystem scoped_fs( 33 kV0ServiceName, fileapi::kFileSystemTypeSyncable, base::FilePath()); 34 35 fileapi::FileSystemURL url = 36 fileapi::ExternalMountPoints::GetSystemInstance()-> 37 CreateExternalFileSystemURL(origin, kV0ServiceName, path); 38 if (!url.is_valid()) 39 return false; 40 *serialized_url = fileapi::GetExternalFileSystemRootURIString( 41 origin, kV0ServiceName) + url.path().AsUTF8Unsafe(); 42 return true; 43} 44 45} // namespace 46 47TEST(DriveMetadataDBMigrationUtilTest, ParseV0FormatFileSystemURL) { 48 const GURL kOrigin("chrome-extension://example"); 49 const base::FilePath kFile(FPL("foo bar")); 50 51 std::string serialized_url; 52 ASSERT_TRUE(CreateV0SerializedSyncableFileSystemURL( 53 kOrigin, kFile, &serialized_url)); 54 55 GURL origin; 56 base::FilePath path; 57 EXPECT_TRUE(ParseV0FormatFileSystemURL(GURL(serialized_url), &origin, &path)); 58 EXPECT_EQ(kOrigin, origin); 59 EXPECT_EQ(kFile, path); 60} 61 62TEST(DriveMetadataDBMigrationUtilTest, AddWapiIdPrefix) { 63 DriveMetadata_ResourceType type_file = 64 DriveMetadata_ResourceType_RESOURCE_TYPE_FILE; 65 DriveMetadata_ResourceType type_folder = 66 DriveMetadata_ResourceType_RESOURCE_TYPE_FOLDER; 67 68 EXPECT_EQ("file:xxx", AddWapiFilePrefix("xxx")); 69 EXPECT_EQ("folder:yyy", AddWapiFolderPrefix("yyy")); 70 EXPECT_EQ("file:xxx", AddWapiIdPrefix("xxx", type_file)); 71 EXPECT_EQ("folder:yyy", AddWapiIdPrefix("yyy", type_folder)); 72 73 EXPECT_EQ("", AddWapiFilePrefix("")); 74 EXPECT_EQ("", AddWapiFolderPrefix("")); 75 EXPECT_EQ("", AddWapiIdPrefix("", type_file)); 76 EXPECT_EQ("", AddWapiIdPrefix("", type_folder)); 77} 78 79TEST(DriveMetadataDBMigrationUtilTest, RemoveWapiIdPrefix) { 80 EXPECT_EQ("xxx", RemoveWapiIdPrefix("xxx")); 81 EXPECT_EQ("yyy", RemoveWapiIdPrefix("file:yyy")); 82 EXPECT_EQ("zzz", RemoveWapiIdPrefix("folder:zzz")); 83 84 EXPECT_EQ("", RemoveWapiIdPrefix("")); 85 EXPECT_EQ("foo:xxx", RemoveWapiIdPrefix("foo:xxx")); 86} 87 88TEST(DriveMetadataDBMigrationUtilTest, MigrationFromV0) { 89 const char kDatabaseVersionKey[] = "VERSION"; 90 const char kChangeStampKey[] = "CHANGE_STAMP"; 91 const char kSyncRootDirectoryKey[] = "SYNC_ROOT_DIR"; 92 const char kDriveMetadataKeyPrefix[] = "METADATA: "; 93 const char kDriveBatchSyncOriginKeyPrefix[] = "BSYNC_ORIGIN: "; 94 const char kDriveIncrementalSyncOriginKeyPrefix[] = "ISYNC_ORIGIN: "; 95 96 const GURL kOrigin1("chrome-extension://example1"); 97 const GURL kOrigin2("chrome-extension://example2"); 98 const std::string kSyncRootResourceId("folder:sync_root_resource_id"); 99 const std::string kResourceId1("folder:hoge"); 100 const std::string kResourceId2("folder:fuga"); 101 const std::string kFileResourceId("file:piyo"); 102 const base::FilePath kFile(FPL("foo bar")); 103 const std::string kFileMD5("file_md5"); 104 105 base::ScopedTempDir base_dir; 106 ASSERT_TRUE(base_dir.CreateUniqueTempDir()); 107 108 leveldb::Options options; 109 options.create_if_missing = true; 110 leveldb::DB* db_ptr = NULL; 111 std::string db_dir = fileapi::FilePathToString( 112 base_dir.path().Append(DriveMetadataStore::kDatabaseName)); 113 leveldb::Status status = leveldb::DB::Open(options, db_dir, &db_ptr); 114 115 scoped_ptr<leveldb::DB> db(db_ptr); 116 ASSERT_TRUE(status.ok()); 117 118 // Setup the database with the schema version 0. 119 leveldb::WriteBatch batch; 120 batch.Put(kChangeStampKey, "1"); 121 batch.Put(kSyncRootDirectoryKey, kSyncRootResourceId); 122 123 // Setup drive metadata. 124 DriveMetadata drive_metadata; 125 drive_metadata.set_resource_id(kFileResourceId); 126 drive_metadata.set_md5_checksum(kFileMD5); 127 drive_metadata.set_conflicted(false); 128 drive_metadata.set_to_be_fetched(false); 129 130 std::string serialized_url; 131 ASSERT_TRUE(CreateV0SerializedSyncableFileSystemURL( 132 kOrigin1, kFile, &serialized_url)); 133 std::string metadata_string; 134 drive_metadata.SerializeToString(&metadata_string); 135 batch.Put(kDriveMetadataKeyPrefix + serialized_url, metadata_string); 136 137 // Setup batch sync origin and incremental sync origin. 138 batch.Put(kDriveBatchSyncOriginKeyPrefix + kOrigin1.spec(), kResourceId1); 139 batch.Put(kDriveIncrementalSyncOriginKeyPrefix + kOrigin2.spec(), 140 kResourceId2); 141 142 status = db->Write(leveldb::WriteOptions(), &batch); 143 EXPECT_EQ(SYNC_STATUS_OK, LevelDBStatusToSyncStatusCode(status)); 144 145 // Migrate the database. 146 MigrateDatabaseFromV0ToV1(db.get()); 147 148 scoped_ptr<leveldb::Iterator> itr(db->NewIterator(leveldb::ReadOptions())); 149 150 // Verify DB schema version. 151 int64 database_version = 0; 152 itr->Seek(kDatabaseVersionKey); 153 EXPECT_TRUE(itr->Valid()); 154 EXPECT_TRUE(base::StringToInt64(itr->value().ToString(), &database_version)); 155 EXPECT_EQ(1, database_version); 156 157 // Verify the largest changestamp. 158 int64 changestamp = 0; 159 itr->Seek(kChangeStampKey); 160 EXPECT_TRUE(itr->Valid()); 161 EXPECT_TRUE(base::StringToInt64(itr->value().ToString(), &changestamp)); 162 EXPECT_EQ(1, changestamp); 163 164 // Verify the sync root directory. 165 itr->Seek(kSyncRootDirectoryKey); 166 EXPECT_TRUE(itr->Valid()); 167 EXPECT_EQ(kSyncRootResourceId, itr->value().ToString()); 168 169 // Verify the metadata. 170 itr->Seek(kDriveMetadataKeyPrefix); 171 EXPECT_TRUE(itr->Valid()); 172 DriveMetadata metadata; 173 EXPECT_TRUE(metadata.ParseFromString(itr->value().ToString())); 174 EXPECT_EQ(kFileResourceId, metadata.resource_id()); 175 EXPECT_EQ(kFileMD5, metadata.md5_checksum()); 176 EXPECT_FALSE(metadata.conflicted()); 177 EXPECT_FALSE(metadata.to_be_fetched()); 178 179 // Verify the batch sync origin. 180 itr->Seek(kDriveBatchSyncOriginKeyPrefix); 181 EXPECT_TRUE(itr->Valid()); 182 EXPECT_EQ(kResourceId1, itr->value().ToString()); 183 184 // Verify the incremental sync origin. 185 itr->Seek(kDriveIncrementalSyncOriginKeyPrefix); 186 EXPECT_TRUE(itr->Valid()); 187 EXPECT_EQ(kResourceId2, itr->value().ToString()); 188} 189 190TEST(DriveMetadataDBMigrationUtilTest, MigrationFromV1) { 191 const char kDatabaseVersionKey[] = "VERSION"; 192 const char kChangeStampKey[] = "CHANGE_STAMP"; 193 const char kSyncRootDirectoryKey[] = "SYNC_ROOT_DIR"; 194 const char kDriveMetadataKeyPrefix[] = "METADATA: "; 195 const char kMetadataKeySeparator = ' '; 196 const char kDriveBatchSyncOriginKeyPrefix[] = "BSYNC_ORIGIN: "; 197 const char kDriveIncrementalSyncOriginKeyPrefix[] = "ISYNC_ORIGIN: "; 198 const char kDriveDisabledOriginKeyPrefix[] = "DISABLED_ORIGIN: "; 199 200 const GURL kOrigin1("chrome-extension://example1"); 201 const GURL kOrigin2("chrome-extension://example2"); 202 const GURL kOrigin3("chrome-extension://example3"); 203 204 const std::string kSyncRootResourceId("folder:sync_root_resource_id"); 205 const std::string kResourceId1("folder:hoge"); 206 const std::string kResourceId2("folder:fuga"); 207 const std::string kResourceId3("folder:hogera"); 208 const std::string kFileResourceId("file:piyo"); 209 const base::FilePath kFile(FPL("foo bar")); 210 const std::string kFileMD5("file_md5"); 211 212 RegisterSyncableFileSystem(); 213 214 base::ScopedTempDir base_dir; 215 ASSERT_TRUE(base_dir.CreateUniqueTempDir()); 216 217 leveldb::Options options; 218 options.create_if_missing = true; 219 leveldb::DB* db_ptr = NULL; 220 std::string db_dir = fileapi::FilePathToString( 221 base_dir.path().Append(DriveMetadataStore::kDatabaseName)); 222 leveldb::Status status = leveldb::DB::Open(options, db_dir, &db_ptr); 223 224 scoped_ptr<leveldb::DB> db(db_ptr); 225 ASSERT_TRUE(status.ok()); 226 227 // Setup the database with the schema version 1. 228 leveldb::WriteBatch batch; 229 batch.Put(kDatabaseVersionKey, "1"); 230 batch.Put(kChangeStampKey, "1"); 231 batch.Put(kSyncRootDirectoryKey, kSyncRootResourceId); 232 233 fileapi::FileSystemURL url = CreateSyncableFileSystemURL(kOrigin1, kFile); 234 235 // Setup drive metadata. 236 DriveMetadata drive_metadata; 237 drive_metadata.set_resource_id(kFileResourceId); 238 drive_metadata.set_md5_checksum(kFileMD5); 239 drive_metadata.set_conflicted(false); 240 drive_metadata.set_to_be_fetched(false); 241 std::string metadata_string; 242 drive_metadata.SerializeToString(&metadata_string); 243 std::string metadata_key = kDriveMetadataKeyPrefix + kOrigin1.spec() + 244 kMetadataKeySeparator + url.path().AsUTF8Unsafe(); 245 batch.Put(metadata_key, metadata_string); 246 247 // Setup origins. 248 batch.Put(kDriveBatchSyncOriginKeyPrefix + kOrigin1.spec(), kResourceId1); 249 batch.Put(kDriveIncrementalSyncOriginKeyPrefix + kOrigin2.spec(), 250 kResourceId2); 251 batch.Put(kDriveDisabledOriginKeyPrefix + kOrigin3.spec(), kResourceId3); 252 253 status = db->Write(leveldb::WriteOptions(), &batch); 254 EXPECT_EQ(SYNC_STATUS_OK, LevelDBStatusToSyncStatusCode(status)); 255 256 RevokeSyncableFileSystem(); 257 258 // Migrate the database. 259 MigrateDatabaseFromV1ToV2(db.get()); 260 261 scoped_ptr<leveldb::Iterator> itr(db->NewIterator(leveldb::ReadOptions())); 262 263 // Verify DB schema version. 264 int64 database_version = 0; 265 itr->Seek(kDatabaseVersionKey); 266 EXPECT_TRUE(itr->Valid()); 267 EXPECT_TRUE(base::StringToInt64(itr->value().ToString(), &database_version)); 268 EXPECT_EQ(2, database_version); 269 270 // Verify the largest changestamp. 271 int64 changestamp = 0; 272 itr->Seek(kChangeStampKey); 273 EXPECT_TRUE(itr->Valid()); 274 EXPECT_TRUE(base::StringToInt64(itr->value().ToString(), &changestamp)); 275 EXPECT_EQ(1, changestamp); 276 277 // Verify the sync root directory. 278 itr->Seek(kSyncRootDirectoryKey); 279 EXPECT_TRUE(itr->Valid()); 280 EXPECT_EQ(RemoveWapiIdPrefix(kSyncRootResourceId), itr->value().ToString()); 281 282 // Verify the metadata. 283 itr->Seek(kDriveMetadataKeyPrefix); 284 EXPECT_TRUE(itr->Valid()); 285 DriveMetadata metadata; 286 EXPECT_TRUE(metadata.ParseFromString(itr->value().ToString())); 287 EXPECT_EQ(RemoveWapiIdPrefix(kFileResourceId), metadata.resource_id()); 288 EXPECT_EQ(kFileMD5, metadata.md5_checksum()); 289 EXPECT_FALSE(metadata.conflicted()); 290 EXPECT_FALSE(metadata.to_be_fetched()); 291 292 // Verify the batch sync origin. 293 itr->Seek(kDriveBatchSyncOriginKeyPrefix); 294 EXPECT_FALSE(StartsWithASCII(kDriveBatchSyncOriginKeyPrefix, 295 itr->key().ToString(), true)); 296 297 // Verify the incremental sync origin. 298 itr->Seek(kDriveIncrementalSyncOriginKeyPrefix); 299 EXPECT_TRUE(itr->Valid()); 300 EXPECT_EQ(RemoveWapiIdPrefix(kResourceId2), itr->value().ToString()); 301 302 // Verify the disabled origin. 303 itr->Seek(kDriveDisabledOriginKeyPrefix); 304 EXPECT_TRUE(itr->Valid()); 305 EXPECT_EQ(RemoveWapiIdPrefix(kResourceId3), itr->value().ToString()); 306} 307 308} // namespace drive_backend 309} // namespace sync_file_system 310