1 # Copyright (c) 2009-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 => 277;
24 use lib '@amperldir@';
25 use Installcheck::Run;
26 use Installcheck::Mock;
31 use POSIX ":sys_wait_h";
35 use Amanda::Header qw( :constants );
38 use Amanda::Device qw( :constants );
42 # We run a sequence of fixed interactions with the taper, putting it
43 # through its paces. Each message to or from the taper is represented
44 # as a test, for readability. If the taper produces unexpected results,
45 # the script dies, on the assumption that subsequent tests will be
48 # This uses IPC::Open3 instead of Expect mainly because the interactions
49 # are so carefully scripted that Expect is not required.
51 # put the debug messages somewhere
52 Amanda::Debug::dbopen("installcheck");
53 Installcheck::log_test_output();
55 my $test_filename = "$Installcheck::TMP/installcheck-taper-holding-file";
56 my $taper_stderr_file = "$Installcheck::TMP/taper-stderr";
57 my $debug = !exists $ENV{'HARNESS_ACTIVE'};
59 # information on the current run
60 my ($datestamp, $handle);
61 my ($taper_pid, $taper_in, $taper_out, $last_taper_reply, $taper_reply_timeout);
64 my ($length, $description, %params) = @_;
68 unless ($params{'keep_config'}) {
70 if ($params{'new_vtapes'}) {
71 $testconf = Installcheck::Run::setup(1);
73 $testconf = Installcheck::Run::setup();
75 $testconf->add_param('autolabel', '"TESTCONF%%" empty volume_error');
76 if ($params{'notapedev'}) {
77 $testconf->remove_param('tapedev');
78 $testconf->remove_param('tpchanger');
79 } elsif ($params{'ndmp_server'}) {
80 my $ndmp = $params{'ndmp_server'};
82 $ndmp->config($testconf);
84 unless ($params{'leom'} or $params{'ndmp_server'}) {
85 $testconf->add_param('device_property', '"LEOM" "OFF"');
87 $testconf->add_param('debug_taper', '9'); ## TEMPORARY
88 $testconf->add_tapetype('TEST-TAPE', [
89 'length' => "$length",
91 if ($params{'taperscan'}) {
92 $testconf->add_param('taperscan', "\"$params{'taperscan'}\"");
93 $testconf->add_taperscan($params{'taperscan'}, [
94 'comment' => '"my taperscan is mine, not yours"',
95 'plugin' => "\"$params{'taperscan'}\"",
102 open(TAPER_ERR, ">", $taper_stderr_file);
103 $taper_in = $taper_out = '';
104 $taper_pid = open3($taper_in, $taper_out, ">&TAPER_ERR",
105 "$amlibexecdir/taper", "TESTCONF");
107 $taper_in->blocking(1);
108 $taper_out->autoflush();
110 if ($params{'keep_config'}) {
111 pass("spawned new taper for $description (same config)");
113 pass("spawned taper for $description (tape length $length kb)");
116 # define this to get the installcheck to wait and allow you to attach
117 # a gdb instance to the taper
118 if ($params{'use_gdb'}) {
119 $taper_reply_timeout = 0; # no timeouts while debugging
120 diag("attach debugger to pid $taper_pid and press ENTER");
123 $taper_reply_timeout = 120;
126 taper_cmd("START-TAPER worker0 $datestamp");
131 waitpid($taper_pid, 0);
137 -f $test_filename and unlink($test_filename);
138 -f $taper_stderr_file and unlink($taper_stderr_file);
140 # make a small effort to collect zombies
142 if (waitpid($taper_pid, WNOHANG) == $taper_pid) {
151 diag(">>> $cmd") if $debug;
152 print $taper_in "$cmd\n";
156 local $SIG{ALRM} = sub { die "Timeout while waiting for reply\n" };
157 alarm($taper_reply_timeout);
158 $last_taper_reply = $taper_out->getline();
161 if (!$last_taper_reply) {
162 die("wrong pid") unless ($taper_pid == waitpid($taper_pid, 0));
163 my $exit_status = $?;
165 open(my $fh, "<", $taper_stderr_file) or die("open $taper_stderr_file: $!");
166 my $stderr = do { local $/; <$fh> };
169 diag("taper stderr:\n$stderr") if $stderr;
170 die("taper (pid $taper_pid) died unexpectedly with status $exit_status");
173 # trim trailing whitespace -- C taper outputs an extra ' ' after
174 # single-word replies
175 $last_taper_reply =~ s/\s*$//;
176 diag("<<< $last_taper_reply") if $debug;
178 return $last_taper_reply;
182 my ($expected, $msg) = @_;
186 # must contain a pid line at the beginning and end
187 unshift @$expected, qr/^INFO taper taper pid \d+$/;
188 push @$expected, qr/^INFO taper pid-done \d+$/;
190 open(my $logfile, "<", "$CONFIG_DIR/TESTCONF/log/log")
191 or die("opening log: $!");
192 my @logfile = grep(/^\S+ taper /, <$logfile>);
195 while (@logfile and @$expected) {
196 my $logline = shift @logfile;
197 my $expline = shift @$expected;
199 if ($logline !~ $expline) {
200 like($logline, $expline, $msg);
205 fail("$msg (extra trailing log lines)");
209 fail("$msg (logfile ends early)");
210 diag("first missing line should match ");
211 diag("".$expected->[0]);
219 my $logfile = "$CONFIG_DIR/TESTCONF/log/log";
220 -f $logfile and unlink($logfile);
223 # functions to create dumpfiles
225 sub write_dumpfile_header_to {
226 my ($fh, $size, $hostname, $disk, $is_partial) = @_;
228 my $hdr = Amanda::Header->new();
229 $hdr->{'type'} = $Amanda::Header::F_DUMPFILE;
230 $hdr->{'datestamp'} = $datestamp;
231 $hdr->{'dumplevel'} = 0;
232 $hdr->{'compressed'} = 0;
233 $hdr->{'comp_suffix'} = ".foo";
234 $hdr->{'name'} = $hostname;
235 $hdr->{'disk'} = $disk;
236 $hdr->{'is_partial'} = 1 if defined $is_partial;
237 $hdr->{'program'} = "INSTALLCHECK";
238 $hdr = $hdr->to_string(32768,32768);
240 $fh->syswrite($hdr, 32768);
243 sub write_dumpfile_data_to {
244 my ($fh, $size, $hostname, $disk, $expect_failure) = @_;
246 my $bytes_to_write = $size;
247 my $bufbase = substr((('='x127)."\n".('-'x127)."\n") x 4, 8, -3) . "1K\n";
248 die length($bufbase) unless length($bufbase) == 1024-8;
250 while ($bytes_to_write > 0) {
251 my $buf = sprintf("%08x", $k++).$bufbase;
252 my $written = $fh->syswrite($buf, $bytes_to_write);
253 if (!defined($written)) {
254 die "writing: $!" unless $expect_failure;
257 $bytes_to_write -= $written;
261 # make a new holding-like file in test_filename
262 sub make_holding_file {
263 my ($size, $hostname, $disk, $is_partial) = @_;
264 open(my $fh, ">", $test_filename);
265 write_dumpfile_header_to($fh, $size, $hostname, $disk, $is_partial);
266 write_dumpfile_data_to($fh, $size, $hostname, $disk);
269 # connect to the given port and write a dumpfile; this *will* create
270 # zombies, but it's OK -- installchecks aren't daemons.
272 my ($port_cmd, $size, $hostname, $disk, $expect_error) = @_;
274 my ($header_port, $data_addr) =
275 ($last_taper_reply =~ /^PORT worker0 $handle (\d+) "?(\d+\.\d+\.\d+\.\d+:\d+)/);
277 # just run this in the child
278 return unless fork() == 0;
280 my $sock = IO::Socket::INET->new(
281 PeerAddr => "127.0.0.1:$header_port",
286 write_dumpfile_header_to($sock, $size, $hostname, $disk);
289 $sock = IO::Socket::INET->new(
290 PeerAddr => $data_addr,
295 write_dumpfile_data_to($sock, $size, $hostname, $disk, $expect_error);
302 # A simple, one-part FILE-WRITE
303 $handle = "11-11111";
304 $datestamp = "20070102030405";
305 run_taper(4096, "single-part and multipart FILE-WRITE");
306 like(taper_reply, qr/^TAPER-OK worker0$/,
307 "got TAPER-OK") or die;
308 make_holding_file(1024*1024, "localhost", "/home");
309 taper_cmd("FILE-WRITE worker0 $handle \"$test_filename\" localhost /home 0 $datestamp \"\" \"\" \"\" \"\" \"\" \"\" \"\" \"\" 12");
310 like(taper_reply, qr/^REQUEST-NEW-TAPE $handle$/,
311 "got REQUEST-NEW-TAPE worker0 $handle") or die;
312 taper_cmd("START-SCAN worker0 $handle");
313 taper_cmd("NEW-TAPE worker0 $handle");
314 like(taper_reply, qr/^NEW-TAPE $handle TESTCONF01$/,
315 "got proper NEW-TAPE worker0 $handle") or die;
316 like(taper_reply, qr/^PARTDONE $handle TESTCONF01 1 1024 "\[sec [\d.]+ bytes 1048576 kps [\d.]+ orig-kb 12\]"$/,
317 "got PARTDONE") or die;
318 like(taper_reply, qr/^DONE $handle INPUT-GOOD TAPE-GOOD "\[sec [\d.]+ bytes 1048576 kps [\d.]+ orig-kb 12\]" "" ""$/,
322 # A multipart FILE-WRITE, using the same taper instance
323 # (note that the third part is of length 0, and is not logged)
325 $handle = '11-22222';
326 make_holding_file(1024*1024, "localhost", "/usr");
327 taper_cmd("FILE-WRITE worker0 $handle \"$test_filename\" localhost /usr 0 $datestamp 524288 \"\" \"\" 1 \"\" \"\" \"\" \"\" 512");
328 like(taper_reply, qr/^PARTDONE $handle TESTCONF01 2 512 "\[sec [\d.]+ bytes 524288 kps [\d.]+ orig-kb 512\]"$/,
329 "got PARTDONE for filenum 2") or die;
330 like(taper_reply, qr/^PARTDONE $handle TESTCONF01 3 512 "\[sec [\d.]+ bytes 524288 kps [\d.]+ orig-kb 512\]"$/,
331 "got PARTDONE for filenum 3") or die;
332 like(taper_reply, qr/^DONE $handle INPUT-GOOD TAPE-GOOD "\[sec [\d.]+ bytes 1048576 kps [\d.]+ orig-kb 512\]" "" ""$/,
338 qr(^INFO taper Slot 1 without label can be labeled$),
339 qr(^START taper datestamp $datestamp label TESTCONF01 tape 1$),
340 qr(^PART taper TESTCONF01 1 localhost /home $datestamp 1/-1 0 \[sec [\d.]+ bytes 1048576 kps [\d.]+ orig-kb 12\]$),
341 qr(^DONE taper localhost /home $datestamp 1 0 \[sec [\d.]+ bytes 1048576 kps [\d.]+ orig-kb 12\]$),
342 qr(^PART taper TESTCONF01 2 localhost /usr $datestamp 1/-1 0 \[sec [\d.]+ bytes 524288 kps [\d.]+ orig-kb 512\]$),
343 qr(^PART taper TESTCONF01 3 localhost /usr $datestamp 2/-1 0 \[sec [\d.]+ bytes 524288 kps [\d.]+ orig-kb 512\]$),
344 qr(^DONE taper localhost /usr $datestamp 2 0 \[sec [\d.]+ bytes 1048576 kps [\d.]+ orig-kb 512\]$),
345 qr(^INFO taper tape TESTCONF01 kb 2048 fm 4 \[OK\]$),
346 ], "single-part and multi-part dump logged correctly");
348 # check out the headers on those files, just to be sure
350 my $dev = Amanda::Device->new("file:" . Installcheck::Run::vtape_dir());
351 die("bad device: " . $dev->error_or_status()) unless $dev->status == $DEVICE_STATUS_SUCCESS;
353 $dev->start($ACCESS_READ, undef, undef)
354 or die("can't start device: " . $dev->error_or_status());
357 my ($hdr, $expected, $msg) = @_;
359 for (keys %$expected) { $got->{$_} = "".$hdr->{$_}; }
360 if (!is_deeply($got, $expected, $msg)) {
361 diag("got: " . Dumper($got));
365 is_hdr($dev->seek_file(1), {
366 type => $F_SPLIT_DUMPFILE,
367 datestamp => $datestamp,
370 }, "header on file 1 is correct");
372 is_hdr($dev->seek_file(2), {
373 type => $F_SPLIT_DUMPFILE,
374 datestamp => $datestamp,
379 }, "header on file 2 is correct");
381 is_hdr($dev->seek_file(3), {
382 type => $F_SPLIT_DUMPFILE,
383 datestamp => $datestamp,
388 }, "header on file 3 is correct");
390 is_hdr($dev->seek_file(4), {
391 type => $F_SPLIT_DUMPFILE,
392 datestamp => $datestamp,
397 }, "header on file 4 is correct");
401 # A multipart FILE-WRITE partial dump.
403 $handle = '11-22223';
404 $datestamp = "20070102030406";
405 run_taper(4096, "multipart partial FILE-WRITE");
406 like(taper_reply, qr/^TAPER-OK worker0$/,
407 "got TAPER-OK") or die;
408 make_holding_file(1024*1024, "localhost", "/usr", 1);
409 taper_cmd("FILE-WRITE worker0 $handle \"$test_filename\" localhost /usr 0 $datestamp 524288 \"\" \"\" 1 \"\" \"\" \"\" \"\" 512");
410 like(taper_reply, qr/^REQUEST-NEW-TAPE $handle$/,
411 "got REQUEST-NEW-TAPE worker0 $handle") or die;
412 taper_cmd("START-SCAN worker0 $handle");
413 taper_cmd("NEW-TAPE worker0 $handle");
414 like(taper_reply, qr/^NEW-TAPE $handle TESTCONF01$/,
415 "got proper NEW-TAPE worker0 $handle") or die;
416 like(taper_reply, qr/^PARTDONE $handle TESTCONF01 1 512 "\[sec [\d.]+ bytes 524288 kps [\d.]+ orig-kb 512\]"$/,
417 "got PARTDONE for filenum 1") or die;
418 like(taper_reply, qr/^PARTDONE $handle TESTCONF01 2 512 "\[sec [\d.]+ bytes 524288 kps [\d.]+ orig-kb 512\]"$/,
419 "got PARTDONE for filenum 2") or die;
420 like(taper_reply, qr/^DONE $handle INPUT-GOOD TAPE-GOOD "\[sec [\d.]+ bytes 1048576 kps [\d.]+ orig-kb 512\]" "" ""$/,
426 qr(^INFO taper Slot 1 without label can be labeled$),
427 qr(^START taper datestamp $datestamp label TESTCONF01 tape 1$),
428 qr(^PART taper TESTCONF01 1 localhost /usr $datestamp 1/-1 0 \[sec [\d.]+ bytes 524288 kps [\d.]+ orig-kb 512\]$),
429 qr(^PART taper TESTCONF01 2 localhost /usr $datestamp 2/-1 0 \[sec [\d.]+ bytes 524288 kps [\d.]+ orig-kb 512\]$),
430 qr(^PARTIAL taper localhost /usr $datestamp 2 0 \[sec [\d.]+ bytes 1048576 kps [\d.]+ orig-kb 512\]$),
431 qr(^INFO taper tape TESTCONF01 kb 1024 fm 3 \[OK\]$),
432 ], "multi-part partial dump logged correctly");
435 # A PORT-WRITE with no disk buffer
437 $handle = "11-33333";
438 $datestamp = "19780615010203";
439 run_taper(4096, "multipart PORT-WRITE");
440 like(taper_reply, qr/^TAPER-OK worker0$/,
441 "got TAPER-OK") or die;
442 taper_cmd("PORT-WRITE worker0 $handle localhost /var 0 $datestamp 524288 \"\" 393216 1 0 \"\" \"\" 0 AMANDA");
443 like(taper_reply, qr/^PORT worker0 $handle (\d+) "?(\d+\.\d+\.\d+\.\d+:\d+;?)+"?$/,
444 "got PORT with data address");
445 write_to_port($last_taper_reply, 63*32768, "localhost", "/var", 0);
446 like(taper_reply, qr/^REQUEST-NEW-TAPE $handle$/,
447 "got REQUEST-NEW-TAPE worker0 $handle") or die;
448 taper_cmd("START-SCAN worker0 $handle");
449 taper_cmd("NEW-TAPE worker0 $handle");
450 like(taper_reply, qr/^NEW-TAPE $handle TESTCONF01$/,
451 "got proper NEW-TAPE worker0 $handle") or die;
452 like(taper_reply, qr/^PARTDONE $handle TESTCONF01 1 384 "\[sec [\d.]+ bytes 393216 kps [\d.]+\]"$/,
453 "got PARTDONE for filenum 1") or die;
454 like(taper_reply, qr/^PARTDONE $handle TESTCONF01 2 384 "\[sec [\d.]+ bytes 393216 kps [\d.]+\]"$/,
455 "got PARTDONE for filenum 2") or die;
456 like(taper_reply, qr/^PARTDONE $handle TESTCONF01 3 384 "\[sec [\d.]+ bytes 393216 kps [\d.]+\]"$/,
457 "got PARTDONE for filenum 3") or die;
458 like(taper_reply, qr/^PARTDONE $handle TESTCONF01 4 384 "\[sec [\d.]+ bytes 393216 kps [\d.]+\]"$/,
459 "got PARTDONE for filenum 4") or die;
460 like(taper_reply, qr/^PARTDONE $handle TESTCONF01 5 384 "\[sec [\d.]+ bytes 393216 kps [\d.]+\]"$/,
461 "got PARTDONE for filenum 5") or die;
462 like(taper_reply, qr/^PARTDONE $handle TESTCONF01 6 96 "\[sec [\d.]+ bytes 98304 kps [\d.]+\]"$/,
463 "got PARTDONE for filenum 6") or die;
464 like(taper_reply, qr/^DUMPER-STATUS $handle$/,
465 "got DUMPER-STATUS request") or die;
466 taper_cmd("DONE worker0 $handle 712");
467 like(taper_reply, qr/^DONE $handle INPUT-GOOD TAPE-GOOD "\[sec [\d.]+ bytes 2064384 kps [\d.]+ orig-kb 712\]" "" ""$/,
473 qr(^INFO taper Slot 1 without label can be labeled$),
474 qr(^START taper datestamp $datestamp label TESTCONF01 tape 1$),
475 qr(^PART taper TESTCONF01 1 localhost /var $datestamp 1/-1 0 \[sec [\d.]+ bytes 393216 kps [\d.]+\]$),
476 qr(^PART taper TESTCONF01 2 localhost /var $datestamp 2/-1 0 \[sec [\d.]+ bytes 393216 kps [\d.]+\]$),
477 qr(^PART taper TESTCONF01 3 localhost /var $datestamp 3/-1 0 \[sec [\d.]+ bytes 393216 kps [\d.]+\]$),
478 qr(^PART taper TESTCONF01 4 localhost /var $datestamp 4/-1 0 \[sec [\d.]+ bytes 393216 kps [\d.]+\]$),
479 qr(^PART taper TESTCONF01 5 localhost /var $datestamp 5/-1 0 \[sec [\d.]+ bytes 393216 kps [\d.]+\]$),
480 qr(^PART taper TESTCONF01 6 localhost /var $datestamp 6/-1 0 \[sec [\d.]+ bytes 98304 kps [\d.]+\]$),
481 qr(^DONE taper localhost /var $datestamp 6 0 \[sec [\d.]+ bytes 2064384 kps [\d.]+ orig-kb 712\]$),
482 qr(^INFO taper tape TESTCONF01 kb 2016 fm 6 \[OK\]$),
483 ], "multipart PORT-WRITE logged correctly");
488 $handle = "11-44444";
489 $datestamp = "19411207000000";
490 run_taper(4096, "testing NO-NEW-TAPE from the driver on 1st request");
491 like(taper_reply, qr/^TAPER-OK worker0$/,
492 "got TAPER-OK") or die;
493 make_holding_file(1024*1024, "localhost", "/home");
494 taper_cmd("FILE-WRITE worker0 $handle \"$test_filename\" localhost /home 0 $datestamp 0 \"\" 0 1 0 \"\" \"\" 0 912");
495 like(taper_reply, qr/^REQUEST-NEW-TAPE $handle$/,
496 "got REQUEST-NEW-TAPE worker0 $handle") or die;
497 taper_cmd("NO-NEW-TAPE worker0 $handle sorry");
498 like(taper_reply, qr/^FAILED $handle INPUT-GOOD TAPE-CONFIG "" "?sorry"?.*$/,
499 "got FAILED") or die;
504 qr(^INFO taper Slot 1 without label can be labeled$),
505 qr(^ERROR taper no-tape config \[sorry\]$),
506 qr(^FAIL taper localhost /home $datestamp 0 config sorry$),
507 ], "NO-NEW-TAPE logged correctly");
510 # Test retrying on EOT (via PORT-WRITE with a mem cache)
512 $handle = "11-55555";
513 $datestamp = "19750711095836";
514 run_taper(1024, "PORT-WRITE retry on EOT (mem cache)");
515 like(taper_reply, qr/^TAPER-OK worker0$/,
516 "got TAPER-OK") or die;
517 taper_cmd("PORT-WRITE worker0 $handle localhost /usr/local 0 $datestamp 786432 \"\" 786432 1 0 \"\" \"\" 0 AMANDA");
518 like(taper_reply, qr/^PORT worker0 $handle (\d+) "?(\d+\.\d+\.\d+\.\d+:\d+;?)+"?$/,
519 "got PORT with data address");
520 write_to_port($last_taper_reply, 1575936, "localhost", "/usr/local", 0);
521 like(taper_reply, qr/^REQUEST-NEW-TAPE $handle$/,
522 "got REQUEST-NEW-TAPE worker0 $handle") or die;
523 taper_cmd("START-SCAN worker0 $handle");
524 taper_cmd("NEW-TAPE worker0 $handle");
525 like(taper_reply, qr/^NEW-TAPE $handle TESTCONF01$/,
526 "got proper NEW-TAPE worker0 $handle") or die;
527 like(taper_reply, qr/^PARTDONE $handle TESTCONF01 1 768 "\[sec [\d.]+ bytes 786432 kps [\d.]+\]"$/,
528 "got PARTDONE for filenum 1") or die;
529 like(taper_reply, qr/^REQUEST-NEW-TAPE $handle$/,
530 "got REQUEST-NEW-TAPE worker0 $handle") or die;
531 taper_cmd("START-SCAN worker0 $handle");
532 taper_cmd("NEW-TAPE worker0 $handle");
533 like(taper_reply, qr/^NEW-TAPE $handle TESTCONF02$/,
534 "got proper NEW-TAPE worker0 $handle") or die;
535 like(taper_reply, qr/^PARTDONE $handle TESTCONF02 1 768 "\[sec [\d.]+ bytes 786432 kps [\d.]+\]"$/,
536 "got PARTDONE for filenum 1 on second tape") or die;
537 like(taper_reply, qr/^PARTDONE $handle TESTCONF02 2 3 "\[sec [\d.]+ bytes 3072 kps [\d.]+\]"$/,
538 "got PARTDONE for filenum 2 on second tape") or die;
539 like(taper_reply, qr/^DUMPER-STATUS $handle$/,
540 "got DUMPER-STATUS request") or die;
541 taper_cmd("DONE worker0 $handle 1012");
542 like(taper_reply, qr/^DONE $handle INPUT-GOOD TAPE-GOOD "\[sec [\d.]+ bytes 1575936 kps [\d.]+ orig-kb 1012\]" "" ""$/,
548 qr(^INFO taper Slot 1 without label can be labeled$),
549 qr(^START taper datestamp $datestamp label TESTCONF01 tape 1$),
550 qr(^PART taper TESTCONF01 1 localhost /usr/local $datestamp 1/-1 0 \[sec [\d.]+ bytes 786432 kps [\d.]+\]$),
551 qr(^PARTPARTIAL taper TESTCONF01 2 localhost /usr/local $datestamp 2/-1 0 \[sec [\d.]+ bytes 163840 kps [\d.]+\] "No space left on device"$),
552 qr(^INFO taper Will request retry of failed split part\.$),
553 qr(^INFO taper tape TESTCONF01 kb 768 fm 2 \[OK\]$),
554 qr(^INFO taper Slot 2 without label can be labeled$),
555 qr(^START taper datestamp $datestamp label TESTCONF02 tape 2$),
556 qr(^PART taper TESTCONF02 1 localhost /usr/local $datestamp 2/-1 0 \[sec [\d.]+ bytes 786432 kps [\d.]+\]$),
557 qr(^PART taper TESTCONF02 2 localhost /usr/local $datestamp 3/-1 0 \[sec [\d.]+ bytes 3072 kps [\d.]+\]$),
558 qr(^DONE taper localhost /usr/local $datestamp 3 0 \[sec [\d.]+ bytes 1575936 kps [\d.]+ orig-kb 1012\]$),
559 qr(^INFO taper tape TESTCONF02 kb 771 fm 2 \[OK\]$),
560 ], "multivolume PORT-WRITE logged correctly");
563 # Test retrying on EOT (via FILE-WRITE)
565 $handle = "11-66666";
566 $datestamp = "19470815000000";
567 run_taper(1024, "FILE-WRITE retry on EOT");
568 like(taper_reply, qr/^TAPER-OK worker0$/,
569 "got TAPER-OK") or die;
570 make_holding_file(1575936, "localhost", "/usr");
571 taper_cmd("FILE-WRITE worker0 $handle \"$test_filename\" localhost /usr 0 $datestamp \"\" \"\" \"\" 1 786432 \"\" \"\" \"\" 1112");
572 like(taper_reply, qr/^REQUEST-NEW-TAPE $handle$/,
573 "got REQUEST-NEW-TAPE worker0 $handle") or die;
574 taper_cmd("START-SCAN worker0 $handle");
575 taper_cmd("NEW-TAPE worker0 $handle");
576 like(taper_reply, qr/^NEW-TAPE $handle TESTCONF01$/,
577 "got proper NEW-TAPE worker0 $handle") or die;
578 like(taper_reply, qr/^PARTDONE $handle TESTCONF01 1 768 "\[sec [\d.]+ bytes 786432 kps [\d.]+ orig-kb 1112\]"$/,
579 "got PARTDONE for filenum 1") or die;
580 like(taper_reply, qr/^REQUEST-NEW-TAPE $handle$/,
581 "got REQUEST-NEW-TAPE worker0 $handle") or die;
582 taper_cmd("START-SCAN worker0 $handle");
583 taper_cmd("NEW-TAPE worker0 $handle");
584 like(taper_reply, qr/^NEW-TAPE $handle TESTCONF02$/,
585 "got proper NEW-TAPE worker0 $handle") or die;
586 like(taper_reply, qr/^PARTDONE $handle TESTCONF02 1 768 "\[sec [\d.]+ bytes 786432 kps [\d.]+ orig-kb 1112\]"$/,
587 "got PARTDONE for filenum 1 on second tape") or die;
588 like(taper_reply, qr/^PARTDONE $handle TESTCONF02 2 3 "\[sec [\d.]+ bytes 3072 kps [\d.]+ orig-kb 1112\]"$/,
589 "got PARTDONE for filenum 2 on second tape") or die;
590 like(taper_reply, qr/^DONE $handle INPUT-GOOD TAPE-GOOD "\[sec [\d.]+ bytes 1575936 kps [\d.]+ orig-kb 1112\]" "" ""$/,
596 qr(^INFO taper Slot 1 without label can be labeled$),
597 qr(^START taper datestamp $datestamp label TESTCONF01 tape 1$),
598 qr(^PART taper TESTCONF01 1 localhost /usr $datestamp 1/-1 0 \[sec [\d.]+ bytes 786432 kps [\d.]+ orig-kb 1112\]$),
599 qr(^PARTPARTIAL taper TESTCONF01 2 localhost /usr $datestamp 2/-1 0 \[sec [\d.]+ bytes 163840 kps [\d.]+ orig-kb 1112\] "No space left on device"$),
600 qr(^INFO taper Will request retry of failed split part\.$),
601 qr(^INFO taper tape TESTCONF01 kb 768 fm 2 \[OK\]$),
602 qr(^INFO taper Slot 2 without label can be labeled$),
603 qr(^START taper datestamp $datestamp label TESTCONF02 tape 2$),
604 qr(^PART taper TESTCONF02 1 localhost /usr $datestamp 2/-1 0 \[sec [\d.]+ bytes 786432 kps [\d.]+ orig-kb 1112\]$),
605 qr(^PART taper TESTCONF02 2 localhost /usr $datestamp 3/-1 0 \[sec [\d.]+ bytes 3072 kps [\d.]+ orig-kb 1112\]$),
606 qr(^DONE taper localhost /usr $datestamp 3 0 \[sec [\d.]+ bytes 1575936 kps [\d.]+ orig-kb 1112\]$),
607 qr(^INFO taper tape TESTCONF02 kb 771 fm 2 \[OK\]$),
608 ], "multivolume FILE-WRITE logged correctly");
611 # Test retrying on EOT (via PORT-WRITE with a disk cache)
613 $handle = "11-77777";
614 $datestamp = "20090427212500";
615 run_taper(1024, "PORT-WRITE retry on EOT (disk cache)");
616 like(taper_reply, qr/^TAPER-OK worker0$/,
617 "got TAPER-OK") or die;
618 taper_cmd("PORT-WRITE worker0 $handle localhost /usr/local 0 $datestamp 786432 \"$Installcheck::TMP\" 786432 1 0 \"\" \"\" 0 AMANDA");
619 like(taper_reply, qr/^PORT worker0 $handle (\d+) "?(\d+\.\d+\.\d+\.\d+:\d+;?)+"?$/,
620 "got PORT with data address");
621 write_to_port($last_taper_reply, 1575936, "localhost", "/usr/local", 0);
622 like(taper_reply, qr/^REQUEST-NEW-TAPE $handle$/,
623 "got REQUEST-NEW-TAPE worker0 $handle") or die;
624 taper_cmd("START-SCAN worker0 $handle");
625 taper_cmd("NEW-TAPE worker0 $handle");
626 like(taper_reply, qr/^NEW-TAPE $handle TESTCONF01$/,
627 "got proper NEW-TAPE worker0 $handle") or die;
628 like(taper_reply, qr/^PARTDONE $handle TESTCONF01 1 768 "\[sec [\d.]+ bytes 786432 kps [\d.]+\]"$/,
629 "got PARTDONE for filenum 1") or die;
630 like(taper_reply, qr/^REQUEST-NEW-TAPE $handle$/,
631 "got REQUEST-NEW-TAPE worker0 $handle") or die;
632 taper_cmd("START-SCAN worker0 $handle");
633 taper_cmd("NEW-TAPE worker0 $handle");
634 like(taper_reply, qr/^NEW-TAPE $handle TESTCONF02$/,
635 "got proper NEW-TAPE worker0 $handle") or die;
636 like(taper_reply, qr/^PARTDONE $handle TESTCONF02 1 768 "\[sec [\d.]+ bytes 786432 kps [\d.]+\]"$/,
637 "got PARTDONE for filenum 1 on second tape") or die;
638 like(taper_reply, qr/^PARTDONE $handle TESTCONF02 2 3 "\[sec [\d.]+ bytes 3072 kps [\d.]+\]"$/,
639 "got PARTDONE for filenum 2 on second tape") or die;
640 like(taper_reply, qr/^DUMPER-STATUS $handle$/,
641 "got DUMPER-STATUS request") or die;
642 taper_cmd("DONE worker0 $handle 1212");
643 like(taper_reply, qr/^DONE $handle INPUT-GOOD TAPE-GOOD "\[sec [\d.]+ bytes 1575936 kps [\d.]+ orig-kb 1212\]" "" ""$/,
649 qr(^INFO taper Slot 1 without label can be labeled$),
650 qr(^START taper datestamp $datestamp label TESTCONF01 tape 1$),
651 qr(^PART taper TESTCONF01 1 localhost /usr/local $datestamp 1/-1 0 \[sec [\d.]+ bytes 786432 kps [\d.]+\]$),
652 qr(^PARTPARTIAL taper TESTCONF01 2 localhost /usr/local $datestamp 2/-1 0 \[sec [\d.]+ bytes 163840 kps [\d.]+\] "No space left on device"$),
653 qr(^INFO taper Will request retry of failed split part\.$),
654 qr(^INFO taper tape TESTCONF01 kb 768 fm 2 \[OK\]$),
655 qr(^INFO taper Slot 2 without label can be labeled$),
656 qr(^START taper datestamp $datestamp label TESTCONF02 tape 2$),
657 qr(^PART taper TESTCONF02 1 localhost /usr/local $datestamp 2/-1 0 \[sec [\d.]+ bytes 786432 kps [\d.]+\]$),
658 qr(^PART taper TESTCONF02 2 localhost /usr/local $datestamp 3/-1 0 \[sec [\d.]+ bytes 3072 kps [\d.]+\]$),
659 qr(^DONE taper localhost /usr/local $datestamp 3 0 \[sec [\d.]+ bytes 1575936 kps [\d.]+ orig-kb 1212\]$),
660 qr(^INFO taper tape TESTCONF02 kb 771 fm 2 \[OK\]$),
661 ], "multivolume PORT-WRITE (disk cache) logged correctly");
664 # Test failure on EOT (via PORT-WRITE with no cache), and a new try on the
667 $handle = "11-88888";
668 $datestamp = "20090424173000";
669 run_taper(1024, "PORT-WRITE failure on EOT (no cache)");
670 like(taper_reply, qr/^TAPER-OK worker0$/,
671 "got TAPER-OK") or die;
672 taper_cmd("PORT-WRITE worker0 $handle localhost /var/log 0 $datestamp 0 \"\" 0 0 0 \"\" \"\" 0 AMANDA");
673 like(taper_reply, qr/^PORT worker0 $handle (\d+) "?(\d+\.\d+\.\d+\.\d+:\d+;?)+"?$/,
674 "got PORT with data address");
675 write_to_port($last_taper_reply, 1575936, "localhost", "/var/log", 1);
676 like(taper_reply, qr/^REQUEST-NEW-TAPE $handle$/,
677 "got REQUEST-NEW-TAPE worker0 $handle") or die;
678 taper_cmd("START-SCAN worker0 $handle");
679 taper_cmd("NEW-TAPE worker0 $handle");
680 like(taper_reply, qr/^NEW-TAPE $handle TESTCONF01$/,
681 "got proper NEW-TAPE worker0 $handle") or die;
682 like(taper_reply, qr/^PARTIAL $handle INPUT-GOOD TAPE-ERROR "\[sec [\d.]+ bytes 0 kps [\d.]+\]" "" "No space left on device: more than MAX_VOLUME_USAGE bytes written, splitting not enabled"$/,
683 "got PARTIAL") or die;
684 # retry on the next tape
685 $handle = "11-88899";
686 taper_cmd("PORT-WRITE worker0 $handle localhost /boot 0 $datestamp 0 \"\" 0 0 0 \"\" \"\" 0 AMANDA");
687 like(taper_reply, qr/^PORT worker0 $handle (\d+) "?(\d+\.\d+\.\d+\.\d+:\d+;?)+"?$/,
688 "got PORT with data address");
689 write_to_port($last_taper_reply, 65536, "localhost", "/boot", 0);
690 like(taper_reply, qr/^REQUEST-NEW-TAPE $handle$/,
691 "got REQUEST-NEW-TAPE worker0 $handle") or die;
692 taper_cmd("START-SCAN worker0 $handle");
693 taper_cmd("NEW-TAPE worker0 $handle");
694 like(taper_reply, qr/^NEW-TAPE $handle TESTCONF02$/,
695 "got proper NEW-TAPE worker0 $handle") or die;
696 like(taper_reply, qr/^PARTDONE $handle TESTCONF02 1 64 "\[sec [\d.]+ bytes 65536 kps [\d.]+\]"$/,
697 "got PARTDONE for filenum 1 on second tape") or die;
698 like(taper_reply, qr/^DUMPER-STATUS $handle$/,
699 "got DUMPER-STATUS request") or die;
700 taper_cmd("DONE worker0 $handle 64");
701 like(taper_reply, qr/^DONE $handle INPUT-GOOD TAPE-GOOD "\[sec [\d.]+ bytes 65536 kps [\d.]+ orig-kb 64\]" "" ""$/,
707 qr(^INFO taper Slot 1 without label can be labeled$),
708 qr(^START taper datestamp $datestamp label TESTCONF01 tape 1$),
709 qr(^PARTPARTIAL taper TESTCONF01 1 localhost /var/log $datestamp 1/-1 0 \[sec [\d.]+ bytes 983040 kps [\d.]+\] "No space left on device"$),
710 qr(^PARTIAL taper localhost /var/log $datestamp 1 0 \[sec [\d.]+ bytes 0 kps [\d.]+\] "No space left on device: more than MAX_VOLUME_USAGE bytes written, splitting not enabled"$),
711 qr(^INFO taper tape TESTCONF01 kb 0 fm 1 \[OK\]$),
712 qr(^INFO taper Slot 2 without label can be labeled$),
713 qr(^START taper datestamp $datestamp label TESTCONF02 tape 2$),
714 qr(^PART taper TESTCONF02 1 localhost /boot $datestamp 1/-1 0 \[sec [\d.]+ bytes 65536 kps [\d.]+\]$),
715 qr(^DONE taper localhost /boot $datestamp 1 0 \[sec [\d.]+ bytes 65536 kps [\d.]+ orig-kb 64\]$),
716 qr(^INFO taper tape TESTCONF02 kb 64 fm 1 \[OK\]$),
717 ], "failure on EOT (no cache) with subsequent dump logged correctly");
720 # Test running out of tapes (second REQUEST-NEW-TAPE fails)
722 $handle = "11-99999";
723 $datestamp = "20100101000000";
724 run_taper(512, "FILE-WRITE runs out of tapes");
725 like(taper_reply, qr/^TAPER-OK worker0$/,
726 "got TAPER-OK") or die;
727 make_holding_file(512*1024, "localhost", "/music");
728 taper_cmd("FILE-WRITE worker0 $handle \"$test_filename\" localhost /music 0 $datestamp \"\" \"\" \"\" 1 262144 \"none\" \"\" 10240 1312");
729 like(taper_reply, qr/^REQUEST-NEW-TAPE $handle$/,
730 "got REQUEST-NEW-TAPE worker0 $handle") or die;
731 taper_cmd("START-SCAN worker0 $handle");
732 taper_cmd("NEW-TAPE worker0 $handle");
733 like(taper_reply, qr/^NEW-TAPE $handle TESTCONF01$/,
734 "got proper NEW-TAPE worker0 $handle") or die;
735 like(taper_reply, qr/^PARTDONE $handle TESTCONF01 1 256 "\[sec [\d.]+ bytes 262144 kps [\d.]+ orig-kb 1312\]"$/,
736 "got PARTDONE for filenum 1 on first tape") or die;
737 like(taper_reply, qr/^REQUEST-NEW-TAPE $handle$/,
738 "got REQUEST-NEW-TAPE worker0 $handle") or die;
739 taper_cmd("NO-NEW-TAPE worker0 $handle \"that's enough\"");
740 like(taper_reply, qr/^PARTIAL $handle INPUT-GOOD TAPE-CONFIG "\[sec [\d.]+ bytes 262144 kps [\d.]+ orig-kb 1312\]" "" "that's enough"$/,
741 "got PARTIAL") or die;
746 qr(^INFO taper Slot 1 without label can be labeled$),
747 qr(^START taper datestamp $datestamp label TESTCONF01 tape 1$),
748 qr(^PART taper TESTCONF01 1 localhost /music $datestamp 1/-1 0 \[sec [\d.]+ bytes 262144 kps [\d.]+ orig-kb 1312\]$),
749 qr(^PARTPARTIAL taper TESTCONF01 2 localhost /music $datestamp 2/-1 0 \[sec [\d.]+ bytes 163840 kps [\d.]+ orig-kb 1312\] "No space left on device"$),
750 qr(^INFO taper Will request retry of failed split part\.$),
751 qr(^INFO taper tape TESTCONF01 kb 256 fm 2 \[OK\]$),
752 qr(^ERROR taper no-tape config \[that's enough\]$),
753 qr(^PARTIAL taper localhost /music $datestamp 2 0 \[sec [\d.]+ bytes 262144 kps [\d.]+ orig-kb 1312\] "that's enough"$),
754 ], "running out of tapes (simulating runtapes=1) logged correctly");
757 # A PORT-WRITE with no disk buffer
759 $handle = "22-00000";
760 $datestamp = "20200202222222";
761 run_taper(4096, "multipart PORT-WRITE");
762 like(taper_reply, qr/^TAPER-OK worker0$/,
763 "got TAPER-OK") or die;
764 taper_cmd("PORT-WRITE worker0 $handle localhost /sbin 0 $datestamp 999999 \"\" 655360 1 \"\" \"\" \"\" \"\" AMANDA");
765 like(taper_reply, qr/^PORT worker0 $handle (\d+) "?(\d+\.\d+\.\d+\.\d+:\d+;?)+"?$/,
766 "got PORT with data address");
767 write_to_port($last_taper_reply, 63*32768, "localhost", "/sbin", 0);
768 like(taper_reply, qr/^REQUEST-NEW-TAPE $handle$/,
769 "got REQUEST-NEW-TAPE worker0 $handle") or die;
770 taper_cmd("START-SCAN worker0 $handle");
771 taper_cmd("NEW-TAPE worker0 $handle");
772 like(taper_reply, qr/^NEW-TAPE $handle TESTCONF01$/,
773 "got proper NEW-TAPE worker0 $handle") or die;
774 like(taper_reply, qr/^PARTDONE $handle TESTCONF01 1 640 "\[sec [\d.]+ bytes 655360 kps [\d.]+\]"$/,
775 "got PARTDONE for filenum 1") or die;
776 like(taper_reply, qr/^PARTDONE $handle TESTCONF01 2 640 "\[sec [\d.]+ bytes 655360 kps [\d.]+\]"$/,
777 "got PARTDONE for filenum 2") or die;
778 like(taper_reply, qr/^PARTDONE $handle TESTCONF01 3 640 "\[sec [\d.]+ bytes 655360 kps [\d.]+\]"$/,
779 "got PARTDONE for filenum 3") or die;
780 like(taper_reply, qr/^PARTDONE $handle TESTCONF01 4 96 "\[sec [\d.]+ bytes 98304 kps [\d.]+\]"$/,
781 "got PARTDONE for filenum 4") or die;
782 like(taper_reply, qr/^DUMPER-STATUS $handle$/,
783 "got DUMPER-STATUS request") or die;
784 taper_cmd("FAILED worker0 $handle");
785 like(taper_reply, qr/^DONE $handle INPUT-GOOD TAPE-GOOD "\[sec [\d.]+ bytes 2064384 kps [\d.]+\]" "" ""$/,
791 qr(^INFO taper Slot 1 without label can be labeled$),
792 qr(^START taper datestamp $datestamp label TESTCONF01 tape 1$),
793 qr(^PART taper TESTCONF01 1 localhost /sbin $datestamp 1/-1 0 \[sec [\d.]+ bytes 655360 kps [\d.]+\]$),
794 qr(^PART taper TESTCONF01 2 localhost /sbin $datestamp 2/-1 0 \[sec [\d.]+ bytes 655360 kps [\d.]+\]$),
795 qr(^PART taper TESTCONF01 3 localhost /sbin $datestamp 3/-1 0 \[sec [\d.]+ bytes 655360 kps [\d.]+\]$),
796 qr(^PART taper TESTCONF01 4 localhost /sbin $datestamp 4/-1 0 \[sec [\d.]+ bytes 98304 kps [\d.]+\]$),
797 qr(^PARTIAL taper localhost /sbin $datestamp 4 0 \[sec [\d.]+ bytes 2064384 kps [\d.]+\]$), # note no error message
798 qr(^INFO taper tape TESTCONF01 kb 2016 fm 4 \[OK\]$),
799 ], "DUMPER_STATUS => FAILED logged correctly");
802 # Test a sequence of writes to the same set of tapes
804 $handle = "33-11111";
805 $datestamp = "20090101010000";
806 run_taper(1024, "first in a sequence");
807 like(taper_reply, qr/^TAPER-OK worker0$/,
808 "got TAPER-OK") or die;
809 make_holding_file(500000, "localhost", "/u01");
810 taper_cmd("FILE-WRITE worker0 $handle \"$test_filename\" localhost /u01 0 $datestamp 262144 \"\" \"\" \"\" \"\" \"\" \"\" \"\" 1412");
811 like(taper_reply, qr/^REQUEST-NEW-TAPE $handle$/,
812 "got REQUEST-NEW-TAPE worker0 $handle") or die;
813 taper_cmd("START-SCAN worker0 $handle");
814 taper_cmd("NEW-TAPE worker0 $handle");
815 like(taper_reply, qr/^NEW-TAPE $handle TESTCONF01$/,
816 "got proper NEW-TAPE worker0 $handle") or die;
817 like(taper_reply, qr/^PARTDONE $handle TESTCONF01 1 256 "\[sec [\d.]+ bytes 262144 kps [\d.]+ orig-kb 1412\]"$/,
818 "got PARTDONE for filenum 1") or die;
819 like(taper_reply, qr/^PARTDONE $handle TESTCONF01 2 232 "\[sec [\d.]+ bytes 237856 kps [\d.]+ orig-kb 1412\]"$/,
820 "got PARTDONE for filenum 2") or die;
821 like(taper_reply, qr/^DONE $handle INPUT-GOOD TAPE-GOOD "\[sec [\d.]+ bytes 500000 kps [\d.]+ orig-kb 1412\]" "" ""$/,
823 $handle = "33-22222";
824 make_holding_file(614400, "localhost", "/u02");
825 taper_cmd("FILE-WRITE worker0 $handle \"$test_filename\" localhost /u02 0 $datestamp 262144 \"\" \"\" \"\" \"\" \"\" \"\" \"\" 1512");
826 like(taper_reply, qr/^PARTDONE $handle TESTCONF01 3 256 "\[sec [\d.]+ bytes 262144 kps [\d.]+ orig-kb 1512\]"$/,
827 "got PARTDONE for filenum 3") or die;
828 like(taper_reply, qr/^REQUEST-NEW-TAPE $handle$/,
829 "got REQUEST-NEW-TAPE worker0 $handle") or die;
830 taper_cmd("START-SCAN worker0 $handle");
831 taper_cmd("NEW-TAPE worker0 $handle");
832 like(taper_reply, qr/^NEW-TAPE $handle TESTCONF02$/,
833 "got proper NEW-TAPE worker0 $handle") or die;
834 like(taper_reply, qr/^PARTDONE $handle TESTCONF02 1 256 "\[sec [\d.]+ bytes 262144 kps [\d.]+ orig-kb 1512\]"$/,
835 "got PARTDONE for filenum 1 on second tape") or die;
836 like(taper_reply, qr/^PARTDONE $handle TESTCONF02 2 88 "\[sec [\d.]+ bytes 90112 kps [\d.]+ orig-kb 1512\]"$/,
837 "got PARTDONE for filenum 2 on second tape") or die;
838 like(taper_reply, qr/^DONE $handle INPUT-GOOD TAPE-GOOD "\[sec [\d.]+ bytes 614400 kps [\d.]+ orig-kb 1512\]" "" ""$/,
844 qr(^INFO taper Slot 1 without label can be labeled$),
845 qr(^START taper datestamp $datestamp label TESTCONF01 tape 1$),
846 qr(^PART taper TESTCONF01 1 localhost /u01 $datestamp 1/-1 0 \[sec [\d.]+ bytes 262144 kps [\d.]+ orig-kb 1412\]$),
847 qr(^PART taper TESTCONF01 2 localhost /u01 $datestamp 2/-1 0 \[sec [\d.]+ bytes 237856 kps [\d.]+ orig-kb 1412\]$),
848 qr(^DONE taper localhost /u01 $datestamp 2 0 \[sec [\d.]+ bytes 500000 kps [\d.]+ orig-kb 1412\]$),
849 qr(^PART taper TESTCONF01 3 localhost /u02 $datestamp 1/-1 0 \[sec [\d.]+ bytes 262144 kps [\d.]+ orig-kb 1512\]$),
850 qr(^PARTPARTIAL taper TESTCONF01 4 localhost /u02 $datestamp 2/-1 0 \[sec [\d.]+ bytes 98304 kps [\d.]+ orig-kb 1512\] "No space left on device"$),
851 qr(^INFO taper Will request retry of failed split part\.$),
852 qr(^INFO taper tape TESTCONF01 kb 744 fm 4 \[OK\]$),
853 qr(^INFO taper Slot 2 without label can be labeled$),
854 qr(^START taper datestamp $datestamp label TESTCONF02 tape 2$),
855 qr(^PART taper TESTCONF02 1 localhost /u02 $datestamp 2/-1 0 \[sec [\d.]+ bytes 262144 kps [\d.]+ orig-kb 1512\]$),
856 qr(^PART taper TESTCONF02 2 localhost /u02 $datestamp 3/-1 0 \[sec [\d.]+ bytes 90112 kps [\d.]+ orig-kb 1512\]$),
857 qr(^DONE taper localhost /u02 $datestamp 3 0 \[sec [\d.]+ bytes 614400 kps [\d.]+ orig-kb 1512\]$),
858 qr(^INFO taper tape TESTCONF02 kb 344 fm 2 \[OK\]$),
859 ], "first taper invocation in sequence logged correctly");
862 $handle = "33-33333";
863 $datestamp = "20090202020000";
864 run_taper(1024, "second in a sequence", keep_config => 1);
865 like(taper_reply, qr/^TAPER-OK worker0$/,
866 "got TAPER-OK") or die;
867 make_holding_file(300000, "localhost", "/u01");
868 taper_cmd("FILE-WRITE worker0 $handle \"$test_filename\" localhost /u01 0 $datestamp 262144 \"\" \"\" \"\" \"\" \"\" \"\" \"\" 1612");
869 like(taper_reply, qr/^REQUEST-NEW-TAPE $handle$/,
870 "got REQUEST-NEW-TAPE worker0 $handle") or die;
871 taper_cmd("START-SCAN worker0 $handle");
872 taper_cmd("NEW-TAPE worker0 $handle");
873 like(taper_reply, qr/^NEW-TAPE $handle TESTCONF03$/,
874 "got proper NEW-TAPE worker0 $handle") or die;
875 like(taper_reply, qr/^PARTDONE $handle TESTCONF03 1 256 "\[sec [\d.]+ bytes 262144 kps [\d.]+ orig-kb 1612\]"$/,
876 "got PARTDONE for filenum 1") or die;
877 like(taper_reply, qr/^PARTDONE $handle TESTCONF03 2 36 "\[sec [\d.]+ bytes 37856 kps [\d.]+ orig-kb 1612\]"$/,
878 "got PARTDONE for filenum 2") or die;
879 like(taper_reply, qr/^DONE $handle INPUT-GOOD TAPE-GOOD "\[sec [\d.]+ bytes 300000 kps [\d.]+ orig-kb 1612\]" "" ""$/,
881 $handle = "33-44444";
882 make_holding_file(614400, "localhost", "/u02");
883 taper_cmd("FILE-WRITE worker0 $handle \"$test_filename\" localhost /u02 0 $datestamp 262144 \"\" \"\" \"\" \"\" \"\" \"\" \"\" 1712");
884 like(taper_reply, qr/^PARTDONE $handle TESTCONF03 3 256 "\[sec [\d.]+ bytes 262144 kps [\d.]+ orig-kb 1712\]"$/,
885 "got PARTDONE for filenum 3") or die;
886 like(taper_reply, qr/^PARTDONE $handle TESTCONF03 4 256 "\[sec [\d.]+ bytes 262144 kps [\d.]+ orig-kb 1712\]"$/,
887 "got PARTDONE for filenum 4") or die;
888 like(taper_reply, qr/^REQUEST-NEW-TAPE $handle$/,
889 "got REQUEST-NEW-TAPE worker0 $handle") or die;
890 taper_cmd("START-SCAN worker0 $handle");
891 taper_cmd("NEW-TAPE worker0 $handle");
892 like(taper_reply, qr/^NEW-TAPE $handle TESTCONF01$/,
893 "got proper NEW-TAPE worker0 $handle") or die;
894 like(taper_reply, qr/^PARTDONE $handle TESTCONF01 1 88 "\[sec [\d.]+ bytes 90112 kps [\d.]+ orig-kb 1712\]"$/,
895 "got PARTDONE for filenum 1 on second tape") or die;
896 like(taper_reply, qr/^DONE $handle INPUT-GOOD TAPE-GOOD "\[sec [\d.]+ bytes 614400 kps [\d.]+ orig-kb 1712\]" "" ""$/,
902 qr(^INFO taper Slot 2 with label TESTCONF02 is not reusable$),
903 qr(^INFO taper Slot 3 without label can be labeled$),
904 qr(^START taper datestamp $datestamp label TESTCONF03 tape 1$),
905 qr(^PART taper TESTCONF03 1 localhost /u01 $datestamp 1/-1 0 \[sec [\d.]+ bytes 262144 kps [\d.]+ orig-kb 1612\]$),
906 qr(^PART taper TESTCONF03 2 localhost /u01 $datestamp 2/-1 0 \[sec [\d.]+ bytes 37856 kps [\d.]+ orig-kb 1612\]$),
907 qr(^DONE taper localhost /u01 $datestamp 2 0 \[sec [\d.]+ bytes 300000 kps [\d.]+ orig-kb 1612\]$),
908 qr(^PART taper TESTCONF03 3 localhost /u02 $datestamp 1/-1 0 \[sec [\d.]+ bytes 262144 kps [\d.]+ orig-kb 1712\]$),
909 qr(^PART taper TESTCONF03 4 localhost /u02 $datestamp 2/-1 0 \[sec [\d.]+ bytes 262144 kps [\d.]+ orig-kb 1712\]$),
910 qr(^PARTPARTIAL taper TESTCONF03 5 localhost /u02 $datestamp 3/-1 0 \[sec [\d.]+ bytes 0 kps [\d.]+ orig-kb 1712\] "No space left on device"$),
911 qr(^INFO taper Will request retry of failed split part\.$),
912 qr(^INFO taper tape TESTCONF03 kb 804 fm 5 \[OK\]$),
913 qr(^INFO taper Slot 1 with label TESTCONF01 is usable$),
914 qr(^START taper datestamp $datestamp label TESTCONF01 tape 2$),
915 qr(^PART taper TESTCONF01 1 localhost /u02 $datestamp 3/-1 0 \[sec [\d.]+ bytes 90112 kps [\d.]+ orig-kb 1712\]$),
916 qr(^DONE taper localhost /u02 $datestamp 3 0 \[sec [\d.]+ bytes 614400 kps [\d.]+ orig-kb 1712\]$),
917 qr(^INFO taper tape TESTCONF01 kb 88 fm 1 \[OK\]$),
918 ], "second taper invocation in sequence logged correctly");
922 # test failure to overwrite a tape label
924 $handle = "33-55555";
925 $datestamp = "20090303030000";
926 run_taper(1024, "failure to overwrite a volume", keep_config => 1);
927 like(taper_reply, qr/^TAPER-OK worker0$/,
928 "got TAPER-OK") or die;
929 make_holding_file(32768, "localhost", "/u03");
930 taper_cmd("FILE-WRITE worker0 $handle \"$test_filename\" localhost /u03 0 $datestamp 262144 \"\" \"\" \"\" \"\" \"\" \"\" \"\" 1812");
931 like(taper_reply, qr/^REQUEST-NEW-TAPE $handle$/,
932 "got REQUEST-NEW-TAPE worker0 $handle") or die;
933 # we've secretly replaced the tape in slot 1 with a read-only tape.. let's see
934 # if anyone can tell the difference!
935 chmod(0555, Installcheck::Run::vtape_dir(2));
936 taper_cmd("START-SCAN worker0 $handle");
937 taper_cmd("NEW-TAPE worker0 $handle");
938 # NO-NEW-TAPE indicates it did *not* overwrite the tape
939 like(taper_reply, qr/^NO-NEW-TAPE $handle$/,
940 "got proper NO-NEW-TAPE worker0 $handle"); # no "die" here, so we can restore perms
941 chmod(0755, Installcheck::Run::vtape_dir(2));
942 like(taper_reply, qr/^REQUEST-NEW-TAPE $handle$/,
943 "got REQUEST-NEW-TAPE worker0 $handle") or die;
944 taper_cmd("NO-NEW-TAPE worker0 $handle \"sorry\"");
945 like(taper_reply, qr/^FAILED $handle INPUT-GOOD TAPE-CONFIG "" "?sorry"?.*$/,
946 "got FAILED") or die;
950 # (logs aren't that interesting here - filled with VFS-specific error messages)
952 # TODO: simulate an "erased" tape, to which taper should reply with "NEW-TAPE worker0 $handle" and
953 # immediately REQUEST-NEW-TAPE. I can't see a way to make the VFS device erase a
954 # volume without start_device succeeding.
957 # A run with a bogus tapedev/tpchanger
958 $handle = "44-11111";
959 $datestamp = "20070102030405";
960 run_taper(4096, "no tapedev", notapedev => 1);
961 like(taper_reply, qr/^TAPE-ERROR SETUP "You must specify one of 'tapedev' or 'tpchanger'"$/,
962 "got TAPE-ERROR") or die;
966 # A run with 2 workers
967 my $handle0 = "66-00000";
968 my $handle1 = "66-11111";
969 $datestamp = "20090202020000";
970 run_taper(1024, "with 2 workers", new_vtapes => 1);
971 like(taper_reply, qr/^TAPER-OK worker0$/,
972 "got TAPER-OK") or die;
973 taper_cmd("START-TAPER worker1 $datestamp");
974 like(taper_reply, qr/^TAPER-OK worker1$/,
975 "got TAPER-OK") or die;
976 make_holding_file(300000, "localhost", "/u01");
977 taper_cmd("FILE-WRITE worker0 $handle0 \"$test_filename\" localhost /u01 0 $datestamp 262144 \"\" \"\" \"\" \"\" \"\" \"\" \"\" 1612");
978 like(taper_reply, qr/^REQUEST-NEW-TAPE $handle0$/,
979 "got REQUEST-NEW-TAPE worker0 $handle0") or die;
980 taper_cmd("START-SCAN worker0 $handle0");
981 taper_cmd("NEW-TAPE worker0 $handle0");
982 like(taper_reply, qr/^NEW-TAPE $handle0 TESTCONF01$/,
983 "got proper NEW-TAPE worker0 $handle0") or die;
984 like(taper_reply, qr/^PARTDONE $handle0 TESTCONF01 1 256 "\[sec [\d.]+ bytes 262144 kps [\d.]+ orig-kb 1612\]"$/,
985 "got PARTDONE for filenum 1") or die;
986 like(taper_reply, qr/^PARTDONE $handle0 TESTCONF01 2 36 "\[sec [\d.]+ bytes 37856 kps [\d.]+ orig-kb 1612\]"$/,
987 "got PARTDONE for filenum 2") or die;
988 like(taper_reply, qr/^DONE $handle0 INPUT-GOOD TAPE-GOOD "\[sec [\d.]+ bytes 300000 kps [\d.]+ orig-kb 1612\]" "" ""$/,
990 make_holding_file(614400, "localhost", "/u02");
991 taper_cmd("FILE-WRITE worker1 $handle1 \"$test_filename\" localhost /u02 0 $datestamp 262144 \"\" \"\" \"\" \"\" \"\" \"\" \"\" 1712");
992 like(taper_reply, qr/^REQUEST-NEW-TAPE $handle1$/,
993 "got REQUEST-NEW-TAPE worker1 $handle1") or die;
994 taper_cmd("START-SCAN worker1 $handle1");
995 taper_cmd("NEW-TAPE worker1 $handle1");
996 like(taper_reply, qr/^NEW-TAPE $handle1 TESTCONF02$/,
997 "got proper NEW-TAPE worker1 $handle1") or die;
998 like(taper_reply, qr/^PARTDONE $handle1 TESTCONF02 1 256 "\[sec [\d.]+ bytes 262144 kps [\d.]+ orig-kb 1712\]"$/,
999 "got PARTDONE for filenum 1 on second tape") or die;
1000 like(taper_reply, qr/^PARTDONE $handle1 TESTCONF02 2 256 "\[sec [\d.]+ bytes 262144 kps [\d.]+ orig-kb 1712\]"$/,
1001 "got PARTDONE for filenum 2 on second tape") or die;
1002 like(taper_reply, qr/^PARTDONE $handle1 TESTCONF02 3 88 "\[sec [\d.]+ bytes 90112 kps [\d.]+ orig-kb 1712\]"$/,
1003 "got PARTDONE for filenum 3 on second tape") or die;
1004 like(taper_reply, qr/^DONE $handle1 INPUT-GOOD TAPE-GOOD "\[sec [\d.]+ bytes 614400 kps [\d.]+ orig-kb 1712\]" "" ""$/,
1010 qr(^INFO taper Slot 1 without label can be labeled$),
1011 qr(^INFO taper Slot 2 without label can be labeled$),
1012 qr(^START taper datestamp $datestamp label TESTCONF01 tape 1$),
1013 qr(^PART taper TESTCONF01 1 localhost /u01 $datestamp 1/-1 0 \[sec [\d.]+ bytes 262144 kps [\d.]+ orig-kb 1612\]$),
1014 qr(^PART taper TESTCONF01 2 localhost /u01 $datestamp 2/-1 0 \[sec [\d.]+ bytes 37856 kps [\d.]+ orig-kb 1612\]$),
1015 qr(^DONE taper localhost /u01 $datestamp 2 0 \[sec [\d.]+ bytes 300000 kps [\d.]+ orig-kb 1612\]$),
1016 qr(^START taper datestamp $datestamp label TESTCONF02 tape 2$),
1017 qr(^PART taper TESTCONF02 1 localhost /u02 $datestamp 1/-1 0 \[sec [\d.]+ bytes 262144 kps [\d.]+ orig-kb 1712\]$),
1018 qr(^PART taper TESTCONF02 2 localhost /u02 $datestamp 2/-1 0 \[sec [\d.]+ bytes 262144 kps [\d.]+ orig-kb 1712\]$),
1019 qr(^PART taper TESTCONF02 3 localhost /u02 $datestamp 3/-1 0 \[sec [\d.]+ bytes 90112 kps [\d.]+ orig-kb 1712\]$),
1020 qr(^DONE taper localhost /u02 $datestamp 3 0 \[sec [\d.]+ bytes 614400 kps [\d.]+ orig-kb 1712\]$),
1021 qr(^INFO taper tape TESTCONF01 kb 292 fm 2 \[OK\]$),
1022 qr(^INFO taper tape TESTCONF02 kb 600 fm 3 \[OK\]$),
1023 ], "two workers logged correctly");
1027 # A run with 2 workers and a take_scribe
1028 $handle = "66-22222";
1029 $datestamp = "20090202020000";
1030 run_taper(1024, "with 2 workers and a take_scribe", new_vtapes => 1);
1031 like(taper_reply, qr/^TAPER-OK worker0$/,
1032 "got TAPER-OK") or die;
1033 taper_cmd("START-TAPER worker1 $datestamp");
1034 like(taper_reply, qr/^TAPER-OK worker1$/,
1035 "got TAPER-OK") or die;
1036 make_holding_file(1000000, "localhost", "/u01");
1037 taper_cmd("FILE-WRITE worker0 $handle \"$test_filename\" localhost /u01 0 $datestamp 262144 \"\" \"\" \"\" \"\" \"\" \"\" \"\" 1612");
1038 like(taper_reply, qr/^REQUEST-NEW-TAPE $handle$/,
1039 "got REQUEST-NEW-TAPE worker0 $handle") or die;
1040 taper_cmd("START-SCAN worker0 $handle");
1041 taper_cmd("NEW-TAPE worker0 $handle");
1042 like(taper_reply, qr/^NEW-TAPE $handle TESTCONF01$/,
1043 "got proper NEW-TAPE worker0 $handle") or die;
1044 like(taper_reply, qr/^PARTDONE $handle TESTCONF01 1 256 "\[sec [\d.]+ bytes 262144 kps [\d.]+ orig-kb 1612\]"$/,
1045 "got PARTDONE for filenum 1") or die;
1046 like(taper_reply, qr/^PARTDONE $handle TESTCONF01 2 256 "\[sec [\d.]+ bytes 262144 kps [\d.]+ orig-kb 1612\]"$/,
1047 "got PARTDONE for filenum 2") or die;
1048 like(taper_reply, qr/^PARTDONE $handle TESTCONF01 3 256 "\[sec [\d.]+ bytes 262144 kps [\d.]+ orig-kb 1612\]"$/,
1049 "got PARTDONE for filenum 3") or die;
1050 like(taper_reply, qr/^REQUEST-NEW-TAPE $handle$/,
1051 "got REQUEST-NEW-TAPE worker0 $handle") or die;
1052 taper_cmd("TAKE-SCRIBE-FROM worker0 $handle worker1");
1053 like(taper_reply, qr/^REQUEST-NEW-TAPE $handle$/,
1054 "got REQUEST-NEW-TAPE worker0 $handle") or die;
1055 taper_cmd("START-SCAN worker0 $handle");
1056 taper_cmd("NEW-TAPE worker0 $handle");
1057 like(taper_reply, qr/^NEW-TAPE $handle TESTCONF02$/,
1058 "got proper NEW-TAPE worker0 $handle") or die;
1059 like(taper_reply, qr/^PARTDONE $handle TESTCONF02 1 208 "\[sec [\d.]+ bytes 213568 kps [\d.]+ orig-kb 1612\]"$/,
1060 "got PARTDONE for filenum 4") or die;
1061 like(taper_reply, qr/^DONE $handle INPUT-GOOD TAPE-GOOD "\[sec [\d.]+ bytes 1000000 kps [\d.]+ orig-kb 1612\]" "" ""$/,
1067 qr(^INFO taper Slot 1 without label can be labeled$),
1068 qr(^INFO taper Slot 2 without label can be labeled$),
1069 qr(^START taper datestamp $datestamp label TESTCONF01 tape 1$),
1070 qr(^PART taper TESTCONF01 1 localhost /u01 $datestamp 1/-1 0 \[sec [\d.]+ bytes 262144 kps [\d.]+ orig-kb 1612\]$),
1071 qr(^PART taper TESTCONF01 2 localhost /u01 $datestamp 2/-1 0 \[sec [\d.]+ bytes 262144 kps [\d.]+ orig-kb 1612\]$),
1072 qr(^PART taper TESTCONF01 3 localhost /u01 $datestamp 3/-1 0 \[sec [\d.]+ bytes 262144 kps [\d.]+ orig-kb 1612\]$),
1073 qr(^PARTPARTIAL taper TESTCONF01 4 localhost /u01 $datestamp 4/-1 0 \[sec [\d.]+ bytes 98304 kps [\d.]+ orig-kb 1612\] \"No space left on device\"$),
1074 qr(^INFO taper Will request retry of failed split part.$),
1075 qr(^INFO taper tape TESTCONF01 kb 768 fm 4 \[OK\]$),
1076 qr(^START taper datestamp $datestamp label TESTCONF02 tape 2$),
1077 qr(^PART taper TESTCONF02 1 localhost /u01 $datestamp 4/-1 0 \[sec [\d.]+ bytes 213568 kps [\d.]+ orig-kb 1612\]$),
1078 qr(^DONE taper localhost /u01 $datestamp 4 0 \[sec [\d.]+ bytes 1000000 kps [\d.]+ orig-kb 1612\]$),
1079 qr(^INFO taper tape TESTCONF02 kb 208 fm 1 \[OK\]$),
1080 ], "TAKE-SCRIBE logged correctly");
1084 # Test with NDMP device (DirectTCP)
1087 skip "not built with NDMP", 33 unless Amanda::Util::built_with_component("ndmp");
1089 my $ndmp = Installcheck::Mock::NdmpServer->new(tape_limit => 1024*1024);
1090 my $ndmp_port = $ndmp->{'port'};
1091 my $drive = $ndmp->{'drive'};
1093 $handle = "55-11111";
1094 $datestamp = "19780615010305";
1095 run_taper(4096, "multipart directtcp PORT-WRITE",
1096 ndmp_server => $ndmp);
1097 like(taper_reply, qr/^TAPER-OK worker0$/,
1098 "got TAPER-OK") or die;
1099 # note that, with the addition of the new splitting params, this does the "sensible"
1100 # thing and uses the tape_splitsize, not the fallback_splitsize (this is a change from
1102 taper_cmd("PORT-WRITE worker0 $handle localhost /var 0 $datestamp 393216 \"\" 327680 \"\" \"\" \"\" \"\" \"\" DIRECTTCP");
1103 like(taper_reply, qr/^PORT worker0 $handle (\d+) "?(\d+\.\d+\.\d+\.\d+:\d+;?)+"?$/,
1104 "got PORT with data address");
1105 write_to_port($last_taper_reply, 1230*1024, "localhost", "/var", 0);
1106 like(taper_reply, qr/^REQUEST-NEW-TAPE $handle$/,
1107 "got REQUEST-NEW-TAPE worker0 $handle") or die;
1108 taper_cmd("START-SCAN worker0 $handle");
1109 taper_cmd("NEW-TAPE worker0 $handle");
1110 like(taper_reply, qr/^NEW-TAPE $handle TESTCONF01$/,
1111 "got proper NEW-TAPE worker0 $handle") or die;
1112 like(taper_reply, qr/^PARTDONE $handle TESTCONF01 1 384 "\[sec [\d.]+ bytes 393216 kps [\d.]+\]"$/,
1113 "got PARTDONE for part 1") or die;
1114 like(taper_reply, qr/^PARTDONE $handle TESTCONF01 2 384 "\[sec [\d.]+ bytes 393216 kps [\d.]+\]"$/,
1115 "got PARTDONE for part 2") or die;
1116 like(taper_reply, qr/^PARTDONE $handle TESTCONF01 3 64 "\[sec [\d.]+ bytes 65536 kps [\d.]+\]"$/,
1117 "got PARTDONE for part 3 (short part)") or die;
1118 like(taper_reply, qr/^REQUEST-NEW-TAPE $handle$/,
1119 "got REQUEST-NEW-TAPE worker0 $handle") or die;
1120 taper_cmd("START-SCAN worker0 $handle");
1121 taper_cmd("NEW-TAPE worker0 $handle");
1122 like(taper_reply, qr/^NEW-TAPE $handle TESTCONF02$/,
1123 "got proper NEW-TAPE worker0 $handle") or die;
1124 like(taper_reply, qr/^PARTDONE $handle TESTCONF02 1 384 "\[sec [\d.]+ bytes 393216 kps [\d.]+\]"$/,
1125 "got PARTDONE for part 4") or die;
1126 like(taper_reply, qr/^PARTDONE $handle TESTCONF02 2 32 "\[sec [\d.]+ bytes 32768 kps [\d.]+\]"$/,
1127 "got PARTDONE for part 5") or die;
1128 like(taper_reply, qr/^DUMPER-STATUS $handle$/,
1129 "got DUMPER-STATUS request") or die;
1130 taper_cmd("DONE worker0 $handle 1912");
1131 like(taper_reply, qr/^DONE $handle INPUT-GOOD TAPE-GOOD "\[sec [\d.]+ bytes 1277952 kps [\d.]+ orig-kb 1912\]" "" ""$/,
1133 $handle = "55-22222";
1134 taper_cmd("PORT-WRITE worker0 $handle localhost /etc 0 $datestamp 524288 \"\" 393216 \"\" \"\" \"\" \"\" \"\" DIRECTTCP");
1135 like(taper_reply, qr/^PORT worker0 $handle (\d+) "?(\d+\.\d+\.\d+\.\d+:\d+;?)+"?$/,
1136 "got PORT with data address");
1137 write_to_port($last_taper_reply, 300*1024, "localhost", "/etc", 0);
1138 like(taper_reply, qr/^PARTDONE $handle TESTCONF02 3 320 "\[sec [\d.]+ bytes 327680 kps [\d.]+\]"$/,
1139 "got PARTDONE for part 1") or die;
1140 like(taper_reply, qr/^DUMPER-STATUS $handle$/,
1141 "got DUMPER-STATUS request") or die;
1142 taper_cmd("DONE worker0 $handle 2012");
1143 like(taper_reply, qr/^DONE $handle INPUT-GOOD TAPE-GOOD "\[sec [\d.]+ bytes 327680 kps [\d.]+ orig-kb 2012\]" "" ""$/,
1149 qr(^INFO taper Slot 3 without label can be labeled$),
1150 qr(^START taper datestamp $datestamp label TESTCONF01 tape 1$),
1151 qr(^PART taper TESTCONF01 1 localhost /var $datestamp 1/-1 0 \[sec [\d.]+ bytes 393216 kps [\d.]+\]$),
1152 qr(^PART taper TESTCONF01 2 localhost /var $datestamp 2/-1 0 \[sec [\d.]+ bytes 393216 kps [\d.]+\]$),
1153 qr(^PART taper TESTCONF01 3 localhost /var $datestamp 3/-1 0 \[sec [\d.]+ bytes 65536 kps [\d.]+\]$),
1154 # note no "Will retry.."
1155 qr(^INFO taper tape TESTCONF01 kb 832 fm 3 \[OK\]$),
1156 qr(^INFO taper Slot 4 without label can be labeled$),
1157 qr(^START taper datestamp $datestamp label TESTCONF02 tape 2$),
1158 qr(^PART taper TESTCONF02 1 localhost /var $datestamp 4/-1 0 \[sec [\d.]+ bytes 393216 kps [\d.]+\]$),
1159 qr(^PART taper TESTCONF02 2 localhost /var $datestamp 5/-1 0 \[sec [\d.]+ bytes 32768 kps [\d.]+\]$),
1160 qr(^DONE taper localhost /var $datestamp 5 0 \[sec [\d.]+ bytes 1277952 kps [\d.]+ orig-kb 1912\]$),
1161 qr(^PART taper TESTCONF02 3 localhost /etc $datestamp 1/-1 0 \[sec [\d.]+ bytes 327680 kps [\d.]+\]$),
1162 qr(^DONE taper localhost /etc $datestamp 1 0 \[sec [\d.]+ bytes 327680 kps [\d.]+ orig-kb 2012\]$),
1163 qr(^INFO taper tape TESTCONF02 kb 736 fm 3 \[OK\]$),
1164 ], "multipart directtcp PORT-WRITE logged correctly");
1166 $handle = "55-33333";
1167 $datestamp = "19780615010305";
1168 run_taper(4096, "multipart directtcp PORT-WRITE, with a zero-byte part",
1169 ndmp_server => $ndmp);
1170 like(taper_reply, qr/^TAPER-OK worker0$/,
1171 "got TAPER-OK") or die;
1172 # use a different part size this time, to hit EOM "on the head"
1173 taper_cmd("PORT-WRITE worker0 $handle localhost /var 0 $datestamp 425984 \"\" 327680 \"\" \"\" \"\" \"\" \"\" DIRECTTCP");
1174 like(taper_reply, qr/^PORT worker0 $handle (\d+) "?(\d+\.\d+\.\d+\.\d+:\d+;?)+"?$/,
1175 "got PORT with data address");
1176 write_to_port($last_taper_reply, 1632*1024, "localhost", "/var", 0);
1177 like(taper_reply, qr/^REQUEST-NEW-TAPE $handle$/,
1178 "got REQUEST-NEW-TAPE worker0 $handle") or die;
1179 taper_cmd("START-SCAN worker0 $handle");
1180 taper_cmd("NEW-TAPE worker0 $handle");
1181 like(taper_reply, qr/^NEW-TAPE $handle TESTCONF01$/,
1182 "got proper NEW-TAPE worker0 $handle") or die;
1183 like(taper_reply, qr/^PARTDONE $handle TESTCONF01 1 416 "\[sec [\d.]+ bytes 425984 kps [\d.]+\]"$/,
1184 "got PARTDONE for part 1") or die;
1185 like(taper_reply, qr/^PARTDONE $handle TESTCONF01 2 416 "\[sec [\d.]+ bytes 425984 kps [\d.]+\]"$/,
1186 "got PARTDONE for part 2") or die;
1187 # note: zero-byte part is not reported as PARTDONE
1188 like(taper_reply, qr/^REQUEST-NEW-TAPE $handle$/,
1189 "got REQUEST-NEW-TAPE worker0 $handle") or die;
1190 taper_cmd("START-SCAN worker0 $handle");
1191 taper_cmd("NEW-TAPE worker0 $handle");
1192 like(taper_reply, qr/^NEW-TAPE $handle TESTCONF02$/,
1193 "got proper NEW-TAPE worker0 $handle") or die;
1194 like(taper_reply, qr/^PARTDONE $handle TESTCONF02 1 416 "\[sec [\d.]+ bytes 425984 kps [\d.]+\]"$/,
1195 "got PARTDONE for part 3") or die;
1196 like(taper_reply, qr/^PARTDONE $handle TESTCONF02 2 384 "\[sec [\d.]+ bytes 393216 kps [\d.]+\]"$/,
1197 "got PARTDONE for part 4") or die;
1198 like(taper_reply, qr/^DUMPER-STATUS $handle$/,
1199 "got DUMPER-STATUS request") or die;
1200 taper_cmd("DONE worker0 $handle 2112");
1201 like(taper_reply, qr/^DONE $handle INPUT-GOOD TAPE-GOOD "\[sec [\d.]+ bytes 1671168 kps [\d.]+ orig-kb 2112\]" "" ""$/,
1207 qr(^INFO taper Slot 3 without label can be labeled$),
1208 qr(^START taper datestamp $datestamp label TESTCONF01 tape 1$),
1209 qr(^PART taper TESTCONF01 1 localhost /var $datestamp 1/-1 0 \[sec [\d.]+ bytes 425984 kps [\d.]+\]$),
1210 qr(^PART taper TESTCONF01 2 localhost /var $datestamp 2/-1 0 \[sec [\d.]+ bytes 425984 kps [\d.]+\]$),
1211 # Note: zero-byte part is not logged, but is counted in this INFO line's 'fm' field
1212 qr(^INFO taper tape TESTCONF01 kb 832 fm 3 \[OK\]$),
1213 qr(^INFO taper Slot 4 without label can be labeled$),
1214 qr(^START taper datestamp $datestamp label TESTCONF02 tape 2$),
1215 qr(^PART taper TESTCONF02 1 localhost /var $datestamp 3/-1 0 \[sec [\d.]+ bytes 425984 kps [\d.]+\]$),
1216 qr(^PART taper TESTCONF02 2 localhost /var $datestamp 4/-1 0 \[sec [\d.]+ bytes 393216 kps [\d.]+\]$),
1217 qr(^DONE taper localhost /var $datestamp 4 0 \[sec [\d.]+ bytes 1671168 kps [\d.]+ orig-kb 2112\]$),
1218 qr(^INFO taper tape TESTCONF02 kb 800 fm 2 \[OK\]$),
1219 ], "multipart directtcp PORT-WRITE with a zero-byte part logged correctly");
1223 } # end of ndmp SKIP
1226 # A run without LEOM and without allow-split
1227 $handle = "77-11111";
1228 $datestamp = "20090302020000";
1229 run_taper(1024, "without LEOM and without allow-split", new_vtapes => 1);
1230 make_holding_file(1024*1024, "localhost", "/usr");
1231 like(taper_reply, qr/^TAPER-OK worker0$/,
1232 "got TAPER-OK") or die;
1233 taper_cmd("FILE-WRITE worker0 $handle \"$test_filename\" localhost /usr 0 $datestamp 262144 \"\" \"\" \"0\" \"\" \"\" \"\" \"\" 1612");
1234 like(taper_reply, qr/^REQUEST-NEW-TAPE $handle$/,
1235 "got REQUEST-NEW-TAPE worker0 $handle") or die;
1236 taper_cmd("START-SCAN worker0 $handle");
1237 taper_cmd("NEW-TAPE worker0 $handle");
1238 like(taper_reply, qr/^NEW-TAPE $handle TESTCONF01$/,
1239 "got proper NEW-TAPE worker0 $handle") or die;
1240 like(taper_reply, qr/^PARTIAL $handle INPUT-GOOD TAPE-ERROR "\[sec [\d.]+ bytes \d* kps [\d.]+ orig-kb 1612\]" "" "No space left on device: more than MAX_VOLUME_USAGE bytes written, splitting not enabled"$/,
1241 "got PARTIAL for filenum 1") or die;
1246 qr(^INFO taper Slot 1 without label can be labeled$),
1247 qr(^START taper datestamp $datestamp label TESTCONF01 tape 1$),
1248 qr(^PARTPARTIAL taper TESTCONF01 1 localhost /usr $datestamp 1/-1 0 \[sec [\d.]+ bytes 983040 kps [\d.]+ orig-kb 1612\] \"No space left on device\"$),
1249 qr(^PARTIAL taper localhost /usr $datestamp 1 0 \[sec [\d.]+ bytes 0 kps [\d.]+ orig-kb 1612\] "No space left on device: more than MAX_VOLUME_USAGE bytes written, splitting not enabled"$),
1250 qr(^INFO taper tape TESTCONF01 kb 0 fm 1 \[OK\]$),
1251 ], "without LEOM and without allow-split logged correctly");
1255 # A run with LEOM and without allow-split
1256 $handle = "77-11112";
1257 $datestamp = "20090303020000";
1258 run_taper(1024, "with LEOM and without allow-split", new_vtapes => 1, leom => 1);
1259 make_holding_file(1024*1024, "localhost", "/usr");
1260 like(taper_reply, qr/^TAPER-OK worker0$/,
1261 "got TAPER-OK") or die;
1262 taper_cmd("FILE-WRITE worker0 $handle \"$test_filename\" localhost /usr 0 $datestamp 262144 \"\" \"\" \"0\" \"\" \"\" \"\" \"\" 1612");
1263 like(taper_reply, qr/^REQUEST-NEW-TAPE $handle$/,
1264 "got REQUEST-NEW-TAPE worker0 $handle") or die;
1265 taper_cmd("START-SCAN worker0 $handle");
1266 taper_cmd("NEW-TAPE worker0 $handle");
1267 like(taper_reply, qr/^NEW-TAPE $handle TESTCONF01$/,
1268 "got proper NEW-TAPE worker0 $handle") or die;
1269 like(taper_reply, qr/^PARTDONE $handle TESTCONF01 1 864 "\[sec [\d.]+ bytes 884736 kps [\d.]+ orig-kb 1612\]"$/,
1270 "got PARTDONE for filenum 1") or die;
1271 like(taper_reply, qr/^PARTIAL $handle INPUT-GOOD TAPE-ERROR "\[sec [\d.]+ bytes 884736 kps [\d.]+ orig-kb 1612\]" "" "No space left on device, splitting not enabled"$/,
1272 "got PARTIAL") or die;
1277 qr(^INFO taper Slot 1 without label can be labeled$),
1278 qr(^START taper datestamp $datestamp label TESTCONF01 tape 1$),
1279 qr(^PART taper TESTCONF01 1 localhost /usr $datestamp 1/-1 0 \[sec [\d.]+ bytes 884736 kps [\d.]+ orig-kb 1612\]$),
1280 qr(^PARTIAL taper localhost /usr $datestamp 1 0 \[sec [\d.]+ bytes 884736 kps [\d.]+ orig-kb 1612\] "No space left on device, splitting not enabled"$),
1281 qr(^INFO taper tape TESTCONF01 kb 864 fm 1 \[OK\]$),
1282 ], "with LEOM and without allow-split logged correctly");
1285 ## test lexical with new changer
1288 # A simple, one-part FILE-WRITE
1289 $handle = "11-11111";
1290 $datestamp = "20070102030405";
1291 run_taper(4096, "single-part and multipart FILE-WRITE", taperscan => "lexical", new_vtapes => 1);
1292 like(taper_reply, qr/^TAPER-OK worker0$/,
1293 "got TAPER-OK") or die;
1294 make_holding_file(1024*1024, "localhost", "/home");
1295 taper_cmd("FILE-WRITE worker0 $handle \"$test_filename\" localhost /home 0 $datestamp \"\" \"\" \"\" \"\" \"\" \"\" \"\" \"\" 12");
1296 like(taper_reply, qr/^REQUEST-NEW-TAPE $handle$/,
1297 "got REQUEST-NEW-TAPE worker0 $handle") or die;
1298 taper_cmd("START-SCAN worker0 $handle");
1299 taper_cmd("NEW-TAPE worker0 $handle");
1300 like(taper_reply, qr/^NEW-TAPE $handle TESTCONF01$/,
1301 "got proper NEW-TAPE worker0 $handle") or die;
1302 like(taper_reply, qr/^PARTDONE $handle TESTCONF01 1 1024 "\[sec [\d.]+ bytes 1048576 kps [\d.]+ orig-kb 12\]"$/,
1303 "got PARTDONE") or die;
1304 like(taper_reply, qr/^DONE $handle INPUT-GOOD TAPE-GOOD "\[sec [\d.]+ bytes 1048576 kps [\d.]+ orig-kb 12\]" "" ""$/,
1308 # A multipart FILE-WRITE, using the same taper instance
1309 # (note that the third part is of length 0, and is not logged)
1311 $handle = '11-22222';
1312 make_holding_file(1024*1024, "localhost", "/usr");
1313 taper_cmd("FILE-WRITE worker0 $handle \"$test_filename\" localhost /usr 0 $datestamp 524288 \"\" \"\" 1 \"\" \"\" \"\" \"\" 512");
1314 like(taper_reply, qr/^PARTDONE $handle TESTCONF01 2 512 "\[sec [\d.]+ bytes 524288 kps [\d.]+ orig-kb 512\]"$/,
1315 "got PARTDONE for filenum 2") or die;
1316 like(taper_reply, qr/^PARTDONE $handle TESTCONF01 3 512 "\[sec [\d.]+ bytes 524288 kps [\d.]+ orig-kb 512\]"$/,
1317 "got PARTDONE for filenum 3") or die;
1318 like(taper_reply, qr/^DONE $handle INPUT-GOOD TAPE-GOOD "\[sec [\d.]+ bytes 1048576 kps [\d.]+ orig-kb 512\]" "" ""$/,
1324 qr(^INFO taper Slot 1 without label can be labeled$),
1325 qr(^START taper datestamp $datestamp label TESTCONF01 tape 1$),
1326 qr(^PART taper TESTCONF01 1 localhost /home $datestamp 1/-1 0 \[sec [\d.]+ bytes 1048576 kps [\d.]+ orig-kb 12\]$),
1327 qr(^DONE taper localhost /home $datestamp 1 0 \[sec [\d.]+ bytes 1048576 kps [\d.]+ orig-kb 12\]$),
1328 qr(^PART taper TESTCONF01 2 localhost /usr $datestamp 1/-1 0 \[sec [\d.]+ bytes 524288 kps [\d.]+ orig-kb 512\]$),
1329 qr(^PART taper TESTCONF01 3 localhost /usr $datestamp 2/-1 0 \[sec [\d.]+ bytes 524288 kps [\d.]+ orig-kb 512\]$),
1330 qr(^DONE taper localhost /usr $datestamp 2 0 \[sec [\d.]+ bytes 1048576 kps [\d.]+ orig-kb 512\]$),
1331 qr(^INFO taper tape TESTCONF01 kb 2048 fm 4 \[OK\]$),
1332 ], "single-part and multi-part dump logged correctly");
1335 # Test a sequence of writes to the same set of tapes
1337 $handle = "33-11111";
1338 $datestamp = "20090101010000";
1339 run_taper(1024, "first in a sequence", taperscan => "lexical", new_vtapes => 1);
1340 like(taper_reply, qr/^TAPER-OK worker0$/,
1341 "got TAPER-OK") or die;
1342 make_holding_file(500000, "localhost", "/u01");
1343 taper_cmd("FILE-WRITE worker0 $handle \"$test_filename\" localhost /u01 0 $datestamp 262144 \"\" \"\" \"\" \"\" \"\" \"\" \"\" 1412");
1344 like(taper_reply, qr/^REQUEST-NEW-TAPE $handle$/,
1345 "got REQUEST-NEW-TAPE worker0 $handle") or die;
1346 taper_cmd("START-SCAN worker0 $handle");
1347 taper_cmd("NEW-TAPE worker0 $handle");
1348 like(taper_reply, qr/^NEW-TAPE $handle TESTCONF01$/,
1349 "got proper NEW-TAPE worker0 $handle") or die;
1350 like(taper_reply, qr/^PARTDONE $handle TESTCONF01 1 256 "\[sec [\d.]+ bytes 262144 kps [\d.]+ orig-kb 1412\]"$/,
1351 "got PARTDONE for filenum 1") or die;
1352 like(taper_reply, qr/^PARTDONE $handle TESTCONF01 2 232 "\[sec [\d.]+ bytes 237856 kps [\d.]+ orig-kb 1412\]"$/,
1353 "got PARTDONE for filenum 2") or die;
1354 like(taper_reply, qr/^DONE $handle INPUT-GOOD TAPE-GOOD "\[sec [\d.]+ bytes 500000 kps [\d.]+ orig-kb 1412\]" "" ""$/,
1356 $handle = "33-22222";
1357 make_holding_file(614400, "localhost", "/u02");
1358 taper_cmd("FILE-WRITE worker0 $handle \"$test_filename\" localhost /u02 0 $datestamp 262144 \"\" \"\" \"\" \"\" \"\" \"\" \"\" 1512");
1359 like(taper_reply, qr/^PARTDONE $handle TESTCONF01 3 256 "\[sec [\d.]+ bytes 262144 kps [\d.]+ orig-kb 1512\]"$/,
1360 "got PARTDONE for filenum 3") or die;
1361 like(taper_reply, qr/^REQUEST-NEW-TAPE $handle$/,
1362 "got REQUEST-NEW-TAPE worker0 $handle") or die;
1363 taper_cmd("START-SCAN worker0 $handle");
1364 taper_cmd("NEW-TAPE worker0 $handle");
1365 like(taper_reply, qr/^NEW-TAPE $handle TESTCONF02$/,
1366 "got proper NEW-TAPE worker0 $handle") or die;
1367 like(taper_reply, qr/^PARTDONE $handle TESTCONF02 1 256 "\[sec [\d.]+ bytes 262144 kps [\d.]+ orig-kb 1512\]"$/,
1368 "got PARTDONE for filenum 1 on second tape") or die;
1369 like(taper_reply, qr/^PARTDONE $handle TESTCONF02 2 88 "\[sec [\d.]+ bytes 90112 kps [\d.]+ orig-kb 1512\]"$/,
1370 "got PARTDONE for filenum 2 on second tape") or die;
1371 like(taper_reply, qr/^DONE $handle INPUT-GOOD TAPE-GOOD "\[sec [\d.]+ bytes 614400 kps [\d.]+ orig-kb 1512\]" "" ""$/,
1377 qr(^INFO taper Slot 1 without label can be labeled$),
1378 qr(^START taper datestamp $datestamp label TESTCONF01 tape 1$),
1379 qr(^PART taper TESTCONF01 1 localhost /u01 $datestamp 1/-1 0 \[sec [\d.]+ bytes 262144 kps [\d.]+ orig-kb 1412\]$),
1380 qr(^PART taper TESTCONF01 2 localhost /u01 $datestamp 2/-1 0 \[sec [\d.]+ bytes 237856 kps [\d.]+ orig-kb 1412\]$),
1381 qr(^DONE taper localhost /u01 $datestamp 2 0 \[sec [\d.]+ bytes 500000 kps [\d.]+ orig-kb 1412\]$),
1382 qr(^PART taper TESTCONF01 3 localhost /u02 $datestamp 1/-1 0 \[sec [\d.]+ bytes 262144 kps [\d.]+ orig-kb 1512\]$),
1383 qr(^PARTPARTIAL taper TESTCONF01 4 localhost /u02 $datestamp 2/-1 0 \[sec [\d.]+ bytes 98304 kps [\d.]+ orig-kb 1512\] "No space left on device"$),
1384 qr(^INFO taper Will request retry of failed split part\.$),
1385 qr(^INFO taper tape TESTCONF01 kb 744 fm 4 \[OK\]$),
1386 qr(^INFO taper Slot 2 without label can be labeled$),
1387 qr(^START taper datestamp $datestamp label TESTCONF02 tape 2$),
1388 qr(^PART taper TESTCONF02 1 localhost /u02 $datestamp 2/-1 0 \[sec [\d.]+ bytes 262144 kps [\d.]+ orig-kb 1512\]$),
1389 qr(^PART taper TESTCONF02 2 localhost /u02 $datestamp 3/-1 0 \[sec [\d.]+ bytes 90112 kps [\d.]+ orig-kb 1512\]$),
1390 qr(^DONE taper localhost /u02 $datestamp 3 0 \[sec [\d.]+ bytes 614400 kps [\d.]+ orig-kb 1512\]$),
1391 qr(^INFO taper tape TESTCONF02 kb 344 fm 2 \[OK\]$),
1392 ], "first taper invocation in sequence logged correctly");
1395 $handle = "33-33333";
1396 $datestamp = "20090202020000";
1397 run_taper(1024, "second in a sequence", keep_config => 1);
1398 like(taper_reply, qr/^TAPER-OK worker0$/,
1399 "got TAPER-OK") or die;
1400 make_holding_file(300000, "localhost", "/u01");
1401 taper_cmd("FILE-WRITE worker0 $handle \"$test_filename\" localhost /u01 0 $datestamp 262144 \"\" \"\" \"\" \"\" \"\" \"\" \"\" 1612");
1402 like(taper_reply, qr/^REQUEST-NEW-TAPE $handle$/,
1403 "got REQUEST-NEW-TAPE worker0 $handle") or die;
1404 taper_cmd("START-SCAN worker0 $handle");
1405 taper_cmd("NEW-TAPE worker0 $handle");
1406 like(taper_reply, qr/^NEW-TAPE $handle TESTCONF03$/,
1407 "got proper NEW-TAPE worker0 $handle") or die;
1408 like(taper_reply, qr/^PARTDONE $handle TESTCONF03 1 256 "\[sec [\d.]+ bytes 262144 kps [\d.]+ orig-kb 1612\]"$/,
1409 "got PARTDONE for filenum 1") or die;
1410 like(taper_reply, qr/^PARTDONE $handle TESTCONF03 2 36 "\[sec [\d.]+ bytes 37856 kps [\d.]+ orig-kb 1612\]"$/,
1411 "got PARTDONE for filenum 2") or die;
1412 like(taper_reply, qr/^DONE $handle INPUT-GOOD TAPE-GOOD "\[sec [\d.]+ bytes 300000 kps [\d.]+ orig-kb 1612\]" "" ""$/,
1414 $handle = "33-44444";
1415 make_holding_file(614400, "localhost", "/u02");
1416 taper_cmd("FILE-WRITE worker0 $handle \"$test_filename\" localhost /u02 0 $datestamp 262144 \"\" \"\" \"\" \"\" \"\" \"\" \"\" 1712");
1417 like(taper_reply, qr/^PARTDONE $handle TESTCONF03 3 256 "\[sec [\d.]+ bytes 262144 kps [\d.]+ orig-kb 1712\]"$/,
1418 "got PARTDONE for filenum 3") or die;
1419 like(taper_reply, qr/^PARTDONE $handle TESTCONF03 4 256 "\[sec [\d.]+ bytes 262144 kps [\d.]+ orig-kb 1712\]"$/,
1420 "got PARTDONE for filenum 4") or die;
1421 like(taper_reply, qr/^REQUEST-NEW-TAPE $handle$/,
1422 "got REQUEST-NEW-TAPE worker0 $handle") or die;
1423 taper_cmd("START-SCAN worker0 $handle");
1424 taper_cmd("NEW-TAPE worker0 $handle");
1425 like(taper_reply, qr/^NEW-TAPE $handle TESTCONF01$/,
1426 "got proper NEW-TAPE worker0 $handle") or die;
1427 like(taper_reply, qr/^PARTDONE $handle TESTCONF01 1 88 "\[sec [\d.]+ bytes 90112 kps [\d.]+ orig-kb 1712\]"$/,
1428 "got PARTDONE for filenum 1 on second tape") or die;
1429 like(taper_reply, qr/^DONE $handle INPUT-GOOD TAPE-GOOD "\[sec [\d.]+ bytes 614400 kps [\d.]+ orig-kb 1712\]" "" ""$/,
1435 qr(^INFO taper Slot 3 without label can be labeled$),
1436 qr(^START taper datestamp $datestamp label TESTCONF03 tape 1$),
1437 qr(^PART taper TESTCONF03 1 localhost /u01 $datestamp 1/-1 0 \[sec [\d.]+ bytes 262144 kps [\d.]+ orig-kb 1612\]$),
1438 qr(^PART taper TESTCONF03 2 localhost /u01 $datestamp 2/-1 0 \[sec [\d.]+ bytes 37856 kps [\d.]+ orig-kb 1612\]$),
1439 qr(^DONE taper localhost /u01 $datestamp 2 0 \[sec [\d.]+ bytes 300000 kps [\d.]+ orig-kb 1612\]$),
1440 qr(^PART taper TESTCONF03 3 localhost /u02 $datestamp 1/-1 0 \[sec [\d.]+ bytes 262144 kps [\d.]+ orig-kb 1712\]$),
1441 qr(^PART taper TESTCONF03 4 localhost /u02 $datestamp 2/-1 0 \[sec [\d.]+ bytes 262144 kps [\d.]+ orig-kb 1712\]$),
1442 qr(^PARTPARTIAL taper TESTCONF03 5 localhost /u02 $datestamp 3/-1 0 \[sec [\d.]+ bytes 0 kps [\d.]+ orig-kb 1712\] "No space left on device"$),
1443 qr(^INFO taper Will request retry of failed split part\.$),
1444 qr(^INFO taper tape TESTCONF03 kb 804 fm 5 \[OK\]$),
1445 qr(^INFO taper Slot 1 with label TESTCONF01 is usable$),
1446 qr(^START taper datestamp $datestamp label TESTCONF01 tape 2$),
1447 qr(^PART taper TESTCONF01 1 localhost /u02 $datestamp 3/-1 0 \[sec [\d.]+ bytes 90112 kps [\d.]+ orig-kb 1712\]$),
1448 qr(^DONE taper localhost /u02 $datestamp 3 0 \[sec [\d.]+ bytes 614400 kps [\d.]+ orig-kb 1712\]$),
1449 qr(^INFO taper tape TESTCONF01 kb 88 fm 1 \[OK\]$),
1450 ], "second taper invocation in sequence logged correctly");
1454 # A run with a bogus tapedev/tpchanger
1455 $handle = "44-11111";
1456 $datestamp = "20070102030405";
1457 run_taper(4096, "no tapedev", notapedev => 1, taperscan => "lexical", new_vtapes => 1);
1458 like(taper_reply, qr/^TAPE-ERROR SETUP "You must specify one of 'tapedev' or 'tpchanger'"$/,
1459 "got TAPE-ERROR") or die;
1463 # A run with 2 workers
1464 $handle0 = "66-00000";
1465 $handle1 = "66-11111";
1466 $datestamp = "20090202020000";
1467 run_taper(1024, "with 2 workers", new_vtapes => 1, taperscan => "lexical", new_vtapes => 1);
1468 like(taper_reply, qr/^TAPER-OK worker0$/,
1469 "got TAPER-OK") or die;
1470 taper_cmd("START-TAPER worker1 $datestamp");
1471 like(taper_reply, qr/^TAPER-OK worker1$/,
1472 "got TAPER-OK") or die;
1473 make_holding_file(300000, "localhost", "/u01");
1474 taper_cmd("FILE-WRITE worker0 $handle0 \"$test_filename\" localhost /u01 0 $datestamp 262144 \"\" \"\" \"\" \"\" \"\" \"\" \"\" 1612");
1475 like(taper_reply, qr/^REQUEST-NEW-TAPE $handle0$/,
1476 "got REQUEST-NEW-TAPE worker0 $handle0") or die;
1477 taper_cmd("START-SCAN worker0 $handle0");
1478 taper_cmd("NEW-TAPE worker0 $handle0");
1479 like(taper_reply, qr/^NEW-TAPE $handle0 TESTCONF01$/,
1480 "got proper NEW-TAPE worker0 $handle0") or die;
1481 like(taper_reply, qr/^PARTDONE $handle0 TESTCONF01 1 256 "\[sec [\d.]+ bytes 262144 kps [\d.]+ orig-kb 1612\]"$/,
1482 "got PARTDONE for filenum 1") or die;
1483 like(taper_reply, qr/^PARTDONE $handle0 TESTCONF01 2 36 "\[sec [\d.]+ bytes 37856 kps [\d.]+ orig-kb 1612\]"$/,
1484 "got PARTDONE for filenum 2") or die;
1485 like(taper_reply, qr/^DONE $handle0 INPUT-GOOD TAPE-GOOD "\[sec [\d.]+ bytes 300000 kps [\d.]+ orig-kb 1612\]" "" ""$/,
1487 make_holding_file(614400, "localhost", "/u02");
1488 taper_cmd("FILE-WRITE worker1 $handle1 \"$test_filename\" localhost /u02 0 $datestamp 262144 \"\" \"\" \"\" \"\" \"\" \"\" \"\" 1712");
1489 like(taper_reply, qr/^REQUEST-NEW-TAPE $handle1$/,
1490 "got REQUEST-NEW-TAPE worker1 $handle1") or die;
1491 taper_cmd("START-SCAN worker1 $handle1");
1492 taper_cmd("NEW-TAPE worker1 $handle1");
1493 like(taper_reply, qr/^NEW-TAPE $handle1 TESTCONF02$/,
1494 "got proper NEW-TAPE worker1 $handle1") or die;
1495 like(taper_reply, qr/^PARTDONE $handle1 TESTCONF02 1 256 "\[sec [\d.]+ bytes 262144 kps [\d.]+ orig-kb 1712\]"$/,
1496 "got PARTDONE for filenum 1 on second tape") or die;
1497 like(taper_reply, qr/^PARTDONE $handle1 TESTCONF02 2 256 "\[sec [\d.]+ bytes 262144 kps [\d.]+ orig-kb 1712\]"$/,
1498 "got PARTDONE for filenum 2 on second tape") or die;
1499 like(taper_reply, qr/^PARTDONE $handle1 TESTCONF02 3 88 "\[sec [\d.]+ bytes 90112 kps [\d.]+ orig-kb 1712\]"$/,
1500 "got PARTDONE for filenum 3 on second tape") or die;
1501 like(taper_reply, qr/^DONE $handle1 INPUT-GOOD TAPE-GOOD "\[sec [\d.]+ bytes 614400 kps [\d.]+ orig-kb 1712\]" "" ""$/,
1507 qr(^INFO taper Slot 1 without label can be labeled$),
1508 qr(^INFO taper Slot 1 is already in use by drive.*$),
1509 qr(^INFO taper Slot 2 without label can be labeled$),
1510 qr(^START taper datestamp $datestamp label TESTCONF01 tape 1$),
1511 qr(^PART taper TESTCONF01 1 localhost /u01 $datestamp 1/-1 0 \[sec [\d.]+ bytes 262144 kps [\d.]+ orig-kb 1612\]$),
1512 qr(^PART taper TESTCONF01 2 localhost /u01 $datestamp 2/-1 0 \[sec [\d.]+ bytes 37856 kps [\d.]+ orig-kb 1612\]$),
1513 qr(^DONE taper localhost /u01 $datestamp 2 0 \[sec [\d.]+ bytes 300000 kps [\d.]+ orig-kb 1612\]$),
1514 qr(^START taper datestamp $datestamp label TESTCONF02 tape 2$),
1515 qr(^PART taper TESTCONF02 1 localhost /u02 $datestamp 1/-1 0 \[sec [\d.]+ bytes 262144 kps [\d.]+ orig-kb 1712\]$),
1516 qr(^PART taper TESTCONF02 2 localhost /u02 $datestamp 2/-1 0 \[sec [\d.]+ bytes 262144 kps [\d.]+ orig-kb 1712\]$),
1517 qr(^PART taper TESTCONF02 3 localhost /u02 $datestamp 3/-1 0 \[sec [\d.]+ bytes 90112 kps [\d.]+ orig-kb 1712\]$),
1518 qr(^DONE taper localhost /u02 $datestamp 3 0 \[sec [\d.]+ bytes 614400 kps [\d.]+ orig-kb 1712\]$),
1519 qr(^INFO taper tape TESTCONF01 kb 292 fm 2 \[OK\]$),
1520 qr(^INFO taper tape TESTCONF02 kb 600 fm 3 \[OK\]$),
1521 ], "two workers logged correctly");