21 my @opt = <<'=back' =~ /B<--(\S+)>/g;
25 Defaults to true. Negate with --nocleanup. If true, all generated
26 files are removed at the end of the test run.
30 Number of files to run through the experiment. Default is 15.
38 Defaults to 0.2. Seconds to sleep between the cration of the initial
43 Defaults to 0.1. Seconds to sleep between the iterations of the second
46 =item B<--iterations=i>
48 Defaults to 30. Number of iterations in the second phase.
54 In the first phase the test creates a couple of files and injects them
55 into the tree, one after the other. There are tunable C<sleep1> pauses
56 between each file creation. In the second phase the test runs
57 alternating C<aggregate> commands on the server and C<rmirror>
58 commands on the client. After each iteration both directories are
59 checksummed and stored in a separate yaml file for later inspection.
61 If you want to inspect the yaml files, be sure to set --nocleanup.
63 =head2 Interpretation of the output
65 Output may look like this:
67 # 17.1575 new state reached in t/serv-5c59696a590715c20f2b7f55c281c667.yaml
68 # 18.0686 new state reached in t/mirr-b9b903e62f31249d2d5836eede1d0420.yaml
69 # 19.2339 new state reached in t/serv-9a9df7f3c8d2fc501c27490696ba1c88.yaml
70 # 33.2662 new state reached in t/serv-7ad22e96a3ecf527e1fa934425ec7516.yaml
71 # 55.2330 new state reached in t/serv-ce628a7ee14eb32054f6744ab9772b2c.yaml
73 This means that the RECENT files on the server have changed 4 times
74 due to calls to C<aggregate> but the RECENT files on the mirror have
81 use lib
"$FindBin::Bin/../lib";
87 use Hash
::Util
qw(lock_keys);
90 lock_keys
%Opt, map { /([^=!]+)/ } @opt;
95 $Opt{cleanup
} = 1 unless defined $Opt{cleanup
};
96 $Opt{sleep1
} = 0.2 unless defined $Opt{sleep1
};
97 $Opt{sleep2
} = 0.1 unless defined $Opt{sleep2
};
98 $Opt{iterations
} = 30 unless defined $Opt{iterations
};
99 $Opt{files
} = 15 unless defined $Opt{files
};
102 use File
::Basename
qw(dirname);
104 use File
::Path
qw(mkpath rmtree);
105 use Time
::HiRes
qw(time sleep);
106 $^T
= time; # force it to float
117 my $root_from = "t/serv";
118 my $root_to = "t/mirr";
119 my $statusfile = "t/recent-rmirror-state.yml";
120 my @unlink = map { "t/$_-ttt.yaml" } qw(serv mirr);
121 rmtree
[$root_from, $root_to];
142 while (@cast > $Opt{files
}) {
147 while (@cast < $Opt{files
}) {
148 push @cast, "leaves ($i)";
156 @intervals = qw( 2s 3s 5s 8s 13s 21s 34s 55s Z );
157 # @intervals = qw( 89s 144s 233s 377s 610s 987s 1597s 2584s 4181s 6765s Z );
158 # @intervals = qw( 2s 5s 13s 34s 89s 233s 610s 1597s 4181s Z );
159 # @intervals = qw( 2s 5s 13s 34s 89s 233s 610s Z );
162 my $rf0 = File
::Rsync
::Mirror
::Recentfile
->new
164 aggregator
=> [@intervals[1..$#intervals]],
165 interval
=> $intervals[0],
166 localroot
=> $root_from,
178 my $rrr = File
::Rsync
::Mirror
::Recent
->new
180 ignore_link_stat_errors
=> 1,
181 localroot
=> $root_to,
182 remote
=> "$root_from/RECENT.recent",
187 # not available in rsync 3.0.3: 'omit-dir-times' => 1,
189 'temp-dir' => "$cwd/t/tmp",
192 my $latest_timestamp = 0;
194 for my $r ($root_from,$root_to) {
196 my $tfile = "$r-ttt.yaml";
197 my $ctx = Digest
::MD5
->new;
204 my $content = do { open my $fh, $File::Find
::name
or die "Could not open '$File::Find::name': $!"; local $/; <$fh>};
205 $y->{substr($File::Find
::name
,1+length($r))} = $content;
212 YAML
::Syck
::DumpFile
$tfile, $y;
213 my @stat = stat $tfile;
214 if ($stat[9] == $latest_timestamp) {
215 # for a better overview over the results, never
216 # let two timestamps be the same
219 $latest_timestamp = $stat[9];
223 open my $fh, $tfile or die $!;
225 my $digest = $ctx->hexdigest;
226 my $pfile = "$r-$digest.yaml";
228 my $t = sprintf "%6.4f", time - $^T
;
229 diag
"$t new state reached in $pfile";
230 rename $tfile, $pfile or die $!;
231 push @unlink, $pfile;
235 my($file, $message) = @_;
236 my $t = sprintf "%6.4f", time - $^T
;
237 mkpath dirname
$file;
238 open my $fh, ">", $file or die "Could not open '$file': $!";
239 print $fh "$message\n";
240 $rf0->update($file,"new");
246 for my $i (0..$#cast) {
247 my $actor = $cast[$i];
248 my $file = sprintf "%s/%02d%s", $root_from, $i, $actor;
249 my $message = "$actor $event";
251 sleep $Opt{"sleep1"};
254 # speeding up the process a little bit:
255 superevent
("sleeping");
256 my $rfs = $rrr->recentfiles;
258 $rf->sleep_per_connection(0);
260 $rrr->_rmirror_sleep_per_connection(0.001);
261 for (my $t=0; $t < $Opt{iterations
}; $t++) {
271 rmtree
[$root_from, $root_to, "t/tmp"];
276 if ($ENV{AUTHOR_TEST
}) {
279 plan
( skip_all
=> "tunable! To run, set env AUTHOR_TEST and tune" );
280 eval "require POSIX; 1" and POSIX
::_exit
(0);
286 use File
::Rsync
::Mirror
::Recent
;
287 use File
::Rsync
::Mirror
::Recentfile
;
291 # cperl-indent-level: 4