From 4774b1db0c3c7040509cd1fa74266725a2c1734b Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 24 Sep 2017 21:48:09 +0100 Subject: [PATCH] Add store test helpers for specialised tests --- lib/backupstore/BackupFileSystem.h | 4 + lib/backupstore/StoreTestUtils.cpp | 119 +++++++++++++++++---------- lib/backupstore/StoreTestUtils.h | 18 +++- test/backupstore/testbackupstore.cpp | 2 +- 4 files changed, 97 insertions(+), 46 deletions(-) diff --git a/lib/backupstore/BackupFileSystem.h b/lib/backupstore/BackupFileSystem.h index 61c25efce..144a5fa64 100644 --- a/lib/backupstore/BackupFileSystem.h +++ b/lib/backupstore/BackupFileSystem.h @@ -157,6 +157,10 @@ class BackupFileSystem SaveRefCountDatabase(*p_refcount_db); mapPermanentRefCountDatabase.reset(); } + BackupStoreRefCountDatabase* GetCurrentRefCountDatabase() + { + return mapPermanentRefCountDatabase.get(); + } protected: virtual std::auto_ptr GetBackupStoreInfoInternal(bool ReadOnly) = 0; diff --git a/lib/backupstore/StoreTestUtils.cpp b/lib/backupstore/StoreTestUtils.cpp index 8ddbe7c0c..2ca238c78 100644 --- a/lib/backupstore/StoreTestUtils.cpp +++ b/lib/backupstore/StoreTestUtils.cpp @@ -16,6 +16,7 @@ #include "BackupAccountControl.h" #include "BackupStoreAccounts.h" #include "BackupStoreAccountDatabase.h" +#include "BackupStoreCheck.h" #include "BackupStoreConfigVerify.h" #include "BackupStoreConstants.h" #include "BackupStoreInfo.h" @@ -136,15 +137,26 @@ bool check_num_files(int files, int old, int deleted, int dirs) std::auto_ptr apInfo = BackupStoreInfo::Load(0x1234567, "backup/01234567/", 0, true); - TEST_EQUAL_LINE(files, apInfo->GetNumCurrentFiles(), "current files"); - TEST_EQUAL_LINE(old, apInfo->GetNumOldFiles(), "old files"); - TEST_EQUAL_LINE(deleted, apInfo->GetNumDeletedFiles(), "deleted files"); - TEST_EQUAL_LINE(dirs, apInfo->GetNumDirectories(), "directories"); - - return (files == apInfo->GetNumCurrentFiles() && - old == apInfo->GetNumOldFiles() && - deleted == apInfo->GetNumDeletedFiles() && - dirs == apInfo->GetNumDirectories()); + return check_num_files(*apInfo, files, old, deleted, dirs); +} + +bool check_num_files(BackupFileSystem& fs, int files, int old, int deleted, int dirs) +{ + std::auto_ptr apInfo = fs.GetBackupStoreInfoUncached(); + return check_num_files(*apInfo, files, old, deleted, dirs); +} + +bool check_num_files(BackupStoreInfo& info, int files, int old, int deleted, int dirs) +{ + TEST_EQUAL_LINE(files, info.GetNumCurrentFiles(), "current files"); + TEST_EQUAL_LINE(old, info.GetNumOldFiles(), "old files"); + TEST_EQUAL_LINE(deleted, info.GetNumDeletedFiles(), "deleted files"); + TEST_EQUAL_LINE(dirs, info.GetNumDirectories(), "directories"); + + return (files == info.GetNumCurrentFiles() && + old == info.GetNumOldFiles() && + deleted == info.GetNumDeletedFiles() && + dirs == info.GetNumDirectories()); } bool check_num_blocks(BackupProtocolCallable& Client, int Current, int Old, @@ -181,27 +193,33 @@ bool change_account_limits(const char* soft, const char* hard) } int check_account_for_errors(Log::Level log_level) +{ + // TODO FIXME remove this backward-compatibility function + RaidBackupFileSystem fs(0x1234567, "backup/01234567/", 0); + return check_account_for_errors(fs, log_level); +} + +int check_account_for_errors(BackupFileSystem& filesystem, Log::Level log_level) { Logger::LevelGuard guard(Logging::GetConsole(), log_level); Logging::Tagger tag("check fix", true); Logging::ShowTagOnConsole show; - std::string errs; - std::auto_ptr config( - Configuration::LoadAndVerify("testfiles/bbstored.conf", - &BackupConfigFileVerify, errs)); - BackupStoreAccountControl control(*config, 0x01234567); - int errors_fixed = control.CheckAccount( - true, // FixErrors - false, // Quiet - true); // ReturnNumErrorsFound - return errors_fixed; -} -bool check_account(Log::Level log_level) -{ - int errors_fixed = check_account_for_errors(log_level); - TEST_EQUAL(0, errors_fixed); - return (errors_fixed == 0); + // The caller may already have opened a permanent read-write database, but + // BackupStoreCheck needs to open a temporary one, so we need to close the + // permanent one in that case. + if(filesystem.GetCurrentRefCountDatabase() && + !filesystem.GetCurrentRefCountDatabase()->IsReadOnly()) + { + filesystem.CloseRefCountDatabase(filesystem.GetCurrentRefCountDatabase()); + } + + filesystem.TryGetLock(); + BackupStoreCheck check(filesystem, + true, // FixErrors + false); // Quiet + check.Check(); + return check.GetNumErrorsFound(); } int64_t run_housekeeping(BackupStoreAccountDatabase::Entry& rAccount) @@ -230,24 +248,35 @@ int64_t run_housekeeping(BackupFileSystem& filesystem) bool run_housekeeping_and_check_account() { - int error_count; + // TODO FIXME remove this backward-compatibility function + RaidBackupFileSystem fs(0x1234567, "backup/01234567/", 0); + return run_housekeeping_and_check_account(fs); +} + +bool run_housekeeping_and_check_account(BackupFileSystem& filesystem) +{ + if(filesystem.GetCurrentRefCountDatabase() != NULL) + { + filesystem.CloseRefCountDatabase(filesystem.GetCurrentRefCountDatabase()); + } + + int num_housekeeping_errors; { Logging::Tagger tag("", true); Logging::ShowTagOnConsole show; - std::auto_ptr apAccounts( - BackupStoreAccountDatabase::Read("testfiles/accounts.txt")); - BackupStoreAccountDatabase::Entry account = - apAccounts->GetEntry(0x1234567); - error_count = run_housekeeping(account); + num_housekeeping_errors = run_housekeeping(filesystem); } + TEST_EQUAL_LINE(0, num_housekeeping_errors, "run_housekeeping"); - TEST_EQUAL_LINE(0, error_count, "housekeeping errors"); + filesystem.CloseRefCountDatabase(filesystem.GetCurrentRefCountDatabase()); - bool check_account_is_ok = check_account(); - TEST_THAT(check_account_is_ok); + int num_check_errors = check_account_for_errors(filesystem); + TEST_EQUAL_LINE(0, num_check_errors, "check_account_for_errors"); - return error_count == 0 && check_account_is_ok; + filesystem.CloseRefCountDatabase(filesystem.GetCurrentRefCountDatabase()); + + return num_housekeeping_errors == 0 && num_check_errors == 0; } bool check_reference_counts() @@ -257,21 +286,25 @@ bool check_reference_counts() BackupStoreAccountDatabase::Entry account = apAccounts->GetEntry(0x1234567); - std::auto_ptr apReferences( - BackupStoreRefCountDatabase::Load(account, true)); - bool counts_ok = true; + std::auto_ptr apReferences = + BackupStoreRefCountDatabase::Load(account, true); + TEST_EQUAL(ExpectedRefCounts.size(), + apReferences->GetLastObjectIDUsed() + 1); - TEST_EQUAL_OR(ExpectedRefCounts.size(), - apReferences->GetLastObjectIDUsed() + 1, - counts_ok = false); + return check_reference_counts(*apReferences); +} + +bool check_reference_counts(BackupStoreRefCountDatabase& references) +{ + bool counts_ok = true; for (unsigned int i = BackupProtocolListDirectory::RootDirectory; i < ExpectedRefCounts.size(); i++) { TEST_EQUAL_LINE(ExpectedRefCounts[i], - apReferences->GetRefCount(i), + references.GetRefCount(i), "object " << BOX_FORMAT_OBJECTID(i)); - if (ExpectedRefCounts[i] != apReferences->GetRefCount(i)) + if (ExpectedRefCounts[i] != references.GetRefCount(i)) { counts_ok = false; } diff --git a/lib/backupstore/StoreTestUtils.h b/lib/backupstore/StoreTestUtils.h index 507c6a414..08e6e7bb3 100644 --- a/lib/backupstore/StoreTestUtils.h +++ b/lib/backupstore/StoreTestUtils.h @@ -43,6 +43,8 @@ std::auto_ptr connect_and_login(TLSContext& rContext, //! Checks the number of files of each type in the store against expectations. bool check_num_files(int files, int old, int deleted, int dirs); +bool check_num_files(BackupFileSystem& fs, int files, int old, int deleted, int dirs); +bool check_num_files(BackupStoreInfo& info, int files, int old, int deleted, int dirs); //! Checks the number of blocks in files of each type against expectations. bool check_num_blocks(BackupProtocolCallable& Client, int Current, int Old, @@ -52,10 +54,13 @@ bool check_num_blocks(BackupProtocolCallable& Client, int Current, int Old, bool change_account_limits(const char* soft, const char* hard); //! Checks an account for errors, returning the number of errors found and fixed. +//! Old interface, only works with RaidBackupFileSystem, deprecated. int check_account_for_errors(Log::Level log_level = Log::WARNING); -//! Checks an account for errors, returning true if it's OK, for use in assertions. -bool check_account(Log::Level log_level = Log::WARNING); +//! Checks an account for errors, returning number of errors found. +//! New interface, takes a BackupFileSystem. +int check_account_for_errors(BackupFileSystem& filesystem, + Log::Level log_level = Log::WARNING); //! Runs housekeeping on an account, to remove old and deleted files if necessary. //! Old interface, only works with RaidBackupFileSystem, deprecated. @@ -66,11 +71,20 @@ int64_t run_housekeeping(BackupStoreAccountDatabase::Entry& rAccount); int64_t run_housekeeping(BackupFileSystem& filesystem); //! Runs housekeeping and checks the account, returning true if it's OK. +//! Old interface, only works with RaidBackupFileSystem, deprecated. bool run_housekeeping_and_check_account(); +//! Runs housekeeping and checks the account, returning true if it's OK. +//! New interface, takes a BackupFileSystem. +bool run_housekeeping_and_check_account(BackupFileSystem& filesystem); + //! Tests that all object reference counts have the expected values. +//! Old interface, only works with RaidBackupFileSystem, deprecated. bool check_reference_counts(); +//! Tests that all object reference counts have the expected values. +bool check_reference_counts(BackupStoreRefCountDatabase& references); + //! Starts the bbstored test server running, which must not already be running. bool StartServer(const std::string& daemon_args = ""); diff --git a/test/backupstore/testbackupstore.cpp b/test/backupstore/testbackupstore.cpp index 191b59e70..6dbe1d792 100644 --- a/test/backupstore/testbackupstore.cpp +++ b/test/backupstore/testbackupstore.cpp @@ -158,7 +158,7 @@ bool teardown_test_backupstore() if (FileExists("testfiles/0_0/backup/01234567/info.rf")) { TEST_THAT_OR(check_reference_counts(), status = false); - TEST_THAT_OR(check_account(), status = false); + TEST_EQUAL_OR(0, check_account_for_errors(), status = false); } return status;