Blame installcheck/Amanda_Util.pl

Packit Service 392537
# Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
Packit Service 392537
# Copyright (c) 2013-2016 Carbonite, Inc.  All Rights Reserved.
Packit Service 392537
#
Packit Service 392537
# This program is free software; you can redistribute it and/or
Packit Service 392537
# modify it under the terms of the GNU General Public License
Packit Service 392537
# as published by the Free Software Foundation; either version 2
Packit Service 392537
# of the License, or (at your option) any later version.
Packit Service 392537
#
Packit Service 392537
# This program is distributed in the hope that it will be useful, but
Packit Service 392537
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
Packit Service 392537
# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
Packit Service 392537
# for more details.
Packit Service 392537
#
Packit Service 392537
# You should have received a copy of the GNU General Public License along
Packit Service 392537
# with this program; if not, write to the Free Software Foundation, Inc.,
Packit Service 392537
# 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
Packit Service 392537
#
Packit Service 392537
# Contact information: Carbonite Inc., 756 N Pastoria Ave
Packit Service 392537
# Sunnyvale, CA 94086, USA, or: http://www.zmanda.com
Packit Service 392537
Packit Service 392537
use Test::More tests => 139;
Packit Service 392537
Packit Service 392537
use lib '@amperldir@';
Packit Service 392537
use warnings;
Packit Service 392537
use strict;
Packit Service 392537
use Data::Dumper;
Packit Service 392537
use Amanda::Util qw(slurp burp safe_overwrite_file);
Packit Service 392537
use Installcheck;
Packit Service 392537
use POSIX;
Packit Service 392537
Packit Service 392537
Amanda::Debug::dbopen("installcheck");
Packit Service 392537
Installcheck::log_test_output();
Packit Service 392537
Packit Service 392537
# Data::Dumper is used to output strings with control characters
Packit Service 392537
# in them, below
Packit Service 392537
$Data::Dumper::Useqq = 1;  # quote strings
Packit Service 392537
$Data::Dumper::Terse = 1;  # no $VAR1 = ..
Packit Service 392537
$Data::Dumper::Indent = 0; # no newlines
Packit Service 392537
Packit Service 392537
# most of Amanda::Util is tested via running applications that use it
Packit Service 392537
Packit Service 392537
# Test hexencode/hexdecode lightly (they have a "make check" test)
Packit Service 392537
is(Amanda::Util::hexencode("hi"), "hi", "no encoding needed");
Packit Service 392537
is(Amanda::Util::hexencode("hi!"), "hi%21", "encoding");
Packit Service 392537
is(Amanda::Util::hexdecode("hi%21"), "hi!", "decoding");
Packit Service 392537
ok(!eval {Amanda::Util::hexdecode("%"); 1}, "decoding error throws exception");
Packit Service 392537
Packit Service 392537
# Tests for quote_string and unquote string.  First, some fuzzing of the
Packit Service 392537
# quote + unquote round-trip.
Packit Service 392537
my @fuzzstrs = (
Packit Service 392537
    '',
Packit Service 392537
    'abcd',
Packit Service 392537
    '"',
Packit Service 392537
    '""',
Packit Service 392537
    '\\',
Packit Service 392537
    "\t", "\r", "\n", "\f",
Packit Service 392537
    '\\\\\\\\', # memory overflow?
Packit Service 392537
    'backslash\nletter',
Packit Service 392537
    'backslash\tletter',
Packit Service 392537
    '"quoted"',
Packit Service 392537
    "line\nanother", # real newline
Packit Service 392537
    "ends with slash\\",
Packit Service 392537
    '"starts with quote',
Packit Service 392537
    'ends with quote"',
Packit Service 392537
    "single'quote",
Packit Service 392537
);
Packit Service 392537
Packit Service 392537
for my $fuzzstr (@fuzzstrs) {
Packit Service 392537
    is(Amanda::Util::unquote_string(Amanda::Util::quote_string($fuzzstr)), $fuzzstr,
Packit Service 392537
	"fuzz " . Dumper($fuzzstr));
Packit Service 392537
}
Packit Service 392537
Packit Service 392537
# since users often provide quoted strings (e.g., in config files), test that chosen
Packit Service 392537
# quoted strings are correctly unquoted.  The need to quote the quoted strings for perl
Packit Service 392537
# makes this a little hard to read..
Packit Service 392537
my %unquote_checks = (
Packit Service 392537
    '""' => '',
Packit Service 392537
    'abcd' => 'abcd',
Packit Service 392537
    '"abcd"' => 'abcd',
Packit Service 392537
    '"\t"' => "\t",
Packit Service 392537
    '"\r"' => "\r",
Packit Service 392537
    '"\n"' => "\n",
Packit Service 392537
    '"\f"' => "\f",
Packit Service 392537
    '"\t"' => "\t",
Packit Service 392537
    '"\\\\n"' => '\n', # literal \
Packit Service 392537
    '"\\\\"' => "\\",
Packit Service 392537
    '"\""' => "\"",
Packit Service 392537
);
Packit Service 392537
Packit Service 392537
while (my ($qstr, $uqstr) = each %unquote_checks) {
Packit Service 392537
    is(Amanda::Util::unquote_string($qstr), $uqstr,
Packit Service 392537
	"unquote " . Dumper($qstr));
Packit Service 392537
}
Packit Service 392537
Packit Service 392537
for my $a (keys %unquote_checks) {
Packit Service 392537
    for my $b ("unquoted", "\"quoted str\"") {
Packit Service 392537
	my ($a_out, $b_out) = Amanda::Util::skip_quoted_string("$a $b");
Packit Service 392537
	is_deeply([$a_out, $b_out], [$a, $b],
Packit Service 392537
	    "skip_quoted string over " . Dumper("$a $b"));
Packit Service 392537
    }
Packit Service 392537
}
Packit Service 392537
Packit Service 392537
is_deeply([ Amanda::Util::skip_quoted_string("foobar") ],
Packit Service 392537
	  [ "foobar", undef ],
Packit Service 392537
   "skip_quoted_string with one quoted string");
