Index: chrome/browser/sync_file_system/drive_backend/metadata_db_migration_util_unittest.cc |
diff --git a/chrome/browser/sync_file_system/drive_backend/metadata_db_migration_util_unittest.cc b/chrome/browser/sync_file_system/drive_backend/metadata_db_migration_util_unittest.cc |
index 4ab2f1c03fcbd3a81e47f63ef8b03e45b57524dd..db62e1ba4620145849b575f72e1b6036af0f1369 100644 |
--- a/chrome/browser/sync_file_system/drive_backend/metadata_db_migration_util_unittest.cc |
+++ b/chrome/browser/sync_file_system/drive_backend/metadata_db_migration_util_unittest.cc |
@@ -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: "; |
nhiroki
2014/08/07 06:26:39
I'd prefer not to spread these constants across pr
|
+ |
+ // 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 |