summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--test/bbackupd/testbbackupd.cpp157
1 files changed, 157 insertions, 0 deletions
diff --git a/test/bbackupd/testbbackupd.cpp b/test/bbackupd/testbbackupd.cpp
index fd250b80..d85d2595 100644
--- a/test/bbackupd/testbbackupd.cpp
+++ b/test/bbackupd/testbbackupd.cpp
@@ -43,7 +43,9 @@
#endif
#include "BackupClientCryptoKeys.h"
+#include "BackupClientContext.h"
#include "BackupClientFileAttributes.h"
+#include "BackupClientInodeToIDMap.h"
#include "BackupClientRestore.h"
#include "BackupDaemon.h"
#include "BackupDaemonConfigVerify.h"
@@ -67,6 +69,7 @@
#include "intercept.h"
#include "IOStreamGetLine.h"
#include "LocalProcessStream.h"
+#include "MemBlockStream.h"
#include "RaidFileController.h"
#include "SSLLib.h"
#include "ServerControl.h"
@@ -1215,6 +1218,158 @@ bool test_getobject_on_nonexistent_file()
TEARDOWN();
}
+// ASSERT((mpBlockIndex == 0) || (NumBlocksInIndex != 0)) in
+// BackupStoreFileEncodeStream::Recipe::Recipe once failed, apparently because
+// a zero byte file had a block index but no entries in it. But this test
+// doesn't reproduce the error, so it's not enabled for now.
+
+bool test_replace_zero_byte_file_with_nonzero_byte_file()
+{
+ SETUP();
+
+ TEST_THAT_OR(mkdir("testfiles/TestDir1", 0755) == 0, FAIL);
+ FileStream emptyFile("testfiles/TestDir1/f2",
+ O_WRONLY | O_CREAT | O_EXCL, 0755);
+ wait_for_operation(5, "f2 to be old enough");
+
+ BackupProtocolLocal2 client(0x01234567, "test",
+ "backup/01234567/", 0, false);
+ MockBackupDaemon bbackupd(client);
+ TEST_THAT(configure_bbackupd(bbackupd, "testfiles/bbackupd.conf"));
+ bbackupd.RunSyncNow();
+ TEST_COMPARE_LOCAL(Compare_Same, client);
+
+ MemBlockStream stream("Hello world");
+ stream.CopyStreamTo(emptyFile);
+ emptyFile.Close();
+ wait_for_operation(5, "f2 to be old enough");
+
+ bbackupd.RunSyncNow();
+ TEST_COMPARE_LOCAL(Compare_Same, client);
+
+ TEARDOWN();
+}
+
+// This caused the issue reported by Brendon Baumgartner and described in my
+// email to the Box Backup list on Mon, 21 Apr 2014 at 18:44:38. If the
+// directory disappears then we used to try to send an empty attributes block
+// to the server, which is illegal.
+bool test_backup_disappearing_directory()
+{
+ SETUP_WITH_BBSTORED();
+
+ class BackupClientDirectoryRecordHooked : public BackupClientDirectoryRecord
+ {
+ public:
+ BackupClientDirectoryRecordHooked(int64_t ObjectID,
+ const std::string &rSubDirName)
+ : BackupClientDirectoryRecord(ObjectID, rSubDirName),
+ mDeletedOnce(false)
+ { }
+ bool mDeletedOnce;
+ bool UpdateItems(SyncParams &rParams, const std::string &rLocalPath,
+ const std::string &rRemotePath,
+ const Location& rBackupLocation,
+ BackupStoreDirectory *pDirOnStore,
+ std::vector<BackupStoreDirectory::Entry *> &rEntriesLeftOver,
+ std::vector<std::string> &rFiles,
+ const std::vector<std::string> &rDirs)
+ {
+ if(!mDeletedOnce)
+ {
+ TEST_THAT(::rmdir("testfiles/TestDir1/dir23") == 0);
+ mDeletedOnce = true;
+ }
+
+ return BackupClientDirectoryRecord::UpdateItems(rParams,
+ rLocalPath, rRemotePath, rBackupLocation,
+ pDirOnStore, rEntriesLeftOver, rFiles, rDirs);
+ }
+ };
+
+ BackupClientContext clientContext
+ (
+ bbackupd, // rLocationResolver
+ context,
+ "localhost",
+ BOX_PORT_BBSTORED_TEST,
+ 0x01234567,
+ false, // ExtendedLogging
+ false, // ExtendedLogFile
+ "", // extendedLogFile
+ bbackupd, // rProgressNotifier
+ false // TcpNice
+ );
+
+ BackupClientInodeToIDMap oldMap, newMap;
+ oldMap.OpenEmpty();
+ newMap.Open("testfiles/test_map.db", false, true);
+ clientContext.SetIDMaps(&oldMap, &newMap);
+
+ BackupClientDirectoryRecord::SyncParams params(
+ bbackupd, // rRunStatusProvider,
+ bbackupd, // rSysadminNotifier,
+ bbackupd, // rProgressNotifier,
+ clientContext,
+ &bbackupd);
+ params.mSyncPeriodEnd = GetCurrentBoxTime();
+
+ BackupProtocolCallable& connection = clientContext.GetConnection();
+
+ BackupClientFileAttributes attr;
+ attr.ReadAttributes("testfiles/TestDir1",
+ false /* put mod times in the attributes, please */);
+ std::auto_ptr<IOStream> attrStream(new MemBlockStream(attr));
+ BackupStoreFilenameClear dirname("Test1");
+ std::auto_ptr<BackupProtocolSuccess>
+ dirCreate(connection.QueryCreateDirectory(
+ BACKUPSTORE_ROOT_DIRECTORY_ID, // containing directory
+ 0, // attrModTime,
+ dirname, // dirname,
+ attrStream));
+
+ // Object ID for later creation
+ int64_t oid = dirCreate->GetObjectID();
+ BackupClientDirectoryRecordHooked record(oid, "Test1");
+
+ TEST_COMPARE(Compare_Different);
+
+ Location fakeLocation;
+ record.SyncDirectory(params,
+ BACKUPSTORE_ROOT_DIRECTORY_ID,
+ "testfiles/TestDir1", // locationPath,
+ "/whee", // remotePath
+ fakeLocation);
+
+ TEST_COMPARE(Compare_Same);
+
+ // Run another backup, check that we haven't got an inconsistent
+ // state that causes a crash.
+ record.SyncDirectory(params,
+ BACKUPSTORE_ROOT_DIRECTORY_ID,
+ "testfiles/TestDir1", // locationPath,
+ "/whee", // remotePath
+ fakeLocation);
+ TEST_COMPARE(Compare_Same);
+
+ // Now recreate it and run another backup, check that we haven't got
+ // an inconsistent state that causes a crash or prevents us from
+ // creating the directory if it appears later.
+ TEST_THAT(::mkdir("testfiles/TestDir1/dir23", 0755) == 0);
+ TEST_COMPARE(Compare_Different);
+
+ record.SyncDirectory(params,
+ BACKUPSTORE_ROOT_DIRECTORY_ID,
+ "testfiles/TestDir1", // locationPath,
+ "/whee", // remotePath
+ fakeLocation);
+ TEST_COMPARE(Compare_Same);
+
+ TEARDOWN();
+}
+
+// TODO FIXME check that directory modtimes are backed up by BackupClientDirectoryRecord.
+
bool test_ssl_keepalives()
{
SETUP_WITH_BBSTORED();
@@ -3917,6 +4072,8 @@ int test(int argc, const char *argv[])
TEST_THAT(test_basics());
TEST_THAT(test_readdirectory_on_nonexistent_dir());
TEST_THAT(test_getobject_on_nonexistent_file());
+ // TEST_THAT(test_replace_zero_byte_file_with_nonzero_byte_file());
+ TEST_THAT(test_backup_disappearing_directory());
TEST_THAT(test_ssl_keepalives());
TEST_THAT(test_backup_pauses_when_store_is_full());
TEST_THAT(test_bbackupd_exclusions());