From 4da1506efb2607f756ec7487eb05335294c354a3 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 28 Nov 2006 20:30:36 +0000 Subject: Added ability for delay intercepts to fire multiple times. Added test for repeat keepalives to test/bbackupd. --- lib/intercept/intercept.cpp | 29 ++++++++------- test/bbackupd/testbbackupd.cpp | 81 +++++++++++++++++++++++++++++++++++++----- 2 files changed, 89 insertions(+), 21 deletions(-) diff --git a/lib/intercept/intercept.cpp b/lib/intercept/intercept.cpp index 4f8ef785..21220cc9 100644 --- a/lib/intercept/intercept.cpp +++ b/lib/intercept/intercept.cpp @@ -59,7 +59,7 @@ #include "MemLeakFindOn.h" -bool intercept_enabled = false; +int intercept_count = 0; const char *intercept_filename = 0; int intercept_filedes = -1; off_t intercept_errorafter = 0; @@ -72,7 +72,7 @@ int intercept_delay_ms = 0; void intercept_clear_setup() { - intercept_enabled = false; + intercept_count = 0; intercept_filename = 0; intercept_filedes = -1; intercept_errorafter = 0; @@ -83,13 +83,13 @@ void intercept_clear_setup() bool intercept_triggered() { - return !intercept_enabled; + return intercept_count == 0; } void intercept_setup_error(const char *filename, unsigned int errorafter, int errortoreturn, int syscalltoerror) { TRACE4("Setup for error: %s, after %d, err %d, syscall %d\n", filename, errorafter, errortoreturn, syscalltoerror); - intercept_enabled = true; + intercept_count = 1; intercept_filename = filename; intercept_filedes = -1; intercept_errorafter = errorafter; @@ -100,11 +100,12 @@ void intercept_setup_error(const char *filename, unsigned int errorafter, int er } void intercept_setup_delay(const char *filename, unsigned int delay_after, - int delay_ms, int syscall_to_delay) + int delay_ms, int syscall_to_delay, int num_delays) { - TRACE4("Setup for delay: %s, after %d, wait %d ms, syscall %d\n", - filename, delay_after, delay_ms, syscall_to_delay); - intercept_enabled = true; + TRACE5("Setup for delay: %s, after %d, wait %d ms, times %d, " + "syscall %d\n", filename, delay_after, delay_ms, + num_delays, syscall_to_delay); + intercept_count = num_delays; intercept_filename = filename; intercept_filedes = -1; intercept_errorafter = delay_after; @@ -154,7 +155,7 @@ int intercept_reterr() } #define CHECK_FOR_FAKE_ERROR_COND(D, S, CALL, FAILRES) \ - if(intercept_enabled) \ + if(intercept_count > 0) \ { \ if(intercept_errornow(D, S, CALL)) \ { \ @@ -166,7 +167,11 @@ int intercept_reterr() * 1000000; \ while (nanosleep(&tm, &tm) != 0 && \ errno == EINTR) { } \ - intercept_clear_setup(); \ + intercept_count --; \ + if (intercept_count == 0) \ + { \ + intercept_clear_setup(); \ + } \ } \ else \ { \ @@ -179,7 +184,7 @@ int intercept_reterr() extern "C" int open(const char *path, int flags, mode_t mode) { - if(intercept_enabled) + if(intercept_count > 0) { if(intercept_syscall == SYS_open && strcmp(path, intercept_filename) == 0) { @@ -192,7 +197,7 @@ open(const char *path, int flags, mode_t mode) #else int r = syscall(SYS_open, path, flags, mode); #endif - if(intercept_enabled && intercept_filedes == -1) + if(intercept_count > 0 && intercept_filedes == -1) { // Right file? if(strcmp(intercept_filename, path) == 0) diff --git a/test/bbackupd/testbbackupd.cpp b/test/bbackupd/testbbackupd.cpp index 36cf4f77..3190970a 100644 --- a/test/bbackupd/testbbackupd.cpp +++ b/test/bbackupd/testbbackupd.cpp @@ -508,8 +508,9 @@ void do_interrupted_restore(const TLSContext &context, int64_t restoredirid) } } -void intercept_setup_delay(const char *filename, unsigned int delay_after, - int delay_ms, int syscall_to_delay); +void intercept_setup_delay(const char *filename, unsigned int delay_after, + int delay_ms, int syscall_to_delay, int num_delays); + bool intercept_triggered(); int start_internal_daemon() @@ -609,7 +610,7 @@ int test_bbackupd() // something to diff against (empty file doesn't work) int fd = open("testfiles/TestDir1/spacetest/f1", O_WRONLY); TEST_THAT(fd > 0); - char buffer[1024]; + char buffer[10000]; TEST_THAT(write(fd, buffer, sizeof(buffer)) == sizeof(buffer)); TEST_THAT(close(fd) == 0); @@ -618,7 +619,7 @@ int test_bbackupd() stop_internal_daemon(pid); intercept_setup_delay("testfiles/TestDir1/spacetest/f1", - 0, 2000, SYS_read); + 0, 2000, SYS_read, 1); TEST_THAT(unlink("testfiles/bbackupd.log") == 0); pid = start_internal_daemon(); @@ -659,13 +660,13 @@ int test_bbackupd() TEST_THAT(reader.GetLine(line)); TEST_THAT(line == "Receive Success(0xe)"); TEST_THAT(reader.GetLine(line)); - TEST_THAT(line == "Receiving stream, size 60"); + TEST_THAT(line == "Receiving stream, size 124"); TEST_THAT(reader.GetLine(line)); TEST_THAT(line == "Send GetIsAlive()"); TEST_THAT(reader.GetLine(line)); TEST_THAT(line == "Receive IsAlive()"); - TEST_THAT(reader.GetLine(line)); + TEST_THAT(reader.GetLine(line)); std::string comp = "Send StoreFile(0x3,"; TEST_THAT(line.substr(0, comp.size()) == comp); comp = ",0xe,\"f1\")"; @@ -674,7 +675,7 @@ int test_bbackupd() } intercept_setup_delay("testfiles/TestDir1/spacetest/f1", - 0, 4000, SYS_read); + 0, 4000, SYS_read, 1); pid = start_internal_daemon(); fd = open("testfiles/TestDir1/spacetest/f1", O_WRONLY); @@ -710,7 +711,7 @@ int test_bbackupd() TEST_THAT(reader.GetLine(line)); TEST_THAT(line == "Receive Success(0xf)"); TEST_THAT(reader.GetLine(line)); - TEST_THAT(line == "Receiving stream, size 60"); + TEST_THAT(line == "Receiving stream, size 124"); // delaying for 4 seconds in one step means that // the diff timer and the keepalive timer will @@ -724,7 +725,69 @@ int test_bbackupd() TEST_THAT(line.substr(line.size() - comp.size()) == comp); } - + + intercept_setup_delay("testfiles/TestDir1/spacetest/f1", + 0, 1000, SYS_read, 3); + pid = start_internal_daemon(); + + 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_THAT(close(fd) == 0); + + wait_for_backup_operation(); + // can't test whether intercept was triggered, because + // it's in a different process. + // TEST_THAT(intercept_triggered()); + stop_internal_daemon(pid); + + // check that the diff was aborted, i.e. upload was not a diff + found1 = false; + + while (!reader.IsEOF()) + { + std::string line; + TEST_THAT(reader.GetLine(line)); + if (line == "Send GetBlockIndexByName(0x3,\"f1\")") + { + found1 = true; + break; + } + } + + TEST_THAT(found1); + if (found1) + { + std::string line; + TEST_THAT(reader.GetLine(line)); + TEST_THAT(line == "Receive Success(0x10)"); + TEST_THAT(reader.GetLine(line)); + TEST_THAT(line == "Receiving stream, size 124"); + + // delaying for 3 seconds in steps of 1 second + // means that the keepalive timer will expire 3 times, + // and on the 3rd time the diff timer will expire too. + // The diff timer is honoured first, so there will be + // only two keepalives. + + TEST_THAT(reader.GetLine(line)); + TEST_THAT(line == "Send GetIsAlive()"); + TEST_THAT(reader.GetLine(line)); + TEST_THAT(line == "Receive IsAlive()"); + TEST_THAT(reader.GetLine(line)); + TEST_THAT(line == "Send GetIsAlive()"); + TEST_THAT(reader.GetLine(line)); + TEST_THAT(line == "Receive IsAlive()"); + + TEST_THAT(reader.GetLine(line)); + std::string comp = "Send StoreFile(0x3,"; + TEST_THAT(line.substr(0, comp.size()) == comp); + comp = ",0x0,\"f1\")"; + TEST_THAT(line.substr(line.size() - comp.size()) + == comp); + } + // restore timers for rest of tests Timers::Init(); } -- cgit v1.2.3