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;
sub fcfg(@)
{
return join(" // ", map({ my $t = $_; chomp $t; $t =~ s/\n/ \/ /g; $t; } @_));
}
sub qm($)
{
shift;
@ -239,8 +234,8 @@ sub qm($)
return $_;
}
# $global, $master, $slave, $channel
sub runsync($$$)
# $global, $master, $slave
sub writecfg($$$)
{
open(FILE, ">", ".mbsyncrc") or
die "Cannot open .mbsyncrc.\n";
@ -259,36 +254,23 @@ Slave :slave:
SyncState *
".shift();
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;
}
sub killcfg()
{
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;
}
}
# $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;
}
# $path
sub readbox($)
{
@ -351,33 +333,54 @@ sub showbox($)
print " ],\n";
}
# $num
sub showchan()
# $filename
sub showstate($)
{
showbox("master");
showbox("slave");
open(FILE, "<", "slave/.mbsyncstate") or
die "Cannot read sync state.\n";
my ($fn) = @_;
if (!open(FILE, "<", $fn)) {
print STDERR " Cannot read sync state $fn: $!\n";
return;
}
$_ = <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 ";
my $frst = 1;
for (<FILE>) {
if (!/^(-?\d+) (-?\d+) (.*)\n$/) {
print STDERR "Malformed sync state entry '$_'.\n";
next;
}
if ($frst) {
$frst = 0;
} else {
print ", ";
}
if (!/^(-?\d+) (-?\d+) (.*)\n$/) {
print "??, ??, \"??\"";
} else {
print "$1, $2, \"$3\"";
}
}
print " ],\n";
close FILE;
}
# $filename
sub showchan($)
{
my ($fn) = @_;
showbox("master");
showbox("slave");
showstate($fn);
}
sub show($$@)
{
my ($sx, $tx, @sfx) = @_;
@ -385,12 +388,14 @@ sub show($$@)
eval "\@sp = \@x$sx";
mkchan($sp[0], $sp[1], @{ $sp[2] });
print "my \@x$sx = (\n";
showchan();
showchan("slave/.mbsyncstate");
print ");\n";
&runsync(@sfx);
&writecfg(@sfx);
runsync("");
killcfg();
print "my \@X$tx = (\n";
print " [ ".join(", ", map('"'.qm($_).'"', @sfx))." ],\n";
showchan();
showchan("slave/.mbsyncstate");
print ");\n";
print "test(\\\@x$sx, \\\@X$tx);\n\n";
rmtree "slave";
@ -471,30 +476,40 @@ sub ckbox($$$@)
return 0;
}
# $config, \@master, \@slave, @syncstate
sub ckchan($$$@)
# $filename, @syncstate
sub ckstate($@)
{
my ($cfg, $M, $S, @T) = @_;
my $rslt = 0;
open(FILE, "<", "slave/.mbsyncstate") or
die "Cannot read sync state.\n";
chomp(my $l = <FILE>);
my ($fn, @T) = @_;
open(FILE, "<", $fn) or die "Cannot read sync state $fn.\n";
my $l = <FILE>;
chomp(my @ls = <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);
if ($l ne $xl) {
print STDERR "Sync state header mismatch: '$l' instead of '$xl'.\n";
$rslt = 1;
return 1;
} else {
for $l (@ls) {
$xl = shift(@T)." ".shift(@T)." ".shift(@T);
if ($l ne $xl) {
print STDERR "Sync state entry mismatch: '$l' instead of '$xl'.\n";
$rslt = 1;
last;
return 1;
}
}
}
return 0;
}
# \@master, \@slave, @syncstate
sub ckchan($$@)
{
my ($M, $S, @T) = @_;
my $rslt = ckstate("slave/.mbsyncstate.new", @T);
$rslt |= &ckbox("master", @{ $M });
$rslt |= &ckbox("slave", @{ $S });
return $rslt;
@ -517,12 +532,11 @@ sub printbox($$@)
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 ";
my $frst = 1;
while (@t) {
@ -537,21 +551,52 @@ sub printchan($$@)
close FILE;
}
# \@master, \@slave, @syncstate
sub printchan($$@)
{
my ($m, $s, @t) = @_;
&printbox("master", @{ $m });
&printbox("slave", @{ $s });
printstate(@t);
}
sub test($$)
{
my ($sx, $tx) = @_;
mkchan($$sx[0], $$sx[1], @{ $$sx[2] });
my @ret = &runsync(@{ $$tx[0] });
if (ckchan(fcfg(@{ $$tx[0] }), $$tx[1], $$tx[2], @{ $$tx[3] })) {
&writecfg(@{ $$tx[0] });
my @ret = runsync("-J");
if (ckchan($$tx[1], $$tx[2], @{ $$tx[3] })) {
print "Input:\n";
printchan($$sx[0], $$sx[1], @{ $$sx[2] });
print "Options:\n";
print " [ ".join(", ", map('"'.qm($_).'"', @{ $$tx[0] }))." ],\n";
print " [ ".join(", ", map('"'.qm($_).'"', @{ $$tx[0] }))." ]\n";
print "Expected result:\n";
printchan($$tx[1], $$tx[2], @{ $$tx[3] });
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 @ret;
exit 1;