blob: 6988a21b04725df9becf15478e0555a2cf3e11e6 [file] [log] [blame]
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/sync_file_system/drive_backend/metadata_db_migration_util.h"
#include <memory>
#include <string>
#include "base/files/scoped_temp_dir.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "chrome/browser/sync_file_system/drive_backend/drive_backend_constants.h"
#include "chrome/browser/sync_file_system/syncable_file_system_util.h"
#include "storage/browser/fileapi/external_mount_points.h"
#include "storage/common/fileapi/file_system_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/leveldatabase/env_chromium.h"
#include "third_party/leveldatabase/src/include/leveldb/db.h"
#include "third_party/leveldatabase/src/include/leveldb/write_batch.h"
#include "url/gurl.h"
#define FPL FILE_PATH_LITERAL
namespace sync_file_system {
namespace drive_backend {
namespace {
void VerifyKeyAndValue(const std::string& key,
const std::string& expect_val,
leveldb::DB* db) {
std::unique_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) {
std::unique_ptr<leveldb::Iterator> itr(
db->NewIterator(leveldb::ReadOptions()));
itr->Seek(key);
EXPECT_TRUE(!itr->Valid() ||
!base::StartsWith(itr->key().ToString(), key,
base::CompareCase::SENSITIVE));
}
} // namespace
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.
std::unique_ptr<leveldb::DB> db;
base::ScopedTempDir base_dir;
ASSERT_TRUE(base_dir.CreateUniqueTempDir());
{
leveldb_env::Options options;
options.create_if_missing = true;
std::string db_dir =
storage::FilePathToString(base_dir.GetPath().Append(kDatabaseName));
leveldb::Status status = leveldb_env::OpenDB(options, db_dir, &db);
ASSERT_TRUE(status.ok());
}
// 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