autotest: implement much more thorough resumption verification

the test will now make a test run for every journaled step, both right
before and right after the logging.
This commit is contained in:
Oswald Buddenhagen 2017-03-19 11:53:16 +01:00
parent 7ce658d14c
commit efd72b85cc
4 changed files with 56 additions and 10 deletions

View File

@ -81,6 +81,7 @@ typedef unsigned int uint;
#define ZERODELAY 0x2000 #define ZERODELAY 0x2000
extern int DFlags; extern int DFlags;
extern int JLimit;
extern int UseFSync; extern int UseFSync;
extern char FieldDelimiter; extern char FieldDelimiter;

View File

@ -32,6 +32,7 @@
#include <sys/wait.h> #include <sys/wait.h>
int DFlags; int DFlags;
int JLimit;
int UseFSync = 1; int UseFSync = 1;
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) || defined(__CYGWIN__) #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) || defined(__CYGWIN__)
char FieldDelimiter = ';'; char FieldDelimiter = ';';
@ -684,6 +685,7 @@ main( int argc, char **argv )
break; break;
case 'J': case 'J':
DFlags |= KEEPJOURNAL; DFlags |= KEEPJOURNAL;
JLimit = strtol( ochar, &ochar, 10 );
break; break;
case 'Z': case 'Z':
DFlags |= ZERODELAY; DFlags |= ZERODELAY;

View File

@ -641,9 +641,10 @@ sub test($$$@)
return 0 if (scalar(@ARGV) && !grep { $_ eq $ttl } @ARGV); return 0 if (scalar(@ARGV) && !grep { $_ eq $ttl } @ARGV);
print "Testing: ".$ttl." ...\n"; print "Testing: ".$ttl." ...\n";
mkchan($$sx[0], $$sx[1], @{ $$sx[2] });
&writecfg(@sfx); &writecfg(@sfx);
mkchan($$sx[0], $$sx[1], @{ $$sx[2] });
my ($xc, @ret) = runsync("-J", "1-initial.log"); my ($xc, @ret) = runsync("-J", "1-initial.log");
if ($xc || ckchan("slave/.mbsyncstate.new", $tx)) { if ($xc || ckchan("slave/.mbsyncstate.new", $tx)) {
print "Input:\n"; print "Input:\n";
@ -662,42 +663,80 @@ sub test($$$@)
} }
my @nj = readfile("slave/.mbsyncstate.journal"); my @nj = readfile("slave/.mbsyncstate.journal");
($xc, @ret) = runsync("-0 --no-expunge", "2-replay.log"); my ($jxc, @jret) = runsync("-0 --no-expunge", "2-replay.log");
if ($xc || ckstate("slave/.mbsyncstate", @{ $$tx[2] })) { if ($jxc || ckstate("slave/.mbsyncstate", @{ $$tx[2] })) {
print "Journal replay failed.\n"; print "Journal replay failed.\n";
print "Options:\n"; print "Options:\n";
print " [ ".join(", ", map('"'.qm($_).'"', @sfx))." ], [ \"-0\", \"--no-expunge\" ]\n"; print " [ ".join(", ", map('"'.qm($_).'"', @sfx))." ], [ \"-0\", \"--no-expunge\" ]\n";
print "Old State:\n"; print "Old State:\n";
printstate(@{ $$sx[2] }); printstate(@{ $$sx[2] });
print "Journal:\n".join("", @nj)."\n"; print "Journal:\n".join("", @nj)."\n";
if (!$xc) { if (!$jxc) {
print "Expected New State:\n"; print "Expected New State:\n";
printstate(@{ $$tx[2] }); printstate(@{ $$tx[2] });
print "New State:\n"; print "New State:\n";
showstate("slave/.mbsyncstate"); showstate("slave/.mbsyncstate");
} }
print "Debug output:\n"; print "Debug output:\n";
print @ret; print @jret;
exit 1; exit 1;
} }
($xc, @ret) = runsync("", "3-verify.log"); my ($ixc, @iret) = runsync("", "3-verify.log");
if ($xc || ckchan("slave/.mbsyncstate", $tx)) { if ($ixc || ckchan("slave/.mbsyncstate", $tx)) {
print "Idempotence verification run failed.\n"; print "Idempotence verification run failed.\n";
print "Input == Expected result:\n"; print "Input == Expected result:\n";
printchan($tx); printchan($tx);
print "Options:\n"; print "Options:\n";
print " [ ".join(", ", map('"'.qm($_).'"', @sfx))." ]\n"; print " [ ".join(", ", map('"'.qm($_).'"', @sfx))." ]\n";
if (!$xc) { if (!$ixc) {
print "Actual result:\n"; print "Actual result:\n";
showchan("slave/.mbsyncstate"); showchan("slave/.mbsyncstate");
} }
print "Debug output:\n"; print "Debug output:\n";
print @ret; print @iret;
exit 1; exit 1;
} }
killcfg();
rmtree "slave"; rmtree "slave";
rmtree "master"; rmtree "master";
my $njl = (@nj - 1) * 2;
for (my $l = 2; $l < $njl; $l++) {
mkchan($$sx[0], $$sx[1], @{ $$sx[2] });
my ($nxc, @nret) = runsync("-J$l", "4-interrupt.log");
if ($nxc != (100 + ($l & 1)) << 8) {
print "Interrupting at step $l/$njl failed.\n";
print "Debug output:\n";
print @nret;
exit 1;
}
($nxc, @nret) = runsync("-J", "5-resume.log");
if ($nxc || ckchan("slave/.mbsyncstate.new", $tx)) {
print "Resuming from step $l/$njl failed.\n";
print "Input:\n";
printchan($sx);
print "Options:\n";
print " [ ".join(", ", map('"'.qm($_).'"', @sfx))." ]\n";
my @nnj = readfile("slave/.mbsyncstate.journal");
print "Journal:\n".join("", @nnj[0..($l / 2 - 1)])."-------\n".join("", @nnj[($l / 2)..$#nnj])."\n";
print "Full journal:\n".join("", @nj)."\n";
if (!$nxc) {
print "Expected result:\n";
printchan($tx);
print "Actual result:\n";
showchan("slave/.mbsyncstate");
}
print "Debug output:\n";
print @nret;
exit 1;
}
rmtree "slave";
rmtree "master";
}
killcfg();
} }

View File

@ -212,9 +212,13 @@ jFprintf( sync_vars_t *svars, const char *msg, ... )
{ {
va_list va; va_list va;
if (JLimit && !--JLimit)
exit( 101 );
va_start( va, msg ); va_start( va, msg );
vFprintf( svars->jfp, msg, va ); vFprintf( svars->jfp, msg, va );
va_end( va ); va_end( va );
if (JLimit && !--JLimit)
exit( 100 );
} }
static void static void