Packit Service 392537
Packit Service 392537
is_deeply([ Amanda::Util::skip_quoted_string("foo  bar") ],
Packit Service 392537
	  [ "foo", " bar" ],
Packit Service 392537
   "skip_quoted_string with two spaces keeps second space");
Packit Service 392537
Packit Service 392537
is_deeply([ Amanda::Util::skip_quoted_string("foo\tbar") ],
Packit Service 392537
	  [ "foo", "bar" ],
Packit Service 392537
   "skip_quoted_string with a tab still splits");
Packit Service 392537
Packit Service 392537
is_deeply([ Amanda::Util::split_quoted_string_friendly("a b c d") ],
Packit Service 392537
	  [ qw(a b c d) ],
Packit Service 392537
	  "split_quoted_string_friendly with a basic split");
Packit Service 392537
Packit Service 392537
is_deeply([ Amanda::Util::split_quoted_string_friendly("\ta   b\nc \t \td   ") ],
Packit Service 392537
	  [ qw(a b c d) ],
Packit Service 392537
	  "split_quoted_string_friendly with extra whitespace");
Packit Service 392537
Packit Service 392537
is_deeply([ Amanda::Util::split_quoted_string_friendly("") ],
Packit Service 392537
	  [ ],
Packit Service 392537
	  "split_quoted_string_friendly with empty string");
Packit Service 392537
Packit Service 392537
is_deeply([ Amanda::Util::split_quoted_string_friendly("\n\t ") ],
Packit Service 392537
	  [ ],
Packit Service 392537
	  "split_quoted_string_friendly with just whitespace");
Packit Service 392537
Packit Service 392537
is_deeply([ Amanda::Util::split_quoted_string_friendly("\n\"hi there\"\t ") ],
Packit Service 392537
	  [ 'hi there' ],
Packit Service 392537
	  "split_quoted_string_friendly with one string (containing whitespace)");
