Chromium Code Reviews| 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 |