much improved journal replay testing.

some clenup.
This commit is contained in:
Oswald Buddenhagen 2006-02-02 10:25:07 +00:00
parent d1c4f8a069
commit 5e01034aee

View File

@ -224,11 +224,6 @@ print "OK.\n";
exit 0; exit 0;
sub fcfg(@)
{
return join(" // ", map({ my $t = $_; chomp $t; $t =~ s/\n/ \/ /g; $t; } @_));
}
sub qm($) sub qm($)
{ {
shift; shift;
@ -239,8 +234,8 @@ sub qm($)
return $_; return $_;
} }
# $global, $master, $slave, $channel # $global, $master, $slave
sub runsync($$$) sub writecfg($$$)
{ {
open(FILE, ">", ".mbsyncrc") or open(FILE, ">", ".mbsyncrc") or
die "Cannot open .mbsyncrc.\n"; die "Cannot open .mbsyncrc.\n";
@ -259,36 +254,23 @@ Slave :slave:
SyncState * SyncState *
".shift(); ".shift();
close FILE; close FILE;
open FILE, "../mbsync -D -J -c .mbsyncrc test 2>&1 |";
my @out = <FILE>;
close FILE;
open(FILE, "<", "slave/.mbsyncstate") or
die "Cannot read old sync state.\n";
my @oss = <FILE>;
close FILE;
open(FILE, "<", "slave/.mbsyncstate.journal") or
die "Cannot read journal.\n";
my @nj = <FILE>;
close FILE;
open(FILE, "<", "slave/.mbsyncstate.new") or
die "Cannot read new sync state.\n";
my @nss = <FILE>;
close FILE;
open FILE, "../mbsync -D -c .mbsyncrc --noop test 2>&1 |";
my @jout = <FILE>;
close FILE;
open(FILE, "<", "slave/.mbsyncstate") or
die "Cannot read sync state.\n";
my @jss = <FILE>;
close FILE;
unlink ".mbsyncrc";
if ("@nss" ne "@jss") {
print "Journalling error.\nOld State:\n".join("", @oss)."\nJournal:\n".join("", @nj)."\nNew State:\n".join("", @jss)."\nExpected New State:\n".join("", @nss)."\n";
exit 1;
} }
sub killcfg()
{
unlink ".mbsyncrc";
}
# $options
sub runsync($)
{
open FILE, "../mbsync -D ".shift()." -c .mbsyncrc test 2>&1 |";
my @out = <FILE>;
close FILE or push(@out, $! ? "*** error closing mbsync: $!\n" : "*** mbsync exited with signal ".($?&127).", code ".($?>>8)."\n");
return @out; return @out;
} }
# $path # $path
sub readbox($) sub readbox($)
{ {
@ -351,33 +333,54 @@ sub showbox($)
print " ],\n"; print " ],\n";
} }
# $num # $filename
sub showchan() sub showstate($)
{ {
showbox("master"); my ($fn) = @_;
showbox("slave");
open(FILE, "<", "slave/.mbsyncstate") or if (!open(FILE, "<", $fn)) {
die "Cannot read sync state.\n"; print STDERR " Cannot read sync state $fn: $!\n";
return;
}
$_ = <FILE>; $_ = <FILE>;
/^1:(\d+) 1:(\d+):(\d+)\n$/; if (!defined $_) {
print STDERR " Missing sync state header.\n";
close FILE;
return;
}
if (!/^1:(\d+) 1:(\d+):(\d+)\n$/) {
print STDERR " Malformed sync state header '$_'.\n";
close FILE;
return;
}
print " [ $1, $2, $3,\n "; print " [ $1, $2, $3,\n ";
my $frst = 1; my $frst = 1;
for (<FILE>) { for (<FILE>) {
if (!/^(-?\d+) (-?\d+) (.*)\n$/) {
print STDERR "Malformed sync state entry '$_'.\n";
next;
}
if ($frst) { if ($frst) {
$frst = 0; $frst = 0;
} else { } else {
print ", "; print ", ";
} }
if (!/^(-?\d+) (-?\d+) (.*)\n$/) {
print "??, ??, \"??\"";
} else {
print "$1, $2, \"$3\""; print "$1, $2, \"$3\"";
} }
}
print " ],\n"; print " ],\n";
close FILE; close FILE;
} }
# $filename
sub showchan($)
{
my ($fn) = @_;
showbox("master");
showbox("slave");
showstate($fn);
}
sub show($$@) sub show($$@)
{ {
my ($sx, $tx, @sfx) = @_; my ($sx, $tx, @sfx) = @_;
@ -385,12 +388,14 @@ sub show($$@)
eval "\@sp = \@x$sx"; eval "\@sp = \@x$sx";
mkchan($sp[0], $sp[1], @{ $sp[2] }); mkchan($sp[0], $sp[1], @{ $sp[2] });
print "my \@x$sx = (\n"; print "my \@x$sx = (\n";
showchan(); showchan("slave/.mbsyncstate");
print ");\n"; print ");\n";
&runsync(@sfx); &writecfg(@sfx);
runsync("");
killcfg();
print "my \@X$tx = (\n"; print "my \@X$tx = (\n";
print " [ ".join(", ", map('"'.qm($_).'"', @sfx))." ],\n"; print " [ ".join(", ", map('"'.qm($_).'"', @sfx))." ],\n";
showchan(); showchan("slave/.mbsyncstate");
print ");\n"; print ");\n";
print "test(\\\@x$sx, \\\@X$tx);\n\n"; print "test(\\\@x$sx, \\\@X$tx);\n\n";
rmtree "slave"; rmtree "slave";
@ -471,30 +476,40 @@ sub ckbox($$$@)
return 0; return 0;
} }
# $config, \@master, \@slave, @syncstate # $filename, @syncstate
sub ckchan($$$@) sub ckstate($@)
{ {
my ($cfg, $M, $S, @T) = @_; my ($fn, @T) = @_;
my $rslt = 0; open(FILE, "<", $fn) or die "Cannot read sync state $fn.\n";
open(FILE, "<", "slave/.mbsyncstate") or my $l = <FILE>;
die "Cannot read sync state.\n";
chomp(my $l = <FILE>);
chomp(my @ls = <FILE>); chomp(my @ls = <FILE>);
close FILE; close FILE;
if (!defined $l) {
print STDERR "Sync state header missing.\n";
return 1;
}
chomp($l);
my $xl = "1:".shift(@T)." 1:".shift(@T).":".shift(@T); my $xl = "1:".shift(@T)." 1:".shift(@T).":".shift(@T);
if ($l ne $xl) { if ($l ne $xl) {
print STDERR "Sync state header mismatch: '$l' instead of '$xl'.\n"; print STDERR "Sync state header mismatch: '$l' instead of '$xl'.\n";
$rslt = 1; return 1;
} else { } else {
for $l (@ls) { for $l (@ls) {
$xl = shift(@T)." ".shift(@T)." ".shift(@T); $xl = shift(@T)." ".shift(@T)." ".shift(@T);
if ($l ne $xl) { if ($l ne $xl) {
print STDERR "Sync state entry mismatch: '$l' instead of '$xl'.\n"; print STDERR "Sync state entry mismatch: '$l' instead of '$xl'.\n";
$rslt = 1; return 1;
last;
} }
} }
} }
return 0;
}
# \@master, \@slave, @syncstate
sub ckchan($$@)
{
my ($M, $S, @T) = @_;
my $rslt = ckstate("slave/.mbsyncstate.new", @T);
$rslt |= &ckbox("master", @{ $M }); $rslt |= &ckbox("master", @{ $M });
$rslt |= &ckbox("slave", @{ $S }); $rslt |= &ckbox("slave", @{ $S });
return $rslt; return $rslt;
@ -517,12 +532,11 @@ sub printbox($$@)
print " ],\n"; print " ],\n";
} }
sub printchan($$@) # @syncstate
sub printstate(@)
{ {
my ($m, $s, @t) = @_; my (@t) = @_;
&printbox("master", @{ $m });
&printbox("slave", @{ $s });
print " [ ".shift(@t).", ".shift(@t).", ".shift(@t).",\n "; print " [ ".shift(@t).", ".shift(@t).", ".shift(@t).",\n ";
my $frst = 1; my $frst = 1;
while (@t) { while (@t) {
@ -537,21 +551,52 @@ sub printchan($$@)
close FILE; close FILE;
} }
# \@master, \@slave, @syncstate
sub printchan($$@)
{
my ($m, $s, @t) = @_;
&printbox("master", @{ $m });
&printbox("slave", @{ $s });
printstate(@t);
}
sub test($$) sub test($$)
{ {
my ($sx, $tx) = @_; my ($sx, $tx) = @_;
mkchan($$sx[0], $$sx[1], @{ $$sx[2] }); mkchan($$sx[0], $$sx[1], @{ $$sx[2] });
my @ret = &runsync(@{ $$tx[0] }); &writecfg(@{ $$tx[0] });
if (ckchan(fcfg(@{ $$tx[0] }), $$tx[1], $$tx[2], @{ $$tx[3] })) { my @ret = runsync("-J");
if (ckchan($$tx[1], $$tx[2], @{ $$tx[3] })) {
print "Input:\n"; print "Input:\n";
printchan($$sx[0], $$sx[1], @{ $$sx[2] }); printchan($$sx[0], $$sx[1], @{ $$sx[2] });
print "Options:\n"; print "Options:\n";
print " [ ".join(", ", map('"'.qm($_).'"', @{ $$tx[0] }))." ],\n"; print " [ ".join(", ", map('"'.qm($_).'"', @{ $$tx[0] }))." ]\n";
print "Expected result:\n"; print "Expected result:\n";
printchan($$tx[1], $$tx[2], @{ $$tx[3] }); printchan($$tx[1], $$tx[2], @{ $$tx[3] });
print "Actual result:\n"; print "Actual result:\n";
showchan(); showchan("slave/.mbsyncstate.new");
print "Debug output:\n";
print @ret;
exit 1;
}
open(FILE, "<", "slave/.mbsyncstate.journal") or
die "Cannot read journal.\n";
my @nj = <FILE>;
close FILE;
@ret = runsync("");
killcfg();
if (ckstate("slave/.mbsyncstate", @{ $$tx[3] })) {
print "Options:\n";
print " [ ".join(", ", map('"'.qm($_).'"', @{ $$tx[0] }))." ]\n";
print "Old State:\n";
printstate(@{ $$sx[2] });
print "Journal:\n".join("", @nj)."\n";
print "Expected New State:\n";
printstate(@{ $$tx[3] });
print "New State:\n";
showstate("slave/.mbsyncstate");
print "Debug output:\n"; print "Debug output:\n";
print @ret; print @ret;
exit 1; exit 1;