Packit Service 392537
Packit Service 392537
my @try_bracing = (
Packit Service 392537
    [ 'abc' ],
Packit Service 392537
    [ 'abc', 'def' ],
Packit Service 392537
    [ 'abc', 'def', 'ghi' ],
Packit Service 392537
    [ 'a,b', 'c' ],
Packit Service 392537
    [ 'a', 'b,c' ],
Packit Service 392537
    [ 'a', 'b,c', 'd' ],
Packit Service 392537
    [ 'a{b', 'c' ],
Packit Service 392537
    [ 'a', 'b{c' ],
Packit Service 392537
    [ 'a', 'b{c', 'd' ],
Packit Service 392537
    [ 'a}b', 'c' ],
Packit Service 392537
    [ 'a', 'b}c' ],
Packit Service 392537
    [ 'a', 'b}c', 'd' ],
Packit Service 392537
    [ 'a\\,b', 'c\\{d', 'e\\}f' ],
Packit Service 392537
);
Packit Service 392537
Packit Service 392537
for my $strs (@try_bracing) {
Packit Service 392537
    my $rt = [ Amanda::Util::expand_braced_alternates(
Packit Service 392537
		    Amanda::Util::collapse_braced_alternates($strs)) ];
Packit Service 392537
    is_deeply($rt, $strs,
Packit Service 392537
	      "round-trip of " . Dumper($strs));
Packit Service 392537
}
Packit Service 392537
Packit Service 392537
is_deeply(
Packit Service 392537
    [ Amanda::Util::expand_braced_alternates("t{0..3,5}") ],
Packit Service 392537
    [ qw(t0 t1 t2 t3 t5) ],
Packit Service 392537
    "expand_braced_alternates('t{0..3,5}')");
Packit Service 392537
Packit Service 392537
is_deeply(
Packit Service 392537
    [ Amanda::Util::expand_braced_alternates("t{13..12}") ],
Packit Service 392537
    [ qw(t13..12) ],
Packit Service 392537
    "expand_braced_alternates('t{13..12}') (sequence not parsed)");
Packit Service 392537
Packit Service 392537
is_deeply(
Packit Service 392537
    [ Amanda::Util::expand_braced_alternates("t{999..999}") ],
Packit Service 392537
    [ qw(t999) ],
Packit Service 392537
    "expand_braced_alternates('t{999..999}')");
Packit Service 392537
Packit Service 392537
is_deeply(
Packit Service 392537
    [ Amanda::Util::expand_braced_alternates("t{0..3}") ],
Packit Service 392537
    [ qw(t0 t1 t2 t3) ],
Packit Service 392537
    "expand_braced_alternates('t{0..3}')");
Packit Service 392537
Packit Service 392537
is_deeply(
Packit Service 392537
    [ Amanda::Util::expand_braced_alternates("t{10..13}") ],
Packit Service 392537
    [ qw(t10 t11 t12 t13) ],
Packit Service 392537
    "expand_braced_alternates('t{10..13}')");
Packit Service 392537
Packit Service 392537
is_deeply(
Packit Service 392537
    [ Amanda::Util::expand_braced_alternates("t{9..13}") ],
Packit Service 392537
    [ qw(t9 t10 t11 t12 t13) ],
Packit Service 392537
    "expand_braced_alternates('t{9..13}')");
Packit Service 392537
Packit Service 392537
is_deeply(
Packit Service 392537
    [ Amanda::Util::expand_braced_alternates("t{09..13}") ],
Packit Service 392537
    [ qw(t09 t10 t11 t12 t13) ],
Packit Service 392537
    "expand_braced_alternates('t{09..13}')");
Packit Service 392537
Packit Service 392537
is_deeply(
Packit Service 392537
    [ Amanda::Util::expand_braced_alternates("t{009..13}") ],
Packit Service 392537
    [ qw(t009 t010 t011 t012 t013) ],
Packit Service 392537
    "expand_braced_alternates('t{009..13}') (ldigits > rdigits)");
Packit Service 392537
Packit Service 392537
is_deeply(
Packit Service 392537
    [ sort(+Amanda::Util::expand_braced_alternates("x{001..004}y{1..2}z")) ],
Packit Service 392537
    [ sort(qw( x001y1z x002y1z x003y1z x004y1z x001y2z x002y2z x003y2z x004y2z )) ],
Packit Service 392537
    "expand_braced_alternates('x{001..004}y{1..2}z')");
Packit Service 392537
Packit Service 392537
is_deeply(
Packit Service 392537
    [ Amanda::Util::expand_braced_alternates("t{1..100}e") ],
Packit Service 392537
    [ map { "t$_"."e" } (1 .. 100) ],
Packit Service 392537
    "expand_braced_alternates('t{1..100}e')");
