diff options
author | Reinhard Tartler <siretart@tauware.de> | 2009-04-02 13:58:11 +0200 |
---|---|---|
committer | Reinhard Tartler <siretart@tauware.de> | 2009-04-02 13:58:11 +0200 |
commit | a84d45498bd861c9225080232948a99c2e317bb8 (patch) | |
tree | 8f1f5fb7bf7ffbf6f24cf4a4fd6888a235dbcc08 /test/bbackupd | |
parent | 25db897553a0db0f912602b375029e724f51556e (diff) |
Import upstream version 0.11~rc3~r2491
Diffstat (limited to 'test/bbackupd')
-rw-r--r-- | test/bbackupd/Makefile.extra | 15 | ||||
-rw-r--r-- | test/bbackupd/testbbackupd.cpp | 1747 | ||||
-rw-r--r-- | test/bbackupd/testfiles/bbackupd-exclude.conf.in | 47 | ||||
-rw-r--r-- | test/bbackupd/testfiles/bbackupd-snapshot.conf.in | 56 | ||||
-rw-r--r-- | test/bbackupd/testfiles/bbackupd-symlink.conf.in | 55 | ||||
-rw-r--r-- | test/bbackupd/testfiles/bbackupd-temploc.conf | 3 | ||||
-rw-r--r-- | test/bbackupd/testfiles/bbackupd.conf.in | 1 | ||||
-rw-r--r-- | test/bbackupd/testfiles/bbstored.conf | 2 | ||||
-rwxr-xr-x | test/bbackupd/testfiles/extcheck1.pl.in | 5 | ||||
-rwxr-xr-x | test/bbackupd/testfiles/extcheck2.pl.in | 5 | ||||
-rwxr-xr-x | test/bbackupd/testfiles/notifyscript.pl.in | 11 |
11 files changed, 1536 insertions, 411 deletions
diff --git a/test/bbackupd/Makefile.extra b/test/bbackupd/Makefile.extra index 1d3f5103..0ae56bd1 100644 --- a/test/bbackupd/Makefile.extra +++ b/test/bbackupd/Makefile.extra @@ -1 +1,14 @@ -link-extra: ../../bin/bbackupd/autogen_ClientException.o ../../bin/bbackupd/BackupClientContext.o ../../bin/bbackupd/BackupClientDeleteList.o ../../bin/bbackupd/BackupClientDirectoryRecord.o ../../bin/bbackupd/Win32BackupService.o ../../bin/bbackupd/BackupClientInodeToIDMap.o ../../bin/bbackupd/Win32ServiceFunctions.o ../../bin/bbackupd/BackupDaemon.o +link-extra: ../../bin/bbackupd/autogen_ClientException.o \ + ../../bin/bbackupd/BackupClientContext.o \ + ../../bin/bbackupd/BackupClientDeleteList.o \ + ../../bin/bbackupd/BackupClientDirectoryRecord.o \ + ../../bin/bbackupd/Win32BackupService.o \ + ../../bin/bbackupd/BackupClientInodeToIDMap.o \ + ../../bin/bbackupd/Win32ServiceFunctions.o \ + ../../bin/bbackupd/BackupDaemon.o \ + ../../bin/bbstored/BackupStoreContext.o \ + ../../bin/bbstored/BBStoreDHousekeeping.o \ + ../../bin/bbstored/HousekeepStoreAccount.o \ + ../../bin/bbstored/autogen_BackupProtocolServer.o \ + ../../bin/bbstored/BackupCommands.o \ + ../../bin/bbstored/BackupStoreDaemon.o diff --git a/test/bbackupd/testbbackupd.cpp b/test/bbackupd/testbbackupd.cpp index a0732c21..9d82a11b 100644 --- a/test/bbackupd/testbbackupd.cpp +++ b/test/bbackupd/testbbackupd.cpp @@ -32,18 +32,26 @@ #include <sys/xattr.h> #endif +#ifdef HAVE_SIGNAL_H + #include <signal.h> +#endif + #include <map> #ifdef HAVE_SYSCALL #include <sys/syscall.h> #endif +#include "autogen_BackupProtocolServer.h" #include "BackupClientCryptoKeys.h" #include "BackupClientFileAttributes.h" #include "BackupClientRestore.h" #include "BackupDaemon.h" #include "BackupDaemonConfigVerify.h" +#include "BackupQueries.h" #include "BackupStoreConstants.h" +#include "BackupStoreContext.h" +#include "BackupStoreDaemon.h" #include "BackupStoreDirectory.h" #include "BackupStoreException.h" #include "BoxPortsAndFiles.h" @@ -79,27 +87,6 @@ // two cycles and a bit #define TIME_TO_WAIT_FOR_BACKUP_OPERATION 12 -// utility macro for comparing two strings in a line -#define TEST_EQUAL(expected, found, line) \ -{ \ - std::string exp_str = expected; \ - std::string found_str = found; \ - TEST_THAT(exp_str == found_str); \ - if(exp_str != found_str) \ - { \ - printf("Expected <%s> but found <%s> in <%s>\n", \ - exp_str.c_str(), found_str.c_str(), line.c_str()); \ - } \ -} - -// utility macro for testing a line -#define TEST_LINE(condition, line) \ - TEST_THAT(condition); \ - if (!(condition)) \ - { \ - printf("Test failed on <%s>\n", line.c_str()); \ - } - void wait_for_backup_operation(int seconds = TIME_TO_WAIT_FOR_BACKUP_OPERATION) { wait_for_operation(seconds); @@ -271,9 +258,9 @@ void finish_with_write_xattr_test() bool attrmatch(const char *f1, const char *f2) { - struct stat s1, s2; - TEST_THAT(::lstat(f1, &s1) == 0); - TEST_THAT(::lstat(f2, &s2) == 0); + EMU_STRUCT_STAT s1, s2; + TEST_THAT(EMU_LSTAT(f1, &s1) == 0); + TEST_THAT(EMU_LSTAT(f2, &s2) == 0); #ifdef HAVE_SYS_XATTR_H { @@ -336,7 +323,11 @@ int test_basics() #endif BackupClientFileAttributes t3; - TEST_CHECK_THROWS(t3.ReadAttributes("doesn't exist"), CommonException, OSFileError); + { + Logging::Guard guard(Log::ERROR); + TEST_CHECK_THROWS(t3.ReadAttributes("doesn't exist"), + CommonException, OSFileError); + } // Create some more files FILE *f = fopen("testfiles/test1_n", "w"); @@ -353,8 +344,13 @@ int test_basics() #endif #ifndef WIN32 - TEST_CHECK_THROWS(t1.WriteAttributes("testfiles/test1_nXX"), CommonException, OSFileError); - TEST_CHECK_THROWS(t3.WriteAttributes("doesn't exist"), BackupStoreException, AttributesNotLoaded); + { + Logging::Guard guard(Log::ERROR); + TEST_CHECK_THROWS(t1.WriteAttributes("testfiles/test1_nXX"), + CommonException, OSFileError); + TEST_CHECK_THROWS(t3.WriteAttributes("doesn't exist"), + BackupStoreException, AttributesNotLoaded); + } // Test that attributes are vaguely similar TEST_THAT(attrmatch("testfiles/test1", "testfiles/test1_n")); @@ -440,7 +436,8 @@ int test_setupaccount() int test_run_bbstored() { - std::string cmd = BBSTORED + bbstored_args + " testfiles/bbstored.conf"; + std::string cmd = BBSTORED " " + bbstored_args + + " testfiles/bbstored.conf"; bbstored_pid = LaunchServer(cmd, "testfiles/bbstored.pid"); TEST_THAT(bbstored_pid != -1 && bbstored_pid != 0); @@ -455,13 +452,19 @@ int test_run_bbstored() return 1; } -int test_kill_bbstored() +int test_kill_bbstored(bool wait_for_process = false) { - TEST_THAT(KillServer(bbstored_pid)); + TEST_THAT(KillServer(bbstored_pid, wait_for_process)); ::safe_sleep(1); TEST_THAT(!ServerIsAlive(bbstored_pid)); + if (!ServerIsAlive(bbstored_pid)) + { + bbstored_pid = 0; + } - #ifndef WIN32 + #ifdef WIN32 + TEST_THAT(unlink("testfiles/bbstored.pid") == 0); + #else TestRemoteProcessMemLeaks("bbstored.memleaks"); #endif @@ -511,7 +514,8 @@ void do_interrupted_restore(const TLSContext &context, int64_t restoredirid) { // connect and log in SocketStreamTLS conn; - conn.Open(context, Socket::TypeINET, "localhost", BOX_PORT_BBSTORED); + conn.Open(context, Socket::TypeINET, "localhost", + 22011); BackupProtocolClient protocol(conn); protocol.QueryVersion(BACKUP_STORE_SERVER_VERSION); std::auto_ptr<BackupProtocolClientLoginConfirmed> loginConf(protocol.QueryLogin(0x01234567, BackupProtocolClientLogin::Flags_ReadOnly)); @@ -601,10 +605,10 @@ int64_t SearchDir(BackupStoreDirectory& rDir, SocketStreamTLS sSocket; -std::auto_ptr<BackupProtocolClient> Connect(TLSContext& rContext, int flags) +std::auto_ptr<BackupProtocolClient> Connect(TLSContext& rContext) { sSocket.Open(rContext, Socket::TypeINET, - "localhost", BOX_PORT_BBSTORED); + "localhost", 22011); std::auto_ptr<BackupProtocolClient> connection; connection.reset(new BackupProtocolClient(sSocket)); connection->Handshake(); @@ -617,10 +621,17 @@ std::auto_ptr<BackupProtocolClient> Connect(TLSContext& rContext, int flags) THROW_EXCEPTION(BackupStoreException, WrongServerVersion); } - connection->QueryLogin(0x01234567, flags); return connection; } +std::auto_ptr<BackupProtocolClient> ConnectAndLogin(TLSContext& rContext, + int flags) +{ + std::auto_ptr<BackupProtocolClient> connection(Connect(rContext)); + connection->QueryLogin(0x01234567, flags); + return connection; +} + std::auto_ptr<BackupStoreDirectory> ReadDirectory ( BackupProtocolClient& rClient, @@ -639,6 +650,7 @@ int start_internal_daemon() { // ensure that no child processes end up running tests! int own_pid = getpid(); + BOX_TRACE("Test PID is " << own_pid); // this is a quick hack to allow passing some options to the daemon const char* argv[] = { @@ -658,18 +670,14 @@ int start_internal_daemon() result = daemon.Main("testfiles/bbackupd.conf", 1, argv); } - TEST_THAT(result == 0); - if (result != 0) - { - printf("Daemon exited with code %d\n", result); - } + TEST_EQUAL_LINE(0, result, "Daemon exit code"); // ensure that no child processes end up running tests! - TEST_THAT(getpid() == own_pid); if (getpid() != own_pid) { // abort! - _exit(1); + BOX_INFO("Daemon child finished, exiting now."); + _exit(0); } TEST_THAT(TestFileExists("testfiles/bbackupd.pid")); @@ -703,20 +711,9 @@ int start_internal_daemon() bool stop_internal_daemon(int pid) { - bool killed_server = KillServer(pid); + bool killed_server = KillServer(pid, false); TEST_THAT(killed_server); return killed_server; - - /* - int status; - TEST_THAT(waitpid(pid, &status, 0) == pid); - TEST_THAT(WIFEXITED(status)); - - if (WIFEXITED(status)) - { - TEST_THAT(WEXITSTATUS(status) == 0); - } - */ } static struct dirent readdir_test_dirent; @@ -728,15 +725,15 @@ static char stat_hook_filename[512]; // This will not match the directory on the store, so a sync will start. // We set up the next intercept for the same directory by passing NULL. -struct dirent *readdir_test_hook_2(DIR *dir); +extern "C" struct dirent *readdir_test_hook_2(DIR *dir); #ifdef LINUX_WEIRD_LSTAT -int lstat_test_hook(int ver, const char *file_name, struct stat *buf); +extern "C" int lstat_test_hook(int ver, const char *file_name, struct stat *buf); #else -int lstat_test_hook(const char *file_name, struct stat *buf); +extern "C" int lstat_test_hook(const char *file_name, struct stat *buf); #endif -struct dirent *readdir_test_hook_1(DIR *dir) +extern "C" struct dirent *readdir_test_hook_1(DIR *dir) { #ifndef PLATFORM_CLIB_FNS_INTERCEPTION_IMPOSSIBLE intercept_setup_readdir_hook(NULL, readdir_test_hook_2); @@ -747,7 +744,7 @@ struct dirent *readdir_test_hook_1(DIR *dir) // Second test hook, during the directory sync stage, keeps returning // new filenames until the timer expires, then disables the intercept. -struct dirent *readdir_test_hook_2(DIR *dir) +extern "C" struct dirent *readdir_test_hook_2(DIR *dir) { if (time(NULL) >= readdir_stop_time) { @@ -783,17 +780,45 @@ struct dirent *readdir_test_hook_2(DIR *dir) } #ifdef LINUX_WEIRD_LSTAT -int lstat_test_hook(int ver, const char *file_name, struct stat *buf) +extern "C" int lstat_test_hook(int ver, const char *file_name, struct stat *buf) #else -int lstat_test_hook(const char *file_name, struct stat *buf) +extern "C" int lstat_test_hook(const char *file_name, struct stat *buf) #endif { - // TRACE1("lstat hook triggered for %s", file_name); + // TRACE1("lstat hook triggered for %s", file_name); memset(buf, 0, sizeof(*buf)); buf->st_mode = S_IFREG; return 0; } +// Simulate a symlink that is on a different device than the file +// that it points to. +int lstat_test_post_hook(int old_ret, const char *file_name, struct stat *buf) +{ + BOX_TRACE("lstat post hook triggered for " << file_name); + if (old_ret == 0 && + strcmp(file_name, "testfiles/symlink-to-TestDir1") == 0) + { + buf->st_dev ^= 0xFFFF; + } + return old_ret; +} + +bool test_entry_deleted(BackupStoreDirectory& rDir, + const std::string& rName) +{ + BackupStoreDirectory::Iterator i(rDir); + + BackupStoreDirectory::Entry *en = i.FindMatchingClearName( + BackupStoreFilenameClear(rName)); + TEST_THAT(en != 0); + if (en == 0) return false; + + int16_t flags = en->GetFlags(); + TEST_THAT(flags && BackupStoreDirectory::Entry::Flags_Deleted); + return flags && BackupStoreDirectory::Entry::Flags_Deleted; +} + int test_bbackupd() { // First, wait for a normal period to make sure the last changes @@ -807,6 +832,23 @@ int test_bbackupd() "testfiles/clientPrivKey.pem", "testfiles/clientTrustedCAs.pem"); + printf("\n==== Testing that ReadDirectory on nonexistent directory " + "does not crash\n"); + { + std::auto_ptr<BackupProtocolClient> client = ConnectAndLogin( + context, 0 /* read-write */); + + { + Logging::Guard guard(Log::ERROR); + TEST_CHECK_THROWS(ReadDirectory(*client, 0x12345678), + ConnectionException, + Conn_Protocol_UnexpectedReply); + } + + client->QueryFinished(); + sSocket.Close(); + } + // unpack the files for the initial test TEST_THAT(::system("rm -rf testfiles/TestDir1") == 0); TEST_THAT(::mkdir("testfiles/TestDir1", 0777) == 0); @@ -818,7 +860,7 @@ int test_bbackupd() TEST_THAT(::system("gzip -d < testfiles/spacetest1.tgz " "| ( cd testfiles/TestDir1 && tar xf - )") == 0); #endif - + #ifdef PLATFORM_CLIB_FNS_INTERCEPTION_IMPOSSIBLE printf("\n==== Skipping intercept-based KeepAlive tests " "on this platform.\n"); @@ -841,7 +883,9 @@ int test_bbackupd() char buffer[10000]; memset(buffer, 0, sizeof(buffer)); - TEST_THAT(write(fd, buffer, sizeof(buffer)) == sizeof(buffer)); + TEST_EQUAL_LINE(sizeof(buffer), + write(fd, buffer, sizeof(buffer)), + "Buffer write"); TEST_THAT(close(fd) == 0); int pid = start_internal_daemon(); @@ -856,11 +900,14 @@ int test_bbackupd() TEST_THAT(unlink("testfiles/bbackupd.log") == 0); pid = start_internal_daemon(); + intercept_clear_setup(); fd = open("testfiles/TestDir1/spacetest/f1", O_WRONLY); TEST_THAT(fd > 0); // write again, to update the file's timestamp - TEST_THAT(write(fd, buffer, sizeof(buffer)) == sizeof(buffer)); + TEST_EQUAL_LINE(sizeof(buffer), + write(fd, buffer, sizeof(buffer)), + "Buffer write"); TEST_THAT(close(fd) == 0); wait_for_backup_operation(); @@ -892,20 +939,22 @@ int test_bbackupd() std::string line; TEST_THAT(reader.GetLine(line)); std::string comp = "Receive Success(0x"; - TEST_EQUAL(comp, line.substr(0, comp.size()), line); + TEST_EQUAL_LINE(comp, line.substr(0, comp.size()), + line); TEST_THAT(reader.GetLine(line)); - TEST_EQUAL("Receiving stream, size 124", line, line); + TEST_EQUAL("Receiving stream, size 124", line); TEST_THAT(reader.GetLine(line)); - TEST_EQUAL("Send GetIsAlive()", line, line); + TEST_EQUAL("Send GetIsAlive()", line); TEST_THAT(reader.GetLine(line)); - TEST_EQUAL("Receive IsAlive()", line, line); + TEST_EQUAL("Receive IsAlive()", line); TEST_THAT(reader.GetLine(line)); comp = "Send StoreFile(0x3,"; - TEST_EQUAL(comp, line.substr(0, comp.size()), line); + TEST_EQUAL_LINE(comp, line.substr(0, comp.size()), + line); comp = ",\"f1\")"; std::string sub = line.substr(line.size() - comp.size()); - TEST_EQUAL(comp, sub, line); + TEST_EQUAL_LINE(comp, sub, line); std::string comp2 = ",0x0,"; sub = line.substr(line.size() - comp.size() - comp2.size() + 1, comp2.size()); @@ -926,11 +975,14 @@ int test_bbackupd() intercept_setup_delay("testfiles/TestDir1/spacetest/f1", 0, 4000, SYS_read, 1); pid = start_internal_daemon(); + intercept_clear_setup(); fd = open("testfiles/TestDir1/spacetest/f1", O_WRONLY); TEST_THAT(fd > 0); // write again, to update the file's timestamp - TEST_THAT(write(fd, buffer, sizeof(buffer)) == sizeof(buffer)); + TEST_EQUAL_LINE(sizeof(buffer), + write(fd, buffer, sizeof(buffer)), + "Buffer write"); TEST_THAT(close(fd) == 0); wait_for_backup_operation(); @@ -959,9 +1011,10 @@ int test_bbackupd() std::string line; TEST_THAT(reader.GetLine(line)); std::string comp = "Receive Success(0x"; - TEST_THAT(line.substr(0, comp.size()) == comp); + TEST_EQUAL_LINE(comp, line.substr(0, comp.size()), + line); TEST_THAT(reader.GetLine(line)); - TEST_THAT(line == "Receiving stream, size 124"); + TEST_EQUAL("Receiving stream, size 124", line); // delaying for 4 seconds in one step means that // the diff timer and the keepalive timer will @@ -970,10 +1023,11 @@ int test_bbackupd() TEST_THAT(reader.GetLine(line)); comp = "Send StoreFile(0x3,"; - TEST_EQUAL(comp, line.substr(0, comp.size()), line); + TEST_EQUAL_LINE(comp, line.substr(0, comp.size()), + line); comp = ",0x0,\"f1\")"; std::string sub = line.substr(line.size() - comp.size()); - TEST_EQUAL(comp, sub, line); + TEST_EQUAL_LINE(comp, sub, line); } if (failures > 0) @@ -986,11 +1040,14 @@ int test_bbackupd() intercept_setup_delay("testfiles/TestDir1/spacetest/f1", 0, 1000, SYS_read, 3); pid = start_internal_daemon(); + intercept_clear_setup(); fd = open("testfiles/TestDir1/spacetest/f1", O_WRONLY); TEST_THAT(fd > 0); // write again, to update the file's timestamp - TEST_THAT(write(fd, buffer, sizeof(buffer)) == sizeof(buffer)); + TEST_EQUAL_LINE(sizeof(buffer), + write(fd, buffer, sizeof(buffer)), + "Buffer write"); TEST_THAT(close(fd) == 0); wait_for_backup_operation(); @@ -1019,9 +1076,10 @@ int test_bbackupd() std::string line; TEST_THAT(reader.GetLine(line)); std::string comp = "Receive Success(0x"; - TEST_THAT(line.substr(0, comp.size()) == comp); + TEST_EQUAL_LINE(comp, line.substr(0, comp.size()), + line); TEST_THAT(reader.GetLine(line)); - TEST_THAT(line == "Receiving stream, size 124"); + TEST_EQUAL("Receiving stream, size 124", line); // delaying for 3 seconds in steps of 1 second // means that the keepalive timer will expire 3 times, @@ -1030,23 +1088,24 @@ int test_bbackupd() // only two keepalives. TEST_THAT(reader.GetLine(line)); - TEST_THAT(line == "Send GetIsAlive()"); + TEST_EQUAL("Send GetIsAlive()", line); TEST_THAT(reader.GetLine(line)); - TEST_THAT(line == "Receive IsAlive()"); + TEST_EQUAL("Receive IsAlive()", line); TEST_THAT(reader.GetLine(line)); - TEST_THAT(line == "Send GetIsAlive()"); + TEST_EQUAL("Send GetIsAlive()", line); TEST_THAT(reader.GetLine(line)); - TEST_THAT(line == "Receive IsAlive()"); + TEST_EQUAL("Receive IsAlive()", line); // but two matching blocks should have been found // already, so the upload should be a diff. TEST_THAT(reader.GetLine(line)); comp = "Send StoreFile(0x3,"; - TEST_EQUAL(comp, line.substr(0, comp.size()), line); + TEST_EQUAL_LINE(comp, line.substr(0, comp.size()), + line); comp = ",\"f1\")"; std::string sub = line.substr(line.size() - comp.size()); - TEST_EQUAL(comp, sub, line); + TEST_EQUAL_LINE(comp, sub, line); std::string comp2 = ",0x0,"; sub = line.substr(line.size() - comp.size() - comp2.size() + 1, comp2.size()); @@ -1067,6 +1126,7 @@ int test_bbackupd() readdir_stop_time = time(NULL) + 12 + 2; pid = start_internal_daemon(); + intercept_clear_setup(); std::string touchfile = "testfiles/TestDir1/spacetest/d1/touch-me"; @@ -1074,7 +1134,9 @@ int test_bbackupd() fd = open(touchfile.c_str(), O_CREAT | O_WRONLY); TEST_THAT(fd > 0); // write again, to update the file's timestamp - TEST_THAT(write(fd, buffer, sizeof(buffer)) == sizeof(buffer)); + TEST_EQUAL_LINE(sizeof(buffer), + write(fd, buffer, sizeof(buffer)), + "Buffer write"); TEST_THAT(close(fd) == 0); wait_for_backup_operation(); @@ -1091,7 +1153,7 @@ int test_bbackupd() { std::string line; TEST_THAT(reader.GetLine(line)); - if (line == "Send ListDirectory(0x3,0xffffffff,0xc,true)") + if (line == "Send ListDirectory(0x3,0xffff,0xc,true)") { found1 = true; break; @@ -1119,17 +1181,17 @@ int test_bbackupd() { std::string line; TEST_THAT(reader.GetLine(line)); - TEST_EQUAL("Receive Success(0x3)", line, line); + TEST_EQUAL("Receive Success(0x3)", line); TEST_THAT(reader.GetLine(line)); - TEST_EQUAL("Receiving stream, size 425", line, line); + TEST_EQUAL("Receiving stream, size 425", line); TEST_THAT(reader.GetLine(line)); - TEST_EQUAL("Send GetIsAlive()", line, line); + TEST_EQUAL("Send GetIsAlive()", line); TEST_THAT(reader.GetLine(line)); - TEST_EQUAL("Receive IsAlive()", line, line); + TEST_EQUAL("Receive IsAlive()", line); TEST_THAT(reader.GetLine(line)); - TEST_EQUAL("Send GetIsAlive()", line, line); + TEST_EQUAL("Send GetIsAlive()", line); TEST_THAT(reader.GetLine(line)); - TEST_EQUAL("Receive IsAlive()", line, line); + TEST_EQUAL("Receive IsAlive()", line); } if (failures > 0) @@ -1146,8 +1208,11 @@ int test_bbackupd() } #endif // PLATFORM_CLIB_FNS_INTERCEPTION_IMPOSSIBLE + // Check that no read error has been reported yet + TEST_THAT(!TestFileExists("testfiles/notifyran.read-error.1")); + std::string cmd = BBACKUPD " " + bbackupd_args + - " testfiles/bbackupd-temploc.conf"; + " testfiles/bbackupd.conf"; bbackupd_pid = LaunchServer(cmd, "testfiles/bbackupd.pid"); TEST_THAT(bbackupd_pid != -1 && bbackupd_pid != 0); @@ -1158,6 +1223,553 @@ int test_bbackupd() if (!ServerIsAlive(bbackupd_pid)) return 1; if (!ServerIsAlive(bbstored_pid)) return 1; + if(bbackupd_pid > 0) + { + printf("\n==== Testing that backup pauses when " + "store is full\n"); + + // wait for files to be uploaded + BOX_TRACE("Waiting for all outstanding files to be uploaded") + wait_for_sync_end(); + BOX_TRACE("done.") + + // Set limit to something very small + // 26 blocks will be used at this point. + // (12 files + location * 2 for raidfile) + // 20 is what we'll need in a minute + // set soft limit to 0 to ensure that all deleted files + // are deleted immediately by housekeeping + TEST_THAT_ABORTONFAIL(::system(BBSTOREACCOUNTS " -c " + "testfiles/bbstored.conf setlimit 01234567 0B 20B") + == 0); + TestRemoteProcessMemLeaks("bbstoreaccounts.memleaks"); + + // Unpack some more files + #ifdef WIN32 + TEST_THAT(::system("tar xzvf testfiles/spacetest2.tgz " + "-C testfiles/TestDir1") == 0); + #else + TEST_THAT(::system("gzip -d < testfiles/spacetest2.tgz " + "| ( cd testfiles/TestDir1 && tar xf - )") == 0); + #endif + + // Delete a file and a directory + TEST_THAT(::unlink("testfiles/TestDir1/spacetest/f1") == 0); + TEST_THAT(::system("rm -rf testfiles/TestDir1/spacetest/d7") == 0); + + // The following files should be on the server: + // 00000001 -d---- 00002 (root) + // 00000002 -d---- 00002 Test1 + // 00000003 -d---- 00002 Test1/spacetest + // 00000004 f-X--- 00002 Test1/spacetest/f1 + // 00000005 f----- 00002 Test1/spacetest/f2 + // 00000006 -d---- 00002 Test1/spacetest/d1 + // 00000007 f----- 00002 Test1/spacetest/d1/f3 + // 00000008 f----- 00002 Test1/spacetest/d1/f4 + // 00000009 -d---- 00002 Test1/spacetest/d2 + // 0000000a -d---- 00002 Test1/spacetest/d3 + // 0000000b -d---- 00002 Test1/spacetest/d3/d4 + // 0000000c f----- 00002 Test1/spacetest/d3/d4/f5 + // 0000000d -d---- 00002 Test1/spacetest/d6 + // 0000000e -dX--- 00002 Test1/spacetest/d7 + // This is 28 blocks total, of which 2 in deleted files + // and 18 in directories. Note that f1 and d7 may or may + // not be deleted yet. + // + // spacetest1 + spacetest2 = 16 files = 32 blocks with raidfile + // minus one file and one dir is 28 blocks + // + // d2/f6, d6/d8 and d6/d8/f7 are new + // even if the client marks f1 and d7 as deleted, and + // housekeeping deleted them, the backup cannot complete + // if the limit is 20 blocks. + + BOX_TRACE("Waiting for bbackupd to notice that the " + "store is full"); + wait_for_sync_end(); + BOX_TRACE("done."); + + BOX_TRACE("Compare to check that there are differences"); + int compareReturnValue = ::system(BBACKUPQUERY " " + "-c testfiles/bbackupd.conf " + "-l testfiles/query0a.log " + "-Werror \"compare -acQ\" quit"); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Compare_Different); + TestRemoteProcessMemLeaks("bbackupquery.memleaks"); + BOX_TRACE("done."); + + // 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")); + + // Kill the daemon + terminate_bbackupd(bbackupd_pid); + + BOX_TRACE("Wait for housekeeping to remove the deleted files"); + wait_for_backup_operation(5); + BOX_TRACE("done."); + + // This removes f1 and d7, which were previously marked + // as deleted, so total usage drops by 4 blocks to 24. + + // BLOCK + { + std::auto_ptr<BackupProtocolClient> client = + ConnectAndLogin(context, 0 /* read-write */); + + std::auto_ptr<BackupProtocolClientAccountUsage> usage( + client->QueryGetAccountUsage()); + TEST_EQUAL_LINE(24, usage->GetBlocksUsed(), + "blocks used"); + TEST_EQUAL_LINE(0, usage->GetBlocksInDeletedFiles(), + "deleted blocks"); + TEST_EQUAL_LINE(16, usage->GetBlocksInDirectories(), + "directory blocks"); + + client->QueryFinished(); + sSocket.Close(); + } + + if (failures > 0) + { + // stop early to make debugging easier + return 1; + } + + // ensure time is different to refresh the cache + ::safe_sleep(1); + + BOX_TRACE("Restart bbackupd with more exclusions"); + // Start again with a new config that excludes d3 and f2, + // and hence also d3/d4 and d3/d4/f5. bbackupd should mark + // them as deleted and housekeeping should clean up, + // making space to upload the new files. + // total required: (13-2-4+3)*2 = 20 blocks + /* + cmd = BBACKUPD " " + bbackupd_args + + " testfiles/bbackupd-exclude.conf"; + bbackupd_pid = LaunchServer(cmd, "testfiles/bbackupd.pid"); + TEST_THAT(bbackupd_pid != -1 && bbackupd_pid != 0); + TEST_THAT(ServerIsAlive(bbackupd_pid)); + TEST_THAT(ServerIsAlive(bbstored_pid)); + if (!ServerIsAlive(bbackupd_pid)) return 1; + if (!ServerIsAlive(bbstored_pid)) return 1; + */ + + BackupDaemon bbackupd; + bbackupd.Configure("testfiles/bbackupd-exclude.conf"); + bbackupd.InitCrypto(); + BOX_TRACE("done."); + + // Should be marked as deleted by this run + // wait_for_sync_end(); + { + // Logging::Guard guard(Log::ERROR); + bbackupd.RunSyncNow(); + } + + TEST_THAT(bbackupd.StorageLimitExceeded()); + + // Check that the notify script was run + // TEST_THAT(TestFileExists("testfiles/notifyran.store-full.2")); + // But only twice! + // TEST_THAT(!TestFileExists("testfiles/notifyran.store-full.3")); + + // All these should be marked as deleted but hopefully + // not removed by housekeeping yet: + // f1 deleted + // f2 excluded + // d1 excluded (why?) + // d1/f3 excluded (why?) + // d3 excluded + // d3/d4 excluded + // d3/d4/f5 excluded + // d7 deleted + // Careful with timing here, these files will be removed by + // housekeeping the next time it runs. On Win32, housekeeping + // runs immediately after disconnect, but only if enough time + // has elapsed since the last housekeeping. Since the + // backup run closely follows the last one, housekeeping + // should not run afterwards. On other platforms, we want to + // get in immediately after the backup and hope that + // housekeeping doesn't beat us to it. + + BOX_TRACE("Find out whether bbackupd marked files as deleted"); + { + std::auto_ptr<BackupProtocolClient> client = + ConnectAndLogin(context, 0 /* read-write */); + + std::auto_ptr<BackupStoreDirectory> rootDir = + ReadDirectory(*client, + BackupProtocolClientListDirectory::RootDirectory); + + int64_t testDirId = SearchDir(*rootDir, "Test1"); + TEST_THAT(testDirId != 0); + + std::auto_ptr<BackupStoreDirectory> Test1_dir = + ReadDirectory(*client, testDirId); + + int64_t spacetestDirId = SearchDir(*Test1_dir, + "spacetest"); + TEST_THAT(spacetestDirId != 0); + + std::auto_ptr<BackupStoreDirectory> spacetest_dir = + ReadDirectory(*client, spacetestDirId); + + // these files were deleted before, they should be + // long gone by now + + TEST_THAT(SearchDir(*spacetest_dir, "f1") == 0); + TEST_THAT(SearchDir(*spacetest_dir, "d7") == 0); + + // these files have just been deleted, because + // they are excluded by the new configuration. + // but housekeeping should not have run yet + + TEST_THAT(test_entry_deleted(*spacetest_dir, "f2")); + TEST_THAT(test_entry_deleted(*spacetest_dir, "d3")); + + int64_t d3_id = SearchDir(*spacetest_dir, "d3"); + TEST_THAT(d3_id != 0); + + std::auto_ptr<BackupStoreDirectory> d3_dir = + ReadDirectory(*client, d3_id); + TEST_THAT(test_entry_deleted(*d3_dir, "d4")); + + int64_t d4_id = SearchDir(*d3_dir, "d4"); + TEST_THAT(d4_id != 0); + + std::auto_ptr<BackupStoreDirectory> d4_dir = + ReadDirectory(*client, d4_id); + TEST_THAT(test_entry_deleted(*d4_dir, "f5")); + + std::auto_ptr<BackupProtocolClientAccountUsage> usage( + client->QueryGetAccountUsage()); + TEST_EQUAL_LINE(24, usage->GetBlocksUsed(), + "blocks used"); + TEST_EQUAL_LINE(4, usage->GetBlocksInDeletedFiles(), + "deleted blocks"); + TEST_EQUAL_LINE(16, usage->GetBlocksInDirectories(), + "directory blocks"); + // d1/f3 and d1/f4 are the only two files on the + // server which are not deleted, they use 2 blocks + // each, the rest is directories and 2 deleted files + // (f1 and d3/d4/f5) + + // Log out. + client->QueryFinished(); + sSocket.Close(); + } + BOX_TRACE("done."); + + if (failures > 0) + { + // stop early to make debugging easier + return 1; + } + + BOX_TRACE("Wait for housekeeping to remove the deleted files"); + wait_for_backup_operation(5); + BOX_TRACE("done."); + + BOX_TRACE("Check that the files were removed"); + { + std::auto_ptr<BackupProtocolClient> client = + ConnectAndLogin(context, 0 /* read-write */); + + std::auto_ptr<BackupStoreDirectory> rootDir = + ReadDirectory(*client, + BackupProtocolClientListDirectory::RootDirectory); + + int64_t testDirId = SearchDir(*rootDir, "Test1"); + TEST_THAT(testDirId != 0); + + std::auto_ptr<BackupStoreDirectory> Test1_dir = + ReadDirectory(*client, testDirId); + + int64_t spacetestDirId = SearchDir(*Test1_dir, + "spacetest"); + TEST_THAT(spacetestDirId != 0); + + std::auto_ptr<BackupStoreDirectory> spacetest_dir = + ReadDirectory(*client, spacetestDirId); + + TEST_THAT(SearchDir(*spacetest_dir, "f1") == 0); + TEST_THAT(SearchDir(*spacetest_dir, "f2") == 0); + TEST_THAT(SearchDir(*spacetest_dir, "d3") == 0); + TEST_THAT(SearchDir(*spacetest_dir, "d7") == 0); + + std::auto_ptr<BackupProtocolClientAccountUsage> usage( + client->QueryGetAccountUsage()); + TEST_EQUAL_LINE(16, usage->GetBlocksUsed(), + "blocks used"); + TEST_EQUAL_LINE(0, usage->GetBlocksInDeletedFiles(), + "deleted blocks"); + TEST_EQUAL_LINE(12, usage->GetBlocksInDirectories(), + "directory blocks"); + // d1/f3 and d1/f4 are the only two files on the + // server, they use 2 blocks each, the rest is + // directories. + + // Log out. + client->QueryFinished(); + sSocket.Close(); + } + + if (failures > 0) + { + // stop early to make debugging easier + return 1; + } + + // Need 22 blocks free to upload everything + TEST_THAT_ABORTONFAIL(::system(BBSTOREACCOUNTS " -c " + "testfiles/bbstored.conf setlimit 01234567 0B 22B") + == 0); + TestRemoteProcessMemLeaks("bbstoreaccounts.memleaks"); + + // Run another backup, now there should be enough space + // for everything we want to upload. + { + Logging::Guard guard(Log::ERROR); + bbackupd.RunSyncNow(); + } + TEST_THAT(!bbackupd.StorageLimitExceeded()); + + // Check that the contents of the store are the same + // as the contents of the disc + // (-a = all, -c = give result in return code) + BOX_TRACE("Check that all files were uploaded successfully"); + compareReturnValue = ::system(BBACKUPQUERY " " + "-c testfiles/bbackupd-exclude.conf " + "-l testfiles/query1.log " + "-Wwarning \"compare -acQ\" quit"); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Compare_Same); + TestRemoteProcessMemLeaks("bbackupquery.memleaks"); + BOX_TRACE("done."); + + // BLOCK + { + std::auto_ptr<BackupProtocolClient> client = + ConnectAndLogin(context, 0 /* read-write */); + + std::auto_ptr<BackupProtocolClientAccountUsage> usage( + client->QueryGetAccountUsage()); + TEST_EQUAL_LINE(22, usage->GetBlocksUsed(), + "blocks used"); + TEST_EQUAL_LINE(0, usage->GetBlocksInDeletedFiles(), + "deleted blocks"); + TEST_EQUAL_LINE(14, usage->GetBlocksInDirectories(), + "directory blocks"); + // d2/f6, d6/d8 and d6/d8/f7 are new + // i.e. 2 new files, 1 new directory + + client->QueryFinished(); + sSocket.Close(); + } + + if (failures > 0) + { + // stop early to make debugging easier + return 1; + } + + // Put the limit back + TEST_THAT_ABORTONFAIL(::system(BBSTOREACCOUNTS " -c " + "testfiles/bbstored.conf setlimit 01234567 " + "1000B 2000B") == 0); + TestRemoteProcessMemLeaks("bbstoreaccounts.memleaks"); + + // Start again with the old config + BOX_TRACE("Restart bbackupd with original configuration"); + // terminate_bbackupd(); + cmd = BBACKUPD " " + bbackupd_args + + " testfiles/bbackupd.conf"; + bbackupd_pid = LaunchServer(cmd, "testfiles/bbackupd.pid"); + TEST_THAT(bbackupd_pid != -1 && bbackupd_pid != 0); + ::safe_sleep(1); + TEST_THAT(ServerIsAlive(bbackupd_pid)); + TEST_THAT(ServerIsAlive(bbstored_pid)); + if (!ServerIsAlive(bbackupd_pid)) return 1; + if (!ServerIsAlive(bbstored_pid)) return 1; + BOX_TRACE("done."); + + // unpack the initial files again + #ifdef WIN32 + TEST_THAT(::system("tar xzvf testfiles/test_base.tgz " + "-C testfiles") == 0); + #else + TEST_THAT(::system("gzip -d < testfiles/test_base.tgz " + "| ( cd testfiles && tar xf - )") == 0); + #endif + + BOX_TRACE("Wait for bbackupd to upload more files"); + wait_for_backup_operation(); + BOX_TRACE("done."); + + // Check that the contents of the store are the same + // as the contents of the disc + // (-a = all, -c = give result in return code) + BOX_TRACE("Check that all files were uploaded successfully"); + compareReturnValue = ::system(BBACKUPQUERY " " + "-c testfiles/bbackupd.conf " + "-l testfiles/query1.log " + "-Wwarning \"compare -acQ\" quit"); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Compare_Same); + TestRemoteProcessMemLeaks("bbackupquery.memleaks"); + BOX_TRACE("done."); + + TEST_THAT(ServerIsAlive(bbackupd_pid)); + TEST_THAT(ServerIsAlive(bbstored_pid)); + if (!ServerIsAlive(bbackupd_pid)) return 1; + if (!ServerIsAlive(bbstored_pid)) return 1; + + if (failures > 0) + { + // stop early to make debugging easier + return 1; + } + } + + // Check that no read error has been reported yet + TEST_THAT(!TestFileExists("testfiles/notifyran.read-error.1")); + + #ifndef WIN32 // requires fork + printf("\n==== Testing that bbackupd responds correctly to " + "connection failure\n"); + + { + // Kill the daemons + terminate_bbackupd(bbackupd_pid); + test_kill_bbstored(); + + // create a new file to force an upload + + const char* new_file = "testfiles/TestDir1/force-upload-2"; + int fd = open(new_file, + O_CREAT | O_EXCL | O_WRONLY, 0700); + if (fd <= 0) + { + perror(new_file); + } + TEST_THAT(fd > 0); + + const char* control_string = "whee!\n"; + TEST_THAT(write(fd, control_string, + strlen(control_string)) == + (int)strlen(control_string)); + close(fd); + + // sleep to make it old enough to upload + safe_sleep(4); + + class MyHook : public BackupStoreContext::TestHook + { + virtual std::auto_ptr<ProtocolObject> StartCommand( + BackupProtocolObject& rCommand) + { + if (rCommand.GetType() == + BackupProtocolServerStoreFile::TypeID) + { + // terminate badly + THROW_EXCEPTION(CommonException, + Internal); + } + return std::auto_ptr<ProtocolObject>(); + } + }; + MyHook hook; + + bbstored_pid = fork(); + + if (bbstored_pid < 0) + { + BOX_LOG_SYS_ERROR("failed to fork()"); + return 1; + } + + if (bbstored_pid == 0) + { + // in fork child + TEST_THAT(setsid() != -1); + + if (!Logging::IsEnabled(Log::TRACE)) + { + Logging::SetGlobalLevel(Log::NOTHING); + } + + // BackupStoreDaemon must be destroyed before exit(), + // to avoid memory leaks being reported. + { + BackupStoreDaemon bbstored; + bbstored.SetTestHook(hook); + bbstored.SetRunInForeground(true); + bbstored.Main("testfiles/bbstored.conf"); + } + + Timers::Cleanup(); // avoid memory leaks + exit(0); + } + + // in fork parent + bbstored_pid = WaitForServerStartup("testfiles/bbstored.pid", + bbstored_pid); + + TEST_THAT(::system("rm -f testfiles/notifyran.store-full.*") == 0); + + // Ignore SIGPIPE so that when the connection is broken, + // the daemon doesn't terminate. + ::signal(SIGPIPE, SIG_IGN); + + { + Log::Level newLevel = Logging::GetGlobalLevel(); + + if (!Logging::IsEnabled(Log::TRACE)) + { + newLevel = Log::NOTHING; + } + + Logging::Guard guard(newLevel); + + BackupDaemon bbackupd; + bbackupd.Configure("testfiles/bbackupd.conf"); + bbackupd.InitCrypto(); + bbackupd.RunSyncNowWithExceptionHandling(); + } + + ::signal(SIGPIPE, SIG_DFL); + + TEST_THAT(TestFileExists("testfiles/notifyran.backup-error.1")); + TEST_THAT(!TestFileExists("testfiles/notifyran.backup-error.2")); + TEST_THAT(!TestFileExists("testfiles/notifyran.store-full.1")); + + test_kill_bbstored(true); + + if (failures > 0) + { + // stop early to make debugging easier + return 1; + } + + test_run_bbstored(); + + cmd = BBACKUPD " " + bbackupd_args + + " testfiles/bbackupd.conf"; + bbackupd_pid = LaunchServer(cmd, "testfiles/bbackupd.pid"); + TEST_THAT(bbackupd_pid != -1 && bbackupd_pid != 0); + ::safe_sleep(1); + TEST_THAT(ServerIsAlive(bbackupd_pid)); + TEST_THAT(ServerIsAlive(bbstored_pid)); + if (!ServerIsAlive(bbackupd_pid)) return 1; + if (!ServerIsAlive(bbstored_pid)) return 1; + } + #endif // !WIN32 + + #ifndef WIN32 printf("\n==== Testing that absolute symlinks are not followed " "during restore\n"); @@ -1179,7 +1791,7 @@ int test_bbackupd() fclose(fp); char buf[PATH_MAX]; - TEST_THAT(getcwd(buf, sizeof(buf)) != NULL); + TEST_THAT(getcwd(buf, sizeof(buf)) == buf); std::string path = buf; path += DIRECTORY_SEPARATOR SYM_DIR DIRECTORY_SEPARATOR "a" @@ -1188,15 +1800,19 @@ int test_bbackupd() DIRECTORY_SEPARATOR "b" DIRECTORY_SEPARATOR "link") == 0); + // also test symlink-to-self loop does not break restore + TEST_THAT(symlink("self", SYM_DIR "/self") == 0); + ::wait_for_operation(4); ::sync_and_wait(); // Check that the backup was successful, i.e. no differences - int compareReturnValue = ::system(BBACKUPQUERY " -q " + int compareReturnValue = ::system(BBACKUPQUERY " " "-c testfiles/bbackupd.conf " "-l testfiles/query1.log " - "\"compare -acQ\" quit"); - TEST_RETURN(compareReturnValue, 1); + "-Wwarning \"compare -acQ\" quit"); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Compare_Same); TestRemoteProcessMemLeaks("bbackupquery.memleaks"); // now stop bbackupd and update the test file, @@ -1215,9 +1831,10 @@ int test_bbackupd() // check that we can restore it compareReturnValue = ::system(BBACKUPQUERY " " "-c testfiles/bbackupd.conf " - "-q \"restore Test1 testfiles/restore-symlink\" " + "-Wwarning \"restore Test1 testfiles/restore-symlink\" " "quit"); - TEST_RETURN(compareReturnValue, 0); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Command_OK); // make it accessible again TEST_THAT(chmod(SYM_DIR, 0755) == 0); @@ -1228,10 +1845,52 @@ int test_bbackupd() std::string line; TEST_THAT(gl.GetLine(line)); TEST_THAT(line != "before"); - TEST_THAT(line == "after"); + TEST_EQUAL("after", line); #undef SYM_DIR + /* + // This is not worth testing or fixing. + // + #ifndef PLATFORM_CLIB_FNS_INTERCEPTION_IMPOSSIBLE + printf("\n==== Testing that symlinks to other filesystems " + "can be backed up as roots\n"); + + intercept_setup_lstat_post_hook(lstat_test_post_hook); + TEST_THAT(symlink("TestDir1", "testfiles/symlink-to-TestDir1") + == 0); + + struct stat stat_st, lstat_st; + TEST_THAT(stat("testfiles/symlink-to-TestDir1", &stat_st) == 0); + TEST_THAT(lstat("testfiles/symlink-to-TestDir1", &lstat_st) == 0); + TEST_EQUAL_LINE((stat_st.st_dev ^ 0xFFFF), lstat_st.st_dev, + "stat vs lstat"); + + BackupDaemon bbackupd; + bbackupd.Configure("testfiles/bbackupd-symlink.conf"); + bbackupd.InitCrypto(); + bbackupd.RunSyncNow(); + intercept_clear_setup(); + + compareReturnValue = ::system(BBACKUPQUERY " " + "-c testfiles/bbackupd.conf " + "-l testfiles/query0a.log " + "-Wwarning \"compare -acQ\" quit"); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Compare_Same); + TestRemoteProcessMemLeaks("bbackupquery.memleaks"); + + // and again using the symlink during compare + compareReturnValue = ::system(BBACKUPQUERY " " + "-c testfiles/bbackupd-symlink.conf " + "-l testfiles/query0a.log " + "-Wwarning \"compare -acQ\" quit"); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Compare_Same); + TestRemoteProcessMemLeaks("bbackupquery.memleaks"); + #endif + */ + bbackupd_pid = LaunchServer(cmd, "testfiles/bbackupd.pid"); TEST_THAT(bbackupd_pid != -1 && bbackupd_pid != 0); ::safe_sleep(1); @@ -1241,31 +1900,65 @@ int test_bbackupd() if (!ServerIsAlive(bbackupd_pid)) return 1; if (!ServerIsAlive(bbstored_pid)) return 1; } + #endif // !WIN32 + + // Check that no read error has been reported yet + TEST_THAT(!TestFileExists("testfiles/notifyran.read-error.1")); printf("\n==== Testing that redundant locations are deleted on time\n"); + // unpack the files for the redundant location test + TEST_THAT(::system("rm -rf testfiles/TestDir2") == 0); + TEST_THAT(::mkdir("testfiles/TestDir2", 0777) == 0); + + #ifdef WIN32 + TEST_THAT(::system("tar xzvf testfiles/spacetest1.tgz " + "-C testfiles/TestDir2") == 0); + #else + TEST_THAT(::system("gzip -d < testfiles/spacetest1.tgz " + "| ( cd testfiles/TestDir2 && tar xf - )") == 0); + #endif + + // BLOCK { - std::auto_ptr<BackupProtocolClient> client = Connect( - context, - BackupProtocolClientLogin::Flags_ReadOnly); - - std::auto_ptr<BackupStoreDirectory> dir = ReadDirectory( - *client, - BackupProtocolClientListDirectory::RootDirectory); + // Kill the daemon + terminate_bbackupd(bbackupd_pid); + + // Start it with a config that has a temporary location + // that will be created on the server + std::string cmd = BBACKUPD " " + bbackupd_args + + " testfiles/bbackupd-temploc.conf"; - // int64_t testDirId = SearchDir(*dir, "Test2"); - // TEST_THAT(testDirId == 0); + bbackupd_pid = LaunchServer(cmd, "testfiles/bbackupd.pid"); + TEST_THAT(bbackupd_pid != -1 && bbackupd_pid != 0); + ::safe_sleep(1); + + TEST_THAT(ServerIsAlive(bbackupd_pid)); + TEST_THAT(ServerIsAlive(bbstored_pid)); + if (!ServerIsAlive(bbackupd_pid)) return 1; + if (!ServerIsAlive(bbstored_pid)) return 1; sync_and_wait(); - dir = ReadDirectory(*client, - BackupProtocolClientListDirectory::RootDirectory); - int64_t testDirId = SearchDir(*dir, "Test2"); - TEST_THAT(testDirId != 0); + { + std::auto_ptr<BackupProtocolClient> client = + ConnectAndLogin(context, + BackupProtocolClientLogin::Flags_ReadOnly); + + std::auto_ptr<BackupStoreDirectory> dir = + ReadDirectory(*client, + BackupProtocolClientListDirectory::RootDirectory); + int64_t testDirId = SearchDir(*dir, "Test2"); + TEST_THAT(testDirId != 0); + + client->QueryFinished(); + sSocket.Close(); + } // Kill the daemon terminate_bbackupd(bbackupd_pid); + // Start it again with the normal config (no Test2) cmd = BBACKUPD " " + bbackupd_args + " testfiles/bbackupd.conf"; bbackupd_pid = LaunchServer(cmd, "testfiles/bbackupd.pid"); @@ -1284,28 +1977,41 @@ int test_bbackupd() wait_for_sync_end(); wait_for_sync_end(); - dir = ReadDirectory(*client, - BackupProtocolClientListDirectory::RootDirectory); - testDirId = SearchDir(*dir, "Test2"); - TEST_THAT(testDirId != 0); + // not yet! should still be there + + { + std::auto_ptr<BackupProtocolClient> client = + ConnectAndLogin(context, + BackupProtocolClientLogin::Flags_ReadOnly); + + std::auto_ptr<BackupStoreDirectory> dir = + ReadDirectory(*client, + BackupProtocolClientListDirectory::RootDirectory); + int64_t testDirId = SearchDir(*dir, "Test2"); + TEST_THAT(testDirId != 0); + + client->QueryFinished(); + sSocket.Close(); + } wait_for_sync_end(); - - dir = ReadDirectory(*client, - BackupProtocolClientListDirectory::RootDirectory); - testDirId = SearchDir(*dir, "Test2"); - TEST_THAT(testDirId != 0); - - BackupStoreDirectory::Iterator i(*dir); - BackupStoreFilenameClear dirname("Test2"); - BackupStoreDirectory::Entry *en = i.FindMatchingClearName(dirname); - TEST_THAT(en != 0); - int16_t en_flags = en->GetFlags(); - TEST_THAT(en_flags && BackupStoreDirectory::Entry::Flags_Deleted); - - // Log out. - client->QueryFinished(); - sSocket.Close(); + + // NOW it should be gone + + { + std::auto_ptr<BackupProtocolClient> client = + ConnectAndLogin(context, + BackupProtocolClientLogin::Flags_ReadOnly); + + std::auto_ptr<BackupStoreDirectory> root_dir = + ReadDirectory(*client, + BackupProtocolClientListDirectory::RootDirectory); + + TEST_THAT(test_entry_deleted(*root_dir, "Test2")); + + client->QueryFinished(); + sSocket.Close(); + } } TEST_THAT(ServerIsAlive(bbackupd_pid)); @@ -1315,85 +2021,14 @@ int test_bbackupd() if(bbackupd_pid > 0) { - printf("\n==== Testing that backup pauses when store is full\n"); - - // wait for files to be uploaded - wait_for_backup_operation(); - - // 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(BBSTOREACCOUNTS " -c " - "testfiles/bbstored.conf setlimit 01234567 9B 10B") - == 0); - TestRemoteProcessMemLeaks("bbstoreaccounts.memleaks"); - - // Unpack some more files - #ifdef WIN32 - TEST_THAT(::system("tar xzvf testfiles/spacetest2.tgz " - "-C testfiles/TestDir1") == 0); - #else - TEST_THAT(::system("gzip -d < testfiles/spacetest2.tgz " - "| ( cd testfiles/TestDir1 && tar xf - )") == 0); - #endif - - // 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(BBACKUPQUERY " -q " - "-c testfiles/bbackupd.conf " - "-l testfiles/query0a.log " - "\"compare -acQ\" quit"); - TEST_RETURN(compareReturnValue, 2); - TestRemoteProcessMemLeaks("bbackupquery.memleaks"); - - // Put the limit back - TEST_THAT_ABORTONFAIL(::system(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 - #ifdef WIN32 - TEST_THAT(::system("tar xzvf testfiles/test_base.tgz " - "-C testfiles") == 0); - #else - TEST_THAT(::system("gzip -d < testfiles/test_base.tgz " - "| ( cd testfiles && tar xf - )") == 0); - #endif - - // 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(BBACKUPQUERY " -q " - "-c testfiles/bbackupd.conf " - "-l testfiles/query1.log " - "\"compare -acQ\" quit"); - TEST_RETURN(compareReturnValue, 1); - TestRemoteProcessMemLeaks("bbackupquery.memleaks"); - - TEST_THAT(ServerIsAlive(bbackupd_pid)); - TEST_THAT(ServerIsAlive(bbstored_pid)); - if (!ServerIsAlive(bbackupd_pid)) return 1; - if (!ServerIsAlive(bbstored_pid)) return 1; - + // Check that no read error has been reported yet + TEST_THAT(!TestFileExists("testfiles/notifyran.read-error.1")); printf("\n==== Check that read-only directories and " "their contents can be restored.\n"); + int compareReturnValue; + { #ifdef WIN32 TEST_THAT(::system("chmod 0555 testfiles/" @@ -1407,35 +2042,45 @@ int test_bbackupd() wait_for_sync_end(); // should be backed up now compareReturnValue = ::system(BBACKUPQUERY " " + "-Wwarning " "-c testfiles/bbackupd.conf " - "-q \"compare -cEQ Test1 testfiles/TestDir1\" " + "\"compare -cEQ Test1 testfiles/TestDir1\" " "quit"); - TEST_RETURN(compareReturnValue, 1); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Compare_Same); TestRemoteProcessMemLeaks("bbackupquery.memleaks"); // check that we can restore it compareReturnValue = ::system(BBACKUPQUERY " " + "-Wwarning " "-c testfiles/bbackupd.conf " - "-q \"restore Test1 testfiles/restore1\" " + "\"restore Test1 testfiles/restore1\" " "quit"); - TEST_RETURN(compareReturnValue, 0); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Command_OK); TestRemoteProcessMemLeaks("bbackupquery.memleaks"); // check that it restored properly compareReturnValue = ::system(BBACKUPQUERY " " + "-Wwarning " "-c testfiles/bbackupd.conf " - "-q \"compare -cEQ Test1 testfiles/restore1\" " + "\"compare -cEQ Test1 testfiles/restore1\" " "quit"); - TEST_RETURN(compareReturnValue, 1); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Compare_Same); TestRemoteProcessMemLeaks("bbackupquery.memleaks"); // put the permissions back to sensible values #ifdef WIN32 TEST_THAT(::system("chmod 0755 testfiles/" "TestDir1/x1") == 0); + TEST_THAT(::system("chmod 0755 testfiles/" + "restore1/x1") == 0); #else TEST_THAT(chmod("testfiles/TestDir1/x1", 0755) == 0); + TEST_THAT(chmod("testfiles/restore1/x1", + 0755) == 0); #endif } @@ -1512,58 +2157,68 @@ int test_bbackupd() // test that bbackupd will let us lcd into the local // directory using a relative path - std::string command = BBACKUPQUERY " -q " + std::string command = BBACKUPQUERY " " + "-Wwarning " "-c testfiles/bbackupd.conf " "\"lcd testfiles/TestDir1/" + systemDirName + "\" " "quit"; compareReturnValue = ::system(command.c_str()); - TEST_RETURN(compareReturnValue, 0); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Command_OK); // and back out again - command = BBACKUPQUERY " -q " + command = BBACKUPQUERY " " + "-Wwarning " "-c testfiles/bbackupd.conf " "\"lcd testfiles/TestDir1/" + systemDirName + "\" " "\"lcd ..\" quit"; compareReturnValue = ::system(command.c_str()); - TEST_RETURN(compareReturnValue, 0); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Command_OK); // and using an absolute path - command = BBACKUPQUERY " -q " + command = BBACKUPQUERY " " + "-Wwarning " "-c testfiles/bbackupd.conf " "\"lcd " + cwd + "/testfiles/TestDir1/" + systemDirName + "\" quit"; compareReturnValue = ::system(command.c_str()); - TEST_RETURN(compareReturnValue, 0); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Command_OK); // and back out again - command = BBACKUPQUERY " -q " + command = BBACKUPQUERY " " + "-Wwarning " "-c testfiles/bbackupd.conf " "\"lcd " + cwd + "/testfiles/TestDir1/" + systemDirName + "\" " "\"lcd ..\" quit"; compareReturnValue = ::system(command.c_str()); - TEST_RETURN(compareReturnValue, 0); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Command_OK); { FileStream fs(filepath.c_str(), O_CREAT | O_RDWR); std::string data("hello world\n"); fs.Write(data.c_str(), data.size()); - TEST_THAT(fs.GetPosition() == 12); + TEST_EQUAL_LINE(12, fs.GetPosition(), + "FileStream position"); fs.Close(); } wait_for_backup_operation(); // Compare to check that the file was uploaded - compareReturnValue = ::system(BBACKUPQUERY " -q " + compareReturnValue = ::system(BBACKUPQUERY " -Wwarning " "-c testfiles/bbackupd.conf \"compare -acQ\" quit"); - TEST_RETURN(compareReturnValue, 1); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Compare_Same); TestRemoteProcessMemLeaks("bbackupquery.memleaks"); // Check that we can find it in directory listing { std::auto_ptr<BackupProtocolClient> client = - Connect(context, 0); + ConnectAndLogin(context, 0); std::auto_ptr<BackupStoreDirectory> dir = ReadDirectory( *client, @@ -1573,19 +2228,18 @@ int test_bbackupd() TEST_THAT(baseDirId != 0); dir = ReadDirectory(*client, baseDirId); - int64_t testDirId = SearchDir(dir, dirname.c_str()); + int64_t testDirId = SearchDir(*dir, dirname.c_str()); TEST_THAT(testDirId != 0); dir = ReadDirectory(*client, testDirId); - TEST_THAT(SearchDir(dir, filename.c_str()) != 0); + TEST_THAT(SearchDir(*dir, filename.c_str()) != 0); // Log out client->QueryFinished(); sSocket.Close(); } - // Check that bbackupquery shows the dir in console encoding - command = BBACKUPQUERY " -q " + command = BBACKUPQUERY " -Wwarning " "-c testfiles/bbackupd.conf " "-q \"list Test1\" quit"; pid_t bbackupquery_pid; @@ -1615,7 +2269,7 @@ int test_bbackupd() // on the command line in system encoding, and shows // the file in console encoding command = BBACKUPQUERY " -c testfiles/bbackupd.conf " - "-q \"list Test1/" + systemDirName + "\" quit"; + "-Wwarning \"list Test1/" + systemDirName + "\" quit"; queryout = LocalProcessStream(command.c_str(), bbackupquery_pid); TEST_THAT(queryout.get() != NULL); @@ -1639,31 +2293,34 @@ int test_bbackupd() // Check that bbackupquery can compare the dir when given // on the command line in system encoding. command = BBACKUPQUERY " -c testfiles/bbackupd.conf " - "-q \"compare -cEQ Test1/" + systemDirName + + "-Wwarning \"compare -cEQ Test1/" + systemDirName + " testfiles/TestDir1/" + systemDirName + "\" quit"; compareReturnValue = ::system(command.c_str()); TestRemoteProcessMemLeaks("bbackupquery.memleaks"); - TEST_RETURN(compareReturnValue, 1); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Compare_Same); // Check that bbackupquery can restore the dir when given // on the command line in system encoding. command = BBACKUPQUERY " -c testfiles/bbackupd.conf " - "-q \"restore Test1/" + systemDirName + + "-Wwarning \"restore Test1/" + systemDirName + " testfiles/restore-" + systemDirName + "\" quit"; compareReturnValue = ::system(command.c_str()); TestRemoteProcessMemLeaks("bbackupquery.memleaks"); - TEST_RETURN(compareReturnValue, 0); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Command_OK); // Compare to make sure it was restored properly. command = BBACKUPQUERY " -c testfiles/bbackupd.conf " - "-q \"compare -cEQ Test1/" + systemDirName + + "-Wwarning \"compare -cEQ Test1/" + systemDirName + " testfiles/restore-" + systemDirName + "\" quit"; compareReturnValue = ::system(command.c_str()); TestRemoteProcessMemLeaks("bbackupquery.memleaks"); - TEST_RETURN(compareReturnValue, 1); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Compare_Same); std::string fileToUnlink = "testfiles/restore-" + dirname + "/" + filename; @@ -1672,22 +2329,25 @@ int test_bbackupd() // Check that bbackupquery can get the file when given // on the command line in system encoding. command = BBACKUPQUERY " -c testfiles/bbackupd.conf " - "-q \"get Test1/" + systemDirName + "/" + + "-Wwarning \"get Test1/" + systemDirName + "/" + systemFileName + " " + "testfiles/restore-" + systemDirName + "/" + systemFileName + "\" quit"; compareReturnValue = ::system(command.c_str()); - TEST_RETURN(compareReturnValue, 0); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Command_OK); TestRemoteProcessMemLeaks("bbackupquery.memleaks"); // And after changing directory to a relative path - command = BBACKUPQUERY " -c testfiles/bbackupd.conf -q " + command = BBACKUPQUERY " -c testfiles/bbackupd.conf " + "-Wwarning " "\"lcd testfiles\" " "\"cd Test1/" + systemDirName + "\" " + "\"get " + systemFileName + "\" quit"; compareReturnValue = ::system(command.c_str()); - TEST_RETURN(compareReturnValue, 0); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Command_OK); TestRemoteProcessMemLeaks("testfiles/bbackupquery.memleaks"); // cannot overwrite a file that exists, so delete it @@ -1695,36 +2355,43 @@ int test_bbackupd() TEST_THAT(::unlink(tmp.c_str()) == 0); // And after changing directory to an absolute path - command = BBACKUPQUERY " -c testfiles/bbackupd.conf -q " + command = BBACKUPQUERY " -c testfiles/bbackupd.conf -Wwarning " "\"lcd " + cwd + "/testfiles\" " "\"cd Test1/" + systemDirName + "\" " + "\"get " + systemFileName + "\" quit"; compareReturnValue = ::system(command.c_str()); - TEST_RETURN(compareReturnValue, 0); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Command_OK); TestRemoteProcessMemLeaks("testfiles/bbackupquery.memleaks"); // Compare to make sure it was restored properly. // The Get command does not restore attributes, so // we must compare without them (-A) to succeed. - command = BBACKUPQUERY " -c testfiles/bbackupd.conf " - "-q \"compare -cAEQ Test1/" + systemDirName + + command = BBACKUPQUERY " " + "-c testfiles/bbackupd.conf " + "-Wwarning \"compare -cAEQ Test1/" + systemDirName + " testfiles/restore-" + systemDirName + "\" quit"; compareReturnValue = ::system(command.c_str()); TestRemoteProcessMemLeaks("bbackupquery.memleaks"); - TEST_RETURN(compareReturnValue, 1); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Compare_Same); // Compare without attributes. This should fail. - command = BBACKUPQUERY " -c testfiles/bbackupd.conf " - "-q \"compare -cEQ Test1/" + systemDirName + + command = BBACKUPQUERY " " + "-c testfiles/bbackupd.conf " + "-Werror \"compare -cEQ Test1/" + systemDirName + " testfiles/restore-" + systemDirName + "\" quit"; - compareReturnValue = ::system(command.c_str()); TestRemoteProcessMemLeaks("bbackupquery.memleaks"); - TEST_RETURN(compareReturnValue, 2); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Compare_Different); #endif // WIN32 + // Check that no read error has been reported yet + TEST_THAT(!TestFileExists("testfiles/notifyran.read-error.1")); + TEST_THAT(ServerIsAlive(bbackupd_pid)); TEST_THAT(ServerIsAlive(bbstored_pid)); if (!ServerIsAlive(bbackupd_pid)) return 1; @@ -1739,7 +2406,7 @@ int test_bbackupd() // we now have 3 seconds before bbackupd // runs the SyncAllowScript again. - char* sync_control_file = "testfiles" + const char* sync_control_file = "testfiles" DIRECTORY_SEPARATOR "syncallowscript.control"; int fd = open(sync_control_file, O_CREAT | O_EXCL | O_WRONLY, 0700); @@ -1749,7 +2416,7 @@ int test_bbackupd() } TEST_THAT(fd > 0); - char* control_string = "10\n"; + const char* control_string = "10\n"; TEST_THAT(write(fd, control_string, strlen(control_string)) == (int)strlen(control_string)); @@ -1758,7 +2425,7 @@ int test_bbackupd() // this will pause backups, bbackupd will check // every 10 seconds to see if they are allowed again. - char* new_test_file = "testfiles" + const char* new_test_file = "testfiles" DIRECTORY_SEPARATOR "TestDir1" DIRECTORY_SEPARATOR "Added_During_Pause"; fd = open(new_test_file, @@ -1799,11 +2466,13 @@ int test_bbackupd() long start_time = time(NULL); // check that no backup has run (compare fails) - compareReturnValue = ::system(BBACKUPQUERY " -q " + compareReturnValue = ::system(BBACKUPQUERY " " + "-Werror " "-c testfiles/bbackupd.conf " "-l testfiles/query3.log " "\"compare -acQ\" quit"); - TEST_RETURN(compareReturnValue, 2); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Compare_Different); TestRemoteProcessMemLeaks("bbackupquery.memleaks"); TEST_THAT(unlink(sync_control_file) == 0); @@ -1819,11 +2488,13 @@ int test_bbackupd() wait_for_sync_end(); // check that backup has run (compare succeeds) - compareReturnValue = ::system(BBACKUPQUERY " -q " + compareReturnValue = ::system(BBACKUPQUERY " " + "-Wwarning " "-c testfiles/bbackupd.conf " "-l testfiles/query3a.log " "\"compare -acQ\" quit"); - TEST_RETURN(compareReturnValue, 1); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Compare_Same); TestRemoteProcessMemLeaks("bbackupquery.memleaks"); if (failures > 0) @@ -1833,6 +2504,9 @@ int test_bbackupd() } } + // Check that no read error has been reported yet + TEST_THAT(!TestFileExists("testfiles/notifyran.read-error.1")); + TEST_THAT(ServerIsAlive(bbackupd_pid)); TEST_THAT(ServerIsAlive(bbstored_pid)); if (!ServerIsAlive(bbackupd_pid)) return 1; @@ -1865,22 +2539,24 @@ int test_bbackupd() 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(BBACKUPQUERY " -q " + compareReturnValue = ::system(BBACKUPQUERY " -Wwarning " "-c testfiles/bbackupd.conf " "-l testfiles/query2.log " "\"compare -acQ\" quit"); - TEST_RETURN(compareReturnValue, 1); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Compare_Same); TestRemoteProcessMemLeaks("bbackupquery.memleaks"); // Try a quick compare, just for fun - compareReturnValue = ::system(BBACKUPQUERY " -q " + compareReturnValue = ::system(BBACKUPQUERY " " "-c testfiles/bbackupd.conf " "-l testfiles/query2q.log " - "\"compare -acqQ\" quit"); - TEST_RETURN(compareReturnValue, 1); + "-Wwarning \"compare -acqQ\" quit"); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Compare_Same); TestRemoteProcessMemLeaks("bbackupquery.memleaks"); TEST_THAT(ServerIsAlive(bbackupd_pid)); @@ -1890,12 +2566,17 @@ int test_bbackupd() // Check that store errors are reported neatly printf("\n==== Create store error\n"); + TEST_THAT(system("rm -f testfiles/notifyran.backup-error.*") + == 0); + + // break the store TEST_THAT(::rename("testfiles/0_0/backup/01234567/info.rf", "testfiles/0_0/backup/01234567/info.rf.bak") == 0); TEST_THAT(::rename("testfiles/0_1/backup/01234567/info.rf", "testfiles/0_1/backup/01234567/info.rf.bak") == 0); TEST_THAT(::rename("testfiles/0_2/backup/01234567/info.rf", "testfiles/0_2/backup/01234567/info.rf.bak") == 0); + // Create a file to trigger an upload { int fd1 = open("testfiles/TestDir1/force-upload", @@ -1903,50 +2584,195 @@ int test_bbackupd() TEST_THAT(fd1 > 0); TEST_THAT(write(fd1, "just do it", 10) == 10); TEST_THAT(close(fd1) == 0); - wait_for_backup_operation(4); } - // Wait and test... - wait_for_backup_operation(); - // Check that it was reported correctly + + wait_for_backup_operation(4); + // Check that an error was reported just once TEST_THAT(TestFileExists("testfiles/notifyran.backup-error.1")); - // Check that the error was only reported once TEST_THAT(!TestFileExists("testfiles/notifyran.backup-error.2")); - // Fix the store + // Now kill bbackupd and start one that's running in + // snapshot mode, check that it automatically syncs after + // an error, without waiting for another sync command. + terminate_bbackupd(bbackupd_pid); + std::string cmd = BBACKUPD " " + bbackupd_args + + " testfiles/bbackupd-snapshot.conf"; + bbackupd_pid = LaunchServer(cmd, "testfiles/bbackupd.pid"); + TEST_THAT(bbackupd_pid != -1 && bbackupd_pid != 0); + ::safe_sleep(1); + TEST_THAT(ServerIsAlive(bbackupd_pid)); + TEST_THAT(ServerIsAlive(bbstored_pid)); + if (!ServerIsAlive(bbackupd_pid)) return 1; + if (!ServerIsAlive(bbstored_pid)) return 1; + + sync_and_wait(); + + // Check that the error was reported once more + TEST_THAT(TestFileExists("testfiles/notifyran.backup-error.2")); + TEST_THAT(!TestFileExists("testfiles/notifyran.backup-error.3")); + + // Fix the store (so that bbackupquery compare works) TEST_THAT(::rename("testfiles/0_0/backup/01234567/info.rf.bak", "testfiles/0_0/backup/01234567/info.rf") == 0); TEST_THAT(::rename("testfiles/0_1/backup/01234567/info.rf.bak", "testfiles/0_1/backup/01234567/info.rf") == 0); TEST_THAT(::rename("testfiles/0_2/backup/01234567/info.rf.bak", "testfiles/0_2/backup/01234567/info.rf") == 0); + + int store_fixed_time = time(NULL); + + // Check that we DO get errors on compare (cannot do this + // until after we fix the store, which creates a race) + compareReturnValue = ::system(BBACKUPQUERY " " + "-c testfiles/bbackupd.conf " + "-l testfiles/query3b.log " + "-Werror \"compare -acQ\" quit"); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Compare_Different); + TestRemoteProcessMemLeaks("bbackupquery.memleaks"); + + // Test initial state + TEST_THAT(!TestFileExists("testfiles/" + "notifyran.backup-start.wait-snapshot.1")); + + // Set a tag for the notify script to distinguish from + // previous runs. + { + int fd1 = open("testfiles/notifyscript.tag", + O_CREAT | O_EXCL | O_WRONLY, 0700); + TEST_THAT(fd1 > 0); + TEST_THAT(write(fd1, "wait-snapshot", 13) == 13); + TEST_THAT(close(fd1) == 0); + } + + // bbackupd should pause for about 90 seconds from store_fixed_time, + // so check that it hasn't run after 85 seconds from store_fixed_time + wait_for_backup_operation(85 - time(NULL) + store_fixed_time); + TEST_THAT(!TestFileExists("testfiles/" + "notifyran.backup-start.wait-snapshot.1")); + + // Should not have backed up, should still get errors + compareReturnValue = ::system(BBACKUPQUERY " " + "-c testfiles/bbackupd.conf " + "-l testfiles/query3b.log " + "-Werror \"compare -acQ\" quit"); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Compare_Different); + TestRemoteProcessMemLeaks("bbackupquery.memleaks"); + + // wait another 10 seconds, bbackup should have run + wait_for_backup_operation(10); + TEST_THAT(TestFileExists("testfiles/" + "notifyran.backup-start.wait-snapshot.1")); - // Check that we DO get errors on compare - compareReturnValue = ::system(BBACKUPQUERY " -q " + // Check that it did get uploaded, and we have no more errors + compareReturnValue = ::system(BBACKUPQUERY " " "-c testfiles/bbackupd.conf " "-l testfiles/query3b.log " - "\"compare -acQ\" quit"); - TEST_RETURN(compareReturnValue, 2); + "-Wwarning \"compare -acQ\" quit"); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Compare_Same); TestRemoteProcessMemLeaks("bbackupquery.memleaks"); + TEST_THAT(::unlink("testfiles/notifyscript.tag") == 0); + + // Stop the snapshot bbackupd + terminate_bbackupd(bbackupd_pid); + + // Break the store again + TEST_THAT(::rename("testfiles/0_0/backup/01234567/info.rf", + "testfiles/0_0/backup/01234567/info.rf.bak") == 0); + TEST_THAT(::rename("testfiles/0_1/backup/01234567/info.rf", + "testfiles/0_1/backup/01234567/info.rf.bak") == 0); + TEST_THAT(::rename("testfiles/0_2/backup/01234567/info.rf", + "testfiles/0_2/backup/01234567/info.rf.bak") == 0); + + // Modify a file to trigger an upload + { + int fd1 = open("testfiles/TestDir1/force-upload", + O_WRONLY, 0700); + TEST_THAT(fd1 > 0); + TEST_THAT(write(fd1, "and again", 9) == 9); + TEST_THAT(close(fd1) == 0); + } + + // Restart the old bbackupd, in automatic mode + cmd = BBACKUPD " " + bbackupd_args + + " testfiles/bbackupd.conf"; + bbackupd_pid = LaunchServer(cmd, "testfiles/bbackupd.pid"); + TEST_THAT(bbackupd_pid != -1 && bbackupd_pid != 0); + ::safe_sleep(1); TEST_THAT(ServerIsAlive(bbackupd_pid)); TEST_THAT(ServerIsAlive(bbstored_pid)); if (!ServerIsAlive(bbackupd_pid)) return 1; if (!ServerIsAlive(bbstored_pid)) return 1; - // Wait until bbackupd recovers from the exception - wait_for_backup_operation(100); - - // Ensure that the force-upload file gets uploaded, - // meaning that bbackupd recovered sync_and_wait(); + // Fix the store again + TEST_THAT(::rename("testfiles/0_0/backup/01234567/info.rf.bak", + "testfiles/0_0/backup/01234567/info.rf") == 0); + TEST_THAT(::rename("testfiles/0_1/backup/01234567/info.rf.bak", + "testfiles/0_1/backup/01234567/info.rf") == 0); + TEST_THAT(::rename("testfiles/0_2/backup/01234567/info.rf.bak", + "testfiles/0_2/backup/01234567/info.rf") == 0); + + store_fixed_time = time(NULL); + + // Check that we DO get errors on compare (cannot do this + // until after we fix the store, which creates a race) + compareReturnValue = ::system(BBACKUPQUERY " " + "-c testfiles/bbackupd.conf " + "-l testfiles/query3b.log " + "-Werror \"compare -acQ\" quit"); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Compare_Different); + TestRemoteProcessMemLeaks("bbackupquery.memleaks"); + + // Test initial state + TEST_THAT(!TestFileExists("testfiles/" + "notifyran.backup-start.wait-automatic.1")); + + // Set a tag for the notify script to distinguist from + // previous runs. + { + int fd1 = open("testfiles/notifyscript.tag", + O_CREAT | O_EXCL | O_WRONLY, 0700); + TEST_THAT(fd1 > 0); + TEST_THAT(write(fd1, "wait-automatic", 14) == 14); + TEST_THAT(close(fd1) == 0); + } + + // bbackupd should pause for about 90 seconds from store_fixed_time, + // so check that it hasn't run after 85 seconds from store_fixed_time + wait_for_backup_operation(85 - time(NULL) + store_fixed_time); + TEST_THAT(!TestFileExists("testfiles/" + "notifyran.backup-start.wait-automatic.1")); + + // Should not have backed up, should still get errors + compareReturnValue = ::system(BBACKUPQUERY " " + "-c testfiles/bbackupd.conf " + "-l testfiles/query3b.log " + "-Werror \"compare -acQ\" quit"); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Compare_Different); + TestRemoteProcessMemLeaks("bbackupquery.memleaks"); + + // wait another 10 seconds, bbackup should have run + wait_for_backup_operation(10); + TEST_THAT(TestFileExists("testfiles/" + "notifyran.backup-start.wait-automatic.1")); + // Check that it did get uploaded, and we have no more errors - compareReturnValue = ::system(BBACKUPQUERY " -q " + compareReturnValue = ::system(BBACKUPQUERY " " "-c testfiles/bbackupd.conf " "-l testfiles/query3b.log " - "\"compare -acQ\" quit"); - TEST_RETURN(compareReturnValue, 1); + "-Wwarning \"compare -acQ\" quit"); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Compare_Same); TestRemoteProcessMemLeaks("bbackupquery.memleaks"); + TEST_THAT(::unlink("testfiles/notifyscript.tag") == 0); + TEST_THAT(ServerIsAlive(bbackupd_pid)); TEST_THAT(ServerIsAlive(bbstored_pid)); if (!ServerIsAlive(bbackupd_pid)) return 1; @@ -1976,11 +2802,12 @@ int test_bbackupd() #endif wait_for_backup_operation(); - compareReturnValue = ::system(BBACKUPQUERY " -q " + compareReturnValue = ::system(BBACKUPQUERY " " "-c testfiles/bbackupd.conf " "-l testfiles/query3c.log " - "\"compare -acQ\" quit"); - TEST_RETURN(compareReturnValue, 1); + "-Wwarning \"compare -acQ\" quit"); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Compare_Same); TestRemoteProcessMemLeaks("bbackupquery.memleaks"); TEST_THAT(ServerIsAlive(bbackupd_pid)); @@ -2004,11 +2831,12 @@ int test_bbackupd() #endif wait_for_backup_operation(); - compareReturnValue = ::system(BBACKUPQUERY " -q " + compareReturnValue = ::system(BBACKUPQUERY " " "-c testfiles/bbackupd.conf " "-l testfiles/query3d.log " - "\"compare -acQ\" quit"); - TEST_RETURN(compareReturnValue, 1); + "-Wwarning \"compare -acQ\" quit"); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Compare_Same); TestRemoteProcessMemLeaks("bbackupquery.memleaks"); TEST_THAT(ServerIsAlive(bbackupd_pid)); @@ -2035,11 +2863,12 @@ int test_bbackupd() #endif wait_for_backup_operation(); - compareReturnValue = ::system(BBACKUPQUERY " -q " + compareReturnValue = ::system(BBACKUPQUERY " " "-c testfiles/bbackupd.conf " "-l testfiles/query3e.log " - "\"compare -acQ\" quit"); - TEST_RETURN(compareReturnValue, 1); + "-Wwarning \"compare -acQ\" quit"); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Compare_Same); TestRemoteProcessMemLeaks("bbackupquery.memleaks"); TEST_THAT(ServerIsAlive(bbackupd_pid)); @@ -2066,11 +2895,12 @@ int test_bbackupd() #endif wait_for_backup_operation(); - compareReturnValue = ::system(BBACKUPQUERY " -q " + compareReturnValue = ::system(BBACKUPQUERY " " "-c testfiles/bbackupd.conf " "-l testfiles/query3f.log " - "\"compare -acQ\" quit"); - TEST_RETURN(compareReturnValue, 1); + "-Wwarning \"compare -acQ\" quit"); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Compare_Same); TestRemoteProcessMemLeaks("bbackupquery.memleaks"); TEST_THAT(ServerIsAlive(bbackupd_pid)); @@ -2097,11 +2927,12 @@ int test_bbackupd() wait_for_operation(5); // back up both files wait_for_backup_operation(); - compareReturnValue = ::system(BBACKUPQUERY " -q " + compareReturnValue = ::system(BBACKUPQUERY " " "-c testfiles/bbackupd.conf " "-l testfiles/query3g.log " - "\"compare -acQ\" quit"); - TEST_RETURN(compareReturnValue, 1); + "-Wwarning \"compare -acQ\" quit"); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Compare_Same); TestRemoteProcessMemLeaks("bbackupquery.memleaks"); #ifdef WIN32 @@ -2114,11 +2945,12 @@ int test_bbackupd() TEST_THAT(!TestFileExists("testfiles/TestDir1/untracked-1")); TEST_THAT( TestFileExists("testfiles/TestDir1/untracked-2")); wait_for_backup_operation(); - compareReturnValue = ::system(BBACKUPQUERY " -q " + compareReturnValue = ::system(BBACKUPQUERY " " "-c testfiles/bbackupd.conf " "-l testfiles/query3g.log " - "\"compare -acQ\" quit"); - TEST_RETURN(compareReturnValue, 1); + "-Wwarning \"compare -acQ\" quit"); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Compare_Same); TestRemoteProcessMemLeaks("bbackupquery.memleaks"); TEST_THAT(ServerIsAlive(bbackupd_pid)); @@ -2148,11 +2980,12 @@ int test_bbackupd() wait_for_operation(5); // back up both files wait_for_backup_operation(); - compareReturnValue = ::system(BBACKUPQUERY " -q " + compareReturnValue = ::system(BBACKUPQUERY " " "-c testfiles/bbackupd.conf " "-l testfiles/query3h.log " - "\"compare -acQ\" quit"); - TEST_RETURN(compareReturnValue, 1); + "-Wwarning \"compare -acQ\" quit"); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Compare_Same); TestRemoteProcessMemLeaks("bbackupquery.memleaks"); #ifdef WIN32 @@ -2165,11 +2998,12 @@ int test_bbackupd() TEST_THAT(!TestFileExists("testfiles/TestDir1/tracked-1")); TEST_THAT( TestFileExists("testfiles/TestDir1/tracked-2")); wait_for_backup_operation(); - compareReturnValue = ::system(BBACKUPQUERY " -q " + compareReturnValue = ::system(BBACKUPQUERY " " "-c testfiles/bbackupd.conf " "-l testfiles/query3i.log " - "\"compare -acQ\" quit"); - TEST_RETURN(compareReturnValue, 1); + "-Wwarning \"compare -acQ\" quit"); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Compare_Same); TestRemoteProcessMemLeaks("bbackupquery.memleaks"); TEST_THAT(ServerIsAlive(bbackupd_pid)); @@ -2185,13 +3019,17 @@ int test_bbackupd() "testfiles/TestDir1/x1/dsfdsfs98.fd") == 0); wait_for_backup_operation(); - compareReturnValue = ::system(BBACKUPQUERY " -q " + compareReturnValue = ::system(BBACKUPQUERY " " "-c testfiles/bbackupd.conf " "-l testfiles/query3j.log " - "\"compare -acQ\" quit"); - TEST_RETURN(compareReturnValue, 1); + "-Wwarning \"compare -acQ\" quit"); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Compare_Same); TestRemoteProcessMemLeaks("bbackupquery.memleaks"); + // Check that no read error has been reported yet + TEST_THAT(!TestFileExists("testfiles/notifyran.read-error.1")); + TEST_THAT(ServerIsAlive(bbackupd_pid)); TEST_THAT(ServerIsAlive(bbstored_pid)); if (!ServerIsAlive(bbackupd_pid)) return 1; @@ -2219,11 +3057,12 @@ int test_bbackupd() // Wait and test wait_for_backup_operation(); - compareReturnValue = ::system(BBACKUPQUERY " -q " + compareReturnValue = ::system(BBACKUPQUERY " " "-c testfiles/bbackupd.conf " "-l testfiles/query3k.log " - "\"compare -acQ\" quit"); - TEST_RETURN(compareReturnValue, 1); + "-Wwarning \"compare -acQ\" quit"); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Compare_Same); TestRemoteProcessMemLeaks("bbackupquery.memleaks"); TEST_THAT(ServerIsAlive(bbackupd_pid)); @@ -2231,6 +3070,9 @@ int test_bbackupd() if (!ServerIsAlive(bbackupd_pid)) return 1; if (!ServerIsAlive(bbstored_pid)) return 1; + // Check that no read error has been reported yet + TEST_THAT(!TestFileExists("testfiles/notifyran.read-error.1")); + // Check that modifying files with old timestamps // still get added printf("\n==== Modify existing file, but change timestamp " @@ -2277,11 +3119,12 @@ int test_bbackupd() wait_for_sync_end(); // files too new wait_for_sync_end(); // should (not) be backed up this time - compareReturnValue = ::system(BBACKUPQUERY " -q " + compareReturnValue = ::system(BBACKUPQUERY " " "-c testfiles/bbackupd.conf " "-l testfiles/query3l.log " - "\"compare -acQ\" quit"); - TEST_RETURN(compareReturnValue, 1); + "-Wwarning \"compare -acQ\" quit"); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Compare_Same); TestRemoteProcessMemLeaks("bbackupquery.memleaks"); TEST_THAT(ServerIsAlive(bbackupd_pid)); @@ -2289,6 +3132,9 @@ int test_bbackupd() if (!ServerIsAlive(bbackupd_pid)) return 1; if (!ServerIsAlive(bbstored_pid)) return 1; + // Check that no read error has been reported yet + TEST_THAT(!TestFileExists("testfiles/notifyran.read-error.1")); + // Add some files and directories which are marked as excluded printf("\n==== Add files and dirs for exclusion test\n"); #ifdef WIN32 @@ -2305,19 +3151,21 @@ int test_bbackupd() wait_for_sync_end(); // compare with exclusions, should not find differences - compareReturnValue = ::system(BBACKUPQUERY " -q " + compareReturnValue = ::system(BBACKUPQUERY " " "-c testfiles/bbackupd.conf " "-l testfiles/query3m.log " - "\"compare -acQ\" quit"); - TEST_RETURN(compareReturnValue, 1); + "-Wwarning \"compare -acQ\" quit"); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Compare_Same); TestRemoteProcessMemLeaks("bbackupquery.memleaks"); // compare without exclusions, should find differences - compareReturnValue = ::system(BBACKUPQUERY " -q " + compareReturnValue = ::system(BBACKUPQUERY " " "-c testfiles/bbackupd.conf " "-l testfiles/query3n.log " - "\"compare -acEQ\" quit"); - TEST_RETURN(compareReturnValue, 2); + "-Werror \"compare -acEQ\" quit"); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Compare_Different); TestRemoteProcessMemLeaks("bbackupquery.memleaks"); TEST_THAT(ServerIsAlive(bbackupd_pid)); @@ -2331,8 +3179,8 @@ int test_bbackupd() "actually work\n"); { - std::auto_ptr<BackupProtocolClient> client = Connect( - context, + std::auto_ptr<BackupProtocolClient> client = + ConnectAndLogin(context, BackupProtocolClientLogin::Flags_ReadOnly); std::auto_ptr<BackupStoreDirectory> dir = ReadDirectory( @@ -2373,6 +3221,9 @@ int test_bbackupd() // These tests only work as non-root users. if(::getuid() != 0) { + // Check that the error has not been reported yet + TEST_THAT(!TestFileExists("testfiles/notifyran.read-error.1")); + // Check that read errors are reported neatly printf("\n==== Add unreadable files\n"); @@ -2389,13 +3240,14 @@ int test_bbackupd() // Wait and test... wait_for_backup_operation(); - compareReturnValue = ::system(BBACKUPQUERY " -q " + compareReturnValue = ::system(BBACKUPQUERY " " "-c testfiles/bbackupd.conf " "-l testfiles/query3o.log " - "\"compare -acQ\" quit"); + "-Werror \"compare -acQ\" quit"); // should find differences - TEST_RETURN(compareReturnValue, 3); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Compare_Error); TestRemoteProcessMemLeaks("bbackupquery.memleaks"); // Check that it was reported correctly @@ -2492,11 +3344,12 @@ int test_bbackupd() // Wait and test wait_for_backup_operation(); - compareReturnValue = ::system(BBACKUPQUERY " -q " + compareReturnValue = ::system(BBACKUPQUERY " " "-c testfiles/bbackupd.conf " "-l testfiles/query4.log " - "\"compare -acQ\" quit"); - TEST_RETURN(compareReturnValue, 1); + "-Werror \"compare -acQ\" quit"); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Compare_Same); TestRemoteProcessMemLeaks("bbackupquery.memleaks"); printf("\n==== Restore files and directories\n"); @@ -2504,8 +3357,8 @@ int test_bbackupd() int64_t restoredirid = 0; { // connect and log in - std::auto_ptr<BackupProtocolClient> client = Connect( - context, + std::auto_ptr<BackupProtocolClient> client = + ConnectAndLogin(context, BackupProtocolClientLogin::Flags_ReadOnly); // Find the ID of the Test1 directory @@ -2528,13 +3381,6 @@ int test_bbackupd() true /* print progress dots */) == Restore_TargetExists); - // Make sure you can't restore to a nonexistant path - printf("Try to restore to a path that doesn't exist\n"); - TEST_THAT(BackupClientRestore(*client, restoredirid, - "testfiles/no-such-path/subdir", - true /* print progress dots */) - == Restore_TargetPathNotFound); - // Find ID of the deleted directory deldirid = GetDirID(*client, "x1", restoredirid); TEST_THAT(deldirid != 0); @@ -2547,18 +3393,34 @@ int test_bbackupd() true /* deleted files */) == Restore_Complete); + // Make sure you can't restore to a nonexistant path + printf("\n==== Try to restore to a path " + "that doesn't exist\n"); + fflush(stdout); + + { + Logging::Guard guard(Log::FATAL); + TEST_THAT(BackupClientRestore(*client, + restoredirid, + "testfiles/no-such-path/subdir", + true /* print progress dots */) + == Restore_TargetPathNotFound); + } + // Log out client->QueryFinished(); sSocket.Close(); } // Compare the restored files - compareReturnValue = ::system(BBACKUPQUERY " -q " + compareReturnValue = ::system(BBACKUPQUERY " " "-c testfiles/bbackupd.conf " "-l testfiles/query10.log " + "-Wwarning " "\"compare -cEQ Test1 testfiles/restore-Test1\" " "quit"); - TEST_RETURN(compareReturnValue, 1); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Compare_Same); TestRemoteProcessMemLeaks("bbackupquery.memleaks"); TEST_THAT(ServerIsAlive(bbackupd_pid)); @@ -2572,12 +3434,14 @@ int test_bbackupd() "testfiles\\restore-Test1\\f1.dat"); TEST_RETURN(compareReturnValue, 0); - compareReturnValue = ::system(BBACKUPQUERY " -q " + compareReturnValue = ::system(BBACKUPQUERY " " "-c testfiles/bbackupd.conf " "-l testfiles/query10a.log " + "-Werror " "\"compare -cEQ Test1 testfiles/restore-Test1\" " "quit"); - TEST_RETURN(compareReturnValue, 2); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Compare_Different); TestRemoteProcessMemLeaks("bbackupquery.memleaks"); // set it back, expect no failures @@ -2585,11 +3449,13 @@ int test_bbackupd() "testfiles\\restore-Test1\\f1.dat"); TEST_RETURN(compareReturnValue, 0); - compareReturnValue = ::system(BBACKUPQUERY " -q " + compareReturnValue = ::system(BBACKUPQUERY " " "-c testfiles/bbackupd.conf -l testfiles/query10a.log " + "-Wwarning " "\"compare -cEQ Test1 testfiles/restore-Test1\" " "quit"); - TEST_RETURN(compareReturnValue, 1); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Compare_Same); TestRemoteProcessMemLeaks("bbackupquery.memleaks"); // change the timestamp on a file, expect a compare failure @@ -2609,46 +3475,54 @@ int test_bbackupd() // a compare failure TEST_THAT(set_file_time(testfile, dummyTime, lastModTime, lastAccessTime)); - compareReturnValue = ::system(BBACKUPQUERY " -q " + compareReturnValue = ::system(BBACKUPQUERY " " "-c testfiles/bbackupd.conf " "-l testfiles/query10a.log " + "-Werror " "\"compare -cEQ Test1 testfiles/restore-Test1\" " "quit"); - TEST_RETURN(compareReturnValue, 2); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Compare_Different); TestRemoteProcessMemLeaks("bbackupquery.memleaks"); // last access time is not backed up, so it cannot be compared TEST_THAT(set_file_time(testfile, creationTime, lastModTime, dummyTime)); - compareReturnValue = ::system(BBACKUPQUERY " -q " + compareReturnValue = ::system(BBACKUPQUERY " " "-c testfiles/bbackupd.conf " "-l testfiles/query10a.log " + "-Wwarning " "\"compare -cEQ Test1 testfiles/restore-Test1\" " "quit"); - TEST_RETURN(compareReturnValue, 1); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Compare_Same); TestRemoteProcessMemLeaks("bbackupquery.memleaks"); // last write time is backed up, so changing it should cause // a compare failure TEST_THAT(set_file_time(testfile, creationTime, dummyTime, lastAccessTime)); - compareReturnValue = ::system(BBACKUPQUERY " -q " + compareReturnValue = ::system(BBACKUPQUERY " " "-c testfiles/bbackupd.conf " "-l testfiles/query10a.log " + "-Werror " "\"compare -cEQ Test1 testfiles/restore-Test1\" " "quit"); - TEST_RETURN(compareReturnValue, 2); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Compare_Different); TestRemoteProcessMemLeaks("bbackupquery.memleaks"); // set back to original values, check that compare succeeds TEST_THAT(set_file_time(testfile, creationTime, lastModTime, lastAccessTime)); - compareReturnValue = ::system(BBACKUPQUERY " -q " + compareReturnValue = ::system(BBACKUPQUERY " " "-c testfiles/bbackupd.conf " "-l testfiles/query10a.log " + "-Wwarning " "\"compare -cEQ Test1 testfiles/restore-Test1\" " "quit"); - TEST_RETURN(compareReturnValue, 1); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Compare_Same); TestRemoteProcessMemLeaks("bbackupquery.memleaks"); #endif // WIN32 @@ -2671,11 +3545,12 @@ int test_bbackupd() // Wait and test wait_for_backup_operation(); - compareReturnValue = ::system(BBACKUPQUERY " -q " + compareReturnValue = ::system(BBACKUPQUERY " " "-c testfiles/bbackupd.conf " "-l testfiles/query5.log " - "\"compare -acQ\" quit"); - TEST_RETURN(compareReturnValue, 1); + "-Wwarning \"compare -acQ\" quit"); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Compare_Same); TestRemoteProcessMemLeaks("bbackupquery.memleaks"); TEST_THAT(ServerIsAlive(bbackupd_pid)); @@ -2688,19 +3563,21 @@ int test_bbackupd() TEST_THAT(rename("testfiles/TestDir1/sub23/dhsfdss", "testfiles/TestDir1/renamed-dir") == 0); wait_for_backup_operation(); - compareReturnValue = ::system(BBACKUPQUERY " -q " + compareReturnValue = ::system(BBACKUPQUERY " " "-c testfiles/bbackupd.conf " "-l testfiles/query6.log " - "\"compare -acQ\" quit"); - TEST_RETURN(compareReturnValue, 1); + "-Wwarning \"compare -acQ\" quit"); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Compare_Same); TestRemoteProcessMemLeaks("bbackupquery.memleaks"); // and again, but with quick flag - compareReturnValue = ::system(BBACKUPQUERY " -q " + compareReturnValue = ::system(BBACKUPQUERY " " "-c testfiles/bbackupd.conf " "-l testfiles/query6q.log " - "\"compare -acqQ\" quit"); - TEST_RETURN(compareReturnValue, 1); + "-Wwarning \"compare -acqQ\" quit"); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Compare_Same); TestRemoteProcessMemLeaks("bbackupquery.memleaks"); // Rename some files -- one under the threshold, others above @@ -2712,11 +3589,12 @@ int test_bbackupd() TEST_THAT(rename("testfiles/TestDir1/sub23/find2perl", "testfiles/TestDir1/find2perl-ren") == 0); wait_for_backup_operation(); - compareReturnValue = ::system(BBACKUPQUERY " -q " + compareReturnValue = ::system(BBACKUPQUERY " " "-c testfiles/bbackupd.conf " "-l testfiles/query6.log " - "\"compare -acQ\" quit"); - TEST_RETURN(compareReturnValue, 1); + "-Wwarning \"compare -acQ\" quit"); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Compare_Same); TestRemoteProcessMemLeaks("bbackupquery.memleaks"); TEST_THAT(ServerIsAlive(bbackupd_pid)); @@ -2754,11 +3632,12 @@ int test_bbackupd() // Wait and test wait_for_backup_operation(); - compareReturnValue = ::system(BBACKUPQUERY " -q " + compareReturnValue = ::system(BBACKUPQUERY " " "-c testfiles/bbackupd.conf " "-l testfiles/query3e.log " - "\"compare -acQ\" quit"); - TEST_RETURN(compareReturnValue, 1); + "-Wwarning \"compare -acQ\" quit"); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Compare_Same); TestRemoteProcessMemLeaks("bbackupquery.memleaks"); TEST_THAT(ServerIsAlive(bbackupd_pid)); @@ -2777,23 +3656,23 @@ int test_bbackupd() { 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 + std::auto_ptr<BackupProtocolClient> + protocol = Connect(context); + // Make sure the marker isn't zero, + // because that's the default, and + // it should have changed + std::auto_ptr<BackupProtocolClientLoginConfirmed> loginConf(protocol->QueryLogin(0x01234567, 0)); TEST_THAT(loginConf->GetClientStoreMarker() != 0); // Change it to something else - protocol.QuerySetClientStoreMarker(12); + protocol->QuerySetClientStoreMarker(12); // Success! done = true; // Log out - protocol.QueryFinished(); + protocol->QueryFinished(); + sSocket.Close(); } catch(...) { @@ -2822,11 +3701,12 @@ int test_bbackupd() // 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(BBACKUPQUERY " -q " + compareReturnValue = ::system(BBACKUPQUERY " " "-c testfiles/bbackupd.conf " "-l testfiles/query6.log " - "\"compare -acQ\" quit"); - TEST_RETURN(compareReturnValue, 2); + "-Werror \"compare -acQ\" quit"); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Compare_Different); TestRemoteProcessMemLeaks("bbackupquery.memleaks"); TEST_THAT(ServerIsAlive(bbackupd_pid)); @@ -2856,8 +3736,8 @@ int test_bbackupd() printf("\n==== Resume restore\n"); - std::auto_ptr<BackupProtocolClient> client = Connect( - context, + std::auto_ptr<BackupProtocolClient> client = + ConnectAndLogin(context, BackupProtocolClientLogin::Flags_ReadOnly); // Check that the restore fn returns resume possible, @@ -2880,12 +3760,13 @@ int test_bbackupd() sSocket.Close(); // Then check it has restored the correct stuff - compareReturnValue = ::system(BBACKUPQUERY " -q " + compareReturnValue = ::system(BBACKUPQUERY " " "-c testfiles/bbackupd.conf " "-l testfiles/query14.log " - "\"compare -cEQ Test1 " + "-Wwarning \"compare -cEQ Test1 " "testfiles/restore-interrupt\" quit"); - TEST_RETURN(compareReturnValue, 1); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Compare_Same); TestRemoteProcessMemLeaks("bbackupquery.memleaks"); } #endif // !WIN32 @@ -2898,8 +3779,8 @@ int test_bbackupd() printf("\n==== Check restore deleted files\n"); { - std::auto_ptr<BackupProtocolClient> client = Connect( - context, 0 /* read-write */); + std::auto_ptr<BackupProtocolClient> client = + ConnectAndLogin(context, 0 /* read-write */); // Do restore and undelete TEST_THAT(BackupClientRestore(*client, deldirid, @@ -2913,12 +3794,14 @@ int test_bbackupd() sSocket.Close(); // Do a compare with the now undeleted files - compareReturnValue = ::system(BBACKUPQUERY " -q " + compareReturnValue = ::system(BBACKUPQUERY " " "-c testfiles/bbackupd.conf " "-l testfiles/query11.log " + "-Wwarning " "\"compare -cEQ Test1/x1 " "testfiles/restore-Test1-x1-2\" quit"); - TEST_RETURN(compareReturnValue, 1); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Compare_Same); TestRemoteProcessMemLeaks("bbackupquery.memleaks"); } @@ -2937,7 +3820,7 @@ int test_bbackupd() // Test that locked files cannot be backed up, // and the appropriate error is reported. // Wait for the sync to finish, so that we have time to work - wait_for_sync_start(); + wait_for_sync_end(); // Now we have about three seconds to work handle = openfile("testfiles/TestDir1/lockedfile", @@ -2950,7 +3833,15 @@ int test_bbackupd() wait_for_sync_end(); TEST_THAT(!TestFileExists("testfiles/" "notifyran.read-error.1")); + } + + TEST_THAT(ServerIsAlive(bbackupd_pid)); + TEST_THAT(ServerIsAlive(bbstored_pid)); + if (!ServerIsAlive(bbackupd_pid)) return 1; + if (!ServerIsAlive(bbstored_pid)) return 1; + if (handle != 0) + { // this sync should try to back up the file, // and fail, because it's locked wait_for_sync_end(); @@ -2958,45 +3849,82 @@ int test_bbackupd() "notifyran.read-error.1")); TEST_THAT(!TestFileExists("testfiles/" "notifyran.read-error.2")); + } + + TEST_THAT(ServerIsAlive(bbackupd_pid)); + TEST_THAT(ServerIsAlive(bbstored_pid)); + if (!ServerIsAlive(bbackupd_pid)) return 1; + if (!ServerIsAlive(bbstored_pid)) return 1; + if (handle != 0) + { // now close the file and check that it is // backed up on the next run. CloseHandle(handle); wait_for_sync_end(); + + // still no read errors? TEST_THAT(!TestFileExists("testfiles/" "notifyran.read-error.2")); + } + TEST_THAT(ServerIsAlive(bbackupd_pid)); + TEST_THAT(ServerIsAlive(bbstored_pid)); + if (!ServerIsAlive(bbackupd_pid)) return 1; + if (!ServerIsAlive(bbstored_pid)) return 1; + + if (handle != 0) + { // compare, and check that it works // reports the correct error message (and finishes) - compareReturnValue = ::system(BBACKUPQUERY " -q " + compareReturnValue = ::system(BBACKUPQUERY " " "-c testfiles/bbackupd.conf " "-l testfiles/query15a.log " - "\"compare -acQ\" quit"); - TEST_RETURN(compareReturnValue, 1); + "-Wwarning \"compare -acQ\" quit"); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Compare_Same); TestRemoteProcessMemLeaks("bbackupquery.memleaks"); + } + TEST_THAT(ServerIsAlive(bbackupd_pid)); + TEST_THAT(ServerIsAlive(bbstored_pid)); + if (!ServerIsAlive(bbackupd_pid)) return 1; + if (!ServerIsAlive(bbstored_pid)) return 1; + + if (handle != 0) + { // open the file again, compare and check that compare // reports the correct error message (and finishes) handle = openfile("testfiles/TestDir1/lockedfile", O_LOCK, 0); TEST_THAT(handle != INVALID_HANDLE_VALUE); - compareReturnValue = ::system(BBACKUPQUERY - " -q -c testfiles/bbackupd.conf " + compareReturnValue = ::system(BBACKUPQUERY " " + "-c testfiles/bbackupd.conf " "-l testfiles/query15.log " - "\"compare -acQ\" quit"); - TEST_RETURN(compareReturnValue, 3); + "-Werror \"compare -acQ\" quit"); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Compare_Error); TestRemoteProcessMemLeaks("bbackupquery.memleaks"); // close the file again, check that compare // works again CloseHandle(handle); + } - compareReturnValue = ::system(BBACKUPQUERY " -q " + TEST_THAT(ServerIsAlive(bbackupd_pid)); + TEST_THAT(ServerIsAlive(bbstored_pid)); + if (!ServerIsAlive(bbackupd_pid)) return 1; + if (!ServerIsAlive(bbstored_pid)) return 1; + + if (handle != 0) + { + compareReturnValue = ::system(BBACKUPQUERY " " "-c testfiles/bbackupd.conf " "-l testfiles/query15a.log " - "\"compare -acQ\" quit"); - TEST_RETURN(compareReturnValue, 1); + "-Wwarning \"compare -acQ\" quit"); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Compare_Same); TestRemoteProcessMemLeaks("bbackupquery.memleaks"); } #endif @@ -3021,11 +3949,12 @@ int test_bbackupd() // Wait and compare (a little bit longer than usual) wait_for_backup_operation( (TIME_TO_WAIT_FOR_BACKUP_OPERATION*3) / 2); - compareReturnValue = ::system(BBACKUPQUERY " -q " + compareReturnValue = ::system(BBACKUPQUERY " " "-c testfiles/bbackupd.conf " "-l testfiles/query4a.log " - "\"compare -acQ\" quit"); - TEST_RETURN(compareReturnValue, 1); + "-Wwarning \"compare -acQ\" quit"); + TEST_RETURN(compareReturnValue, + BackupQueries::ReturnCode::Compare_Same); TestRemoteProcessMemLeaks("bbackupquery.memleaks"); // Kill it again @@ -3033,10 +3962,12 @@ int test_bbackupd() } } - // List the files on the server + /* + // List the files on the server - why? ::system(BBACKUPQUERY " -q -c testfiles/bbackupd.conf " "-l testfiles/queryLIST.log \"list -rotdh\" quit"); TestRemoteProcessMemLeaks("bbackupquery.memleaks"); + */ #ifndef WIN32 if(::getuid() == 0) @@ -3080,8 +4011,14 @@ int test(int argc, const char *argv[]) r = test_bbackupd(); if(r != 0) { - KillServer(bbackupd_pid); - KillServer(bbstored_pid); + if (bbackupd_pid) + { + KillServer(bbackupd_pid); + } + if (bbstored_pid) + { + KillServer(bbstored_pid); + } return r; } diff --git a/test/bbackupd/testfiles/bbackupd-exclude.conf.in b/test/bbackupd/testfiles/bbackupd-exclude.conf.in new file mode 100644 index 00000000..4c08753f --- /dev/null +++ b/test/bbackupd/testfiles/bbackupd-exclude.conf.in @@ -0,0 +1,47 @@ + +CertificateFile = testfiles/clientCerts.pem +PrivateKeyFile = testfiles/clientPrivKey.pem +TrustedCAsFile = testfiles/clientTrustedCAs.pem + +KeysFile = testfiles/bbackupd.keys + +DataDirectory = testfiles/bbackupd-data + +StoreHostname = localhost +StorePort = 22011 +AccountNumber = 0x01234567 + +UpdateStoreInterval = 3 +MinimumFileAge = 4 +MaxUploadWait = 24 +DeleteRedundantLocationsAfter = 10 + +FileTrackingSizeThreshold = 1024 +DiffingUploadSizeThreshold = 1024 + +MaximumDiffingTime = 3 +KeepAliveTime = 1 + +ExtendedLogging = no +ExtendedLogFile = testfiles/bbackupd.log + +CommandSocket = testfiles/bbackupd.sock + +NotifyScript = @TARGET_PERL@ testfiles/notifyscript.pl +SyncAllowScript = @TARGET_PERL@ testfiles/syncallowscript.pl + +Server +{ + PidFile = testfiles/bbackupd.pid +} + +BackupLocations +{ + Test1 + { + Path = testfiles/TestDir1 + ExcludeDir = testfiles/TestDir1/spacetest/d3 + ExcludeFile = testfiles/TestDir1/spacetest/f2 + } +} + diff --git a/test/bbackupd/testfiles/bbackupd-snapshot.conf.in b/test/bbackupd/testfiles/bbackupd-snapshot.conf.in new file mode 100644 index 00000000..d245d077 --- /dev/null +++ b/test/bbackupd/testfiles/bbackupd-snapshot.conf.in @@ -0,0 +1,56 @@ + +CertificateFile = testfiles/clientCerts.pem +PrivateKeyFile = testfiles/clientPrivKey.pem +TrustedCAsFile = testfiles/clientTrustedCAs.pem + +KeysFile = testfiles/bbackupd.keys + +DataDirectory = testfiles/bbackupd-data + +StoreHostname = localhost +StorePort = 22011 +AccountNumber = 0x01234567 + +AutomaticBackup = no +UpdateStoreInterval = 0 +MinimumFileAge = 4 +MaxUploadWait = 24 +DeleteRedundantLocationsAfter = 10 + +FileTrackingSizeThreshold = 1024 +DiffingUploadSizeThreshold = 1024 + +MaximumDiffingTime = 3 +KeepAliveTime = 1 + +ExtendedLogging = no +ExtendedLogFile = testfiles/bbackupd.log + +CommandSocket = testfiles/bbackupd.sock + +NotifyScript = @TARGET_PERL@ testfiles/notifyscript.pl +SyncAllowScript = @TARGET_PERL@ testfiles/syncallowscript.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-symlink.conf.in b/test/bbackupd/testfiles/bbackupd-symlink.conf.in new file mode 100644 index 00000000..33bb6157 --- /dev/null +++ b/test/bbackupd/testfiles/bbackupd-symlink.conf.in @@ -0,0 +1,55 @@ + +CertificateFile = testfiles/clientCerts.pem +PrivateKeyFile = testfiles/clientPrivKey.pem +TrustedCAsFile = testfiles/clientTrustedCAs.pem + +KeysFile = testfiles/bbackupd.keys + +DataDirectory = testfiles/bbackupd-data + +StoreHostname = localhost +StorePort = 22011 +AccountNumber = 0x01234567 + +UpdateStoreInterval = 3 +MinimumFileAge = 4 +MaxUploadWait = 24 +DeleteRedundantLocationsAfter = 10 + +FileTrackingSizeThreshold = 1024 +DiffingUploadSizeThreshold = 1024 + +MaximumDiffingTime = 3 +KeepAliveTime = 1 + +ExtendedLogging = no +ExtendedLogFile = testfiles/bbackupd.log + +CommandSocket = testfiles/bbackupd.sock + +NotifyScript = @TARGET_PERL@ testfiles/notifyscript.pl +SyncAllowScript = @TARGET_PERL@ testfiles/syncallowscript.pl + +Server +{ + PidFile = testfiles/bbackupd.pid +} + +BackupLocations +{ + Test1 + { + Path = testfiles/symlink-to-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-temploc.conf b/test/bbackupd/testfiles/bbackupd-temploc.conf index 86901298..07cbdcd1 100644 --- a/test/bbackupd/testfiles/bbackupd-temploc.conf +++ b/test/bbackupd/testfiles/bbackupd-temploc.conf @@ -8,6 +8,7 @@ KeysFile = testfiles/bbackupd.keys DataDirectory = testfiles/bbackupd-data StoreHostname = localhost +StorePort = 22011 AccountNumber = 0x01234567 UpdateStoreInterval = 3 @@ -48,7 +49,7 @@ BackupLocations } Test2 { - Path = testfiles/TestDir1 + Path = testfiles/TestDir2 } } diff --git a/test/bbackupd/testfiles/bbackupd.conf.in b/test/bbackupd/testfiles/bbackupd.conf.in index aecb3884..712b58b2 100644 --- a/test/bbackupd/testfiles/bbackupd.conf.in +++ b/test/bbackupd/testfiles/bbackupd.conf.in @@ -8,6 +8,7 @@ KeysFile = testfiles/bbackupd.keys DataDirectory = testfiles/bbackupd-data StoreHostname = localhost +StorePort = 22011 AccountNumber = 0x01234567 UpdateStoreInterval = 3 diff --git a/test/bbackupd/testfiles/bbstored.conf b/test/bbackupd/testfiles/bbstored.conf index 18c73a40..87f4fe6b 100644 --- a/test/bbackupd/testfiles/bbstored.conf +++ b/test/bbackupd/testfiles/bbstored.conf @@ -9,7 +9,7 @@ TimeBetweenHousekeeping = 5 Server { PidFile = testfiles/bbstored.pid - ListenAddresses = inet:localhost + ListenAddresses = inet:localhost:22011 CertificateFile = testfiles/serverCerts.pem PrivateKeyFile = testfiles/serverPrivKey.pem TrustedCAsFile = testfiles/serverTrustedCAs.pem diff --git a/test/bbackupd/testfiles/extcheck1.pl.in b/test/bbackupd/testfiles/extcheck1.pl.in index 4d0f2157..74884dd8 100755 --- a/test/bbackupd/testfiles/extcheck1.pl.in +++ b/test/bbackupd/testfiles/extcheck1.pl.in @@ -3,7 +3,10 @@ use strict; my $flags = $ARGV[0] or ""; -unless(open IN,"../../bin/bbackupquery/bbackupquery -q -c testfiles/bbackupd.conf -l testfiles/query4.log \"compare -ac$flags\" quit 2>&1 |") +unless(open IN,"../../bin/bbackupquery/bbackupquery -Wwarning " . + "-c testfiles/bbackupd.conf " . + "-l testfiles/query4.log " . + "\"compare -ac$flags\" quit 2>&1 |") { print "Couldn't open compare utility\n"; exit 2; diff --git a/test/bbackupd/testfiles/extcheck2.pl.in b/test/bbackupd/testfiles/extcheck2.pl.in index 074defc0..3671ad93 100755 --- a/test/bbackupd/testfiles/extcheck2.pl.in +++ b/test/bbackupd/testfiles/extcheck2.pl.in @@ -3,7 +3,10 @@ use strict; my $flags = $ARGV[0] or ""; -unless(open IN,"../../bin/bbackupquery/bbackupquery -q -c testfiles/bbackupd.conf -l testfiles/query4.log \"compare -ac$flags\" quit 2>&1 |") +unless(open IN,"../../bin/bbackupquery/bbackupquery -Wwarning " . + "-c testfiles/bbackupd.conf " . + "-l testfiles/query4.log " . + "\"compare -ac$flags\" quit 2>&1 |") { print "Couldn't open compare utility\n"; exit 2; diff --git a/test/bbackupd/testfiles/notifyscript.pl.in b/test/bbackupd/testfiles/notifyscript.pl.in index 89741e46..d3e324e9 100755 --- a/test/bbackupd/testfiles/notifyscript.pl.in +++ b/test/bbackupd/testfiles/notifyscript.pl.in @@ -1,7 +1,16 @@ #!@TARGET_PERL@ - my $f = 'testfiles/notifyran.'.$ARGV[0].'.'; + +if (-e 'testfiles/notifyscript.tag') +{ + open FILE, '< testfiles/notifyscript.tag' or die $!; + my $tag = <FILE>; + chomp $tag; + $f .= "$tag."; + close FILE; +} + my $n = 1; while(-e $f.$n) |