summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorReinhard Tartler <siretart@tauware.de>2009-04-02 14:02:56 +0200
committerReinhard Tartler <siretart@tauware.de>2009-04-02 14:02:56 +0200
commit76089c3bb5b915241da6d2f8f8c34eb65a78be95 (patch)
tree6b9524a5277ab57762cb01e9ea14131401c44ef5 /test
parent76af1c5e724dc558506be411e85a21122aef840d (diff)
parenta84d45498bd861c9225080232948a99c2e317bb8 (diff)
merge new upstream version
Diffstat (limited to 'test')
-rw-r--r--test/backupdiff/testbackupdiff.cpp83
-rw-r--r--test/backupstore/testbackupstore.cpp52
-rw-r--r--test/backupstorefix/testbackupstorefix.cpp9
-rwxr-xr-xtest/backupstorefix/testfiles/testbackupstorefix.pl.in16
-rw-r--r--test/basicserver/testbasicserver.cpp4
-rw-r--r--test/bbackupd/Makefile.extra15
-rw-r--r--test/bbackupd/testbbackupd.cpp1747
-rw-r--r--test/bbackupd/testfiles/bbackupd-exclude.conf.in47
-rw-r--r--test/bbackupd/testfiles/bbackupd-snapshot.conf.in56
-rw-r--r--test/bbackupd/testfiles/bbackupd-symlink.conf.in55
-rw-r--r--test/bbackupd/testfiles/bbackupd-temploc.conf3
-rw-r--r--test/bbackupd/testfiles/bbackupd.conf.in1
-rw-r--r--test/bbackupd/testfiles/bbstored.conf2
-rwxr-xr-xtest/bbackupd/testfiles/extcheck1.pl.in5
-rwxr-xr-xtest/bbackupd/testfiles/extcheck2.pl.in5
-rwxr-xr-xtest/bbackupd/testfiles/notifyscript.pl.in11
-rw-r--r--test/common/testcommon.cpp57
-rw-r--r--test/compress/testcompress.cpp3
-rw-r--r--test/httpserver/testfiles/httpserver.conf8
-rw-r--r--test/httpserver/testfiles/photos/puppy.jpg1
-rwxr-xr-xtest/httpserver/testfiles/testrequests.pl143
-rw-r--r--test/httpserver/testhttpserver.cpp661
-rw-r--r--test/raidfile/testraidfile.cpp3
23 files changed, 2492 insertions, 495 deletions
diff --git a/test/backupdiff/testbackupdiff.cpp b/test/backupdiff/testbackupdiff.cpp
index a91d6dfe..816f50d1 100644
--- a/test/backupdiff/testbackupdiff.cpp
+++ b/test/backupdiff/testbackupdiff.cpp
@@ -64,7 +64,7 @@ bool files_identical(const char *file1, const char *file2)
return true;
}
-void make_file_of_zeros(const char *filename, size_t size)
+bool make_file_of_zeros(const char *filename, size_t size)
{
#ifdef WIN32
HANDLE handle = openfile(filename, O_WRONLY | O_CREAT | O_EXCL, 0);
@@ -75,7 +75,9 @@ void make_file_of_zeros(const char *filename, size_t size)
BOOL result = SetEndOfFile(handle);
if (result != TRUE)
{
- printf("Error %u\n", GetLastError());
+ BOX_ERROR("Failed to create large file " << filename <<
+ " (" << (size >> 20) << " MB): " <<
+ GetErrorMessage(GetLastError()));
}
TEST_THAT(result == TRUE);
TEST_THAT(CloseHandle(handle) == TRUE);
@@ -87,7 +89,16 @@ void make_file_of_zeros(const char *filename, size_t size)
TEST_THAT(close(fd) == 0);
#endif
- TEST_THAT((size_t)TestGetFileSize(filename) == size);
+ bool correct_size = ((size_t)TestGetFileSize(filename) == size);
+ TEST_THAT(correct_size);
+ if (!correct_size)
+ {
+ BOX_ERROR("Failed to create large file " << filename <<
+ " (" << (size >> 20) << " MB): " <<
+ "got " << (TestGetFileSize(filename) >> 20) <<
+ " MB instead");
+ }
+ return correct_size;
}
@@ -110,8 +121,10 @@ void check_encoded_file(const char *filename, int64_t OtherFileID, int new_block
TEST_THAT((uint64_t)box_ntoh64(hdr.mOtherFileID) == (uint64_t)OtherFileID);
// number of blocks
int64_t nblocks = box_ntoh64(hdr.mNumBlocks);
- TRACE2("Reading index from '%s', has %lld blocks\n", filename, nblocks);
- TRACE0("======== ===== ========== ======== ========\n Index Where EncSz/Idx Size WChcksm\n");
+ BOX_TRACE("Reading index from '" << filename << "', has " <<
+ nblocks << " blocks");
+ BOX_TRACE("======== ===== ========== ======== ========");
+ BOX_TRACE(" Index Where EncSz/Idx Size WChcksm");
// Read them all in
int64_t nnew = 0, nold = 0;
for(int64_t b = 0; b < nblocks; ++b)
@@ -119,35 +132,36 @@ void check_encoded_file(const char *filename, int64_t OtherFileID, int new_block
file_BlockIndexEntry en;
TEST_THAT(enc.ReadFullBuffer(&en, sizeof(en), 0));
int64_t s = box_ntoh64(en.mEncodedSize);
+
+ // Decode the rest
+ uint64_t iv = box_ntoh64(hdr.mEntryIVBase);
+ iv += b;
+ sBlowfishDecryptBlockEntry.SetIV(&iv);
+ file_BlockIndexEntryEnc entryEnc;
+ sBlowfishDecryptBlockEntry.TransformBlock(&entryEnc,
+ sizeof(entryEnc), en.mEnEnc, sizeof(en.mEnEnc));
+
+
if(s > 0)
{
nnew++;
- #ifdef WIN32
- TRACE2("%8I64d this s=%8I64d", b, s);
- #else
- TRACE2("%8lld this s=%8lld", b, s);
- #endif
+ BOX_TRACE(std::setw(8) << b << " this s=" <<
+ std::setw(8) << s << " " <<
+ std::setw(8) << ntohl(entryEnc.mSize) << " " <<
+ std::setw(8) << std::setfill('0') <<
+ std::hex << ntohl(entryEnc.mWeakChecksum));
}
else
{
nold++;
- #ifdef WIN32
- TRACE2("%8I64d other i=%8I64d", b, 0 - s);
- #else
- TRACE2("%8lld other i=%8lld", b, 0 - s);
- #endif
+ BOX_TRACE(std::setw(8) << b << " other i=" <<
+ std::setw(8) << (0-s) << " " <<
+ std::setw(8) << ntohl(entryEnc.mSize) << " " <<
+ std::setw(8) << std::setfill('0') <<
+ std::hex << ntohl(entryEnc.mWeakChecksum));
}
- // Decode the rest
- uint64_t iv = box_ntoh64(hdr.mEntryIVBase);
- iv += b;
- sBlowfishDecryptBlockEntry.SetIV(&iv);
- file_BlockIndexEntryEnc entryEnc;
- sBlowfishDecryptBlockEntry.TransformBlock(&entryEnc, sizeof(entryEnc),
- en.mEnEnc, sizeof(en.mEnEnc));
- TRACE2(" %8d %08x\n", ntohl(entryEnc.mSize), ntohl(entryEnc.mWeakChecksum));
-
}
- TRACE0("======== ===== ========== ======== ========\n");
+ BOX_TRACE("======== ===== ========== ======== ========");
TEST_THAT(new_blocks_expected == nnew);
TEST_THAT(old_blocks_expected == nold);
}
@@ -374,7 +388,7 @@ void test_combined_diffs()
int test(int argc, const char *argv[])
{
// Want to trace out all the details
- #ifndef NDEBUG
+ #ifndef BOX_RELEASE_BUILD
#ifndef WIN32
BackupStoreFile::TraceDetailsOfDiffProcess = true;
#endif
@@ -512,13 +526,20 @@ int test(int argc, const char *argv[])
// found. Check this out!
#ifdef WIN32
- ::fprintf(stdout, "Testing diffing two large streams, "
- "may take a while!\n");
- ::fflush(stdout);
+ BOX_WARNING("Testing diffing two large streams, may take a while!");
+ ::fflush(stderr);
#endif
- make_file_of_zeros("testfiles/zero.0", 20*1024*1024);
- make_file_of_zeros("testfiles/zero.1", 200*1024*1024);
+ if (!make_file_of_zeros("testfiles/zero.0", 20*1024*1024))
+ {
+ return 1;
+ }
+
+ if (!make_file_of_zeros("testfiles/zero.1", 200*1024*1024))
+ {
+ remove("testfiles/zero.0");
+ return 1;
+ }
// Generate a first encoded file
{
diff --git a/test/backupstore/testbackupstore.cpp b/test/backupstore/testbackupstore.cpp
index a5eacc7d..0266d097 100644
--- a/test/backupstore/testbackupstore.cpp
+++ b/test/backupstore/testbackupstore.cpp
@@ -72,7 +72,7 @@ static const char *ens_filenames[] = {"obj1ertewt", "obj2", "obj3", "obj4dfedfg4
typedef struct
{
- char *fnextra;
+ const char *fnextra;
BackupStoreFilenameClear name;
int seed;
int size;
@@ -232,7 +232,8 @@ int test1(int argc, const char *argv[])
TEST_THAT(fn1 == fn3);
// Check that it's been encrypted
- TEST_THAT(fn2.find("name") == fn2.npos);
+ std::string name(fn2.GetEncodedFilename());
+ TEST_THAT(name.find("name") == name.npos);
// Bung it in a stream, get it out in a Clear filename
{
@@ -974,6 +975,9 @@ int test_server(const char *hostname)
test_server_1(protocol, protocolReadOnly);
+ // sleep to ensure that the timestamp on the file will change
+ ::safe_sleep(1);
+
// Create and upload some test files
int64_t maxID = 0;
for(int t = 0; t < UPLOAD_NUM; ++t)
@@ -1048,11 +1052,16 @@ int test_server(const char *hostname)
StreamableMemBlock attrtest(attr3, sizeof(attr3));
// Use the read only connection to verify that the directory is as we expect
+ printf("\n\n==== Reading directory using read-only connection\n");
check_dir_after_uploads(protocolReadOnly, attrtest);
+ printf("done.\n\n");
// And on the read/write one
check_dir_after_uploads(protocol, attrtest);
}
+ // sleep to ensure that the timestamp on the file will change
+ ::safe_sleep(1);
+
// Check diffing and rsync like stuff...
// Build a modified file
{
@@ -1149,6 +1158,8 @@ int test_server(const char *hostname)
*upload));
subdirfileid = stored->GetObjectID();
}
+
+ printf("\n==== Checking upload using read-only connection\n");
// Check the directories on the read only connection
{
// Command
@@ -1181,6 +1192,7 @@ int test_server(const char *hostname)
TEST_THAT(en->GetObjectID() == subdirid);
TEST_THAT(en->GetModificationTime() == 0); // dirs don't have modification times.
}
+
{
// Command
std::auto_ptr<BackupProtocolClientSuccess> dirreply(protocolReadOnly.QueryListDirectory(
@@ -1211,6 +1223,7 @@ int test_server(const char *hostname)
StreamableMemBlock attr(attr1, sizeof(attr1));
TEST_THAT(dir.GetAttributes() == attr);
}
+ printf("done.\n\n");
// Check that we don't get attributes if we don't ask for them
{
@@ -1258,6 +1271,9 @@ int test_server(const char *hostname)
TEST_THAT(dir.GetAttributes() == attrtest);
}
+ // sleep to ensure that the timestamp on the file will change
+ ::safe_sleep(1);
+
// Test moving a file
{
BackupStoreFilenameClear newName("moved-files");
@@ -1281,9 +1297,6 @@ int test_server(const char *hostname)
ConnectionException, Conn_Protocol_UnexpectedReply);
}
- // sleep to ensure that the timestamp on the file will change
- ::safe_sleep(1);
-
// Rename within a directory
{
BackupStoreFilenameClear newName("moved-files-x");
@@ -1342,6 +1355,9 @@ int test_server(const char *hostname)
TEST_THAT(foundOld);
}
+ // sleep to ensure that the timestamp on the file will change
+ ::safe_sleep(1);
+
// make a little bit more of a thing to look at
int64_t subsubdirid = 0;
int64_t subsubfileid = 0;
@@ -1763,9 +1779,12 @@ int test3(int argc, const char *argv[])
TEST_THAT(KillServer(pid));
::sleep(1);
TEST_THAT(!ServerIsAlive(pid));
-#ifndef WIN32
- TestRemoteProcessMemLeaks("bbstored.memleaks");
-#endif
+
+ #ifdef WIN32
+ TEST_THAT(unlink("testfiles/bbstored.pid") == 0);
+ #else
+ TestRemoteProcessMemLeaks("bbstored.memleaks");
+ #endif
// Set a new limit on the account -- leave the hard limit
// high to make sure the target for freeing space is the
@@ -1857,9 +1876,11 @@ int test3(int argc, const char *argv[])
::sleep(1);
TEST_THAT(!ServerIsAlive(pid));
-#ifndef WIN32
- TestRemoteProcessMemLeaks("bbstored.memleaks");
-#endif
+ #ifdef WIN32
+ TEST_THAT(unlink("testfiles/bbstored.pid") == 0);
+ #else
+ TestRemoteProcessMemLeaks("bbstored.memleaks");
+ #endif
}
return 0;
@@ -1896,9 +1917,12 @@ int multi_server()
TEST_THAT(KillServer(pid));
::sleep(1);
TEST_THAT(!ServerIsAlive(pid));
-#ifndef WIN32
- TestRemoteProcessMemLeaks("bbstored.memleaks");
-#endif
+
+ #ifdef WIN32
+ TEST_THAT(unlink("testfiles/bbstored.pid") == 0);
+ #else
+ TestRemoteProcessMemLeaks("bbstored.memleaks");
+ #endif
}
diff --git a/test/backupstorefix/testbackupstorefix.cpp b/test/backupstorefix/testbackupstorefix.cpp
index 34565bd5..2d4ce052 100644
--- a/test/backupstorefix/testbackupstorefix.cpp
+++ b/test/backupstorefix/testbackupstorefix.cpp
@@ -338,7 +338,7 @@ int test(int argc, const char *argv[])
}
// Generate a list of all the object IDs
- TEST_THAT_ABORTONFAIL(::system(BBACKUPQUERY " -q "
+ TEST_THAT_ABORTONFAIL(::system(BBACKUPQUERY " -Wwarning "
"-c testfiles/bbackupd.conf \"list -r\" quit "
"> testfiles/initial-listing.txt") == 0);
@@ -598,10 +598,13 @@ int test(int argc, const char *argv[])
" testfiles/testbackupstorefix.pl reroot 6") == 0);
- // ------------------------------------------------------------------------------------------------
+ // ---------------------------------------------------------
// Stop server
TEST_THAT(KillServer(pid));
- #ifndef WIN32
+
+ #ifdef WIN32
+ TEST_THAT(unlink("testfiles/bbstored.pid") == 0);
+ #else
TestRemoteProcessMemLeaks("bbstored.memleaks");
#endif
}
diff --git a/test/backupstorefix/testfiles/testbackupstorefix.pl.in b/test/backupstorefix/testfiles/testbackupstorefix.pl.in
index e64474f0..d27c1106 100755
--- a/test/backupstorefix/testfiles/testbackupstorefix.pl.in
+++ b/test/backupstorefix/testfiles/testbackupstorefix.pl.in
@@ -93,8 +93,12 @@ elsif($ARGV[0] eq 'check')
}
# read in the new listing, and compare
- open LISTING,"../../bin/bbackupquery/bbackupquery -q -c testfiles/bbackupd.conf \"list -r\" quit |" or die "Can't open list utility";
- open LISTING_COPY,'>testfiles/listing'.$ARGV[1].'.txt' or die "can't open copy listing file";
+ open LISTING,"../../bin/bbackupquery/bbackupquery -Wwarning " .
+ "-c testfiles/bbackupd.conf " .
+ "\"list -r\" quit |"
+ or die "Can't open list utility";
+ open LISTING_COPY,'>testfiles/listing'.$ARGV[1].'.txt'
+ or die "can't open copy listing file";
my $err = 0;
while(<LISTING>)
{
@@ -125,8 +129,12 @@ elsif($ARGV[0] eq 'check')
}
elsif($ARGV[0] eq 'reroot')
{
- open LISTING,"../../bin/bbackupquery/bbackupquery -q -c testfiles/bbackupd.conf \"list -r\" quit |" or die "Can't open list utility";
- open LISTING_COPY,'>testfiles/listing'.$ARGV[1].'.txt' or die "can't open copy listing file";
+ open LISTING,"../../bin/bbackupquery/bbackupquery -Wwarning " .
+ "-c testfiles/bbackupd.conf " .
+ "\"list -r\" quit |"
+ or die "Can't open list utility";
+ open LISTING_COPY,'>testfiles/listing'.$ARGV[1].'.txt'
+ or die "can't open copy listing file";
my $err = 0;
my $count = 0;
while(<LISTING>)
diff --git a/test/basicserver/testbasicserver.cpp b/test/basicserver/testbasicserver.cpp
index 18329441..18bc0aa8 100644
--- a/test/basicserver/testbasicserver.cpp
+++ b/test/basicserver/testbasicserver.cpp
@@ -185,7 +185,7 @@ const ConfigurationVerify *testserver::GetConfigVerify() const
{
static ConfigurationVerifyKey verifyserverkeys[] =
{
- SERVERSTREAM_VERIFY_SERVER_KEYS(0) // no default addresses
+ SERVERSTREAM_VERIFY_SERVER_KEYS(ConfigurationVerifyKey::NoDefaultValue) // no default listen addresses
};
static ConfigurationVerify verifyserver[] =
@@ -258,7 +258,7 @@ const ConfigurationVerify *testTLSserver::GetConfigVerify() const
{
static ConfigurationVerifyKey verifyserverkeys[] =
{
- SERVERTLS_VERIFY_SERVER_KEYS(0) // no default listen addresses
+ SERVERTLS_VERIFY_SERVER_KEYS(ConfigurationVerifyKey::NoDefaultValue) // no default listen addresses
};
static ConfigurationVerify verifyserver[] =
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)
diff --git a/test/common/testcommon.cpp b/test/common/testcommon.cpp
index eb057228..da2133cd 100644
--- a/test/common/testcommon.cpp
+++ b/test/common/testcommon.cpp
@@ -57,15 +57,15 @@ void test_conversions()
ConfigurationVerifyKey verifykeys1_1_1[] =
{
- {"bing", 0, ConfigTest_Exists, 0},
- {"carrots", 0, ConfigTest_Exists | ConfigTest_IsInt, 0},
- {"terrible", 0, ConfigTest_Exists | ConfigTest_LastEntry, 0}
+ ConfigurationVerifyKey("bing", ConfigTest_Exists),
+ ConfigurationVerifyKey("carrots", ConfigTest_Exists | ConfigTest_IsInt),
+ ConfigurationVerifyKey("terrible", ConfigTest_Exists | ConfigTest_LastEntry)
};
ConfigurationVerifyKey verifykeys1_1_2[] =
{
- {"fish", 0, ConfigTest_Exists | ConfigTest_IsInt, 0},
- {"string", 0, ConfigTest_Exists | ConfigTest_LastEntry, 0}
+ ConfigurationVerifyKey("fish", ConfigTest_Exists | ConfigTest_IsInt),
+ ConfigurationVerifyKey("string", ConfigTest_Exists | ConfigTest_LastEntry)
};
@@ -89,15 +89,15 @@ ConfigurationVerify verifysub1_1[] =
ConfigurationVerifyKey verifykeys1_1[] =
{
- {"value", 0, ConfigTest_Exists | ConfigTest_IsInt, 0},
- {"string1", 0, ConfigTest_Exists, 0},
- {"string2", 0, ConfigTest_Exists | ConfigTest_LastEntry, 0}
+ ConfigurationVerifyKey("value", ConfigTest_Exists | ConfigTest_IsInt),
+ ConfigurationVerifyKey("string1", ConfigTest_Exists),
+ ConfigurationVerifyKey("string2", ConfigTest_Exists | ConfigTest_LastEntry)
};
ConfigurationVerifyKey verifykeys1_2[] =
{
- {"carrots", 0, ConfigTest_Exists | ConfigTest_IsInt, 0},
- {"string", 0, ConfigTest_Exists | ConfigTest_LastEntry, 0}
+ ConfigurationVerifyKey("carrots", ConfigTest_Exists | ConfigTest_IsInt),
+ ConfigurationVerifyKey("string", ConfigTest_Exists | ConfigTest_LastEntry)
};
ConfigurationVerify verifysub1[] =
@@ -120,14 +120,15 @@ ConfigurationVerify verifysub1[] =
ConfigurationVerifyKey verifykeys1[] =
{
- {"notExpected", 0, 0, 0},
- {"HasDefaultValue", "Lovely default value", 0, 0},
- {"MultiValue", 0, ConfigTest_MultiValueAllowed, 0},
- {"BoolTrue1", 0, ConfigTest_IsBool, 0},
- {"BoolTrue2", 0, ConfigTest_IsBool, 0},
- {"BoolFalse1", 0, ConfigTest_IsBool, 0},
- {"BoolFalse2", 0, ConfigTest_IsBool, 0},
- {"TOPlevel", 0, ConfigTest_LastEntry | ConfigTest_Exists, 0}
+ ConfigurationVerifyKey("notExpected", 0),
+ ConfigurationVerifyKey("HasDefaultValue", 0, "Lovely default value"),
+ ConfigurationVerifyKey("MultiValue", ConfigTest_MultiValueAllowed),
+ ConfigurationVerifyKey("BoolTrue1", ConfigTest_IsBool),
+ ConfigurationVerifyKey("BoolTrue2", ConfigTest_IsBool),
+ ConfigurationVerifyKey("BoolFalse1", ConfigTest_IsBool),
+ ConfigurationVerifyKey("BoolFalse2", ConfigTest_IsBool),
+ ConfigurationVerifyKey("TOPlevel",
+ ConfigTest_LastEntry | ConfigTest_Exists)
};
ConfigurationVerify verify =
@@ -297,7 +298,7 @@ int test(int argc, const char *argv[])
// Check that using timer methods without initialisation
// throws an assertion failure. Can only do this in debug mode
- #ifndef NDEBUG
+ #ifndef BOX_RELEASE_BUILD
TEST_CHECK_THROWS(Timers::Add(*(Timer*)NULL),
CommonException, AssertFailed);
TEST_CHECK_THROWS(Timers::Remove(*(Timer*)NULL),
@@ -305,7 +306,7 @@ int test(int argc, const char *argv[])
#endif
// TEST_CHECK_THROWS(Timers::Signal(), CommonException, AssertFailed);
- #ifndef NDEBUG
+ #ifndef BOX_RELEASE_BUILD
TEST_CHECK_THROWS(Timers::Cleanup(), CommonException,
AssertFailed);
#endif
@@ -314,7 +315,7 @@ int test(int argc, const char *argv[])
Timers::Init();
// Check that double initialisation throws an exception
- #ifndef NDEBUG
+ #ifndef BOX_RELEASE_BUILD
TEST_CHECK_THROWS(Timers::Init(), CommonException,
AssertFailed);
#endif
@@ -323,17 +324,17 @@ int test(int argc, const char *argv[])
Timers::Cleanup();
// Check that double cleanup throws an exception
- #ifndef NDEBUG
+ #ifndef BOX_RELEASE_BUILD
TEST_CHECK_THROWS(Timers::Cleanup(), CommonException,
AssertFailed);
#endif
Timers::Init();
- Timer t0(0); // should never expire
- Timer t1(1);
- Timer t2(2);
- Timer t3(3);
+ Timer t0(0, "t0"); // should never expire
+ Timer t1(1, "t1");
+ Timer t2(2, "t2");
+ Timer t3(3, "t3");
TEST_THAT(!t0.HasExpired());
TEST_THAT(!t1.HasExpired());
@@ -352,8 +353,8 @@ int test(int argc, const char *argv[])
TEST_THAT(t2.HasExpired());
TEST_THAT(!t3.HasExpired());
- t1 = Timer(1);
- t2 = Timer(2);
+ t1 = Timer(1, "t1a");
+ t2 = Timer(2, "t2a");
TEST_THAT(!t0.HasExpired());
TEST_THAT(!t1.HasExpired());
TEST_THAT(!t2.HasExpired());
diff --git a/test/compress/testcompress.cpp b/test/compress/testcompress.cpp
index 592dd641..4a522d31 100644
--- a/test/compress/testcompress.cpp
+++ b/test/compress/testcompress.cpp
@@ -90,7 +90,8 @@ int test_stream()
// Check sizes
TEST_THAT(poutput->GetSize() < source.GetSize());
- TRACE2("compressed size = %d, source size = %d\n", poutput->GetSize(), source.GetSize());
+ BOX_TRACE("compressed size = " << poutput->GetSize() <<
+ ", source size = " << source.GetSize());
// Decompress the data
{
diff --git a/test/httpserver/testfiles/httpserver.conf b/test/httpserver/testfiles/httpserver.conf
new file mode 100644
index 00000000..1a1c4644
--- /dev/null
+++ b/test/httpserver/testfiles/httpserver.conf
@@ -0,0 +1,8 @@
+
+AddressPrefix = http://localhost:1080
+
+Server
+{
+ PidFile = testfiles/httpserver.pid
+ ListenAddresses = inet:localhost:1080
+}
diff --git a/test/httpserver/testfiles/photos/puppy.jpg b/test/httpserver/testfiles/photos/puppy.jpg
new file mode 100644
index 00000000..a326a6a7
--- /dev/null
+++ b/test/httpserver/testfiles/photos/puppy.jpg
@@ -0,0 +1 @@
+omgpuppies!
diff --git a/test/httpserver/testfiles/testrequests.pl b/test/httpserver/testfiles/testrequests.pl
new file mode 100755
index 00000000..85380ee0
--- /dev/null
+++ b/test/httpserver/testfiles/testrequests.pl
@@ -0,0 +1,143 @@
+#!/usr/bin/perl
+use strict;
+use LWP::UserAgent;
+
+my $url_base = 'http://localhost:1080';
+
+my $ua = LWP::UserAgent->new(env_proxy => 0, keep_alive => 1, timeout => 30);
+
+print "GET request...\n";
+
+my $response1 = $ua->get("$url_base/test-one/34/341s/234?p1=vOne&p2=vTwo");
+die $response1->content unless $response1->is_success();
+
+my $content = $response1->content();
+
+check_url($content, '/test-one/34/341s/234');
+check_params($content, 'p1'=>'vOne','p2'=>'vTwo');
+
+print "POST request...\n";
+
+my %post = ('sdfgksjhdfsd'=>'dfvsiufy2e3434','sxciuhwf8723e4'=>'238947829334',
+ '&sfsfsfskfhs'=>'?hdkfjhsjfds','fdsf=sdf2342'=>'3984sajhksda');
+
+my $response2 = $ua->post("$url_base/tdskjhfsjdkhf2943734?p1=vOne&p2=vTwo", \%post);
+
+my $content2 = $response2->content();
+
+check_url($content2, '/tdskjhfsjdkhf2943734');
+check_params($content2, %post);
+
+print "HEAD request...\n";
+
+my $response3 = $ua->head("$url_base/tdskjhfsdfkjhs");
+
+if($response3->content() ne '')
+{
+ print "Content not zero length\n";
+ exit(1);
+}
+
+if($response3->code() != 200)
+{
+ print "Wrong response code\n";
+ exit(1);
+}
+
+print "Redirected GET request...\n";
+
+my $response4 = $ua->get("$url_base/redirect?key=value");
+exit 4 unless $response4->is_success();
+
+my $content4 = $response4->content();
+
+check_url($content4, '/redirected');
+check_params($content4);
+
+print "Cookie tests...\n";
+
+# from examples in specs
+test_cookies('CUSTOMER=WILE_E_COYOTE', 'CUSTOMER=WILE_E_COYOTE');
+test_cookies('CUSTOMER="WILE_E_COYOTE"; C2="pants"', 'CUSTOMER=WILE_E_COYOTE', 'C2=pants');
+test_cookies('CUSTOMER=WILE_E_COYOTE; PART_NUMBER=ROCKET_LAUNCHER_0001', 'CUSTOMER=WILE_E_COYOTE', 'PART_NUMBER=ROCKET_LAUNCHER_0001');
+test_cookies('CUSTOMER=WILE_E_COYOTE; PART_NUMBER=ROCKET_LAUNCHER_0001; SHIPPING=FEDEX', 'CUSTOMER=WILE_E_COYOTE', 'PART_NUMBER=ROCKET_LAUNCHER_0001', 'SHIPPING=FEDEX');
+test_cookies('$Version="1"; Customer="WILE_E_COYOTE"; $Path="/acme"', 'Customer=WILE_E_COYOTE');
+test_cookies('$Version="1"; Customer="WILE_E_COYOTE"; $Path="/acme"; Part_Number="Rocket_Launcher_0001"; $Path="/acme" ',
+ 'Customer=WILE_E_COYOTE', 'Part_Number=Rocket_Launcher_0001');
+test_cookies(qq!\$Version="1"; Customer="WILE_E_COYOTE"; \$Path="/acme"; Part_Number="Rocket_Launcher_0001"; \$Path="/acme"; Shipping="FedEx"; \t \$Path="/acme"!,
+ 'Customer=WILE_E_COYOTE', 'Part_Number=Rocket_Launcher_0001', 'Shipping=FedEx');
+
+# test the server setting cookies in the UA
+require HTTP::Cookies;
+$ua->cookie_jar(HTTP::Cookies->new());
+$ua->get("$url_base/set-cookie");
+test_cookies('', 'SetByServer=Value1');
+
+sub test_cookies
+{
+ my ($c_str, @cookies) = @_;
+ test_cookies2($c_str, @cookies);
+ $c_str =~ s/;/,/g;
+ test_cookies2($c_str, @cookies);
+}
+
+sub test_cookies2
+{
+ my ($c_str, @cookies) = @_;
+ my $r;
+ if($c_str ne '')
+ {
+ $r = $ua->get("$url_base/cookie", 'Cookie' => $c_str);
+ }
+ else
+ {
+ $r = $ua->get("$url_base/cookie");
+ }
+ my $c = $r->content();
+ for(@cookies)
+ {
+ unless($c =~ m/COOKIE:$_<br>/)
+ {
+ print "Cookie $_ not found\n";
+ exit(1);
+ }
+ }
+}
+
+
+sub check_url
+{
+ my ($c,$url) = @_;
+ unless($c =~ m~URI:</b> (.+?)</p>~)
+ {
+ print "URI not found\n";
+ exit(1);
+ }
+ if($url ne $1)
+ {
+ print "Wrong URI in content\n";
+ exit(1);
+ }
+}
+
+sub check_params
+{
+ my ($c,%params) = @_;
+
+ while($c =~ m/^PARAM:(.+)=(.+?)<br>/mg)
+ {
+ if($params{$1} ne $2)
+ {
+ print "$1=$2 not found in response\n";
+ exit(1);
+ }
+ delete $params{$1}
+ }
+
+ my @k = keys %params;
+ if($#k != -1)
+ {
+ print "Didn't find all params\n";
+ exit(1);
+ }
+}
diff --git a/test/httpserver/testhttpserver.cpp b/test/httpserver/testhttpserver.cpp
new file mode 100644
index 00000000..c38ef8fe
--- /dev/null
+++ b/test/httpserver/testhttpserver.cpp
@@ -0,0 +1,661 @@
+// --------------------------------------------------------------------------
+//
+// File
+// Name: testhttpserver.cpp
+// Purpose: Test code for HTTP server class
+// Created: 26/3/04
+//
+// --------------------------------------------------------------------------
+
+#include "Box.h"
+
+#include <cstdio>
+#include <cstring>
+#include <ctime>
+
+#ifdef HAVE_SIGNAL_H
+ #include <signal.h>
+#endif
+
+#include <openssl/hmac.h>
+
+#include "autogen_HTTPException.h"
+#include "HTTPRequest.h"
+#include "HTTPResponse.h"
+#include "HTTPServer.h"
+#include "IOStreamGetLine.h"
+#include "S3Client.h"
+#include "ServerControl.h"
+#include "Test.h"
+#include "decode.h"
+#include "encode.h"
+
+#include "MemLeakFindOn.h"
+
+class TestWebServer : public HTTPServer
+{
+public:
+ TestWebServer();
+ ~TestWebServer();
+
+ virtual void Handle(HTTPRequest &rRequest, HTTPResponse &rResponse);
+
+};
+
+// Build a nice HTML response, so this can also be tested neatly in a browser
+void TestWebServer::Handle(HTTPRequest &rRequest, HTTPResponse &rResponse)
+{
+ // Test redirection mechanism
+ if(rRequest.GetRequestURI() == "/redirect")
+ {
+ rResponse.SetAsRedirect("/redirected");
+ return;
+ }
+
+ // Set a cookie?
+ if(rRequest.GetRequestURI() == "/set-cookie")
+ {
+ rResponse.SetCookie("SetByServer", "Value1");
+ }
+
+ #define DEFAULT_RESPONSE_1 "<html>\n<head><title>TEST SERVER RESPONSE</title></head>\n<body><h1>Test response</h1>\n<p><b>URI:</b> "
+ #define DEFAULT_RESPONSE_3 "</p>\n<p><b>Query string:</b> "
+ #define DEFAULT_RESPONSE_4 "</p>\n<p><b>Method:</b> "
+ #define DEFAULT_RESPONSE_5 "</p>\n<p><b>Decoded query:</b><br>"
+ #define DEFAULT_RESPONSE_6 "</p>\n<p><b>Content type:</b> "
+ #define DEFAULT_RESPONSE_7 "</p>\n<p><b>Content length:</b> "
+ #define DEFAULT_RESPONSE_8 "</p>\n<p><b>Cookies:</b><br>\n"
+ #define DEFAULT_RESPONSE_2 "</p>\n</body>\n</html>\n"
+
+ rResponse.SetResponseCode(HTTPResponse::Code_OK);
+ rResponse.SetContentType("text/html");
+ rResponse.Write(DEFAULT_RESPONSE_1, sizeof(DEFAULT_RESPONSE_1) - 1);
+ const std::string &ruri(rRequest.GetRequestURI());
+ rResponse.Write(ruri.c_str(), ruri.size());
+ rResponse.Write(DEFAULT_RESPONSE_3, sizeof(DEFAULT_RESPONSE_3) - 1);
+ const std::string &rquery(rRequest.GetQueryString());
+ rResponse.Write(rquery.c_str(), rquery.size());
+ rResponse.Write(DEFAULT_RESPONSE_4, sizeof(DEFAULT_RESPONSE_4) - 1);
+ {
+ const char *m = "????";
+ switch(rRequest.GetMethod())
+ {
+ case HTTPRequest::Method_GET: m = "GET "; break;
+ case HTTPRequest::Method_HEAD: m = "HEAD"; break;
+ case HTTPRequest::Method_POST: m = "POST"; break;
+ default: m = "UNKNOWN";
+ }
+ rResponse.Write(m, 4);
+ }
+ rResponse.Write(DEFAULT_RESPONSE_5, sizeof(DEFAULT_RESPONSE_5) - 1);
+ {
+ const HTTPRequest::Query_t &rquery(rRequest.GetQuery());
+ for(HTTPRequest::Query_t::const_iterator i(rquery.begin()); i != rquery.end(); ++i)
+ {
+ rResponse.Write("\nPARAM:", 7);
+ rResponse.Write(i->first.c_str(), i->first.size());
+ rResponse.Write("=", 1);
+ rResponse.Write(i->second.c_str(), i->second.size());
+ rResponse.Write("<br>\n", 4);
+ }
+ }
+ rResponse.Write(DEFAULT_RESPONSE_6, sizeof(DEFAULT_RESPONSE_6) - 1);
+ const std::string &rctype(rRequest.GetContentType());
+ rResponse.Write(rctype.c_str(), rctype.size());
+ rResponse.Write(DEFAULT_RESPONSE_7, sizeof(DEFAULT_RESPONSE_7) - 1);
+ {
+ char l[32];
+ rResponse.Write(l, ::sprintf(l, "%d", rRequest.GetContentLength()));
+ }
+ rResponse.Write(DEFAULT_RESPONSE_8, sizeof(DEFAULT_RESPONSE_8) - 1);
+ const HTTPRequest::CookieJar_t *pcookies = rRequest.GetCookies();
+ if(pcookies != 0)
+ {
+ HTTPRequest::CookieJar_t::const_iterator i(pcookies->begin());
+ for(; i != pcookies->end(); ++i)
+ {
+ char t[512];
+ rResponse.Write(t, ::sprintf(t, "COOKIE:%s=%s<br>\n", i->first.c_str(), i->second.c_str()));
+ }
+ }
+ rResponse.Write(DEFAULT_RESPONSE_2, sizeof(DEFAULT_RESPONSE_2) - 1);
+}
+
+TestWebServer::TestWebServer() {}
+TestWebServer::~TestWebServer() {}
+
+class S3Simulator : public HTTPServer
+{
+public:
+ S3Simulator() { }
+ ~S3Simulator() { }
+
+ virtual void Handle(HTTPRequest &rRequest, HTTPResponse &rResponse);
+ virtual void HandleGet(HTTPRequest &rRequest, HTTPResponse &rResponse);
+ virtual void HandlePut(HTTPRequest &rRequest, HTTPResponse &rResponse);
+};
+
+void S3Simulator::Handle(HTTPRequest &rRequest, HTTPResponse &rResponse)
+{
+ // if anything goes wrong, return a 500 error
+ rResponse.SetResponseCode(HTTPResponse::Code_InternalServerError);
+ rResponse.SetContentType("text/plain");
+
+ try
+ {
+ // http://docs.amazonwebservices.com/AmazonS3/2006-03-01/RESTAuthentication.html
+ std::string access_key = "0PN5J17HBGZHT7JJ3X82";
+ std::string secret_key = "uV3F3YluFJax1cknvbcGwgjvx4QpvB+leU8dUj2o";
+
+ std::string md5, date, bucket;
+ rRequest.GetHeader("Content-MD5", &md5);
+ rRequest.GetHeader("Date", &date);
+
+ std::string host = rRequest.GetHostName();
+ std::string s3suffix = ".s3.amazonaws.com";
+ if (host.size() > s3suffix.size())
+ {
+ std::string suffix = host.substr(host.size() -
+ s3suffix.size(), s3suffix.size());
+ if (suffix == s3suffix)
+ {
+ bucket = host.substr(0, host.size() -
+ s3suffix.size());
+ }
+ }
+
+ std::ostringstream data;
+ data << rRequest.GetVerb() << "\n";
+ data << md5 << "\n";
+ data << rRequest.GetContentType() << "\n";
+ data << date << "\n";
+
+ std::vector<HTTPRequest::Header> headers = rRequest.GetHeaders();
+
+ for (std::vector<HTTPRequest::Header>::iterator
+ i = headers.begin(); i != headers.end(); i++)
+ {
+ std::string& rHeaderName = i->first;
+
+ for (std::string::iterator c = rHeaderName.begin();
+ c != rHeaderName.end() && *c != ':'; c++)
+ {
+ *c = tolower(*c);
+ }
+ }
+
+ sort(headers.begin(), headers.end());
+
+ for (std::vector<HTTPRequest::Header>::iterator
+ i = headers.begin(); i != headers.end(); i++)
+ {
+ if (i->first.substr(0, 5) == "x-amz")
+ {
+ data << i->first << ":" << i->second << "\n";
+ }
+ }
+
+ if (! bucket.empty())
+ {
+ data << "/" << bucket;
+ }
+
+ data << rRequest.GetRequestURI();
+ std::string data_string = data.str();
+
+ unsigned char digest_buffer[EVP_MAX_MD_SIZE];
+ unsigned int digest_size = sizeof(digest_buffer);
+ /* unsigned char* mac = */ HMAC(EVP_sha1(),
+ secret_key.c_str(), secret_key.size(),
+ (const unsigned char*)data_string.c_str(),
+ data_string.size(), digest_buffer, &digest_size);
+ std::string digest((const char *)digest_buffer, digest_size);
+
+ base64::encoder encoder;
+ std::string expectedAuth = "AWS " + access_key + ":" +
+ encoder.encode(digest);
+
+ if (expectedAuth[expectedAuth.size() - 1] == '\n')
+ {
+ expectedAuth = expectedAuth.substr(0,
+ expectedAuth.size() - 1);
+ }
+
+ std::string actualAuth;
+ if (!rRequest.GetHeader("Authorization", &actualAuth) ||
+ actualAuth != expectedAuth)
+ {
+ rResponse.SetResponseCode(HTTPResponse::Code_Unauthorized);
+ }
+ else if (rRequest.GetMethod() == HTTPRequest::Method_GET)
+ {
+ HandleGet(rRequest, rResponse);
+ }
+ else if (rRequest.GetMethod() == HTTPRequest::Method_PUT)
+ {
+ HandlePut(rRequest, rResponse);
+ }
+ else
+ {
+ rResponse.SetResponseCode(HTTPResponse::Code_MethodNotAllowed);
+ }
+ }
+ catch (CommonException &ce)
+ {
+ rResponse.IOStream::Write(ce.what());
+ }
+ catch (std::exception &e)
+ {
+ rResponse.IOStream::Write(e.what());
+ }
+ catch (...)
+ {
+ rResponse.IOStream::Write("Unknown error");
+ }
+
+ return;
+}
+
+void S3Simulator::HandleGet(HTTPRequest &rRequest, HTTPResponse &rResponse)
+{
+ std::string path = "testfiles";
+ path += rRequest.GetRequestURI();
+ std::auto_ptr<FileStream> apFile;
+
+ try
+ {
+ apFile.reset(new FileStream(path));
+ }
+ catch (CommonException &ce)
+ {
+ if (ce.GetSubType() == CommonException::OSFileOpenError)
+ {
+ rResponse.SetResponseCode(HTTPResponse::Code_NotFound);
+ }
+ else if (ce.GetSubType() == CommonException::AccessDenied)
+ {
+ rResponse.SetResponseCode(HTTPResponse::Code_Forbidden);
+ }
+ throw;
+ }
+
+ // http://docs.amazonwebservices.com/AmazonS3/2006-03-01/UsingRESTOperations.html
+ apFile->CopyStreamTo(rResponse);
+ rResponse.AddHeader("x-amz-id-2", "qBmKRcEWBBhH6XAqsKU/eg24V3jf/kWKN9dJip1L/FpbYr9FDy7wWFurfdQOEMcY");
+ rResponse.AddHeader("x-amz-request-id", "F2A8CCCA26B4B26D");
+ rResponse.AddHeader("Date", "Wed, 01 Mar 2006 12:00:00 GMT");
+ rResponse.AddHeader("Last-Modified", "Sun, 1 Jan 2006 12:00:00 GMT");
+ rResponse.AddHeader("ETag", "\"828ef3fdfa96f00ad9f27c383fc9ac7f\"");
+ rResponse.AddHeader("Server", "AmazonS3");
+ rResponse.SetResponseCode(HTTPResponse::Code_OK);
+}
+
+void S3Simulator::HandlePut(HTTPRequest &rRequest, HTTPResponse &rResponse)
+{
+ std::string path = "testfiles";
+ path += rRequest.GetRequestURI();
+ std::auto_ptr<FileStream> apFile;
+
+ try
+ {
+ apFile.reset(new FileStream(path, O_CREAT | O_WRONLY));
+ }
+ catch (CommonException &ce)
+ {
+ if (ce.GetSubType() == CommonException::OSFileOpenError)
+ {
+ rResponse.SetResponseCode(HTTPResponse::Code_NotFound);
+ }
+ else if (ce.GetSubType() == CommonException::AccessDenied)
+ {
+ rResponse.SetResponseCode(HTTPResponse::Code_Forbidden);
+ }
+ throw;
+ }
+
+ if (rRequest.IsExpectingContinue())
+ {
+ rResponse.SendContinue();
+ }
+
+ rRequest.ReadContent(*apFile);
+
+ // http://docs.amazonwebservices.com/AmazonS3/2006-03-01/RESTObjectPUT.html
+ rResponse.AddHeader("x-amz-id-2", "LriYPLdmOdAiIfgSm/F1YsViT1LW94/xUQxMsF7xiEb1a0wiIOIxl+zbwZ163pt7");
+ rResponse.AddHeader("x-amz-request-id", "F2A8CCCA26B4B26D");
+ rResponse.AddHeader("Date", "Wed, 01 Mar 2006 12:00:00 GMT");
+ rResponse.AddHeader("Last-Modified", "Sun, 1 Jan 2006 12:00:00 GMT");
+ rResponse.AddHeader("ETag", "\"828ef3fdfa96f00ad9f27c383fc9ac7f\"");
+ rResponse.SetContentType("");
+ rResponse.AddHeader("Server", "AmazonS3");
+ rResponse.SetResponseCode(HTTPResponse::Code_OK);
+}
+
+int test(int argc, const char *argv[])
+{
+ if(argc >= 2 && ::strcmp(argv[1], "server") == 0)
+ {
+ // Run a server
+ TestWebServer server;
+ return server.Main("doesnotexist", argc - 1, argv + 1);
+ }
+
+ if(argc >= 2 && ::strcmp(argv[1], "s3server") == 0)
+ {
+ // Run a server
+ S3Simulator server;
+ return server.Main("doesnotexist", argc - 1, argv + 1);
+ }
+
+ // Start the server
+ int pid = LaunchServer("./test server testfiles/httpserver.conf", "testfiles/httpserver.pid");
+ TEST_THAT(pid != -1 && pid != 0);
+ if(pid <= 0)
+ {
+ return 0;
+ }
+
+ // Run the request script
+ TEST_THAT(::system("perl testfiles/testrequests.pl") == 0);
+
+ signal(SIGPIPE, SIG_IGN);
+
+ SocketStream sock;
+ sock.Open(Socket::TypeINET, "localhost", 1080);
+
+ for (int i = 0; i < 4; i++)
+ {
+ HTTPRequest request(HTTPRequest::Method_GET,
+ "/test-one/34/341s/234?p1=vOne&p2=vTwo");
+
+ if (i < 2)
+ {
+ // first set of passes has keepalive off by default,
+ // so when i == 1 the socket has already been closed
+ // by the server, and we'll get -EPIPE when we try
+ // to send the request.
+ request.SetClientKeepAliveRequested(false);
+ }
+ else
+ {
+ request.SetClientKeepAliveRequested(true);
+ }
+
+ if (i == 1)
+ {
+ sleep(1); // need time for our process to realise
+ // that the peer has died, otherwise no SIGPIPE :(
+ TEST_CHECK_THROWS(request.Send(sock,
+ IOStream::TimeOutInfinite),
+ ConnectionException, SocketWriteError);
+ sock.Close();
+ sock.Open(Socket::TypeINET, "localhost", 1080);
+ continue;
+ }
+ else
+ {
+ request.Send(sock, IOStream::TimeOutInfinite);
+ }
+
+ HTTPResponse response;
+ response.Receive(sock);
+
+ TEST_THAT(response.GetResponseCode() == HTTPResponse::Code_OK);
+ TEST_THAT(response.GetContentType() == "text/html");
+
+ IOStreamGetLine getline(response);
+ std::string line;
+
+ TEST_THAT(getline.GetLine(line));
+ TEST_EQUAL("<html>", line);
+ TEST_THAT(getline.GetLine(line));
+ TEST_EQUAL("<head><title>TEST SERVER RESPONSE</title></head>",
+ line);
+ TEST_THAT(getline.GetLine(line));
+ TEST_EQUAL("<body><h1>Test response</h1>", line);
+ TEST_THAT(getline.GetLine(line));
+ TEST_EQUAL("<p><b>URI:</b> /test-one/34/341s/234</p>", line);
+ TEST_THAT(getline.GetLine(line));
+ TEST_EQUAL("<p><b>Query string:</b> p1=vOne&p2=vTwo</p>", line);
+ TEST_THAT(getline.GetLine(line));
+ TEST_EQUAL("<p><b>Method:</b> GET </p>", line);
+ TEST_THAT(getline.GetLine(line));
+ TEST_EQUAL("<p><b>Decoded query:</b><br>", line);
+ TEST_THAT(getline.GetLine(line));
+ TEST_EQUAL("PARAM:p1=vOne<br>", line);
+ TEST_THAT(getline.GetLine(line));
+ TEST_EQUAL("PARAM:p2=vTwo<br></p>", line);
+ TEST_THAT(getline.GetLine(line));
+ TEST_EQUAL("<p><b>Content type:</b> </p>", line);
+ TEST_THAT(getline.GetLine(line));
+ TEST_EQUAL("<p><b>Content length:</b> -1</p>", line);
+ TEST_THAT(getline.GetLine(line));
+ TEST_EQUAL("<p><b>Cookies:</b><br>", line);
+ TEST_THAT(getline.GetLine(line));
+ TEST_EQUAL("</p>", line);
+ TEST_THAT(getline.GetLine(line));
+ TEST_EQUAL("</body>", line);
+ TEST_THAT(getline.GetLine(line));
+ TEST_EQUAL("</html>", line);
+ }
+
+ // Kill it
+ TEST_THAT(KillServer(pid));
+ TestRemoteProcessMemLeaks("generic-httpserver.memleaks");
+
+ // correct, official signature should succeed
+ {
+ // http://docs.amazonwebservices.com/AmazonS3/2006-03-01/RESTAuthentication.html
+ HTTPRequest request(HTTPRequest::Method_GET, "/photos/puppy.jpg");
+ request.SetHostName("johnsmith.s3.amazonaws.com");
+ request.AddHeader("Date", "Tue, 27 Mar 2007 19:36:42 +0000");
+ request.AddHeader("Authorization",
+ "AWS 0PN5J17HBGZHT7JJ3X82:xXjDGYUmKxnwqr5KXNPGldn5LbA=");
+
+ S3Simulator simulator;
+
+ CollectInBufferStream response_buffer;
+ HTTPResponse response(&response_buffer);
+
+ simulator.Handle(request, response);
+ TEST_EQUAL(200, response.GetResponseCode());
+
+ std::string response_data((const char *)response.GetBuffer(),
+ response.GetSize());
+ TEST_EQUAL("omgpuppies!\n", response_data);
+ }
+
+ // modified signature should fail
+ {
+ // http://docs.amazonwebservices.com/AmazonS3/2006-03-01/RESTAuthentication.html
+ HTTPRequest request(HTTPRequest::Method_GET, "/photos/puppy.jpg");
+ request.SetHostName("johnsmith.s3.amazonaws.com");
+ request.AddHeader("Date", "Tue, 27 Mar 2007 19:36:42 +0000");
+ request.AddHeader("Authorization",
+ "AWS 0PN5J17HBGZHT7JJ3X82:xXjDGYUmKxnwqr5KXNPGldn5LbB=");
+
+ S3Simulator simulator;
+
+ CollectInBufferStream response_buffer;
+ HTTPResponse response(&response_buffer);
+
+ simulator.Handle(request, response);
+ TEST_EQUAL(401, response.GetResponseCode());
+
+ std::string response_data((const char *)response.GetBuffer(),
+ response.GetSize());
+ TEST_EQUAL("", response_data);
+ }
+
+ // S3Client tests
+ {
+ S3Simulator simulator;
+ S3Client client(&simulator, "johnsmith.s3.amazonaws.com",
+ "0PN5J17HBGZHT7JJ3X82",
+ "uV3F3YluFJax1cknvbcGwgjvx4QpvB+leU8dUj2o");
+
+ HTTPResponse response = client.GetObject("/photos/puppy.jpg");
+ TEST_EQUAL(200, response.GetResponseCode());
+ std::string response_data((const char *)response.GetBuffer(),
+ response.GetSize());
+ TEST_EQUAL("omgpuppies!\n", response_data);
+
+ // make sure that assigning to HTTPResponse does clear stream
+ response = client.GetObject("/photos/puppy.jpg");
+ TEST_EQUAL(200, response.GetResponseCode());
+ response_data = std::string((const char *)response.GetBuffer(),
+ response.GetSize());
+ TEST_EQUAL("omgpuppies!\n", response_data);
+
+ response = client.GetObject("/nonexist");
+ TEST_EQUAL(404, response.GetResponseCode());
+
+ FileStream fs("testfiles/testrequests.pl");
+ response = client.PutObject("/newfile", fs);
+ TEST_EQUAL(200, response.GetResponseCode());
+
+ response = client.GetObject("/newfile");
+ TEST_EQUAL(200, response.GetResponseCode());
+ TEST_THAT(fs.CompareWith(response));
+ TEST_EQUAL(0, ::unlink("testfiles/newfile"));
+ }
+
+ {
+ HTTPRequest request(HTTPRequest::Method_PUT,
+ "/newfile");
+ request.SetHostName("quotes.s3.amazonaws.com");
+ request.AddHeader("Date", "Wed, 01 Mar 2006 12:00:00 GMT");
+ request.AddHeader("Authorization", "AWS 0PN5J17HBGZHT7JJ3X82:XtMYZf0hdOo4TdPYQknZk0Lz7rw=");
+ request.AddHeader("Content-Type", "text/plain");
+
+ FileStream fs("testfiles/testrequests.pl");
+ fs.CopyStreamTo(request);
+ request.SetForReading();
+
+ CollectInBufferStream response_buffer;
+ HTTPResponse response(&response_buffer);
+
+ S3Simulator simulator;
+ simulator.Handle(request, response);
+
+ TEST_EQUAL(200, response.GetResponseCode());
+ TEST_EQUAL("LriYPLdmOdAiIfgSm/F1YsViT1LW94/xUQxMsF7xiEb1a0wiIOIxl+zbwZ163pt7", response.GetHeaderValue("x-amz-id-2"));
+ TEST_EQUAL("F2A8CCCA26B4B26D", response.GetHeaderValue("x-amz-request-id"));
+ TEST_EQUAL("Wed, 01 Mar 2006 12:00:00 GMT", response.GetHeaderValue("Date"));
+ TEST_EQUAL("Sun, 1 Jan 2006 12:00:00 GMT", response.GetHeaderValue("Last-Modified"));
+ TEST_EQUAL("\"828ef3fdfa96f00ad9f27c383fc9ac7f\"", response.GetHeaderValue("ETag"));
+ TEST_EQUAL("", response.GetContentType());
+ TEST_EQUAL("AmazonS3", response.GetHeaderValue("Server"));
+ TEST_EQUAL(0, response.GetSize());
+
+ FileStream f1("testfiles/testrequests.pl");
+ FileStream f2("testfiles/newfile");
+ TEST_THAT(f1.CompareWith(f2));
+ TEST_EQUAL(0, ::unlink("testfiles/newfile"));
+ }
+
+ // Start the S3Simulator server
+ pid = LaunchServer("./test s3server testfiles/httpserver.conf",
+ "testfiles/httpserver.pid");
+ TEST_THAT(pid != -1 && pid != 0);
+ if(pid <= 0)
+ {
+ return 0;
+ }
+
+ sock.Close();
+ sock.Open(Socket::TypeINET, "localhost", 1080);
+
+ {
+ HTTPRequest request(HTTPRequest::Method_GET, "/nonexist");
+ request.SetHostName("quotes.s3.amazonaws.com");
+ request.AddHeader("Date", "Wed, 01 Mar 2006 12:00:00 GMT");
+ request.AddHeader("Authorization", "AWS 0PN5J17HBGZHT7JJ3X82:0cSX/YPdtXua1aFFpYmH1tc0ajA=");
+ request.SetClientKeepAliveRequested(true);
+ request.Send(sock, IOStream::TimeOutInfinite);
+
+ HTTPResponse response;
+ response.Receive(sock);
+ std::string value;
+ TEST_EQUAL(404, response.GetResponseCode());
+ }
+
+ // Make file inaccessible, should cause server to return a 403 error,
+ // unless of course the test is run as root :)
+ {
+ TEST_THAT(chmod("testfiles/testrequests.pl", 0) == 0);
+ HTTPRequest request(HTTPRequest::Method_GET,
+ "/testrequests.pl");
+ request.SetHostName("quotes.s3.amazonaws.com");
+ request.AddHeader("Date", "Wed, 01 Mar 2006 12:00:00 GMT");
+ request.AddHeader("Authorization", "AWS 0PN5J17HBGZHT7JJ3X82:qc1e8u8TVl2BpIxwZwsursIb8U8=");
+ request.SetClientKeepAliveRequested(true);
+ request.Send(sock, IOStream::TimeOutInfinite);
+
+ HTTPResponse response;
+ response.Receive(sock);
+ std::string value;
+ TEST_EQUAL(403, response.GetResponseCode());
+ TEST_THAT(chmod("testfiles/testrequests.pl", 0755) == 0);
+ }
+
+ {
+ HTTPRequest request(HTTPRequest::Method_GET,
+ "/testrequests.pl");
+ request.SetHostName("quotes.s3.amazonaws.com");
+ request.AddHeader("Date", "Wed, 01 Mar 2006 12:00:00 GMT");
+ request.AddHeader("Authorization", "AWS 0PN5J17HBGZHT7JJ3X82:qc1e8u8TVl2BpIxwZwsursIb8U8=");
+ request.SetClientKeepAliveRequested(true);
+ request.Send(sock, IOStream::TimeOutInfinite);
+
+ HTTPResponse response;
+ response.Receive(sock);
+ std::string value;
+ TEST_EQUAL(200, response.GetResponseCode());
+ TEST_EQUAL("qBmKRcEWBBhH6XAqsKU/eg24V3jf/kWKN9dJip1L/FpbYr9FDy7wWFurfdQOEMcY", response.GetHeaderValue("x-amz-id-2"));
+ TEST_EQUAL("F2A8CCCA26B4B26D", response.GetHeaderValue("x-amz-request-id"));
+ TEST_EQUAL("Wed, 01 Mar 2006 12:00:00 GMT", response.GetHeaderValue("Date"));
+ TEST_EQUAL("Sun, 1 Jan 2006 12:00:00 GMT", response.GetHeaderValue("Last-Modified"));
+ TEST_EQUAL("\"828ef3fdfa96f00ad9f27c383fc9ac7f\"", response.GetHeaderValue("ETag"));
+ TEST_EQUAL("text/plain", response.GetContentType());
+ TEST_EQUAL("AmazonS3", response.GetHeaderValue("Server"));
+
+ FileStream file("testfiles/testrequests.pl");
+ TEST_THAT(file.CompareWith(response));
+ }
+
+ {
+ HTTPRequest request(HTTPRequest::Method_PUT,
+ "/newfile");
+ request.SetHostName("quotes.s3.amazonaws.com");
+ request.AddHeader("Date", "Wed, 01 Mar 2006 12:00:00 GMT");
+ request.AddHeader("Authorization", "AWS 0PN5J17HBGZHT7JJ3X82:kfY1m6V3zTufRy2kj92FpQGKz4M=");
+ request.AddHeader("Content-Type", "text/plain");
+ FileStream fs("testfiles/testrequests.pl");
+ HTTPResponse response;
+ request.SendWithStream(sock,
+ IOStream::TimeOutInfinite /* or 10000 milliseconds */,
+ &fs, response);
+ std::string value;
+ TEST_EQUAL(200, response.GetResponseCode());
+ TEST_EQUAL("LriYPLdmOdAiIfgSm/F1YsViT1LW94/xUQxMsF7xiEb1a0wiIOIxl+zbwZ163pt7", response.GetHeaderValue("x-amz-id-2"));
+ TEST_EQUAL("F2A8CCCA26B4B26D", response.GetHeaderValue("x-amz-request-id"));
+ TEST_EQUAL("Wed, 01 Mar 2006 12:00:00 GMT", response.GetHeaderValue("Date"));
+ TEST_EQUAL("Sun, 1 Jan 2006 12:00:00 GMT", response.GetHeaderValue("Last-Modified"));
+ TEST_EQUAL("\"828ef3fdfa96f00ad9f27c383fc9ac7f\"", response.GetHeaderValue("ETag"));
+ TEST_EQUAL("", response.GetContentType());
+ TEST_EQUAL("AmazonS3", response.GetHeaderValue("Server"));
+ TEST_EQUAL(0, response.GetSize());
+
+ FileStream f1("testfiles/testrequests.pl");
+ FileStream f2("testfiles/newfile");
+ TEST_THAT(f1.CompareWith(f2));
+ }
+
+ // Kill it
+ TEST_THAT(KillServer(pid));
+ TestRemoteProcessMemLeaks("generic-httpserver.memleaks");
+
+ return 0;
+}
+
diff --git a/test/raidfile/testraidfile.cpp b/test/raidfile/testraidfile.cpp
index 40703de5..f15fec27 100644
--- a/test/raidfile/testraidfile.cpp
+++ b/test/raidfile/testraidfile.cpp
@@ -622,7 +622,8 @@ int test(int argc, const char *argv[])
TEST_THAT(n2 != n3);
TEST_THAT(n1 != n3);
TEST_THAT(n1 == n4); // ie wraps around
- TRACE3("Gen paths= '%s','%s',%s'\n", n1.c_str(), n2.c_str(), n3.c_str());
+ BOX_TRACE("Gen paths = '" << n1 << "', '" << n2 <<
+ "', '" << n3);
}
// Create a RaidFile