summaryrefslogtreecommitdiff
path: root/test/bbackupd
diff options
context:
space:
mode:
authorBen Summers <ben@fluffy.co.uk>2005-10-14 08:50:54 +0000
committerBen Summers <ben@fluffy.co.uk>2005-10-14 08:50:54 +0000
commit99f8ce096bc5569adbfea1911dbcda24c28d8d8b (patch)
tree049c302161fea1f2f6223e1e8f3c40d9e8aadc8b /test/bbackupd
Box Backup 0.09 with a few tweeks
Diffstat (limited to 'test/bbackupd')
-rwxr-xr-xtest/bbackupd/testbbackupd.cpp829
-rwxr-xr-xtest/bbackupd/testextra4
-rwxr-xr-xtest/bbackupd/testfiles/accounts.txt0
-rwxr-xr-xtest/bbackupd/testfiles/bbackupd.conf50
-rw-r--r--test/bbackupd/testfiles/bbackupd.keysbin0 -> 1024 bytes
-rwxr-xr-xtest/bbackupd/testfiles/bbstored.conf17
-rwxr-xr-xtest/bbackupd/testfiles/clientCerts.pem11
-rwxr-xr-xtest/bbackupd/testfiles/clientPrivKey.pem15
-rwxr-xr-xtest/bbackupd/testfiles/clientTrustedCAs.pem11
-rwxr-xr-xtest/bbackupd/testfiles/extcheck1.pl33
-rwxr-xr-xtest/bbackupd/testfiles/extcheck2.pl29
-rwxr-xr-xtest/bbackupd/testfiles/notifyscript.pl15
-rwxr-xr-xtest/bbackupd/testfiles/raidfile.conf10
-rwxr-xr-xtest/bbackupd/testfiles/serverCerts.pem11
-rwxr-xr-xtest/bbackupd/testfiles/serverPrivKey.pem15
-rwxr-xr-xtest/bbackupd/testfiles/serverTrustedCAs.pem11
-rw-r--r--test/bbackupd/testfiles/spacetest1.tgzbin0 -> 288 bytes
-rw-r--r--test/bbackupd/testfiles/spacetest2.tgzbin0 -> 203 bytes
-rwxr-xr-xtest/bbackupd/testfiles/test2.tgzbin0 -> 25190 bytes
-rwxr-xr-xtest/bbackupd/testfiles/test3.tgzbin0 -> 44957 bytes
-rwxr-xr-xtest/bbackupd/testfiles/test_base.tgzbin0 -> 14950 bytes
-rw-r--r--test/bbackupd/testfiles/testexclude.tgzbin0 -> 377 bytes
22 files changed, 1061 insertions, 0 deletions
diff --git a/test/bbackupd/testbbackupd.cpp b/test/bbackupd/testbbackupd.cpp
new file mode 100755
index 00000000..acd13a10
--- /dev/null
+++ b/test/bbackupd/testbbackupd.cpp
@@ -0,0 +1,829 @@
+// --------------------------------------------------------------------------
+//
+// File
+// Name: testbbackupd.cpp
+// Purpose: test backup daemon (and associated client bits)
+// Created: 2003/10/07
+//
+// --------------------------------------------------------------------------
+
+#include "Box.h"
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <limits.h>
+#include <string.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include "Test.h"
+#include "BackupClientFileAttributes.h"
+#include "CommonException.h"
+#include "BackupStoreException.h"
+#include "FileModificationTime.h"
+#include "autogen_BackupProtocolClient.h"
+#include "SSLLib.h"
+#include "TLSContext.h"
+#include "SocketStreamTLS.h"
+#include "BoxPortsAndFiles.h"
+#include "BackupStoreConstants.h"
+#include "Socket.h"
+#include "BackupClientRestore.h"
+#include "BackupStoreDirectory.h"
+#include "BackupClientCryptoKeys.h"
+#include "CollectInBufferStream.h"
+#include "Utils.h"
+#include "BoxTime.h"
+#include "BoxTimeToUnix.h"
+
+#include "MemLeakFindOn.h"
+
+// two cycles and a bit
+#define TIME_TO_WAIT_FOR_BACKUP_OPERATION 12
+
+void wait_for_backup_operation(int seconds = TIME_TO_WAIT_FOR_BACKUP_OPERATION)
+{
+ printf("waiting: ");
+ fflush(stdout);
+ for(int l = 0; l < seconds; ++l)
+ {
+ sleep(1);
+ printf(".");
+ fflush(stdout);
+ }
+ printf("\n");
+}
+
+int bbstored_pid = 0;
+
+bool attrmatch(const char *f1, const char *f2)
+{
+ struct stat s1, s2;
+ TEST_THAT(::lstat(f1, &s1) == 0);
+ TEST_THAT(::lstat(f2, &s2) == 0);
+
+ // if link, just make sure other file is a link too, and that the link to names match
+ if((s1.st_mode & S_IFMT) == S_IFLNK)
+ {
+ if((s2.st_mode & S_IFMT) != S_IFLNK) return false;
+
+ char p1[PATH_MAX], p2[PATH_MAX];
+ int p1l = ::readlink(f1, p1, PATH_MAX);
+ int p2l = ::readlink(f2, p2, PATH_MAX);
+ TEST_THAT(p1l != -1 && p2l != -1);
+ // terminate strings properly
+ p1[p1l] = '\0';
+ p2[p2l] = '\0';
+ return strcmp(p1, p2) == 0;
+ }
+
+ // modification times
+ if(FileModificationTime(s1) != FileModificationTime(s2))
+ {
+ return false;
+ }
+
+ // compare the rest
+ return (s1.st_mode == s2.st_mode && s1.st_uid == s2.st_uid && s1.st_gid == s2.st_gid);
+}
+
+int test_basics()
+{
+ // Read attributes from files
+ BackupClientFileAttributes t1;
+ t1.ReadAttributes("testfiles/test1");
+ TEST_THAT(!t1.IsSymLink());
+ BackupClientFileAttributes t2;
+ t2.ReadAttributes("testfiles/test2");
+ TEST_THAT(t2.IsSymLink());
+ // Check that it's actually been encrypted (search for symlink name encoded in it)
+ void *te = ::memchr(t2.GetBuffer(), 't', t2.GetSize() - 3);
+ TEST_THAT(te == 0 || ::memcmp(te, "test", 4) != 0);
+
+ BackupClientFileAttributes t3;
+ TEST_CHECK_THROWS(t3.ReadAttributes("doesn't exist"), CommonException, OSFileError);
+
+ // Create some more files
+ FILE *f = fopen("testfiles/test1_n", "w");
+ fclose(f);
+ f = fopen("testfiles/test2_n", "w");
+ fclose(f);
+
+ // Apply attributes to these new files
+ t1.WriteAttributes("testfiles/test1_n");
+ t2.WriteAttributes("testfiles/test2_n");
+ TEST_CHECK_THROWS(t1.WriteAttributes("testfiles/test1_nXX"), CommonException, OSFileError);
+ TEST_CHECK_THROWS(t3.WriteAttributes("doesn't exist"), BackupStoreException, AttributesNotLoaded);
+
+ // Test that atttributes are vaguely similar
+ TEST_THAT(attrmatch("testfiles/test1", "testfiles/test1_n"));
+ TEST_THAT(attrmatch("testfiles/test2", "testfiles/test2_n"));
+
+ // Check encryption, and recovery from encryption
+ // First, check that two attributes taken from the same thing have different encrypted values (think IV)
+ BackupClientFileAttributes t1b;
+ t1b.ReadAttributes("testfiles/test1");
+ TEST_THAT(::memcmp(t1.GetBuffer(), t1b.GetBuffer(), t1.GetSize()) != 0);
+ // But that comparing them works OK.
+ TEST_THAT(t1 == t1b);
+ // Then store them both to a stream
+ CollectInBufferStream stream;
+ t1.WriteToStream(stream);
+ t1b.WriteToStream(stream);
+ // Read them back again
+ stream.SetForReading();
+ BackupClientFileAttributes t1_r, t1b_r;
+ t1_r.ReadFromStream(stream, 1000);
+ t1b_r.ReadFromStream(stream, 1000);
+ TEST_THAT(::memcmp(t1_r.GetBuffer(), t1b_r.GetBuffer(), t1_r.GetSize()) != 0);
+ TEST_THAT(t1_r == t1b_r);
+ TEST_THAT(t1 == t1_r);
+ TEST_THAT(t1b == t1b_r);
+ TEST_THAT(t1_r == t1b);
+ TEST_THAT(t1b_r == t1);
+
+ return 0;
+}
+
+int test_setupaccount()
+{
+ TEST_THAT_ABORTONFAIL(::system("../../bin/bbstoreaccounts/bbstoreaccounts -c testfiles/bbstored.conf create 01234567 0 1000B 2000B") == 0);
+ TestRemoteProcessMemLeaks("bbstoreaccounts.memleaks");
+ return 0;
+}
+
+int test_run_bbstored()
+{
+ bbstored_pid = LaunchServer("../../bin/bbstored/bbstored testfiles/bbstored.conf", "testfiles/bbstored.pid");
+ TEST_THAT(bbstored_pid != -1 && bbstored_pid != 0);
+ if(bbstored_pid > 0)
+ {
+ ::sleep(1);
+ TEST_THAT(ServerIsAlive(bbstored_pid));
+ return 0; // success
+ }
+
+ return 1;
+}
+
+int test_kill_bbstored()
+{
+ TEST_THAT(KillServer(bbstored_pid));
+ ::sleep(1);
+ TEST_THAT(!ServerIsAlive(bbstored_pid));
+ TestRemoteProcessMemLeaks("bbstored.memleaks");
+ return 0;
+}
+
+int64_t GetDirID(BackupProtocolClient &protocol, const char *name, int64_t InDirectory)
+{
+ protocol.QueryListDirectory(
+ InDirectory,
+ BackupProtocolClientListDirectory::Flags_Dir,
+ BackupProtocolClientListDirectory::Flags_EXCLUDE_NOTHING,
+ true /* want attributes */);
+
+ // Retrieve the directory from the stream following
+ BackupStoreDirectory dir;
+ std::auto_ptr<IOStream> dirstream(protocol.ReceiveStream());
+ dir.ReadFromStream(*dirstream, protocol.GetTimeout());
+
+ BackupStoreDirectory::Iterator i(dir);
+ BackupStoreDirectory::Entry *en = 0;
+ int64_t dirid = 0;
+ BackupStoreFilenameClear dirname(name);
+ while((en = i.Next()) != 0)
+ {
+ if(en->GetName() == dirname)
+ {
+ dirid = en->GetObjectID();
+ }
+ }
+ return dirid;
+}
+
+void terminate_on_alarm(int sigraised)
+{
+ abort();
+}
+
+void do_interrupted_restore(const TLSContext &context, int64_t restoredirid)
+{
+ int pid = 0;
+ switch((pid = fork()))
+ {
+ case 0:
+ // child process
+ {
+ // connect and log in
+ SocketStreamTLS conn;
+ conn.Open(context, Socket::TypeINET, "localhost", BOX_PORT_BBSTORED);
+ BackupProtocolClient protocol(conn);
+ protocol.QueryVersion(BACKUP_STORE_SERVER_VERSION);
+ std::auto_ptr<BackupProtocolClientLoginConfirmed> loginConf(protocol.QueryLogin(0x01234567, BackupProtocolClientLogin::Flags_ReadOnly));
+
+ // Test the restoration
+ TEST_THAT(BackupClientRestore(protocol, restoredirid, "testfiles/restore-interrupt", true /* print progress dots */) == Restore_Complete);
+
+ // Log out
+ protocol.QueryFinished();
+ }
+ exit(0);
+ break;
+
+ case -1:
+ {
+ printf("Fork failed\n");
+ exit(1);
+ }
+
+ default:
+ {
+ // Wait until a resume file is written, then terminate the child
+ while(true)
+ {
+ // Test for existence of the result file
+ int64_t resumesize = 0;
+ if(FileExists("testfiles/restore-interrupt.boxbackupresume", &resumesize) && resumesize > 16)
+ {
+ // It's done something. Terminate it.
+ ::kill(pid, SIGTERM);
+ break;
+ }
+
+ // Process finished?
+ int status = 0;
+ if(waitpid(pid, &status, WNOHANG) != 0)
+ {
+ // child has finished anyway.
+ return;
+ }
+
+ // Give up timeslot so as not to hog the processor
+ ::sleep(0);
+ }
+
+ // Just wait until the child has completed
+ int status = 0;
+ waitpid(pid, &status, 0);
+ }
+ }
+}
+
+
+int test_bbackupd()
+{
+// // First, wait for a normal period to make sure the last changes attributes are within a normal backup timeframe.
+// wait_for_backup_operation();
+
+ // Connection gubbins
+ TLSContext context;
+ context.Initialise(false /* client */,
+ "testfiles/clientCerts.pem",
+ "testfiles/clientPrivKey.pem",
+ "testfiles/clientTrustedCAs.pem");
+
+ // unpack the files for the initial test
+ TEST_THAT(::system("rm -rf testfiles/TestDir1") == 0);
+ TEST_THAT(::system("mkdir testfiles/TestDir1") == 0);
+ TEST_THAT(::system("tar xzf testfiles/spacetest1.tgz -C testfiles/TestDir1/") == 0);
+
+ int pid = LaunchServer("../../bin/bbackupd/bbackupd testfiles/bbackupd.conf", "testfiles/bbackupd.pid");
+ TEST_THAT(pid != -1 && pid != 0);
+ if(pid > 0)
+ {
+ ::sleep(1);
+ TEST_THAT(ServerIsAlive(pid));
+
+ // First, check storage space handling -- wait for file to be uploaded
+ wait_for_backup_operation();
+ //TEST_THAT_ABORTONFAIL(::system("../../bin/bbstoreaccounts/bbstoreaccounts -c testfiles/bbstored.conf info 01234567") == 0);
+ // Set limit to something very small
+ // About 28 blocks will be used at this point. bbackupd will only pause if the size used is
+ // greater than soft limit + 1/3 of (hard - soft). Set small values for limits accordingly.
+ TEST_THAT_ABORTONFAIL(::system("../../bin/bbstoreaccounts/bbstoreaccounts -c testfiles/bbstored.conf setlimit 01234567 10B 40B") == 0);
+ TestRemoteProcessMemLeaks("bbstoreaccounts.memleaks");
+
+ // Unpack some more files
+ TEST_THAT(::system("tar xzf testfiles/spacetest2.tgz -C testfiles/TestDir1/") == 0);
+ // Delete a file and a directory
+ TEST_THAT(::unlink("testfiles/TestDir1/spacetest/d1/f3") == 0);
+ TEST_THAT(::system("rm -rf testfiles/TestDir1/spacetest/d3/d4") == 0);
+ wait_for_backup_operation();
+
+ // Make sure there are some differences
+ int compareReturnValue = ::system("../../bin/bbackupquery/bbackupquery -q -c testfiles/bbackupd.conf -l testfiles/query0a.log \"compare -ac\" quit");
+ TEST_THAT(compareReturnValue == 2*256);
+ TestRemoteProcessMemLeaks("bbackupquery.memleaks");
+
+ // Put the limit back
+ TEST_THAT_ABORTONFAIL(::system("../../bin/bbstoreaccounts/bbstoreaccounts -c testfiles/bbstored.conf setlimit 01234567 1000B 2000B") == 0);
+ TestRemoteProcessMemLeaks("bbstoreaccounts.memleaks");
+
+ // Check that the notify script was run
+ TEST_THAT(TestFileExists("testfiles/notifyran.store-full.1"));
+ // But only once!
+ TEST_THAT(!TestFileExists("testfiles/notifyran.store-full.2"));
+
+ // unpack the initial files again
+ TEST_THAT(::system("tar xzf testfiles/test_base.tgz -C testfiles/") == 0);
+
+ // wait for it to do it's stuff
+ wait_for_backup_operation();
+
+ // Check that the contents of the store are the same as the contents
+ // of the disc (-a = all, -c = give result in return code)
+ compareReturnValue = ::system("../../bin/bbackupquery/bbackupquery -q -c testfiles/bbackupd.conf -l testfiles/query1.log \"compare -ac\" quit");
+ TEST_THAT(compareReturnValue == 1*256);
+ TestRemoteProcessMemLeaks("bbackupquery.memleaks");
+
+ printf("Delete file and update another, create symlink.\n");
+
+ // Delete a file
+ TEST_THAT(::unlink("testfiles/TestDir1/x1/dsfdsfs98.fd") == 0);
+ // New symlink
+ TEST_THAT(::symlink("does-not-exist", "testfiles/TestDir1/symlink-to-dir") == 0);
+
+ // Update a file (will be uploaded as a diff)
+ {
+ // Check that the file is over the diffing threshold in the bbstored.conf file
+ TEST_THAT(TestGetFileSize("testfiles/TestDir1/f45.df") > 1024);
+
+ // Add a bit to the end
+ FILE *f = ::fopen("testfiles/TestDir1/f45.df", "a");
+ TEST_THAT(f != 0);
+ ::fprintf(f, "EXTRA STUFF");
+ ::fclose(f);
+ TEST_THAT(TestGetFileSize("testfiles/TestDir1/f45.df") > 1024);
+ }
+
+ // wait for backup daemon to do it's stuff, and compare again
+ wait_for_backup_operation();
+ compareReturnValue = ::system("../../bin/bbackupquery/bbackupquery -q -c testfiles/bbackupd.conf -l testfiles/query2.log \"compare -ac\" quit");
+ TEST_THAT(compareReturnValue == 1*256);
+ TestRemoteProcessMemLeaks("bbackupquery.memleaks");
+ // Try a quick compare, just for fun
+ compareReturnValue = ::system("../../bin/bbackupquery/bbackupquery -q -c testfiles/bbackupd.conf -l testfiles/query2q.log \"compare -acq\" quit");
+ TEST_THAT(compareReturnValue == 1*256);
+ TestRemoteProcessMemLeaks("bbackupquery.memleaks");
+
+ // Bad case: delete a file/symlink, replace it with a directory
+ printf("Replace symlink with directory, add new directory\n");
+ TEST_THAT(::unlink("testfiles/TestDir1/symlink-to-dir") == 0);
+ TEST_THAT(::mkdir("testfiles/TestDir1/symlink-to-dir", 0755) == 0);
+ TEST_THAT(::mkdir("testfiles/TestDir1/x1/dir-to-file", 0755) == 0);
+ // NOTE: create a file within the directory to avoid deletion by the housekeeping process later
+ TEST_THAT(::symlink("does-not-exist", "testfiles/TestDir1/x1/dir-to-file/contents") == 0);
+ wait_for_backup_operation();
+ compareReturnValue = ::system("../../bin/bbackupquery/bbackupquery -q -c testfiles/bbackupd.conf -l testfiles/query3s.log \"compare -ac\" quit");
+ TEST_THAT(compareReturnValue == 1*256);
+ TestRemoteProcessMemLeaks("bbackupquery.memleaks");
+
+ // And the inverse, replace a directory with a file/symlink
+ printf("Replace directory with symlink\n");
+ TEST_THAT(::unlink("testfiles/TestDir1/x1/dir-to-file/contents") == 0);
+ TEST_THAT(::rmdir("testfiles/TestDir1/x1/dir-to-file") == 0);
+ TEST_THAT(::symlink("does-not-exist", "testfiles/TestDir1/x1/dir-to-file") == 0);
+ wait_for_backup_operation();
+ compareReturnValue = ::system("../../bin/bbackupquery/bbackupquery -q -c testfiles/bbackupd.conf -l testfiles/query3s.log \"compare -ac\" quit");
+ TEST_THAT(compareReturnValue == 1*256);
+ TestRemoteProcessMemLeaks("bbackupquery.memleaks");
+
+ // And then, put it back to how it was before.
+ printf("Replace symlink with directory (which was a symlink)\n");
+ TEST_THAT(::unlink("testfiles/TestDir1/x1/dir-to-file") == 0);
+ TEST_THAT(::mkdir("testfiles/TestDir1/x1/dir-to-file", 0755) == 0);
+ TEST_THAT(::symlink("does-not-exist", "testfiles/TestDir1/x1/dir-to-file/contents2") == 0);
+ wait_for_backup_operation();
+ compareReturnValue = ::system("../../bin/bbackupquery/bbackupquery -q -c testfiles/bbackupd.conf -l testfiles/query3s.log \"compare -ac\" quit");
+ TEST_THAT(compareReturnValue == 1*256);
+ TestRemoteProcessMemLeaks("bbackupquery.memleaks");
+
+ // And finally, put it back to how it was before it was put back to how it was before
+ // This gets lots of nasty things in the store with directories over other old directories.
+ printf("Put it all back to how it was\n");
+ TEST_THAT(::unlink("testfiles/TestDir1/x1/dir-to-file/contents2") == 0);
+ TEST_THAT(::rmdir("testfiles/TestDir1/x1/dir-to-file") == 0);
+ TEST_THAT(::symlink("does-not-exist", "testfiles/TestDir1/x1/dir-to-file") == 0);
+ wait_for_backup_operation();
+ compareReturnValue = ::system("../../bin/bbackupquery/bbackupquery -q -c testfiles/bbackupd.conf -l testfiles/query3s.log \"compare -ac\" quit");
+ TEST_THAT(compareReturnValue == 1*256);
+ TestRemoteProcessMemLeaks("bbackupquery.memleaks");
+
+ // case which went wrong: rename a tracked file over a deleted file
+ printf("Rename an existing file over a deleted file\n");
+ TEST_THAT(::rename("testfiles/TestDir1/df9834.dsf", "testfiles/TestDir1/x1/dsfdsfs98.fd") == 0);
+ wait_for_backup_operation();
+ compareReturnValue = ::system("../../bin/bbackupquery/bbackupquery -q -c testfiles/bbackupd.conf -l testfiles/query3s.log \"compare -ac\" quit");
+ TEST_THAT(compareReturnValue == 1*256);
+ TestRemoteProcessMemLeaks("bbackupquery.memleaks");
+
+ printf("Add files with old times, update attributes of one to latest time\n");
+
+ // Move that file back
+ TEST_THAT(::rename("testfiles/TestDir1/x1/dsfdsfs98.fd", "testfiles/TestDir1/df9834.dsf") == 0);
+
+ // Add some more files
+ // Because the 'm' option is not used, these files will look very old to the daemon.
+ // Lucky it'll upload them then!
+ TEST_THAT(::system("tar xzf testfiles/test2.tgz -C testfiles/") == 0);
+ ::chmod("testfiles/TestDir1/sub23/dhsfdss/blf.h", 0415);
+
+ // Wait and test
+ wait_for_backup_operation();
+ compareReturnValue = ::system("../../bin/bbackupquery/bbackupquery -q -c testfiles/bbackupd.conf -l testfiles/query3.log \"compare -ac\" quit");
+ TEST_THAT(compareReturnValue == 1*256);
+ TestRemoteProcessMemLeaks("bbackupquery.memleaks");
+
+ // Check that modifying files with old timestamps still get added
+ printf("Modify existing file, but change timestamp to rather old\n");
+ // Time critical, so sync
+ TEST_THAT(::system("../../bin/bbackupctl/bbackupctl -q -c testfiles/bbackupd.conf wait-for-sync") == 0);
+ TestRemoteProcessMemLeaks("bbackupctl.memleaks");
+ // Then wait a second, to make sure the scan is complete
+ ::sleep(1);
+ // Then modify an existing file
+ {
+ chmod("testfiles/TestDir1/sub23/rand.h", 0777); // in the archive, it's read only
+ FILE *f = fopen("testfiles/TestDir1/sub23/rand.h", "w+");
+ TEST_THAT(f != 0);
+ fprintf(f, "MODIFIED!\n");
+ fclose(f);
+ // and then move the time backwards!
+ struct timeval times[2];
+ BoxTimeToTimeval(SecondsToBoxTime((uint32_t)(365*24*60*60)), times[1]);
+ times[0] = times[1];
+ TEST_THAT(::utimes("testfiles/TestDir1/sub23/rand.h", times) == 0);
+ }
+ // Wait and test
+ wait_for_backup_operation();
+ compareReturnValue = ::system("../../bin/bbackupquery/bbackupquery -q -c testfiles/bbackupd.conf -l testfiles/query3e.log \"compare -ac\" quit");
+ TEST_THAT(compareReturnValue == 1*256);
+ TestRemoteProcessMemLeaks("bbackupquery.memleaks");
+
+ // Add some files and directories which are marked as excluded
+ printf("Add files and dirs for exclusion test\n");
+ TEST_THAT(::system("tar xzf testfiles/testexclude.tgz -C testfiles/") == 0);
+ // Wait and test
+ wait_for_backup_operation();
+ compareReturnValue = ::system("../../bin/bbackupquery/bbackupquery -q -c testfiles/bbackupd.conf -l testfiles/query3c.log \"compare -ac\" quit");
+ TEST_THAT(compareReturnValue == 1*256);
+ TestRemoteProcessMemLeaks("bbackupquery.memleaks");
+ compareReturnValue = ::system("../../bin/bbackupquery/bbackupquery -q -c testfiles/bbackupd.conf -l testfiles/query3d.log \"compare -acE\" quit");
+ TEST_THAT(compareReturnValue == 2*256); // should find differences
+ TestRemoteProcessMemLeaks("bbackupquery.memleaks");
+
+ // These tests only work as non-root users.
+ if(::getuid() != 0)
+ {
+ // Check that read errors are reported neatly
+ printf("Add unreadable files\n");
+ {
+ // Dir and file which can't be read
+ TEST_THAT(::mkdir("testfiles/TestDir1/sub23/read-fail-test-dir", 0000) == 0);
+ int fd = ::open("testfiles/TestDir1/read-fail-test-file", O_CREAT | O_WRONLY, 0000);
+ TEST_THAT(fd != -1);
+ ::close(fd);
+ }
+ // Wait and test...
+ wait_for_backup_operation();
+ compareReturnValue = ::system("../../bin/bbackupquery/bbackupquery -q -c testfiles/bbackupd.conf -l testfiles/query3e.log \"compare -ac\" quit");
+ TEST_THAT(compareReturnValue == 2*256); // should find differences
+ TestRemoteProcessMemLeaks("bbackupquery.memleaks");
+ // Check that it was reported correctly
+ TEST_THAT(TestFileExists("testfiles/notifyran.read-error.1"));
+ TEST_THAT(!TestFileExists("testfiles/notifyran.read-error.2"));
+ // Set permissions on file and dir to stop errors in the future
+ ::chmod("testfiles/TestDir1/sub23/read-fail-test-dir", 0770);
+ ::chmod("testfiles/TestDir1/read-fail-test-file", 0770);
+ }
+
+ printf("Continuously update file, check isn't uploaded\n");
+
+ // Make sure everything happens at the same point in the sync cycle: wait until exactly the start of a sync
+ TEST_THAT(::system("../../bin/bbackupctl/bbackupctl -c testfiles/bbackupd.conf wait-for-sync") == 0);
+ TestRemoteProcessMemLeaks("bbackupctl.memleaks");
+ // Then wait a second, to make sure the scan is complete
+ ::sleep(1);
+
+ {
+ // Open a file, then save something to it every second
+ for(int l = 0; l < 12; ++l)
+ {
+ FILE *f = ::fopen("testfiles/TestDir1/continousupdate", "w+");
+ TEST_THAT(f != 0);
+ fprintf(f, "Loop iteration %d\n", l);
+ fflush(f);
+ sleep(1);
+ printf(".");
+ fflush(stdout);
+ ::fclose(f);
+ }
+ printf("\n");
+
+ // Check there's a difference
+ compareReturnValue = ::system("testfiles/extcheck1.pl");
+ TEST_THAT(compareReturnValue == 1*256);
+ TestRemoteProcessMemLeaks("bbackupquery.memleaks");
+
+ printf("Keep on continuously updating file, check it is uploaded eventually\n");
+
+ for(int l = 0; l < 18; ++l)
+ {
+ FILE *f = ::fopen("testfiles/TestDir1/continousupdate", "w+");
+ TEST_THAT(f != 0);
+ fprintf(f, "Loop 2 iteration %d\n", l);
+ fflush(f);
+ sleep(1);
+ printf(".");
+ fflush(stdout);
+ ::fclose(f);
+ }
+ printf("\n");
+
+ compareReturnValue = ::system("testfiles/extcheck2.pl");
+ TEST_THAT(compareReturnValue == 1*256);
+ TestRemoteProcessMemLeaks("bbackupquery.memleaks");
+ }
+
+ printf("Delete directory, change attributes\n");
+
+ // Delete a directory
+ TEST_THAT(::system("rm -rf testfiles/TestDir1/x1") == 0);
+ // Change attributes on an original file.
+ ::chmod("testfiles/TestDir1/df9834.dsf", 0423);
+
+ // Wait and test
+ wait_for_backup_operation();
+ compareReturnValue = ::system("../../bin/bbackupquery/bbackupquery -q -c testfiles/bbackupd.conf -l testfiles/query4.log \"compare -ac\" quit");
+ TEST_THAT(compareReturnValue == 1*256);
+ TestRemoteProcessMemLeaks("bbackupquery.memleaks");
+
+ printf("Restore files and directories\n");
+ int64_t deldirid = 0;
+ int64_t restoredirid = 0;
+ {
+ // connect and log in
+ SocketStreamTLS conn;
+ conn.Open(context, Socket::TypeINET, "localhost", BOX_PORT_BBSTORED);
+ BackupProtocolClient protocol(conn);
+ protocol.QueryVersion(BACKUP_STORE_SERVER_VERSION);
+ std::auto_ptr<BackupProtocolClientLoginConfirmed> loginConf(protocol.QueryLogin(0x01234567, BackupProtocolClientLogin::Flags_ReadOnly));
+
+ // Find the ID of the Test1 directory
+ restoredirid = GetDirID(protocol, "Test1", BackupProtocolClientListDirectory::RootDirectory);
+ TEST_THAT(restoredirid != 0);
+
+ // Test the restoration
+ TEST_THAT(BackupClientRestore(protocol, restoredirid, "testfiles/restore-Test1", true /* print progress dots */) == Restore_Complete);
+
+ // Compare it
+ compareReturnValue = ::system("../../bin/bbackupquery/bbackupquery -q -c testfiles/bbackupd.conf -l testfiles/query10.log \"compare -cE Test1 testfiles/restore-Test1\" quit");
+ TEST_THAT(compareReturnValue == 1*256);
+ TestRemoteProcessMemLeaks("bbackupquery.memleaks");
+
+ // Make sure you can't restore a restored directory
+ TEST_THAT(BackupClientRestore(protocol, restoredirid, "testfiles/restore-Test1", true /* print progress dots */) == Restore_TargetExists);
+
+ // Find ID of the deleted directory
+ deldirid = GetDirID(protocol, "x1", restoredirid);
+ TEST_THAT(deldirid != 0);
+
+ // Just check it doesn't bomb out -- will check this properly later (when bbackupd is stopped)
+ TEST_THAT(BackupClientRestore(protocol, deldirid, "testfiles/restore-Test1-x1", true /* print progress dots */, true /* deleted files */) == Restore_Complete);
+
+ // Log out
+ protocol.QueryFinished();
+ }
+
+ printf("Add files with current time\n");
+
+ // Add some more files and modify others
+ // Use the m flag this time so they have a recent modification time
+ TEST_THAT(::system("tar xzmf testfiles/test3.tgz -C testfiles/") == 0);
+
+ // Wait and test
+ wait_for_backup_operation();
+ compareReturnValue = ::system("../../bin/bbackupquery/bbackupquery -q -c testfiles/bbackupd.conf -l testfiles/query5.log \"compare -ac\" quit");
+ TEST_THAT(compareReturnValue == 1*256);
+ TestRemoteProcessMemLeaks("bbackupquery.memleaks");
+
+ // Rename directory
+ printf("Rename directory\n");
+ TEST_THAT(rename("testfiles/TestDir1/sub23/dhsfdss", "testfiles/TestDir1/renamed-dir") == 0);
+ wait_for_backup_operation();
+ compareReturnValue = ::system("../../bin/bbackupquery/bbackupquery -q -c testfiles/bbackupd.conf -l testfiles/query6.log \"compare -ac\" quit");
+ TEST_THAT(compareReturnValue == 1*256);
+ TestRemoteProcessMemLeaks("bbackupquery.memleaks");
+ // and again, but with quick flag
+ compareReturnValue = ::system("../../bin/bbackupquery/bbackupquery -q -c testfiles/bbackupd.conf -l testfiles/query6q.log \"compare -acq\" quit");
+ TEST_THAT(compareReturnValue == 1*256);
+ TestRemoteProcessMemLeaks("bbackupquery.memleaks");
+
+ // Rename some files -- one under the threshold, others above
+ printf("Rename files\n");
+ TEST_THAT(rename("testfiles/TestDir1/continousupdate", "testfiles/TestDir1/continousupdate-ren") == 0);
+ TEST_THAT(rename("testfiles/TestDir1/df324", "testfiles/TestDir1/df324-ren") == 0);
+ TEST_THAT(rename("testfiles/TestDir1/sub23/find2perl", "testfiles/TestDir1/find2perl-ren") == 0);
+ wait_for_backup_operation();
+ compareReturnValue = ::system("../../bin/bbackupquery/bbackupquery -q -c testfiles/bbackupd.conf -l testfiles/query6.log \"compare -ac\" quit");
+ TEST_THAT(compareReturnValue == 1*256);
+ TestRemoteProcessMemLeaks("bbackupquery.memleaks");
+
+ // Check that modifying files with madly in the future timestamps still get added
+ printf("Create a file with timestamp to way ahead in the future\n");
+ // Time critical, so sync
+ TEST_THAT(::system("../../bin/bbackupctl/bbackupctl -q -c testfiles/bbackupd.conf wait-for-sync") == 0);
+ TestRemoteProcessMemLeaks("bbackupctl.memleaks");
+ // Then wait a second, to make sure the scan is complete
+ ::sleep(1);
+ // Then modify an existing file
+ {
+ FILE *f = fopen("testfiles/TestDir1/sub23/in-the-future", "w");
+ TEST_THAT(f != 0);
+ fprintf(f, "Back to the future!\n");
+ fclose(f);
+ // and then move the time forwards!
+ struct timeval times[2];
+ BoxTimeToTimeval(GetCurrentBoxTime() + SecondsToBoxTime((uint32_t)(365*24*60*60)), times[1]);
+ times[0] = times[1];
+ TEST_THAT(::utimes("testfiles/TestDir1/sub23/in-the-future", times) == 0);
+ }
+ // Wait and test
+ wait_for_backup_operation();
+ compareReturnValue = ::system("../../bin/bbackupquery/bbackupquery -q -c testfiles/bbackupd.conf -l testfiles/query3e.log \"compare -ac\" quit");
+ TEST_THAT(compareReturnValue == 1*256);
+ TestRemoteProcessMemLeaks("bbackupquery.memleaks");
+
+ printf("Change client store marker\n");
+
+ // Then... connect to the server, and change the client store marker. See what that does!
+ {
+ bool done = false;
+ int tries = 4;
+ while(!done && tries > 0)
+ {
+ try
+ {
+ SocketStreamTLS conn;
+ conn.Open(context, Socket::TypeINET, "localhost", BOX_PORT_BBSTORED);
+ BackupProtocolClient protocol(conn);
+ protocol.QueryVersion(BACKUP_STORE_SERVER_VERSION);
+ std::auto_ptr<BackupProtocolClientLoginConfirmed> loginConf(protocol.QueryLogin(0x01234567, 0)); // read-write
+ // Make sure the marker isn't zero, because that's the default, and it should have changed
+ TEST_THAT(loginConf->GetClientStoreMarker() != 0);
+
+ // Change it to something else
+ protocol.QuerySetClientStoreMarker(12);
+
+ // Success!
+ done = true;
+
+ // Log out
+ protocol.QueryFinished();
+ }
+ catch(...)
+ {
+ tries--;
+ }
+ }
+ TEST_THAT(done);
+ }
+
+ printf("Check change of store marker pauses daemon\n");
+
+ // Make a change to a file, to detect whether or not it's hanging around
+ // waiting to retry.
+ {
+ FILE *f = ::fopen("testfiles/TestDir1/fileaftermarker", "w");
+ TEST_THAT(f != 0);
+ ::fprintf(f, "Lovely file you got there.");
+ ::fclose(f);
+ }
+
+ // Wait and test that there *are* differences
+ wait_for_backup_operation((TIME_TO_WAIT_FOR_BACKUP_OPERATION*3) / 2); // little bit longer than usual
+ compareReturnValue = ::system("../../bin/bbackupquery/bbackupquery -q -c testfiles/bbackupd.conf -l testfiles/query6.log \"compare -ac\" quit");
+ TEST_THAT(compareReturnValue == 2*256);
+ TestRemoteProcessMemLeaks("bbackupquery.memleaks");
+
+ printf("Interrupted restore\n");
+ {
+ do_interrupted_restore(context, restoredirid);
+ int64_t resumesize = 0;
+ TEST_THAT(FileExists("testfiles/restore-interrupt.boxbackupresume", &resumesize));
+ TEST_THAT(resumesize > 16); // make sure it has recorded something to resume
+
+ printf("\nResume restore\n");
+
+ SocketStreamTLS conn;
+ conn.Open(context, Socket::TypeINET, "localhost", BOX_PORT_BBSTORED);
+ BackupProtocolClient protocol(conn);
+ protocol.QueryVersion(BACKUP_STORE_SERVER_VERSION);
+ std::auto_ptr<BackupProtocolClientLoginConfirmed> loginConf(protocol.QueryLogin(0x01234567, 0)); // read-write
+
+ // Check that the restore fn returns resume possible, rather than doing anything
+ TEST_THAT(BackupClientRestore(protocol, restoredirid, "testfiles/restore-interrupt", true /* print progress dots */) == Restore_ResumePossible);
+
+ // Then resume it
+ TEST_THAT(BackupClientRestore(protocol, restoredirid, "testfiles/restore-interrupt", true /* print progress dots */, false /* deleted files */, false /* undelete server */, true /* resume */) == Restore_Complete);
+
+ protocol.QueryFinished();
+
+ // Then check it has restored the correct stuff
+ compareReturnValue = ::system("../../bin/bbackupquery/bbackupquery -q -c testfiles/bbackupd.conf -l testfiles/query14.log \"compare -cE Test1 testfiles/restore-interrupt\" quit");
+ TEST_THAT(compareReturnValue == 1*256);
+ TestRemoteProcessMemLeaks("bbackupquery.memleaks");
+ }
+
+ printf("Check restore deleted files\n");
+ {
+ SocketStreamTLS conn;
+ conn.Open(context, Socket::TypeINET, "localhost", BOX_PORT_BBSTORED);
+ BackupProtocolClient protocol(conn);
+ protocol.QueryVersion(BACKUP_STORE_SERVER_VERSION);
+ std::auto_ptr<BackupProtocolClientLoginConfirmed> loginConf(protocol.QueryLogin(0x01234567, 0)); // read-write
+
+ // Do restore and undelete
+ TEST_THAT(BackupClientRestore(protocol, deldirid, "testfiles/restore-Test1-x1-2", true /* print progress dots */, true /* deleted files */, true /* undelete on server */) == Restore_Complete);
+
+ protocol.QueryFinished();
+
+ // Do a compare with the now undeleted files
+ compareReturnValue = ::system("../../bin/bbackupquery/bbackupquery -q -c testfiles/bbackupd.conf -l testfiles/query11.log \"compare -cE Test1/x1 testfiles/restore-Test1-x1-2\" quit");
+ TEST_THAT(compareReturnValue == 1*256);
+ TestRemoteProcessMemLeaks("bbackupquery.memleaks");
+ }
+
+ // Final check on notifications
+ TEST_THAT(!TestFileExists("testfiles/notifyran.store-full.2"));
+ TEST_THAT(!TestFileExists("testfiles/notifyran.read-error.2"));
+
+ // Kill the daemon
+ TEST_THAT(KillServer(pid));
+ ::sleep(1);
+ TEST_THAT(!ServerIsAlive(pid));
+ TestRemoteProcessMemLeaks("bbackupd.memleaks");
+
+ // Start it again
+ pid = LaunchServer("../../bin/bbackupd/bbackupd testfiles/bbackupd.conf", "testfiles/bbackupd.pid");
+ TEST_THAT(pid != -1 && pid != 0);
+ if(pid != -1 && pid != 0)
+ {
+ // Wait and comapre
+ wait_for_backup_operation((TIME_TO_WAIT_FOR_BACKUP_OPERATION*3) / 2); // little bit longer than usual
+ compareReturnValue = ::system("../../bin/bbackupquery/bbackupquery -q -c testfiles/bbackupd.conf -l testfiles/query4.log \"compare -ac\" quit");
+ TEST_THAT(compareReturnValue == 1*256);
+ TestRemoteProcessMemLeaks("bbackupquery.memleaks");
+
+ // Kill it again
+ TEST_THAT(KillServer(pid));
+ ::sleep(1);
+ TEST_THAT(!ServerIsAlive(pid));
+ TestRemoteProcessMemLeaks("bbackupd.memleaks");
+ }
+ }
+
+ // List the files on the server
+ ::system("../../bin/bbackupquery/bbackupquery -q -c testfiles/bbackupd.conf -l testfiles/queryLIST.log \"list -rotdh\" quit");
+ TestRemoteProcessMemLeaks("bbackupquery.memleaks");
+
+ if(::getuid() == 0)
+ {
+ ::printf("WARNING: This test was run as root. Some tests have been omitted.\n");
+ }
+
+ return 0;
+}
+
+int test(int argc, const char *argv[])
+{
+ // SSL library
+ SSLLib::Initialise();
+
+ // Keys for subsystems
+ BackupClientCryptoKeys_Setup("testfiles/bbackupd.keys");
+
+ // Initial files
+ TEST_THAT(::system("tar xzf testfiles/test_base.tgz -C testfiles/") == 0);
+
+ // Do the tests
+
+ int r = test_basics();
+ if(r != 0) return r;
+
+ r = test_setupaccount();
+ if(r != 0) return r;
+
+ r = test_run_bbstored();
+ if(r != 0) return r;
+
+ r = test_bbackupd();
+ if(r != 0) return r;
+
+ test_kill_bbstored();
+
+ return 0;
+}
+
diff --git a/test/bbackupd/testextra b/test/bbackupd/testextra
new file mode 100755
index 00000000..798c8c67
--- /dev/null
+++ b/test/bbackupd/testextra
@@ -0,0 +1,4 @@
+mkdir testfiles/0_0
+mkdir testfiles/0_1
+mkdir testfiles/0_2
+mkdir testfiles/bbackupd-data
diff --git a/test/bbackupd/testfiles/accounts.txt b/test/bbackupd/testfiles/accounts.txt
new file mode 100755
index 00000000..e69de29b
--- /dev/null
+++ b/test/bbackupd/testfiles/accounts.txt
diff --git a/test/bbackupd/testfiles/bbackupd.conf b/test/bbackupd/testfiles/bbackupd.conf
new file mode 100755
index 00000000..c25b4eab
--- /dev/null
+++ b/test/bbackupd/testfiles/bbackupd.conf
@@ -0,0 +1,50 @@
+
+CertificateFile = testfiles/clientCerts.pem
+PrivateKeyFile = testfiles/clientPrivKey.pem
+TrustedCAsFile = testfiles/clientTrustedCAs.pem
+
+KeysFile = testfiles/bbackupd.keys
+
+DataDirectory = testfiles/bbackupd-data
+
+StoreHostname = localhost
+AccountNumber = 0x01234567
+
+UpdateStoreInterval = 3
+MinimumFileAge = 4
+MaxUploadWait = 24
+
+FileTrackingSizeThreshold = 1024
+DiffingUploadSizeThreshold = 1024
+
+MaximumDiffingTime = 8
+
+ExtendedLogging = yes
+
+CommandSocket = testfiles/bbackupd.sock
+
+NotifyScript = perl testfiles/notifyscript.pl
+
+Server
+{
+ PidFile = testfiles/bbackupd.pid
+}
+
+BackupLocations
+{
+ Test1
+ {
+ Path = testfiles/TestDir1
+
+ ExcludeFile = testfiles/TestDir1/excluded_1
+ ExcludeFile = testfiles/TestDir1/excluded_2
+ ExcludeFilesRegex = \.excludethis$
+ ExcludeFilesRegex = EXCLUDE
+ AlwaysIncludeFile = testfiles/TestDir1/dont.excludethis
+ ExcludeDir = testfiles/TestDir1/exclude_dir
+ ExcludeDir = testfiles/TestDir1/exclude_dir_2
+ ExcludeDirsRegex = not_this_dir
+ AlwaysIncludeDirsRegex = ALWAYSINCLUDE
+ }
+}
+
diff --git a/test/bbackupd/testfiles/bbackupd.keys b/test/bbackupd/testfiles/bbackupd.keys
new file mode 100644
index 00000000..d9135b97
--- /dev/null
+++ b/test/bbackupd/testfiles/bbackupd.keys
Binary files differ
diff --git a/test/bbackupd/testfiles/bbstored.conf b/test/bbackupd/testfiles/bbstored.conf
new file mode 100755
index 00000000..18c73a40
--- /dev/null
+++ b/test/bbackupd/testfiles/bbstored.conf
@@ -0,0 +1,17 @@
+
+RaidFileConf = testfiles/raidfile.conf
+AccountDatabase = testfiles/accounts.txt
+
+ExtendedLogging = no
+
+TimeBetweenHousekeeping = 5
+
+Server
+{
+ PidFile = testfiles/bbstored.pid
+ ListenAddresses = inet:localhost
+ CertificateFile = testfiles/serverCerts.pem
+ PrivateKeyFile = testfiles/serverPrivKey.pem
+ TrustedCAsFile = testfiles/serverTrustedCAs.pem
+}
+
diff --git a/test/bbackupd/testfiles/clientCerts.pem b/test/bbackupd/testfiles/clientCerts.pem
new file mode 100755
index 00000000..c1f14fa7
--- /dev/null
+++ b/test/bbackupd/testfiles/clientCerts.pem
@@ -0,0 +1,11 @@
+-----BEGIN CERTIFICATE-----
+MIIBmDCCAQECAQMwDQYJKoZIhvcNAQEFBQAwDzENMAsGA1UEAxMEUk9PVDAeFw0w
+MzEwMDcwOTAwMDRaFw0zMTAyMjIwOTAwMDRaMBoxGDAWBgNVBAMTD0JBQ0tVUC0w
+MTIzNDU2NzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAvptM6A++ZdkxYN92
+OI6d0O32giRdybSdUVNJk09V1pdVJFhXr4owhtVv6d8yDnPaNOgS1LlxZ9CHcR5A
+LtFwI9wmGHBc5a2uFCZGORTaSggntCythvRV3DGm/fU7mRME7Le1/tWWxjycnk2k
+Rez6d7Ffj56SXDFoxY2dK8MwRasCAwEAATANBgkqhkiG9w0BAQUFAAOBgQB4D3LU
+knCM4UZHMJhlbGnvc+N4O5SGrNKrHs94juMF8dPXJNgboBflkYJKNx1qDf47C/Cx
+hxXjju2ucGHytNQ8kiWsz7vCzeS7Egkl0QhFcBcYVCeXNn7zc34aAUyVlLCuas2o
+EGpfF4se7D3abg7J/3ioW0hx8bSal7kROleKCQ==
+-----END CERTIFICATE-----
diff --git a/test/bbackupd/testfiles/clientPrivKey.pem b/test/bbackupd/testfiles/clientPrivKey.pem
new file mode 100755
index 00000000..34b1af2a
--- /dev/null
+++ b/test/bbackupd/testfiles/clientPrivKey.pem
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXAIBAAKBgQC+m0zoD75l2TFg33Y4jp3Q7faCJF3JtJ1RU0mTT1XWl1UkWFev
+ijCG1W/p3zIOc9o06BLUuXFn0IdxHkAu0XAj3CYYcFzlra4UJkY5FNpKCCe0LK2G
+9FXcMab99TuZEwTst7X+1ZbGPJyeTaRF7Pp3sV+PnpJcMWjFjZ0rwzBFqwIDAQAB
+AoGAMW8Lqh/zLG0A/nPWMGLkkTw2M5iE7nw2VNI6AceQpqAHB+8VhsRbQ4z1gn1N
+eSwYyqHpyFv0Co2touvKj5nn8CJfMmm571cvdOlD/n/mQsW+xZqd9WmvSE8Jh4Qq
+iOQqwbwJlTYTV4BEo90qtfR+MDqffSCB8bHh4l3oO3fSp4kCQQDgbllQeq2kwlLp
+81oDfrk+J7vpiq9hZ/HxFY1fZAOa6iylazZz0JSzvNAtQNLI1LeKAzBc8FuPPSG9
+qSHAKoDHAkEA2Wrziib5OgY/G86yAWVn2hPM7Ky6wGtsJxYnObXUiTwVM7lM1nZU
+LpQaq//vzVDcWggqyEBTYkVcdEPYIJn3/QJBAL3e/bblowRx1p3Q4MV2L5gTG5pQ
+V2HsA7c3yZv7TEWCenUUSEQhIb0SL3kpj2qS9BhR7FekjYGYcXQ4o7IlAz8CQD1B
+BJxHnq/aUq1i7oO2Liwip/mGMJdFrJLWivaXY+nGI7MO4bcKX21ADMOot8cAoRQ8
+eNEyTkvBfurCsoF834ECQCPejz6x1bh/H7SeeANP17HKlwx1Lshw2JzxfF96MA26
+Eige4f0ttKHhMY/bnMcOzfPUSe/LvIN3AiMtphkl0pw=
+-----END RSA PRIVATE KEY-----
diff --git a/test/bbackupd/testfiles/clientTrustedCAs.pem b/test/bbackupd/testfiles/clientTrustedCAs.pem
new file mode 100755
index 00000000..2a065879
--- /dev/null
+++ b/test/bbackupd/testfiles/clientTrustedCAs.pem
@@ -0,0 +1,11 @@
+-----BEGIN CERTIFICATE-----
+MIIBjDCB9gIBADANBgkqhkiG9w0BAQUFADAPMQ0wCwYDVQQDEwRST09UMB4XDTAz
+MTAwNzA4NTkzMloXDTMxMDIyMjA4NTkzMlowDzENMAsGA1UEAxMEUk9PVDCBnzAN
+BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAtZypR/5m5fuNMPNrSLdzwmXKqhdVZj/e
+cZHUZvVuXQZboosAznDrbh8HgpuTw5vaZDEz8VfPwgIaROZDT3ztFIedLapJ7Ot9
+I4JNqSv/y3V9MKb7trTSPVvyYLqk9isLmw8wmEidJiLbWbIc2cHFXDvWNqTr2jF6
+u4Q8DvdVfAECAwEAATANBgkqhkiG9w0BAQUFAAOBgQAL1lyJ/5y44yjk2BK+tnrZ
+hbK7Ghtqrq/uZ8RQq5sAme919TnPijh2tRBqSaUaD2K+Sgo3RNgUGbKhfHRU1pfM
+USllHskTKiJu74ix/T3UOnjpQ946OLSl5zNsOdOgbjBDnozfPSrKeEGN0huBbmmt
+SlL3iQzVXlF6NAhkzS54fQ==
+-----END CERTIFICATE-----
diff --git a/test/bbackupd/testfiles/extcheck1.pl b/test/bbackupd/testfiles/extcheck1.pl
new file mode 100755
index 00000000..7481593d
--- /dev/null
+++ b/test/bbackupd/testfiles/extcheck1.pl
@@ -0,0 +1,33 @@
+#!/usr/bin/perl
+use strict;
+
+unless(open IN,"../../bin/bbackupquery/bbackupquery -q -c testfiles/bbackupd.conf -l testfiles/query4.log \"compare -ac\" quit|")
+{
+ print "Couldn't open compare utility\n";
+ exit 2;
+}
+
+my $ret = 1;
+my $seen = 0;
+
+while(<IN>)
+{
+ next unless m/\S/;
+ if(m/continousupdate/)
+ {
+ $ret = 2 unless m/exists/;
+ $seen = 1;
+ }
+ else
+ {
+ $ret = 2 unless m/\AWARNING/ || m/\ADifferences/ || /might be reason/ || /probably due to file mod/;
+ }
+ print;
+}
+
+close IN;
+
+$ret = 2 unless $seen;
+
+exit $ret;
+
diff --git a/test/bbackupd/testfiles/extcheck2.pl b/test/bbackupd/testfiles/extcheck2.pl
new file mode 100755
index 00000000..a0c7d3cd
--- /dev/null
+++ b/test/bbackupd/testfiles/extcheck2.pl
@@ -0,0 +1,29 @@
+#!/usr/bin/perl
+use strict;
+
+unless(open IN,"../../bin/bbackupquery/bbackupquery -q -c testfiles/bbackupd.conf -l testfiles/query4.log \"compare -ac\" quit|")
+{
+ print "Couldn't open compare utility\n";
+ exit 2;
+}
+
+my $ret = 1;
+
+while(<IN>)
+{
+ next unless m/\S/;
+ if(m/continousupdate/)
+ {
+ $ret = 2 unless m/contents/ || m/attributes/;
+ }
+ else
+ {
+ $ret = 2 unless m/\AWARNING/ || m/\ADifferences/ || /might be reason/ || /probably due to file mod/;
+ }
+ print;
+}
+
+close IN;
+
+exit $ret;
+
diff --git a/test/bbackupd/testfiles/notifyscript.pl b/test/bbackupd/testfiles/notifyscript.pl
new file mode 100755
index 00000000..a31d072e
--- /dev/null
+++ b/test/bbackupd/testfiles/notifyscript.pl
@@ -0,0 +1,15 @@
+#!/usr/bin/perl
+
+
+my $f = 'testfiles/notifyran.'.$ARGV[0].'.';
+my $n = 1;
+
+while(-e $f.$n)
+{
+ $n ++;
+}
+
+open FL,'>'.$f.$n;
+print FL localtime();
+close FL;
+
diff --git a/test/bbackupd/testfiles/raidfile.conf b/test/bbackupd/testfiles/raidfile.conf
new file mode 100755
index 00000000..641872b0
--- /dev/null
+++ b/test/bbackupd/testfiles/raidfile.conf
@@ -0,0 +1,10 @@
+
+disc0
+{
+ SetNumber = 0
+ BlockSize = 2048
+ Dir0 = testfiles/0_0
+ Dir1 = testfiles/0_1
+ Dir2 = testfiles/0_2
+}
+
diff --git a/test/bbackupd/testfiles/serverCerts.pem b/test/bbackupd/testfiles/serverCerts.pem
new file mode 100755
index 00000000..92467618
--- /dev/null
+++ b/test/bbackupd/testfiles/serverCerts.pem
@@ -0,0 +1,11 @@
+-----BEGIN CERTIFICATE-----
+MIIBlzCCAQACAQQwDQYJKoZIhvcNAQEFBQAwDzENMAsGA1UEAxMEUk9PVDAeFw0w
+MzEwMDcwOTAwMTFaFw0zMTAyMjIwOTAwMTFaMBkxFzAVBgNVBAMTDlNUT1JFLTAw
+MDAwMDA4MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDNj1fGSCaSl/1w1lRV
+I8qE6BqjvT6R0XXGdIV+dk/mHmE3NOCPcBq/gxZOYevp+QnwMc+nUSS7Px/n+q92
+cl3a8ttInfZjLqg9o/wpd6dBfH4gLTG4bEujhMt1x4bEUJk/uWfnk5FhsJXDBrlH
+RJZNiS9Asme+5Zvjfz3Phy0YWwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBABhmdun/
+myn3l4SbH+PxSUaW/mSvBubFhbbl9wolwhzvGCrtY968jn464JUP1UwUnnvePUU2
+SSVPZOVCvobCfM6s20aOdlKvnn+7GZkjoFONuCw3O+1hIFTSyXFcJWBaYLuczVk1
+HfdIKKcVZ1CpAfnMhMxuu+nA7fjor4p1/K0t
+-----END CERTIFICATE-----
diff --git a/test/bbackupd/testfiles/serverPrivKey.pem b/test/bbackupd/testfiles/serverPrivKey.pem
new file mode 100755
index 00000000..fd87607d
--- /dev/null
+++ b/test/bbackupd/testfiles/serverPrivKey.pem
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXQIBAAKBgQDNj1fGSCaSl/1w1lRVI8qE6BqjvT6R0XXGdIV+dk/mHmE3NOCP
+cBq/gxZOYevp+QnwMc+nUSS7Px/n+q92cl3a8ttInfZjLqg9o/wpd6dBfH4gLTG4
+bEujhMt1x4bEUJk/uWfnk5FhsJXDBrlHRJZNiS9Asme+5Zvjfz3Phy0YWwIDAQAB
+AoGBAI88mjo1noM528Wb4+nr5bvVDHMadJYhccMXAMqNYMGGW9GfS/dHc6wNiSaX
+P0+rVIyF+R+rAEBmDTKV0Vxk9xZQuAaDKjLluDkxSxSR869D2YOWYUfvjDo3OFlT
+LMZf0eE7u/3Pm0MtxPctXszqvNnmb+IvPXzttGRgUfU5G+tJAkEA+IphkGMI4A3l
+4KfxotZZU+HiJbRDFpm81RzCc2709KCMkXMEz/+xkvnqlo28jqOf7PRBeq/ecsZN
+8BGvtyoqVQJBANO6uj6sPI66GaRqxV83VyUUdMmL9uFOccIMqW5q0rx5UDi0mG7t
+Pjjz+ul1D247+dvVxnEBeW4C85TSNbbKR+8CQQChpV7PCZo8Hs3jz1bZEZAHfmIX
+I6Z+jH7EHHBbo06ty72g263FmgdkECcCxCxemQzqj/IGWVvUSiVmfhpKhqIBAkAl
+XbjswpzVW4aW+7jlevDIPHn379mcHan54x4rvHKAjLBZsZWNThVDG9vWQ7B7dd48
+q9efrfDuN1shko+kOMLFAkAGIc5w0bJNC4eu91Wr6AFgTm2DntyVQ9keVhYbrwrE
+xY37dgVhAWVeLDOk6eVOVSYqEI1okXPVqvfOIoRJUYkn
+-----END RSA PRIVATE KEY-----
diff --git a/test/bbackupd/testfiles/serverTrustedCAs.pem b/test/bbackupd/testfiles/serverTrustedCAs.pem
new file mode 100755
index 00000000..2a065879
--- /dev/null
+++ b/test/bbackupd/testfiles/serverTrustedCAs.pem
@@ -0,0 +1,11 @@
+-----BEGIN CERTIFICATE-----
+MIIBjDCB9gIBADANBgkqhkiG9w0BAQUFADAPMQ0wCwYDVQQDEwRST09UMB4XDTAz
+MTAwNzA4NTkzMloXDTMxMDIyMjA4NTkzMlowDzENMAsGA1UEAxMEUk9PVDCBnzAN
+BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAtZypR/5m5fuNMPNrSLdzwmXKqhdVZj/e
+cZHUZvVuXQZboosAznDrbh8HgpuTw5vaZDEz8VfPwgIaROZDT3ztFIedLapJ7Ot9
+I4JNqSv/y3V9MKb7trTSPVvyYLqk9isLmw8wmEidJiLbWbIc2cHFXDvWNqTr2jF6
+u4Q8DvdVfAECAwEAATANBgkqhkiG9w0BAQUFAAOBgQAL1lyJ/5y44yjk2BK+tnrZ
+hbK7Ghtqrq/uZ8RQq5sAme919TnPijh2tRBqSaUaD2K+Sgo3RNgUGbKhfHRU1pfM
+USllHskTKiJu74ix/T3UOnjpQ946OLSl5zNsOdOgbjBDnozfPSrKeEGN0huBbmmt
+SlL3iQzVXlF6NAhkzS54fQ==
+-----END CERTIFICATE-----
diff --git a/test/bbackupd/testfiles/spacetest1.tgz b/test/bbackupd/testfiles/spacetest1.tgz
new file mode 100644
index 00000000..c653c0ae
--- /dev/null
+++ b/test/bbackupd/testfiles/spacetest1.tgz
Binary files differ
diff --git a/test/bbackupd/testfiles/spacetest2.tgz b/test/bbackupd/testfiles/spacetest2.tgz
new file mode 100644
index 00000000..aa47312d
--- /dev/null
+++ b/test/bbackupd/testfiles/spacetest2.tgz
Binary files differ
diff --git a/test/bbackupd/testfiles/test2.tgz b/test/bbackupd/testfiles/test2.tgz
new file mode 100755
index 00000000..ac7f18af
--- /dev/null
+++ b/test/bbackupd/testfiles/test2.tgz
Binary files differ
diff --git a/test/bbackupd/testfiles/test3.tgz b/test/bbackupd/testfiles/test3.tgz
new file mode 100755
index 00000000..c7d60cd7
--- /dev/null
+++ b/test/bbackupd/testfiles/test3.tgz
Binary files differ
diff --git a/test/bbackupd/testfiles/test_base.tgz b/test/bbackupd/testfiles/test_base.tgz
new file mode 100755
index 00000000..9c8ddfc0
--- /dev/null
+++ b/test/bbackupd/testfiles/test_base.tgz
Binary files differ
diff --git a/test/bbackupd/testfiles/testexclude.tgz b/test/bbackupd/testfiles/testexclude.tgz
new file mode 100644
index 00000000..ac7329d8
--- /dev/null
+++ b/test/bbackupd/testfiles/testexclude.tgz
Binary files differ