Packit Service 392537
Packit Service 392537
my @try_sanitise = (
Packit Service 392537
    [ '', '' ],
Packit Service 392537
    [ 'foo', 'foo' ],
Packit Service 392537
    [ '/', '_' ],
Packit Service 392537
    [ ':', '_' ],
Packit Service 392537
    [ '\\', '_' ],
Packit Service 392537
    [ 'foo/bar:baz', 'foo_bar_baz' ],
Packit Service 392537
);
Packit Service 392537
Packit Service 392537
for my $strs (@try_sanitise) {
Packit Service 392537
    my ($in, $exp) = @{$strs};
Packit Service 392537
    is(Amanda::Util::sanitise_filename($in), $exp, "sanitise " . $in);
Packit Service 392537
}
Packit Service 392537
Packit Service 392537
## test full_read and full_write
Packit Service 392537
Packit Service 392537
my $testfile = "$Installcheck::TMP/Amanda_Util";
Packit Service 392537
my $fd;
Packit Service 392537
my $buf;
Packit Service 392537
Packit Service 392537
# set up a 1K test file
Packit Service 392537
{
Packit Service 392537
    open (my $fh, ">", $testfile) or die("Opening $testfile: $!");
Packit Service 392537
    print $fh 'abcd' x 256;
Packit Service 392537
    close($fh);
Packit Service 392537
}
Packit Service 392537
Packit Service 392537
$! = 0;
Packit Service 392537
my $rv = Amanda::Util::full_read(-1, 13);
Packit Service 392537
isnt($!, '', "bad full_read gives a nonzero errno ($!)");
Packit Service 392537
Packit Service 392537
$! = 0;
Packit Service 392537
$rv = Amanda::Util::full_write(-1, "hello", 5);
Packit Service 392537
isnt($!, '', "bad full_write gives a nonzero errno ($!)");
Packit Service 392537
Packit Service 392537
$fd = POSIX::open($testfile, POSIX::O_RDONLY);
Packit Service 392537
die "Could not open '$testfile'" unless defined $fd;
Packit Service 392537
Packit Service 392537
$! = 0;
Packit Service 392537
$buf = Amanda::Util::full_read($fd, 1000);
Packit Service 392537
is(length($buf), 1000, "a valid read gets the right number of bytes");
Packit Service 392537
is(substr($buf, 0, 8), "abcdabcd", "..and what looks like the right data");
Packit Service 392537
is($!, '', "..and no error");
Packit Service 392537
Packit Service 392537
$! = 0;
Packit Service 392537
$buf = Amanda::Util::full_read($fd, 1000);
Packit Service 392537
is(length($buf), 24, "a second read, to EOF, gets the right number of bytes");
Packit Service 392537
is(substr($buf, 0, 8), "abcdabcd", "..and what looks like the right data");
Packit Service 392537
is($!, '', "..and no error");
Packit Service 392537
Packit Service 392537
POSIX::close($fd);
Packit Service 392537
Packit Service 392537
$fd = POSIX::open($testfile, POSIX::O_WRONLY);
Packit Service 392537
die "Could not open '$testfile'" unless defined $fd;
Packit Service 392537
Packit Service 392537
$! = 0;
Packit Service 392537
$rv = Amanda::Util::full_write($fd, "swank!", 6);
Packit Service 392537
is($rv, 6, "full_write returns number of bytes written");
Packit Service 392537
is($!, '', "..and no error");
Packit Service 392537
Packit Service 392537
POSIX::close($fd);
Packit Service 392537
Packit Service 392537
unlink($testfile);
Packit Service 392537
Packit Service 392537
# just a quick check for split_quoted_strings - thorough checks are done in
Packit Service 392537
# common-src/quoting-test.c.
Packit Service 392537
is_deeply([ Amanda::Util::split_quoted_strings('one "T W O" thr\ ee'), ],
Packit Service 392537
          [ "one", "T W O", "thr ee" ],
Packit Service 392537
          "split_quoted_strings seems to work");
