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_backend/drive_backend_constants.h" 11#include "chrome/browser/sync_file_system/syncable_file_system_util.h" 12#include "storage/browser/fileapi/external_mount_points.h" 13#include "storage/common/fileapi/file_system_util.h" 14#include "testing/gtest/include/gtest/gtest.h" 15#include "third_party/leveldatabase/src/include/leveldb/db.h" 16#include "third_party/leveldatabase/src/include/leveldb/write_batch.h" 17#include "url/gurl.h" 18 19#define FPL FILE_PATH_LITERAL 20 21namespace sync_file_system { 22namespace drive_backend { 23 24namespace { 25 26void VerifyKeyAndValue(const std::string& key, 27 const std::string& expect_val, 28 leveldb::DB* db) { 29 scoped_ptr<leveldb::Iterator> itr(db->NewIterator(leveldb::ReadOptions())); 30 31 itr->Seek(key); 32 EXPECT_TRUE(itr->Valid()); 33 EXPECT_EQ(expect_val, itr->value().ToString()); 34} 35 36void VerifyNotExist(const std::string& key, leveldb::DB* db) { 37 scoped_ptr<leveldb::Iterator> itr(db->NewIterator(leveldb::ReadOptions())); 38 39 itr->Seek(key); 40 EXPECT_TRUE(!itr->Valid() || 41 !StartsWithASCII(itr->key().ToString(), key, true)); 42} 43 44} // namespace 45 46TEST(DriveMetadataDBMigrationUtilTest, RollbackFromV4ToV3) { 47 // Rollback from version 4 to version 3. 48 // Please see metadata_database_index.cc for version 3 format, and 49 // metadata_database_index_on_disk.cc for version 4 format. 50 51 const char kDatabaseVersionKey[] = "VERSION"; 52 const char kServiceMetadataKey[] = "SERVICE"; 53 const char kFileMetadataKeyPrefix[] = "FILE: "; 54 const char kFileTrackerKeyPrefix[] = "TRACKER: "; 55 56 // Key prefixes used in version 4. 57 const char kAppRootIDByAppIDKeyPrefix[] = "APP_ROOT: "; 58 const char kActiveTrackerIDByFileIDKeyPrefix[] = "ACTIVE_FILE: "; 59 const char kTrackerIDByFileIDKeyPrefix[] = "TRACKER_FILE: "; 60 const char kMultiTrackerByFileIDKeyPrefix[] = "MULTI_FILE: "; 61 const char kActiveTrackerIDByParentAndTitleKeyPrefix[] = "ACTIVE_PATH: "; 62 const char kTrackerIDByParentAndTitleKeyPrefix[] = "TRACKER_PATH: "; 63 const char kMultiBackingParentAndTitleKeyPrefix[] = "MULTI_PATH: "; 64 const char kDirtyIDKeyPrefix[] = "DIRTY: "; 65 const char kDemotedDirtyIDKeyPrefix[] = "DEMOTED_DIRTY: "; 66 67 // Set up environment. 68 leveldb::DB* db_ptr = NULL; 69 base::ScopedTempDir base_dir; 70 ASSERT_TRUE(base_dir.CreateUniqueTempDir()); 71 { 72 leveldb::Options options; 73 options.create_if_missing = true; 74 std::string db_dir = 75 storage::FilePathToString(base_dir.path().Append(kDatabaseName)); 76 leveldb::Status status = leveldb::DB::Open(options, db_dir, &db_ptr); 77 ASSERT_TRUE(status.ok()); 78 } 79 scoped_ptr<leveldb::DB> db(db_ptr); 80 81 // Setup the database with the schema version 4, without IDs. 82 leveldb::WriteBatch batch; 83 batch.Put(kDatabaseVersionKey, "4"); 84 batch.Put(kServiceMetadataKey, "service_metadata"); 85 batch.Put(kFileMetadataKeyPrefix, "file_metadata"); 86 batch.Put(kFileTrackerKeyPrefix, "file_tracker"); 87 batch.Put(kAppRootIDByAppIDKeyPrefix, "app_root_id"); 88 batch.Put(kActiveTrackerIDByFileIDKeyPrefix, "active_id_by_file"); 89 batch.Put(kTrackerIDByFileIDKeyPrefix, "tracker_id_by_file"); 90 batch.Put(kMultiTrackerByFileIDKeyPrefix, "multi_tracker_by_file"); 91 batch.Put(kActiveTrackerIDByParentAndTitleKeyPrefix, "active_id_by_path"); 92 batch.Put(kTrackerIDByParentAndTitleKeyPrefix, "tracker_id_by_path"); 93 batch.Put(kMultiBackingParentAndTitleKeyPrefix, "multi_tracker_by_path"); 94 batch.Put(kDirtyIDKeyPrefix, "dirty"); 95 batch.Put(kDemotedDirtyIDKeyPrefix, "demoted_dirty"); 96 97 leveldb::Status status = db->Write(leveldb::WriteOptions(), &batch); 98 EXPECT_EQ(SYNC_STATUS_OK, LevelDBStatusToSyncStatusCode(status)); 99 100 // Migrate the database. 101 MigrateDatabaseFromV4ToV3(db.get()); 102 103 // Verify DB schema verison 104 VerifyKeyAndValue(kDatabaseVersionKey, "3", db.get()); 105 106 // Verify remained entries. 107 VerifyKeyAndValue(kServiceMetadataKey, "service_metadata", db.get()); 108 VerifyKeyAndValue(kFileMetadataKeyPrefix, "file_metadata", db.get()); 109 VerifyKeyAndValue(kFileTrackerKeyPrefix, "file_tracker", db.get()); 110 111 // Verify 112 VerifyNotExist(kAppRootIDByAppIDKeyPrefix, db.get()); 113 VerifyNotExist(kActiveTrackerIDByFileIDKeyPrefix, db.get()); 114 VerifyNotExist(kTrackerIDByFileIDKeyPrefix, db.get()); 115 VerifyNotExist(kMultiTrackerByFileIDKeyPrefix, db.get()); 116 VerifyNotExist(kActiveTrackerIDByParentAndTitleKeyPrefix, db.get()); 117 VerifyNotExist(kTrackerIDByParentAndTitleKeyPrefix, db.get()); 118 VerifyNotExist(kMultiBackingParentAndTitleKeyPrefix, db.get()); 119 VerifyNotExist(kDirtyIDKeyPrefix, db.get()); 120 VerifyNotExist(kDemotedDirtyIDKeyPrefix, db.get()); 121} 122 123} // namespace drive_backend 124} // namespace sync_file_system 125