Commit 9c0663b1 authored by peria@chromium.org's avatar peria@chromium.org

[SyncFS] Rollback function from version 4 to version 3.

Make a routine, but it is not called.


BUG=347425
TEST=./unit_tests --gtest_filter="DriveMetadata*"

Review URL: https://codereview.chromium.org/446653003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@288012 0039d316-1c4b-4281-b951-d872f2087c98
parent ddf8e5d6
......@@ -244,5 +244,61 @@ SyncStatusCode MigrateDatabaseFromV1ToV2(leveldb::DB* db) {
db->Write(leveldb::WriteOptions(), &write_batch));
}
SyncStatusCode MigrateDatabaseFromV4ToV3(leveldb::DB* db) {
// Rollback from version 4 to version 3.
// Please see metadata_database_index.cc for version 3 format, and
// metadata_database_index_on_disk.cc for version 4 format.
const char kDatabaseVersionKey[] = "VERSION";
const char kServiceMetadataKey[] = "SERVICE";
const char kFileMetadataKeyPrefix[] = "FILE: ";
const char kFileTrackerKeyPrefix[] = "TRACKER: ";
// Key prefixes used in version 4.
const char kAppRootIDByAppIDKeyPrefix[] = "APP_ROOT: ";
const char kActiveTrackerIDByFileIDKeyPrefix[] = "ACTIVE_FILE: ";
const char kTrackerIDByFileIDKeyPrefix[] = "TRACKER_FILE: ";
const char kMultiTrackerByFileIDKeyPrefix[] = "MULTI_FILE: ";
const char kActiveTrackerIDByParentAndTitleKeyPrefix[] = "ACTIVE_PATH: ";
const char kTrackerIDByParentAndTitleKeyPrefix[] = "TRACKER_PATH: ";
const char kMultiBackingParentAndTitleKeyPrefix[] = "MULTI_PATH: ";
const char kDirtyIDKeyPrefix[] = "DIRTY: ";
const char kDemotedDirtyIDKeyPrefix[] = "DEMOTED_DIRTY: ";
leveldb::WriteBatch write_batch;
write_batch.Put(kDatabaseVersionKey, "3");
scoped_ptr<leveldb::Iterator> itr(db->NewIterator(leveldb::ReadOptions()));
for (itr->SeekToFirst(); itr->Valid(); itr->Next()) {
std::string key = itr->key().ToString();
// Do nothing for valid entries in both versions.
if (StartsWithASCII(key, kServiceMetadataKey, true) ||
StartsWithASCII(key, kFileMetadataKeyPrefix, true) ||
StartsWithASCII(key, kFileTrackerKeyPrefix, true)) {
continue;
}
// Drop entries used in version 4 only.
if (StartsWithASCII(key, kAppRootIDByAppIDKeyPrefix, true) ||
StartsWithASCII(key, kActiveTrackerIDByFileIDKeyPrefix, true) ||
StartsWithASCII(key, kTrackerIDByFileIDKeyPrefix, true) ||
StartsWithASCII(key, kMultiTrackerByFileIDKeyPrefix, true) ||
StartsWithASCII(key, kActiveTrackerIDByParentAndTitleKeyPrefix, true) ||
StartsWithASCII(key, kTrackerIDByParentAndTitleKeyPrefix, true) ||
StartsWithASCII(key, kMultiBackingParentAndTitleKeyPrefix, true) ||
StartsWithASCII(key, kDirtyIDKeyPrefix, true) ||
StartsWithASCII(key, kDemotedDirtyIDKeyPrefix, true)) {
write_batch.Delete(key);
continue;
}
DVLOG(3) << "Unknown key: " << key << " was found.";
}
return LevelDBStatusToSyncStatusCode(
db->Write(leveldb::WriteOptions(), &write_batch));
}
} // namespace drive_backend
} // namespace sync_file_system
......@@ -58,6 +58,9 @@ SyncStatusCode MigrateDatabaseFromV0ToV1(leveldb::DB* db);
// Migrate |db| schema from version 1 to version 2.
SyncStatusCode MigrateDatabaseFromV1ToV2(leveldb::DB* db);
// Rollback |db| schema from version 4 to version 3.
SyncStatusCode MigrateDatabaseFromV4ToV3(leveldb::DB* db);
} // namespace drive_backend
} // namespace sync_file_system
......
......@@ -45,6 +45,24 @@ bool CreateV0SerializedSyncableFileSystemURL(
return true;
}
void VerifyKeyAndValue(const std::string& key,
const std::string& expect_val,
leveldb::DB* db) {
scoped_ptr<leveldb::Iterator> itr(db->NewIterator(leveldb::ReadOptions()));
itr->Seek(key);
EXPECT_TRUE(itr->Valid());
EXPECT_EQ(expect_val, itr->value().ToString());
}
void VerifyNotExist(const std::string& key, leveldb::DB* db) {
scoped_ptr<leveldb::Iterator> itr(db->NewIterator(leveldb::ReadOptions()));
itr->Seek(key);
EXPECT_TRUE(!itr->Valid() ||
!StartsWithASCII(itr->key().ToString(), key, true));
}
} // namespace
TEST(DriveMetadataDBMigrationUtilTest, ParseV0FormatFileSystemURL) {
......@@ -309,5 +327,83 @@ TEST(DriveMetadataDBMigrationUtilTest, MigrationFromV1) {
EXPECT_EQ(RemoveWapiIdPrefix(kResourceId3), itr->value().ToString());
}
TEST(DriveMetadataDBMigrationUtilTest, RollbackFromV4ToV3) {
// Rollback from version 4 to version 3.
// Please see metadata_database_index.cc for version 3 format, and
// metadata_database_index_on_disk.cc for version 4 format.
const char kDatabaseVersionKey[] = "VERSION";
const char kServiceMetadataKey[] = "SERVICE";
const char kFileMetadataKeyPrefix[] = "FILE: ";
const char kFileTrackerKeyPrefix[] = "TRACKER: ";
// Key prefixes used in version 4.
const char kAppRootIDByAppIDKeyPrefix[] = "APP_ROOT: ";
const char kActiveTrackerIDByFileIDKeyPrefix[] = "ACTIVE_FILE: ";
const char kTrackerIDByFileIDKeyPrefix[] = "TRACKER_FILE: ";
const char kMultiTrackerByFileIDKeyPrefix[] = "MULTI_FILE: ";
const char kActiveTrackerIDByParentAndTitleKeyPrefix[] = "ACTIVE_PATH: ";
const char kTrackerIDByParentAndTitleKeyPrefix[] = "TRACKER_PATH: ";
const char kMultiBackingParentAndTitleKeyPrefix[] = "MULTI_PATH: ";
const char kDirtyIDKeyPrefix[] = "DIRTY: ";
const char kDemotedDirtyIDKeyPrefix[] = "DEMOTED_DIRTY: ";
// Set up environment.
leveldb::DB* db_ptr = NULL;
{
base::ScopedTempDir base_dir;
ASSERT_TRUE(base_dir.CreateUniqueTempDir());
leveldb::Options options;
options.create_if_missing = true;
std::string db_dir = fileapi::FilePathToString(
base_dir.path().Append(DriveMetadataStore::kDatabaseName));
leveldb::Status status = leveldb::DB::Open(options, db_dir, &db_ptr);
ASSERT_TRUE(status.ok());
}
scoped_ptr<leveldb::DB> db(db_ptr);
// Setup the database with the schema version 4, without IDs.
leveldb::WriteBatch batch;
batch.Put(kDatabaseVersionKey, "4");
batch.Put(kServiceMetadataKey, "service_metadata");
batch.Put(kFileMetadataKeyPrefix, "file_metadata");
batch.Put(kFileTrackerKeyPrefix, "file_tracker");
batch.Put(kAppRootIDByAppIDKeyPrefix, "app_root_id");
batch.Put(kActiveTrackerIDByFileIDKeyPrefix, "active_id_by_file");
batch.Put(kTrackerIDByFileIDKeyPrefix, "tracker_id_by_file");
batch.Put(kMultiTrackerByFileIDKeyPrefix, "multi_tracker_by_file");
batch.Put(kActiveTrackerIDByParentAndTitleKeyPrefix, "active_id_by_path");
batch.Put(kTrackerIDByParentAndTitleKeyPrefix, "tracker_id_by_path");
batch.Put(kMultiBackingParentAndTitleKeyPrefix, "multi_tracker_by_path");
batch.Put(kDirtyIDKeyPrefix, "dirty");
batch.Put(kDemotedDirtyIDKeyPrefix, "demoted_dirty");
leveldb::Status status = db->Write(leveldb::WriteOptions(), &batch);
EXPECT_EQ(SYNC_STATUS_OK, LevelDBStatusToSyncStatusCode(status));
// Migrate the database.
MigrateDatabaseFromV4ToV3(db.get());
// Verify DB schema verison
VerifyKeyAndValue(kDatabaseVersionKey, "3", db.get());
// Verify remained entries.
VerifyKeyAndValue(kServiceMetadataKey, "service_metadata", db.get());
VerifyKeyAndValue(kFileMetadataKeyPrefix, "file_metadata", db.get());
VerifyKeyAndValue(kFileTrackerKeyPrefix, "file_tracker", db.get());
// Verify
VerifyNotExist(kAppRootIDByAppIDKeyPrefix, db.get());
VerifyNotExist(kActiveTrackerIDByFileIDKeyPrefix, db.get());
VerifyNotExist(kTrackerIDByFileIDKeyPrefix, db.get());
VerifyNotExist(kMultiTrackerByFileIDKeyPrefix, db.get());
VerifyNotExist(kActiveTrackerIDByParentAndTitleKeyPrefix, db.get());
VerifyNotExist(kTrackerIDByParentAndTitleKeyPrefix, db.get());
VerifyNotExist(kMultiBackingParentAndTitleKeyPrefix, db.get());
VerifyNotExist(kDirtyIDKeyPrefix, db.get());
VerifyNotExist(kDemotedDirtyIDKeyPrefix, db.get());
}
} // namespace drive_backend
} // namespace sync_file_system
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment