summaryrefslogtreecommitdiff
path: root/lib/backupstore/StoreTestUtils.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/backupstore/StoreTestUtils.cpp')
-rw-r--r--lib/backupstore/StoreTestUtils.cpp300
1 files changed, 300 insertions, 0 deletions
diff --git a/lib/backupstore/StoreTestUtils.cpp b/lib/backupstore/StoreTestUtils.cpp
new file mode 100644
index 00000000..2b773cb1
--- /dev/null
+++ b/lib/backupstore/StoreTestUtils.cpp
@@ -0,0 +1,300 @@
+// --------------------------------------------------------------------------
+//
+// File
+// Name: StoreTestUtils.cpp
+// Purpose: Utilities for housekeeping and checking a test store
+// Created: 18/02/14
+//
+// --------------------------------------------------------------------------
+
+#include "Box.h"
+
+#include <cstdio>
+#include <vector>
+
+#include "autogen_BackupProtocol.h"
+#include "BoxPortsAndFiles.h"
+#include "BackupStoreAccounts.h"
+#include "BackupStoreAccountDatabase.h"
+#include "BackupStoreConfigVerify.h"
+#include "BackupStoreConstants.h"
+#include "BackupStoreInfo.h"
+#include "HousekeepStoreAccount.h"
+#include "Logging.h"
+#include "ServerControl.h"
+#include "SocketStreamTLS.h"
+#include "StoreTestUtils.h"
+#include "TLSContext.h"
+#include "Test.h"
+
+bool create_account(int soft, int hard)
+{
+ std::string errs;
+ std::auto_ptr<Configuration> config(
+ Configuration::LoadAndVerify
+ ("testfiles/bbstored.conf", &BackupConfigFileVerify, errs));
+ BackupStoreAccountsControl control(*config);
+
+ Logger::LevelGuard guard(Logging::GetConsole(), Log::WARNING);
+ int result = control.CreateAccount(0x01234567, 0, soft, hard);
+ TEST_EQUAL(0, result);
+ return (result == 0);
+}
+
+bool delete_account()
+{
+ std::string errs;
+ std::auto_ptr<Configuration> config(
+ Configuration::LoadAndVerify
+ ("testfiles/bbstored.conf", &BackupConfigFileVerify, errs));
+ BackupStoreAccountsControl control(*config);
+ Logger::LevelGuard guard(Logging::GetConsole(), Log::WARNING);
+ TEST_THAT_THROWONFAIL(control.DeleteAccount(0x01234567, false) == 0);
+ return true;
+}
+
+std::vector<uint32_t> ExpectedRefCounts;
+int bbstored_pid = 0, bbackupd_pid = 0;
+
+void set_refcount(int64_t ObjectID, uint32_t RefCount)
+{
+ if ((int64_t)ExpectedRefCounts.size() <= ObjectID)
+ {
+ ExpectedRefCounts.resize(ObjectID + 1, 0);
+ }
+ ExpectedRefCounts[ObjectID] = RefCount;
+ for (size_t i = ExpectedRefCounts.size() - 1; i >= 1; i--)
+ {
+ if (ExpectedRefCounts[i] == 0)
+ {
+ // BackupStoreCheck and housekeeping will both
+ // regenerate the refcount DB without any missing
+ // items at the end, so we need to prune ourselves
+ // of all items with no references to match.
+ ExpectedRefCounts.resize(i);
+ }
+ }
+}
+
+void init_context(TLSContext& rContext)
+{
+ rContext.Initialise(false /* client */,
+ "testfiles/clientCerts.pem",
+ "testfiles/clientPrivKey.pem",
+ "testfiles/clientTrustedCAs.pem");
+}
+
+std::auto_ptr<SocketStream> open_conn(const char *hostname,
+ TLSContext& rContext)
+{
+ init_context(rContext);
+ std::auto_ptr<SocketStreamTLS> conn(new SocketStreamTLS);
+ conn->Open(rContext, Socket::TypeINET, hostname,
+ BOX_PORT_BBSTORED_TEST);
+ return static_cast<std::auto_ptr<SocketStream> >(conn);
+}
+
+std::auto_ptr<BackupProtocolCallable> connect_to_bbstored(TLSContext& rContext)
+{
+ // Make a protocol
+ std::auto_ptr<BackupProtocolCallable> protocol(new
+ BackupProtocolClient(open_conn("localhost", rContext)));
+
+ // Check the version
+ std::auto_ptr<BackupProtocolVersion> serverVersion(
+ protocol->QueryVersion(BACKUP_STORE_SERVER_VERSION));
+ TEST_THAT(serverVersion->GetVersion() == BACKUP_STORE_SERVER_VERSION);
+
+ return protocol;
+}
+
+std::auto_ptr<BackupProtocolCallable> connect_and_login(TLSContext& rContext,
+ int flags)
+{
+ // Make a protocol
+ std::auto_ptr<BackupProtocolCallable> protocol =
+ connect_to_bbstored(rContext);
+
+ // Login
+ protocol->QueryLogin(0x01234567, flags);
+
+ return protocol;
+}
+
+bool check_num_files(int files, int old, int deleted, int dirs)
+{
+ std::auto_ptr<BackupStoreInfo> 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());
+}
+
+bool check_num_blocks(BackupProtocolCallable& Client, int Current, int Old,
+ int Deleted, int Dirs, int Total)
+{
+ std::auto_ptr<BackupProtocolAccountUsage2> usage =
+ Client.QueryGetAccountUsage2();
+ TEST_EQUAL_LINE(Total, usage->GetBlocksUsed(), "wrong BlocksUsed");
+ TEST_EQUAL_LINE(Current, usage->GetBlocksInCurrentFiles(),
+ "wrong BlocksInCurrentFiles");
+ TEST_EQUAL_LINE(Old, usage->GetBlocksInOldFiles(),
+ "wrong BlocksInOldFiles");
+ TEST_EQUAL_LINE(Deleted, usage->GetBlocksInDeletedFiles(),
+ "wrong BlocksInDeletedFiles");
+ TEST_EQUAL_LINE(Dirs, usage->GetBlocksInDirectories(),
+ "wrong BlocksInDirectories");
+ return (Total == usage->GetBlocksUsed() &&
+ Current == usage->GetBlocksInCurrentFiles() &&
+ Old == usage->GetBlocksInOldFiles() &&
+ Deleted == usage->GetBlocksInDeletedFiles() &&
+ Dirs == usage->GetBlocksInDirectories());
+}
+
+bool change_account_limits(const char* soft, const char* hard)
+{
+ std::string errs;
+ std::auto_ptr<Configuration> config(
+ Configuration::LoadAndVerify
+ ("testfiles/bbstored.conf", &BackupConfigFileVerify, errs));
+ BackupStoreAccountsControl control(*config);
+ int result = control.SetLimit(0x01234567, soft, hard);
+ TEST_EQUAL(0, result);
+ return (result == 0);
+}
+
+int check_account_for_errors(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<Configuration> config(
+ Configuration::LoadAndVerify("testfiles/bbstored.conf",
+ &BackupConfigFileVerify, errs));
+ BackupStoreAccountsControl control(*config);
+ int errors_fixed = control.CheckAccount(0x01234567,
+ 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);
+}
+
+int64_t run_housekeeping(BackupStoreAccountDatabase::Entry& rAccount)
+{
+ std::string rootDir = BackupStoreAccounts::GetAccountRoot(rAccount);
+ int discSet = rAccount.GetDiscSet();
+
+ // Do housekeeping on this account
+ HousekeepStoreAccount housekeeping(rAccount.GetID(), rootDir,
+ discSet, NULL);
+ TEST_THAT(housekeeping.DoHousekeeping(true /* keep trying forever */));
+ return housekeeping.GetErrorCount();
+}
+
+// Run housekeeping (for which we need to disconnect ourselves) and check
+// that it doesn't change the numbers of files.
+//
+// Also check that bbstoreaccounts doesn't change anything
+
+bool run_housekeeping_and_check_account()
+{
+ int error_count;
+
+ {
+ Logging::Tagger tag("", true);
+ Logging::ShowTagOnConsole show;
+ std::auto_ptr<BackupStoreAccountDatabase> apAccounts(
+ BackupStoreAccountDatabase::Read("testfiles/accounts.txt"));
+ BackupStoreAccountDatabase::Entry account =
+ apAccounts->GetEntry(0x1234567);
+ error_count = run_housekeeping(account);
+ }
+
+ TEST_EQUAL_LINE(0, error_count, "housekeeping errors");
+
+ bool check_account_is_ok = check_account();
+ TEST_THAT(check_account_is_ok);
+
+ return error_count == 0 && check_account_is_ok;
+}
+
+bool check_reference_counts()
+{
+ std::auto_ptr<BackupStoreAccountDatabase> apAccounts(
+ BackupStoreAccountDatabase::Read("testfiles/accounts.txt"));
+ BackupStoreAccountDatabase::Entry account =
+ apAccounts->GetEntry(0x1234567);
+
+ std::auto_ptr<BackupStoreRefCountDatabase> apReferences(
+ BackupStoreRefCountDatabase::Load(account, true));
+ TEST_EQUAL(ExpectedRefCounts.size(),
+ apReferences->GetLastObjectIDUsed() + 1);
+
+ bool counts_ok = true;
+
+ for (unsigned int i = BackupProtocolListDirectory::RootDirectory;
+ i < ExpectedRefCounts.size(); i++)
+ {
+ TEST_EQUAL_LINE(ExpectedRefCounts[i],
+ apReferences->GetRefCount(i),
+ "object " << BOX_FORMAT_OBJECTID(i));
+ if (ExpectedRefCounts[i] != apReferences->GetRefCount(i))
+ {
+ counts_ok = false;
+ }
+ }
+
+ return counts_ok;
+}
+
+bool StartServer()
+{
+ bbstored_pid = StartDaemon(bbstored_pid,
+ BBSTORED " " + bbstored_args + " testfiles/bbstored.conf",
+ "testfiles/bbstored.pid");
+ return bbstored_pid != 0;
+}
+
+bool StopServer(bool wait_for_process)
+{
+ bool result = StopDaemon(bbstored_pid, "testfiles/bbstored.pid",
+ "bbstored.memleaks", wait_for_process);
+ bbstored_pid = 0;
+ return result;
+}
+
+bool StartClient(const std::string& bbackupd_conf_file)
+{
+ bbackupd_pid = StartDaemon(bbackupd_pid,
+ BBACKUPD " " + bbackupd_args + " " + bbackupd_conf_file,
+ "testfiles/bbackupd.pid");
+ return bbackupd_pid != 0;
+}
+
+bool StopClient(bool wait_for_process)
+{
+ bool result = StopDaemon(bbackupd_pid, "testfiles/bbackupd.pid",
+ "bbackupd.memleaks", wait_for_process);
+ bbackupd_pid = 0;
+ return result;
+}
+