Packit Service 392537
Packit Service 392537
## tests for slurp and burp
Packit Service 392537
Packit Service 392537
my $corpus = <
Packit Service 392537
Packit Service 392537
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean id
Packit Service 392537
neque interdum ligula euismod cursus at vel tortor. Praesent interdum
Packit Service 392537
molestie felis, nec vehicula lorem luctus quis. Suspendisse in laoreet
Packit Service 392537
diam. Maecenas fringilla lectus vel libero vehicula
Packit Service 392537
condimentum. Aenean ac luctus nulla. Nullam sagittis lacinia orci, et
Packit Service 392537
consectetur nunc malesuada sed. Nulla eu felis ipsum. Duis feugiat
Packit Service 392537
risus a lectus blandit lobortis. Fusce quis neque neque. Class aptent
Packit Service 392537
taciti sociosqu ad litora torquent per conubia nostra, per inceptos
Packit Service 392537
himenaeos.
Packit Service 392537
Packit Service 392537
Nulla at auctor mi. Mauris vestibulum ante vel metus auctor at iaculis
Packit Service 392537
neque semper. Nullam ipsum lorem, convallis ullamcorper ornare in,
Packit Service 392537
lacinia eu magna. Vivamus vulputate fermentum quam, quis pulvinar eros
Packit Service 392537
varius at. Phasellus ac diam nec erat elementum facilisis et ac
Packit Service 392537
est. Nunc nec nulla nec quam tristique dignissim at ut arcu. Integer
Packit Service 392537
accumsan tincidunt nisi non consectetur. Donec nec massa sed dui
Packit Service 392537
auctor sodales eget ac elit. Aliquam luctus sollicitudin nibh, eu
Packit Service 392537
volutpat augue tempor sed. Mauris ac est et neque mollis iaculis vel
Packit Service 392537
in libero. Duis molestie felis ultrices elit fringilla varius. In eget
Packit Service 392537
turpis dignissim sem varius sagittis eget vel neque.
Packit Service 392537
Packit Service 392537
EOF
Packit Service 392537
Packit Service 392537
my $burp_corpus_fname = "$Installcheck::TMP/burp_corpus";
Packit Service 392537
Packit Service 392537
ok( burp( $burp_corpus_fname, $corpus ), "burp round-trip test" );
Packit Service 392537
is( slurp($burp_corpus_fname), $corpus, "slurp round-trip test" );
Packit Service 392537
Packit Service 392537
# test safe_overwrite_file
Packit Service 392537
Packit Service 392537
my $sof_data = <
Packit Service 392537
DISK planner somebox /lib
Packit Service 392537
START planner date 20080111
Packit Service 392537
START driver date 20080111
Packit Service 392537
STATS driver hostname somebox
Packit Service 392537
STATS driver startup time 0.051
Packit Service 392537
FINISH planner date 20080111 time 82.721
Packit Service 392537
START taper datestamp 20080111 label Conf-001 tape 1
Packit Service 392537
SUCCESS dumper somebox /lib 20080111 0 [sec 0.209 kb 1970 kps 9382.2 orig-kb 1970]
Packit Service 392537
SUCCESS chunker somebox /lib 20080111 0 [sec 0.305 kb 420 kps 1478.7]
Packit Service 392537
STATS driver estimate somebox /lib 20080111 0 [sec 1 nkb 2002 ckb 480 kps 385]
Packit Service 392537
PART taper Conf-001 1 somebox /lib 20080111 1/1 0 [sec 4.813543 kb 419 kps 87.133307]
Packit Service 392537
DONE taper somebox /lib 20080111 1 0 [sec 4.813543 kb 419 kps 87.133307]
Packit Service 392537
FINISH driver date 20080111 time 2167.581
Packit Service 392537
EOF
Packit Service 392537
Packit Service 392537
ok(safe_overwrite_file($burp_corpus_fname, $sof_data),
Packit Service 392537
    "safe_overwrite_file success");
Packit Service 392537
is(slurp($burp_corpus_fname), $sof_data,
Packit Service 392537
    "safe_overwrite_file round-trip check");
