diff --git a/src/run-tests.pl b/src/run-tests.pl index 4e37a3e..ab1958a 100755 --- a/src/run-tests.pl +++ b/src/run-tests.pl @@ -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 = ; - close FILE; - open(FILE, "<", "slave/.mbsyncstate") or - die "Cannot read old sync state.\n"; - my @oss = ; - close FILE; - open(FILE, "<", "slave/.mbsyncstate.journal") or - die "Cannot read journal.\n"; - my @nj = ; - close FILE; - open(FILE, "<", "slave/.mbsyncstate.new") or - die "Cannot read new sync state.\n"; - my @nss = ; - close FILE; - open FILE, "../mbsync -D -c .mbsyncrc --noop test 2>&1 |"; - my @jout = ; - close FILE; - open(FILE, "<", "slave/.mbsyncstate") or - die "Cannot read sync state.\n"; - my @jss = ; - 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 = ; + 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; + } $_ = ; - /^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 () { - if (!/^(-?\d+) (-?\d+) (.*)\n$/) { - print STDERR "Malformed sync state entry '$_'.\n"; - next; - } if ($frst) { $frst = 0; } else { print ", "; } - print "$1, $2, \"$3\""; + 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 = ); + my ($fn, @T) = @_; + open(FILE, "<", $fn) or die "Cannot read sync state $fn.\n"; + my $l = ; chomp(my @ls = ); 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 = ; + 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;