1 # Copyright (c) 2010-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 => 105;
29 use lib '@amperldir@';
31 use Installcheck::Run qw( $diskname $holdingdir );
32 use Installcheck::Dumpcache;
33 use Installcheck::ClientService qw( :constants );
39 use Amanda::Util qw( slurp burp );
41 Amanda::Debug::dbopen("installcheck");
42 Installcheck::log_test_output();
43 my $debug = !exists $ENV{'HARNESS_ACTIVE'};
46 # emulate - inetd or amandad (default)
48 # none: do not send fe_amidxtaped_datapath
49 # amanda: send fe_amidxtaped_datapath and do datapath negotiation, but send AMANDA
50 # directtcp: send fe_amidxtaped_datapath and do datapath negotiation and send both
51 # (expects an answer of AMANDA, too)
52 # header - send HEADER and expect a header
53 # splits - send fe_recover_splits (value is 0, 'basic' (one part; default), or 'parts' (multiple))
54 # digit_end - end command with digits instead of 'END'
55 # dumpspec - include DISK=, HOST=, (but not DATESTAMP=) that match the dump (default 1)
56 # feedme - send a bad device initially, and expect FEEDME response
57 # holding - filename of holding file to recover from
58 # bad_auth - send incorrect auth in OPTIONS (amandad only)
59 # holding_err - 'could not open' error from bogus holding file
60 # holding_no_colon_zero - do not append a :0 to the holding filename in DEVICE=
61 # no_tapespec - do not send a tapespec in LABEL=, and send the first partnum in FSF=
62 # no_fsf - or don't send the first partnum in FSF= and leave amidxtaped to guess
63 # ndmp - using NDMP device (so expect directtcp connection)
64 # bad_cmd - send a bogus command line and expect an error
65 # bad_quoting - send a bogus DISK= without fe_amrecover_correct_disk_quoting
66 # recovery_limit - set a non-matching recovery-limit config
67 # no_peer_name - do not set AMANDA_AUTHENTICATED_PEER
71 my $datasize = -1; # -1 means EOF never arrived
76 my ($data_stream, $cmd_stream);
79 my $disklist_file = "$CONFIG_DIR/TESTCONF/disklist";
87 my $steps = define_steps
88 cb_ref => \$params{'finished_cb'};
90 # walk the service through its paces, using the Expect functionality from
91 # ClientService. This has lots of $params conditionals, so it can be a bit
95 # sort out the parameters
96 $params{'emulate'} ||= 'amandad';
97 $params{'datapath'} ||= 'none';
98 $params{'splits'} = 'basic' unless exists $params{'splits'};
99 $params{'dumpspec'} = 1 unless exists $params{'dumpspec'};
101 # ignore some incompatible combinations
102 return $params{'finished_cb'}->()
103 if ($params{'datapath'} ne 'none' and not $params{'splits'});
104 return $params{'finished_cb'}->()
105 if ($params{'bad_auth'} and $params{'emulate'} ne 'amandad');
106 return $params{'finished_cb'}->()
107 if ($params{'feedme'} and not $params{'splits'});
108 return $params{'finished_cb'}->()
109 if ($params{'feedme'} and $params{'holding'});
110 return $params{'finished_cb'}->()
111 if ($params{'holding_err'} and not $params{'holding'});
112 return $params{'finished_cb'}->()
113 if ($params{'emulate'} eq 'amandad' and not $params{'splits'});
114 return $params{'finished_cb'}->()
115 if ($params{'holding_no_colon_zero'} and not $params{'holding'});
117 $expect_error = ($params{'bad_auth'}
118 or $params{'holding_err'}
119 or $params{'bad_cmd'});
121 if ($params{'ndmp'}) {
122 $chg_name = "ndmp_server"; # changer name from ndmp dumpcache
124 $chg_name = "chg-disk:" . Installcheck::Run::vtape_dir();
128 local $SIG{'ALRM'} = sub {
133 $testmsg = $params{'emulate'} . " ";
134 $testmsg .= $params{'header'}? "header " : "no-header ";
135 $testmsg .= "datapath($params{'datapath'}) ";
136 $testmsg .= $params{'splits'}? "fe-splits($params{splits}) " : "!fe-splits ";
137 $testmsg .= $params{'feedme'}? "feedme " : "!feedme ";
138 $testmsg .= $params{'holding'}? "holding " : "media ";
139 $testmsg .= $params{'dumpspec'}? "dumpspec " : "";
140 $testmsg .= $params{'digit_end'}? "digits " : "";
141 $testmsg .= $params{'bad_auth'}? "bad_auth " : "";
142 $testmsg .= $params{'holding_err'}? "holding_err " : "";
143 $testmsg .= $params{'ndmp'}? "ndmp " : "";
144 $testmsg .= $params{'holding_no_colon_zero'}? "holding-no-:0 " : "";
145 $testmsg .= $params{'no_tapespec'}? "no-tapespec " : "";
146 $testmsg .= $params{'no_fsf'}? "no-fsf " : "";
147 $testmsg .= $params{'bad_cmd'}? "bad_cmd " : "";
148 $testmsg .= $params{'bad_quoting'}? "bad_quoting " : "";
149 $testmsg .= $params{'recovery_limit'}? "recovery_limit " : "";
150 $testmsg .= $params{'no_peer_name'}? "no_peer_name " : "";
152 # "hack" the disklist to check recovery_limit
153 if ($params{'recovery_limit'}) {
154 $old_disklist = slurp($disklist_file);
155 my $new_disklist = "localhost $diskname {\n installcheck-test\n".
156 "recovery-limit \"some-other-host\"\n}\n";
157 burp($disklist_file, $new_disklist);
160 diag("starting $testmsg") if $debug;
162 $service = Installcheck::ClientService->new(
163 emulate => $params{'emulate'},
164 service => 'amidxtaped',
166 ($params{'emulate'} eq 'amandad' && !$params{'no_peer_name'})?
168 process_done => $steps->{'process_done'});
170 $steps->{'start'}->();
174 $cmd_stream = 'main';
175 if ($params{'emulate'} eq 'inetd') {
177 $service->send('main', "SECURITY USER installcheck\r\n");
178 $event->("MAIN-SECURITY");
179 $steps->{'send_cmd1'}->();
182 my $featstr = Amanda::Feature::Set->mine()->as_string();
183 my $auth = $params{'bad_auth'}? 'bogus' : 'bsdtcp';
184 $service->send('main', "OPTIONS features=$featstr;auth=$auth;");
185 $service->close('main', 'w');
186 $event->('SENT-REQ');
187 $steps->{'expect_rep'}->();
191 step expect_rep => sub {
192 my $ctl_hdl = DATA_FD_OFFSET;
193 my $data_hdl = DATA_FD_OFFSET+1;
194 $service->expect('main',
195 [ re => qr/^CONNECT CTL $ctl_hdl DATA $data_hdl\n\n/, $steps->{'got_rep'} ],
196 [ re => qr/^ERROR .*\n/, $steps->{'got_rep_err'} ]);
199 step got_rep => sub {
201 $cmd_stream = 'stream1';
202 $service->expect('main',
203 [ eof => $steps->{'send_cmd1'} ]);
206 step got_rep_err => sub {
207 die "$_[0]" unless $expect_error;
208 $event->('GOT-REP-ERR');
211 step send_cmd1 => sub {
212 # note that the earlier features are ignored..
213 my $sendfeat = Amanda::Feature::Set->mine();
214 if ($params{'datapath'} eq 'none') {
215 $sendfeat->remove($Amanda::Feature::fe_amidxtaped_datapath);
217 if ($params{'bad_quoting'}) {
218 $sendfeat->remove($Amanda::Feature::fe_amrecover_correct_disk_quoting);
220 unless ($params{'splits'}) {
221 $sendfeat->remove($Amanda::Feature::fe_recover_splits);
223 if (!$params{'holding'}) {
224 if ($params{'splits'} eq 'parts') {
226 if ($params{'no_tapespec'}) {
227 $service->send($cmd_stream, "LABEL=TESTCONF01\r\n");
229 $service->send($cmd_stream, "LABEL=TESTCONF01:1,2,3,4,5,6,7,8,9\r\n");
233 $service->send($cmd_stream, "LABEL=TESTCONF01:1\r\n");
236 if (!$params{'no_fsf'}) {
237 if ($params{'no_tapespec'}) {
238 $service->send($cmd_stream, "FSF=1\r\n");
240 $service->send($cmd_stream, "FSF=0\r\n");
243 if ($params{'bad_cmd'}) {
244 $service->send($cmd_stream, "AWESOMENESS=11\r\n");
245 return $steps->{'expect_err_message'}->();
247 $service->send($cmd_stream, "HEADER\r\n") if $params{'header'};
248 $service->send($cmd_stream, "FEATURES=" . $sendfeat->as_string() . "\r\n");
249 $event->("SEND-FEAT");
251 # the feature line looks different depending on what we're emulating
252 if ($params{'emulate'} eq 'inetd') {
253 # note that this has no trailing newline. Rather than rely on the
254 # TCP connection to feed us all the bytes and no more, we just look
255 # for the exact feature sequence we expect.
256 my $mine = Amanda::Feature::Set->mine()->as_string();
257 $service->expect($cmd_stream,
258 [ re => qr/^$mine/, $steps->{'got_feat'} ]);
260 $service->expect($cmd_stream,
261 [ re => qr/^FEATURES=[0-9a-f]+\r\n/, $steps->{'got_feat'} ]);
265 step got_feat => sub {
266 $event->("GOT-FEAT");
268 # continue sending the command
269 if ($params{'holding'}) {
270 my $safe = $params{'holding'};
271 $safe =~ s/([\\:;,])/\\$1/g;
272 $safe .= ':0' unless $params{'holding_no_colon_zero'};
273 $service->send($cmd_stream, "DEVICE=$safe\r\n");
274 } elsif ($params{'feedme'}) {
276 $service->send($cmd_stream, "DEVICE=file:/does/not/exist\r\n");
278 $service->send($cmd_stream, "DEVICE=$chg_name\r\n");
280 if ($params{'dumpspec'}) {
281 $service->send($cmd_stream, "HOST=^localhost\$\r\n");
282 if ($params{'bad_quoting'}) {
283 $service->send($cmd_stream, "DISK=^/foo/bar\$\r\n");
285 $service->send($cmd_stream, "DISK=^$Installcheck::Run::diskname\$\r\n");
287 if ($params{'holding'}) {
288 $service->send($cmd_stream, "DATESTAMP=^20111111090909\$\r\n");
290 my $timestamp = $Installcheck::Dumpcache::timestamps[0];
291 $service->send($cmd_stream, "DATESTAMP=^$timestamp\$\r\n");
294 $service->send($cmd_stream, "CONFIG=TESTCONF\r\n");
295 if ($params{'digit_end'}) {
296 $service->send($cmd_stream, "999\r\n"); # dunno why this works..
298 $service->send($cmd_stream, "END\r\n");
300 $event->("SENT-CMD");
302 $steps->{'expect_connect'}->();
305 step expect_connect => sub {
306 if ($params{'splits'}) {
307 if ($params{'emulate'} eq 'inetd') {
308 $service->expect($cmd_stream,
309 [ re => qr/^CONNECT \d+\n/, $steps->{'got_connect'} ]);
311 $data_stream = 'stream2';
312 $steps->{'expect_feedme'}->();
315 # with no split parts, data comes on the command stream
316 $data_stream = $cmd_stream;
317 $steps->{'expect_feedme'}->();
321 step got_connect => sub {
322 my ($port) = ($_[0] =~ /CONNECT (\d+)/);
323 $event->("GOT-CONNECT");
325 $service->connect('data', $port);
326 $data_stream = 'data';
327 $service->send($data_stream, "SECURITY USER installcheck\r\n");
328 $event->("DATA-SECURITY");
330 $steps->{'expect_feedme'}->();
333 step expect_feedme => sub {
334 Amanda::Debug::debug("HERE");
335 if ($params{'feedme'}) {
336 $service->expect($cmd_stream,
337 [ re => qr/^FEEDME TESTCONF01\r\n/, $steps->{'got_feedme'} ],
338 [ re => qr/^MESSAGE [^\r]*\r\n/, $steps->{'got_message'} ]);
339 } elsif ($params{'holding_err'} || $params{'recovery_limit'}) {
340 $steps->{'expect_err_message'}->();
342 $steps->{'expect_header'}->();
346 step got_message => sub {
347 # this is usually an error message
348 $event->('GOT-MESSAGE');
349 # loop back to expect a feedme..
350 $steps->{'expect_feedme'}->();
353 step got_feedme => sub {
354 $event->('GOT-FEEDME');
355 my $dev_name = "file:" . Installcheck::Run::vtape_dir();
356 $service->send($cmd_stream, "TAPE $dev_name\r\n");
357 $steps->{'expect_header'}->();
360 step expect_header => sub {
361 if ($params{'header'}) {
362 $service->expect($data_stream,
363 [ bytes => 32768, $steps->{'got_header'} ]);
365 $steps->{'expect_datapath'}->();
369 step got_header => sub {
371 $event->("GOT-HEADER");
373 if ($params{'datapath'} ne 'none') {
374 $service->expect($data_stream,
375 [ bytes => 1, $steps->{'got_early_bytes'} ]);
377 $hdr = Amanda::Header->from_string($buf);
378 $steps->{'expect_datapath'}->();
381 step got_early_bytes => sub {
382 $event->("GOT-EARLY-BYTES");
385 step expect_datapath => sub {
386 if ($params{'datapath'} ne 'none') {
387 my $dp = ($params{'datapath'} eq 'amanda')? 'AMANDA' : 'AMANDA DIRECT-TCP';
388 $service->send($cmd_stream, "AVAIL-DATAPATH $dp\r\n");
389 $event->("SENT-DATAPATH");
391 $service->expect($cmd_stream,
392 [ re => qr/^USE-DATAPATH .*\r\n/, $steps->{'got_dp'} ]);
394 $steps->{'expect_data'}->();
399 my ($dp, $addrs) = ($_[0] =~ /USE-DATAPATH (\S+)(.*)\r\n/);
400 $event->("GOT-DP-$dp");
402 # if this is a direct-tcp connection, then we need to connect to
403 # it and expect the data across it
404 if ($dp eq 'DIRECT-TCP') {
405 my ($port) = ($addrs =~ / 127.0.0.1:(\d+).*/);
406 die "invalid DIRECT-TCP reply $addrs" unless ($port);
407 #remove got_early_bytes on $data_stream
408 $service->expect($data_stream,
409 [ eof => $steps->{'do_nothing'} ]);
411 $service->connect('directtcp', $port);
412 $data_stream = 'directtcp';
415 $steps->{'expect_data'}->();
418 step do_nothing => sub {
421 step expect_data => sub {
422 $service->expect($data_stream,
423 [ bytes_to_eof => $steps->{'got_data'} ]);
424 # note that we ignore EOF on the control connection,
425 # as its timing is not very predictable
427 if ($params{'datapath'} ne 'none') {
428 $service->send($cmd_stream, "DATAPATH-OK\r\n");
429 $event->("SENT-DATAPATH-OK");
434 step got_data => sub {
438 $event->("DATA-TO-EOF");
441 # expected errors jump right to this
442 step expect_err_message => sub {
444 $service->expect($cmd_stream,
445 [ re => qr/^MESSAGE.*\r\n/, $steps->{'got_err_message'} ])
448 step got_err_message => sub {
450 if ($line =~ /^MESSAGE invalid command.*/) {
451 $event->("ERR-INVAL-CMD");
452 } elsif ($line =~ /^MESSAGE could not open.*/) {
453 $event->('GOT-HOLDING-ERR');
454 } elsif ($line =~ /^MESSAGE No matching dumps found.*/) {
455 $event->('GOT-NOMATCH');
457 $event->('UNKNOWN-MSG');
460 # process should exit now
463 step process_done => sub {
465 my $exitstatus = POSIX::WIFEXITED($w)? POSIX::WEXITSTATUS($w) : -1;
466 $event->("EXIT-$exitstatus");
467 $steps->{'verify'}->();
471 # reset the alarm - the risk of deadlock has passed
474 # reset the disklist, if necessary
476 burp($disklist_file, $old_disklist);
479 # do a little bit of gymnastics to only treat this as one test
483 if ($ok and !$expect_error and $params{'header'}) {
484 if ($hdr->{'name'} ne 'localhost' or $hdr->{'disk'} ne $diskname) {
486 is_deeply([ $hdr->{'name'}, $hdr->{'disk'} ],
487 [ 'localhost', $diskname ],
488 "$testmsg (header mismatch; header logged to debug log)")
489 or $hdr->debug_dump();
493 if ($ok and !$expect_error) {
494 if ($params{'holding'}) {
495 $ok = 0 if ($datasize != 131072);
496 diag("got $datasize bytes of data but expected exactly 128k from holding file")
499 # get the original size from the header and calculate the size we
500 # read, rounded up to the next kilobyte
501 my $orig_size = $hdr? $hdr->{'orig_size'} : 0;
502 my $got_kb = int($datasize / 1024);
505 my $diff = abs($got_kb - $orig_size);
507 # allow 32k of "slop" here, for rounding, etc.
508 $ok = 0 if $diff > 32;
509 diag("got $got_kb kb; expected about $orig_size kb based on header")
512 $ok = 0 if $got_kb < 64;
513 diag("got $got_kb; expected at least 64k")
524 my $inetd = $params{'emulate'} eq 'inetd';
526 my @sec_evts = $inetd? ('MAIN-SECURITY') : ('SENT-REQ', 'GOT-REP'),
528 if ($params{'datapath'} eq 'amanda') {
529 @datapath_evts = ('SENT-DATAPATH', 'GOT-DP-AMANDA', 'SENT-DATAPATH-OK');
530 } elsif ($params{'datapath'} eq 'directtcp' and not $params{'ndmp'}) {
531 @datapath_evts = ('SENT-DATAPATH', 'GOT-DP-AMANDA', 'SENT-DATAPATH-OK');
532 } elsif ($params{'datapath'} eq 'directtcp' and $params{'ndmp'}) {
533 @datapath_evts = ('SENT-DATAPATH', 'GOT-DP-DIRECT-TCP', 'SENT-DATAPATH-OK');
538 'SEND-FEAT', 'GOT-FEAT', 'SENT-CMD',
539 ($inetd and $params{'splits'})? ('GOT-CONNECT', 'DATA-SECURITY') : (),
540 $params{'feedme'}? ('GOT-MESSAGE', 'GOT-FEEDME') : (),
541 $params{'header'}? ('GOT-HEADER') : (),
543 'DATA-TO-EOF', 'EXIT-0', );
544 # handle a few error conditions differently
545 if ($params{'bad_cmd'}) {
546 @exp_events = ( @sec_evts, 'ERR-INVAL-CMD', 'EXIT-0' );
548 if ($params{'bad_auth'}) {
549 @exp_events = ( 'SENT-REQ', 'GOT-REP-ERR', 'EXIT-1' );
551 if ($params{'holding_err'}) {
554 'SEND-FEAT', 'GOT-FEAT', 'SENT-CMD',
555 ($inetd and $params{'splits'})? ('GOT-CONNECT', 'DATA-SECURITY') : (),
556 'GOT-HOLDING-ERR', 'EXIT-0' );
558 if ($params{'recovery_limit'}) {
561 'SEND-FEAT', 'GOT-FEAT', 'SENT-CMD',
562 'GOT-NOMATCH', 'EXIT-0' );
564 $ok = is_deeply([@events], [@exp_events],
568 diag(Dumper([@events])) if not $ok;
570 $params{'finished_cb'}->();
576 $params{'finished_cb'} = \&Amanda::MainLoop::quit;
577 run_amidxtaped(%params);
578 Amanda::MainLoop::run();
581 sub make_holding_file {
583 my $hdir = "$holdingdir/20111111090909";
584 my $safe_diskname = Amanda::Util::sanitise_filename($diskname);
585 my $filename = "$hdir/localhost.$safe_diskname.3";
587 mkpath($hdir) or die("Could not create $hdir");
588 open(my $fh, ">", $filename) or die "opening '$filename': $!";
592 my $hdr = Amanda::Header->new();
593 $hdr->{'type'} = $Amanda::Header::F_DUMPFILE;
594 $hdr->{'datestamp'} = '20111111090909';
595 $hdr->{'dumplevel'} = 3;
596 $hdr->{'compressed'} = 0;
597 $hdr->{'comp_suffix'} = ".foo";
598 $hdr->{'name'} = 'localhost';
599 $hdr->{'disk'} = "$diskname";
600 $hdr->{'program'} = "INSTALLCHECK";
601 $fh->syswrite($hdr->to_string(32768,32768), 32768);
603 my $bytes_to_write = 131072;
604 my $bufbase = substr((('='x127)."\n".('-'x127)."\n") x 4, 8, -3) . "1K\n";
605 die length($bufbase) unless length($bufbase) == 1024-8;
607 while ($bytes_to_write > 0) {
608 my $buf = sprintf("%08x", $k++).$bufbase;
609 my $written = $fh->syswrite($buf, $bytes_to_write);
610 if (!defined($written)) {
611 die "writing holding file: $!";
613 $bytes_to_write -= $written;
622 Installcheck::Dumpcache::load('basic');
623 my $loaded_dumpcache = 'basic';
627 for my $splits (0, 'basic', 'parts') { # two flavors of 'true'
628 if ($splits and $splits ne $loaded_dumpcache) {
629 Installcheck::Dumpcache::load($splits);
630 $loaded_dumpcache = $splits;
632 for $emulate ('inetd', 'amandad') {
633 # note that 'directtcp' here expects amidxtaped to reply with AMANDA
634 for my $datapath ('none', 'amanda', 'directtcp') {
635 for my $header (0, 1) {
636 for my $feedme (0, 1) {
637 for my $holding (0, 1) {
638 if ($holding and (!$holdingfile or ! -e $holdingfile)) {
639 $holdingfile = make_holding_file();
643 datapath => $datapath,
647 $holding? (holding => $holdingfile):(),
654 # dumps from media can omit the tapespec in the label (amrecover-2.4.5 does
655 # this). We try it with multiple
656 test(emulate => $emulate, splits => $splits, no_tapespec => 1);
658 # and may even omit the FSF! (not sure what does this, but it's testable)
659 test(emulate => $emulate, splits => $splits, no_tapespec => 1, no_fsf => 1);
663 Installcheck::Dumpcache::load("basic");
664 $holdingfile = make_holding_file();
665 $loaded_dumpcache = 'basic';
667 ## miscellaneous edge cases
669 for $emulate ('inetd', 'amandad') {
670 # can send something beginning with a digit instead of "END\r\n"
671 test(emulate => $emulate, digit_end => 1);
673 # missing dumpspec doesn't cause an error
674 test(emulate => $emulate, dumpspec => 0);
676 # missing holding generates error message
677 test(emulate => $emulate,
678 holding => "$Installcheck::TMP/no-such-file", holding_err => 1);
680 # holding can omit the :0 suffix (amrecover-2.4.5 does this)
681 test(emulate => $emulate, holding => $holdingfile,
682 holding_no_colon_zero => 1);
685 # missing peer name is not normally a problem
686 test(emulate => 'amandad', no_peer_name => 1);
688 # if the recovery_limit is given and not matching, we get an error..
689 test(emulate => 'amandad', recovery_limit => 1);
691 # bad authentication triggers an error message
692 test(emulate => 'amandad', bad_auth => 1);
694 # bad quoting should work just fine, with the proper feature missing
695 test(emulate => 'amandad', bad_quoting => 1);
697 # and a bad command triggers an error
698 test(emulate => 'amandad', bad_cmd => 1);
700 ## check decompression
702 Installcheck::Dumpcache::load('compress');
704 test(dumpspec => 0, emulate => 'amandad',
705 datapath => 'none', header => 1,
706 splits => 'basic', feedme => 0, holding => 0);
708 ## directtcp device (NDMP)
711 skip "not built with ndmp and server", 5 unless
712 Amanda::Util::built_with_component("ndmp") and
713 Amanda::Util::built_with_component("server");
715 my $ndmp = Installcheck::Mock::NdmpServer->new();
716 Installcheck::Dumpcache::load('ndmp');
717 $ndmp->edit_config();
719 # test a real directtcp transfer both with and without a header
720 test(emulate => 'amandad', splits => 'basic',
721 datapath => 'directtcp', header => 1, ndmp => $ndmp);
722 test(emulate => 'amandad', splits => 'basic',
723 datapath => 'directtcp', header => 0, ndmp => $ndmp);
725 # and likewise an amanda transfer with a directtcp device
726 test(emulate => 'amandad', splits => 'basic',
727 datapath => 'amanda', header => 1, ndmp => $ndmp);
728 test(emulate => 'amandad', splits => 'basic',
729 datapath => 'amanda', header => 0, ndmp => $ndmp);
731 # and finally a datapath-free transfer with such a device
732 test(emulate => 'amandad', splits => 'basic',
733 datapath => 'none', header => 1, ndmp => $ndmp);
738 unlink($holdingfile);
739 Installcheck::Run::cleanup();