|
|
|
@ -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 ", "; |
|
|
|
|
} |
|
|
|
|
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 = <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; |
|
|
|
|