Packit Service 392537
Packit Service 392537
# check out get_fs_usage
Packit Service 392537
my $fs_usage = Amanda::Util::get_fs_usage(POSIX::getcwd);
Packit Service 392537
if ($fs_usage) {
Packit Service 392537
    ok($fs_usage->{'blocks'}, "get_fs_usage returns something");
Packit Service 392537
} else {
Packit Service 392537
    fail("get_fs_usage fails: $!");
Packit Service 392537
}
Packit Service 392537
Packit Service 392537
# check file_lock -- again, full checks are in common-src/amflock-test.c
Packit Service 392537
my $filename = "$Installcheck::TMP/testlock";
Packit Service 392537
unlink($filename);
Packit Service 392537
my $fl = Amanda::Util::file_lock->new($filename);
Packit Service 392537
is($fl->data, undef, "data is initially undefined");
Packit Service 392537
$fl->lock();
Packit Service 392537
is($fl->data, undef, "data is undefined even after lock");
Packit Service 392537
$fl->write("THIS IS MY DATA");
Packit Service 392537
is($fl->data, "THIS IS MY DATA", "data is set correctly after write()");
Packit Service 392537
$fl->unlock();
Packit Service 392537
Packit Service 392537
# new lock object
Packit Service 392537
$fl = Amanda::Util::file_lock->new($filename);
Packit Service 392537
is($fl->data, undef, "data is initially undefined");
Packit Service 392537
$fl->lock();
Packit Service 392537
is($fl->data, "THIS IS MY DATA", "data is set correctly after lock");
Packit Service 392537
Packit Service 392537
## check (un)marshal_tapespec
Packit Service 392537
Packit Service 392537
my @tapespecs = (
Packit Service 392537
    "TESTCONF:FOO:1,2;TESTCONF:BAR:3" =>
Packit Service 392537
	[ "TESTCONF", "FOO", [ 1, 2 ], "TESTCONF", "BAR", [ 3 ] ],
Packit Service 392537
    "TEST\\;CONF:SE\\;MI:0;TEST\\:CONF:COL\\:ON:3" =>
Packit Service 392537
	[ 'TEST;CONF', 'SE;MI', [0], 'TEST:CONF', 'COL:ON', [3] ],
Packit Service 392537
    "TEST\\,CONF:CO\\,MMA:88,99;TEST\\\\CONF:BACK\\\\SLASH:3" =>
Packit Service 392537
	[ 'TEST,CONF', 'CO,MMA', [88,99], 'TEST\\CONF', 'BACK\\SLASH', [3] ],
Packit Service 392537
    "TESTCONF\\;:FUNNY\\;:1;TESTCONF\\::CHARS\\::2;TESTCONF\\,:AT\\,:3;TESTCONF\\\\:END\\\\:4" =>
Packit Service 392537
	[ 'TESTCONF;', 'FUNNY;', [ 1 ], 'TESTCONF:', 'CHARS:', [ 2 ], 'TESTCONF,', 'AT,', [ 3 ], 'TESTCONF\\', 'END\\', [ 4 ], ],
Packit Service 392537
    "\\;TESTCONF:\\;FUNNY:1;\\:TESTCONF:\\:CHARS:2;\\,TESTCONF:\\,AT:3;\\\\TESTCONF:\\\\BEG:4" =>
Packit Service 392537
	[ ';TESTCONF', ';FUNNY', [ 1 ], ':TESTCONF', ':CHARS', [ 2 ], ',TESTCONF', ',AT', [ 3 ], '\\TESTCONF', '\\BEG', [ 4 ], ],
Packit Service 392537
);
Packit Service 392537
Packit Service 392537
while (@tapespecs) {
Packit Service 392537
    my $tapespec = shift @tapespecs;
Packit Service 392537
    my $filelist = shift @tapespecs;
Packit Service 392537
    is(Amanda::Util::marshal_tapespec(1, $filelist), $tapespec,
Packit Service 392537
	    "marshal '$tapespec'");
Packit Service 392537
    is_deeply(Amanda::Util::unmarshal_tapespec(1, $tapespec), $filelist,
Packit Service 392537
	    "unmarshal '$tapespec'");
Packit Service 392537
}
Packit Service 392537
Packit Service 392537
is_deeply(Amanda::Util::unmarshal_tapespec(0, "x:100,99"), [undef, 'x', [99,100] ],
Packit Service 392537
    "filenums are sorted when unmarshalled");
Packit Service 392537
Packit Service 392537
is_deeply(Amanda::Util::marshal_tapespec(0, [ undef, 'x', [100, 99] ]), "x:100,99",
Packit Service 392537
    "un-sorted filenums are NOT sorted when marshalled");
Packit Service 392537
Packit Service 392537
is_deeply(Amanda::Util::unmarshal_tapespec(0, "x:34,34"), [ undef, 'x', [34, 34] ],
Packit Service 392537
    "duplicate filenums are NOT collapsed when unmarshalled");
Packit Service 392537
Packit Service 392537
is_deeply(Amanda::Util::marshal_tapespec(0, [ undef, 'x', [34, 34] ]), "x:34,34",
Packit Service 392537
    "duplicate filenums are NOT collapsed when marshalled");
Packit Service 392537
Packit Service 392537
is_deeply(Amanda::Util::unmarshal_tapespec(0, "sim\\\\ple\\:quoted\\;file\\,name"),
Packit Service 392537
    [ undef, "sim\\ple:quoted;file,name", [0] ],
Packit Service 392537
    "simple non-tapespec string translated like string:0");
