1 # Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved.
3 # This program is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU General Public License
5 # as published by the Free Software Foundation; either version 2
6 # of the License, or (at your option) any later version.
8 # This program is distributed in the hope that it will be useful, but
9 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10 # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 # You should have received a copy of the GNU General Public License along
14 # with this program; if not, write to the Free Software Foundation, Inc.,
15 # 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 # Contact information: Zmanda Inc, 465 S. Mathilda Ave., Suite 300
18 # Sunnyvale, CA 94086, USA, or: http://www.zmanda.com
20 use Test::More tests => 33;
22 use lib "@amperldir@";
24 use Installcheck::Config;
25 use Installcheck::Run qw(run run_get run_err $diskname);
26 use Installcheck::Dumpcache;
27 use File::Path qw(rmtree mkpath);
36 unless ($Installcheck::Run::have_expect) {
38 skip("Expect.pm not available", Test::More->builder->expected_tests);
45 # Not all features of amfetchdump can be tested without a lot of extra work:
46 # --header-fd: Expect doesn't pass through nonstandard fd's
47 # -p: Expect would have to deal with the dumpfile data, which it won't like
57 my $testdir = "$Installcheck::TMP/amfetchdump-installcheck/files";
64 Amanda::Debug::dbopen("installcheck");
65 Installcheck::log_test_output();
68 for my $filename (<$testdir/*>) {
74 my ($count, $msg) = @_;
77 my @filenames = <localhost.*>;
79 # check for .tmp files and empty files
80 for my $fn (@filenames) {
81 if ($fn =~ /\.tmp$/ || -z "$testdir/$fn") {
86 if (scalar @filenames != $count) {
87 diag("expected $count files");
91 # capture file size if there's only one file
92 if (@filenames == 1) {
93 $last_file_size = -s $filenames[0];
96 ok($ok, $msg) or diag(`ls -l $testdir`);
99 Installcheck::Dumpcache::load("basic");
101 like(run_err('amfetchdump', 'TESTCONF'),
103 "'amfetchdump TESTCONF' gives usage message on stderr");
105 like(run_err('amfetchdump', '-b', '65536', 'TESTCONF', 'localhost'),
106 qr{ERROR: The -b option is no longer},
107 "-b option gives a warning stderr");
114 $exp = Installcheck::Run::run_expect('amfetchdump', 'TESTCONF', 'localhost');
119 [ qr{1 (tape|volume)\(s\) needed for restoration}, sub {
120 push @results, "tape-count";
123 [ qr{The following (tapes|volumes) are needed: TESTCONF01}, sub {
124 push @results, "tapes-needed";
127 [ qr{amfetchdump: 1: restoring split dumpfile: date [[:digit:]]+ host localhost disk .*},
129 push @results, "restoring";
132 [ 'Press enter when ready', sub {
133 push @results, "press-enter";
138 push @results, "eof";
141 is_deeply([ @results ], [ "tape-count", "tapes-needed", "press-enter", "restoring", "eof" ],
142 "simple restore follows the correct steps");
144 got_files(1, "..and restored file is present in testdir");
151 ok(run('amfetchdump', '-a', '-l', 'TESTCONF', 'localhost'),
152 "run with -a and -l successful");
154 got_files(1, "..and restored file is present in testdir ($last_file_size bytes)");
155 my $uncomp_size = $last_file_size;
158 # -C (should make output file smaller)
162 ok(run('amfetchdump', '-a', '-C', 'TESTCONF', 'localhost'),
163 "run with -a and -C successful");
165 got_files(1, "..and restored file is present in testdir");
167 ok($last_file_size < $uncomp_size,
168 "..and is smaller than previous run ($last_file_size bytes)");
174 chdir($Installcheck::TMP);
176 $exp = Installcheck::Run::run_expect('amfetchdump', '-O', $testdir, 'TESTCONF', 'localhost');
181 [ qr{1 (tape|volume)\(s\) needed for restoration}, sub {
182 push @results, "tape-count";
185 [ qr{The following (tapes|volumes) are needed: TESTCONF01}, sub {
186 push @results, "tapes-needed";
189 [ qr{amfetchdump: 1: restoring split dumpfile: date [[:digit:]]+ host localhost disk .*},
191 push @results, "restoring";
194 [ 'Press enter when ready', sub {
195 push @results, "press-enter";
200 push @results, "eof";
203 is_deeply([ @results ], [ "tape-count", "tapes-needed", "press-enter", "restoring", "eof" ],
204 "restore with -O follows the correct steps");
207 got_files(1, "..and restored file is present in testdir");
214 $exp = Installcheck::Run::run_expect('amfetchdump', '-h', 'TESTCONF', 'localhost');
219 [ qr{1 (tape|volume)\(s\) needed for restoration}, sub {
220 push @results, "tape-count";
223 [ qr{The following (tapes|volumes) are needed: TESTCONF01}, sub {
224 push @results, "tapes-needed";
227 [ qr{amfetchdump: 1: restoring split dumpfile: date [[:digit:]]+ host localhost disk .*},
229 push @results, "restoring";
232 [ 'Press enter when ready', sub {
233 push @results, "press-enter";
238 push @results, "eof";
241 is_deeply([ @results ], [ "tape-count", "tapes-needed", "press-enter", "restoring", "eof" ],
242 "restore with -h follows the correct steps");
244 $fok = got_files(1, "..and restored file is present in testdir");
246 # check that it starts with a header
248 my @filenames = <localhost.*>;
249 open(my $fh, "<", $filenames[0]) or die "error opening: $!";
250 sysread($fh, my $hdr_dat, 32768) or die "error reading: $!";
252 my $hdr = Amanda::Header->from_string($hdr_dat);
253 is($hdr->{type}+0, $Amanda::Header::F_SPLIT_DUMPFILE,
254 "..dumpfile begins with a split dumpfile header");
264 $exp = Installcheck::Run::run_expect('amfetchdump', '--header-file', 'hdr',
265 'TESTCONF', 'localhost');
270 [ qr{1 (tape|volume)\(s\) needed for restoration}, sub {
271 push @results, "tape-count";
274 [ qr{The following (tapes|volumes) are needed: TESTCONF01}, sub {
275 push @results, "tapes-needed";
278 [ qr{amfetchdump: 1: restoring split dumpfile: date [[:digit:]]+ host localhost disk .*},
280 push @results, "restoring";
283 [ 'Press enter when ready', sub {
284 push @results, "press-enter";
289 push @results, "eof";
292 is_deeply([ @results ], [ "tape-count", "tapes-needed", "press-enter", "restoring", "eof" ],
293 "restore with --header-file follows the correct steps");
295 $fok = got_files(1, "..and restored file is present in testdir");
297 # check that it starts with a header
299 my @filenames = <localhost.*>;
300 open(my $fh, "<", "$testdir/hdr") or die "error opening: $!";
301 sysread($fh, my $hdr_dat, 32768) or die "error reading: $!";
303 my $hdr = Amanda::Header->from_string($hdr_dat);
304 is($hdr->{type}+0, $Amanda::Header::F_SPLIT_DUMPFILE,
305 "..and the header file contains the right header");
311 # -d and prompting for volumes one at a time
315 my $vfsdev = 'file:' . Installcheck::Run::vtape_dir();
316 Installcheck::Run::load_vtape(3); # wrong vtape
317 $exp = Installcheck::Run::run_expect('amfetchdump', '-d', $vfsdev,
318 'TESTCONF', 'localhost');
323 [ qr{1 (tape|volume)\(s\) needed for restoration}, sub {
324 push @results, "tape-count";
327 [ qr{The following (tapes|volumes) are needed: TESTCONF01}, sub {
328 push @results, "tapes-needed";
331 [ 'Press enter when ready', sub {
332 push @results, "press-enter";
336 [ qr{Insert (tape|volume) labeled '?TESTCONF01'? in .*\n.*to abort}, sub {
337 push @results, "insert-tape";
338 Installcheck::Run::load_vtape(1); # right vtape
342 [ qr{amfetchdump: 1: restoring split dumpfile: date [[:digit:]]+ host localhost disk .*},
344 push @results, "restoring";
348 push @results, "eof";
351 is_deeply([ @results ], [ "tape-count", "tapes-needed", "press-enter",
352 "insert-tape", "restoring", "eof" ],
353 "restore with an explicit device follows the correct steps, prompting for each");
355 got_files(1, "..and restored file is present in testdir");
358 # -n (using a multipart dump)
360 Installcheck::Dumpcache::load("parts");
363 $exp = Installcheck::Run::run_expect('amfetchdump', '-n', 'TESTCONF', 'localhost');
368 [ qr{1 (tape|volume)\(s\) needed for restoration}, sub {
369 push @results, "tape-count";
372 [ qr{The following (tapes|volumes) are needed: TESTCONF01}, sub {
373 push @results, "tapes-needed";
376 [ qr{amfetchdump: (\d+): restoring split dumpfile: date [[:digit:]]+ host localhost disk .*},
378 push @results, "restoring";
381 [ 'Press enter when ready', sub {
382 push @results, "press-enter";
387 push @results, "eof";
390 is_deeply([ @results ], [ "tape-count", "tapes-needed", "press-enter",
391 ("restoring",)x9, "eof" ],
392 "restore with -n follows the correct steps");
394 got_files(9, "..and restored file is present in testdir");
397 # -l, no options, and -c for compressed dumps
399 Installcheck::Dumpcache::load("compress");
402 ok(run('amfetchdump', '-a', 'TESTCONF', 'localhost'),
403 "run with -a successful (should uncompress)");
405 got_files(1, "..and restored file is present in testdir ($last_file_size bytes)");
406 $uncomp_size = $last_file_size;
410 ok(run('amfetchdump', '-a', '-l', 'TESTCONF', 'localhost'),
411 "run with -a and -l successful (should not uncompress)");
413 got_files(1, "..and restored file is present in testdir");
415 ok($last_file_size < $uncomp_size,
416 "..and is smaller than previous run ($last_file_size bytes)");
420 ok(run('amfetchdump', '-a', '-c', 'TESTCONF', 'localhost'),
421 "run with -a and -c successful (should not uncompress)");
423 got_files(1, "..and restored file is present in testdir");
425 ok($last_file_size < $uncomp_size,
426 "..and is smaller than previous run ($last_file_size bytes)");
428 Installcheck::Dumpcache::load("multi");
431 $exp = Installcheck::Run::run_expect('amfetchdump', 'TESTCONF', 'localhost');
436 [ qr{2 (tape|volume)\(s\) needed for restoration}, sub {
437 push @results, "tape-count";
440 [ qr{The following (tapes|volumes) are needed: TESTCONF01 TESTCONF02.*}, sub {
441 push @results, "tapes-needed";
444 [ qr{2 holding file\(s\) needed for restoration}, sub {
445 push @results, "holding-count";
448 [ qr{Reading .*\nFILE: date [[:digit:]]+ host localhost disk .*},
450 push @results, "reading";
453 [ 'Press enter when ready', sub {
454 push @results, "press-enter";
459 push @results, "eof";
462 is_deeply([ @results ], [ "tape-count", "tapes-needed", "holding-count",
463 "press-enter", "reading", "reading", "eof" ],
464 "restore from holding follows the correct steps");
466 got_files(6, "..and all restored files are present in testdir");
470 skip "Expect not installed or not built with ndmp and server", 2 unless
471 Amanda::Util::built_with_component("ndmp") and
472 Amanda::Util::built_with_component("server") and
473 $Installcheck::Run::have_expect;
476 Installcheck::Dumpcache::load("ndmp");
477 my $ndmp = Installcheck::Mock::NdmpServer->new(no_reset => 1);
478 $ndmp->edit_config();
482 $exp = Installcheck::Run::run_expect('amfetchdump', 'TESTCONF', 'localhost');
487 [ qr{1 (tape|volume)\(s\) needed for restoration}, sub {
488 push @results, "tape-count";
491 [ qr{The following (tapes|volumes) are needed: TESTCONF01}, sub {
492 push @results, "tapes-needed";
495 [ qr{amfetchdump: 1: restoring split dumpfile: date [[:digit:]]+ host localhost disk .*},
497 push @results, "restoring";
500 [ 'Press enter when ready', sub {
501 push @results, "press-enter";
506 push @results, "eof";
509 is_deeply([ @results ], [ "tape-count", "tapes-needed", "press-enter", "restoring", "eof" ],
510 "ndmp restore follows the correct steps");
512 got_files(1, "..and restored file is present in testdir");
515 chdir("$testdir/..");