Packit Service 392537
Packit Service 392537
is_deeply(Amanda::Util::unmarshal_tapespec(0, "tricky\\,tricky\\:1,2,3"),
Packit Service 392537
    [ undef, "tricky,tricky:1,2,3", [0] ],
Packit Service 392537
    "tricky non-tapespec string also translated to string:0");
Packit Service 392537
Packit Service 392537
is_deeply(Amanda::Util::unmarshal_tapespec(0, "\\:3"), # one slash
Packit Service 392537
    [ undef, ":3" , [0] ],
Packit Service 392537
    "one slash escapes the colon");
Packit Service 392537
Packit Service 392537
is_deeply(Amanda::Util::unmarshal_tapespec(0, "\\\\:3"), # two slashes
Packit Service 392537
    [ undef, "\\" , [3] ],
Packit Service 392537
    "two slashes escape to one");
Packit Service 392537
Packit Service 392537
is_deeply(Amanda::Util::unmarshal_tapespec(0, "\\\\\\:3"), # three slashes
Packit Service 392537
    [ undef, "\\:3", [0] ],
Packit Service 392537
    "three slashes escape to a slash and a colon");
Packit Service 392537
Packit Service 392537
is_deeply(Amanda::Util::unmarshal_tapespec(0, "\\\\\\\\:3"), # four slashes
Packit Service 392537
    [ undef, "\\\\", [3] ],
Packit Service 392537
    "four slashes escape to two");
Packit Service 392537
Packit Service 392537
my $labelstr = {'match_autolabel'=> 0,
Packit Service 392537
		'template' => ""};
Packit Service 392537
my $autolabel = {'autolabel'=> 0,
Packit Service 392537
		'template' => ""};
Packit Service 392537
$labelstr->{'template'} = "^000[0-9][0-9][0-9]L[0-9]\$";
Packit Service 392537
is(Amanda::Util::match_labelstr($labelstr, $autolabel, "000123L7", undef, undef, undef), 1, "match_labelstr 1");
Packit Service 392537
$labelstr->{'template'} = "^000[0-9][0-9][0-9]L\$";
Packit Service 392537
is(Amanda::Util::match_labelstr($labelstr, $autolabel, "000123L7", undef, undef, undef), '', "match_labelstr 2");
Packit Service 392537
$labelstr->{'template'} = "^000[0-9][0-9][0-9]L[0-9]";
Packit Service 392537
is(Amanda::Util::match_labelstr($labelstr, $autolabel, "000123L7", undef, undef, undef), 1, "match_labelstr 3");
Packit Service 392537
$labelstr->{'template'} = "^000[0-9][0-9][0-9]L";
Packit Service 392537
is(Amanda::Util::match_labelstr($labelstr, $autolabel, "000123L7", undef, undef, undef), 1, "match_labelstr 4");
Packit Service 392537
$labelstr->{'template'} = "000[0-9][0-9][0-9]L[0-9]\$";
Packit Service 392537
is(Amanda::Util::match_labelstr($labelstr, $autolabel, "000123L7", undef, undef, undef), 1, "match_labelstr 5");
Packit Service 392537
$labelstr->{'template'} = "00[0-9][0-9][0-9]L[0-9]\$";
Packit Service 392537
is(Amanda::Util::match_labelstr($labelstr, $autolabel, "000123L7", undef, undef, undef), 1, "match_labelstr 6");
Packit Service 392537
Packit Service 392537
$labelstr = {'match_autolabel'=> 1,
Packit Service 392537
	     'template' => ""};
Packit Service 392537
$autolabel = {'autolabel'=> 0,
Packit Service 392537
	      'template' => ""};
Packit Service 392537
$autolabel->{'template'} = "000[0-9][0-9][0-9]L[0-9]";
Packit Service 392537
is(Amanda::Util::match_labelstr($labelstr, $autolabel, "000123L7", undef, undef, undef), 1, "match_labelstr 7");
Packit Service 392537
$autolabel->{'template'} = "000[0-9][0-9][0-9]L";
Packit Service 392537
is(Amanda::Util::match_labelstr($labelstr, $autolabel, "000123L7", undef, undef, undef), '', "match_labelstr 8");
Packit Service 392537
$autolabel->{'template'} = "00[0-9][0-9][0-9]L[0-9]";
Packit Service 392537
is(Amanda::Util::match_labelstr($labelstr, $autolabel, "000123L7", undef, undef, undef), '', "match_labelstr 9");
Packit Service 392537