Imported Upstream version 3.3.3
[debian/amanda] / installcheck / Amanda_Cmdline.pl
1 # Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
2 #
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.
7 #
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
11 # for more details.
12 #
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
16 #
17 # Contact information: Zmanda Inc, 465 S. Mathilda Ave., Suite 300
18 # Sunnyvale, CA 94086, USA, or: http://www.zmanda.com
19
20 use Test::More tests => 54;
21 use strict;
22 use warnings;
23
24 use lib "@amperldir@";
25 use Amanda::Paths;
26 use Amanda::Cmdline qw( header_matches_dumpspecs );
27 use Amanda::Header;
28
29 my @specs;
30 my $hdr;
31
32 # convert a dumpspec_t object to an array, for easy is_deeply() comparisons
33 sub ds2av {
34     my ($ds) = @_;
35     return (
36         $ds->{'host'},
37         $ds->{'disk'},
38         $ds->{'datestamp'},
39         $ds->{'level'},
40         $ds->{'write_timestamp'},
41     );
42 }
43
44 # test dumpspec_t objects
45
46 is_deeply([ ds2av(Amanda::Cmdline::dumpspec_t->new("h", "di", "ds", "l", undef)) ],
47           [ "h", "di", "ds", "l", undef ],
48           "dumpspec_t constructor returns a valid dumpspec");
49
50 is_deeply([ ds2av(Amanda::Cmdline::dumpspec_t->new("h", "di", "ds", undef, undef)) ],
51           [ "h", "di", "ds", undef, undef ],
52           "dumpspec_t constructor returns a valid dumpspec with only 3 args");
53
54 is_deeply([ ds2av(Amanda::Cmdline::dumpspec_t->new("h", "di", undef, undef, undef)) ],
55           [ "h", "di", undef, undef, undef ],
56           "dumpspec_t constructor returns a valid dumpspec with only 2 args");
57
58 is_deeply([ ds2av(Amanda::Cmdline::dumpspec_t->new("h", undef, undef, undef, undef)) ],
59           [ "h", undef, undef, undef, undef ],
60           "dumpspec_t constructor returns a valid dumpspec with only 1 arg");
61
62 is_deeply([ ds2av(Amanda::Cmdline::dumpspec_t->new(undef, undef, undef, undef, "wt")) ],
63           [ undef, undef, undef, undef, "wt" ],
64           "dumpspec_t constructor returns a valid dumpspec with only write_timestamp arg");
65
66 @specs = Amanda::Cmdline::parse_dumpspecs(["h1", "d1", "h2", "d2"], 0);
67 is(@specs, 2, "parse of four elements with no flags yields 2 specs");
68 is_deeply([ ds2av($specs[0]) ], [ "h1", "d1", undef, undef, undef ], "..first spec is correct");
69 is_deeply([ ds2av($specs[1]) ], [ "h2", "d2", undef, undef, undef ], "..second spec is correct");
70
71 @specs = Amanda::Cmdline::parse_dumpspecs(["h1", "d1", "h2", "d2"], $Amanda::Cmdline::CMDLINE_EXACT_MATCH);
72 is(@specs, 2, "parse of four elements with CMDLINE_EXACT_MATCH yields 2 specs");
73 is_deeply([ ds2av($specs[0]) ], [ "=h1", "=d1", undef, undef, undef ], "..first spec is correct");
74 is_deeply([ ds2av($specs[1]) ], [ "=h2", "=d2", undef, undef, undef ], "..second spec is correct");
75
76 @specs = Amanda::Cmdline::parse_dumpspecs(["h1", "d1", "ds1", "h2", "d2", "ds2" ], $Amanda::Cmdline::CMDLINE_PARSE_DATESTAMP);
77 is(@specs, 2, "parse of six elements with CMDLINE_PARSE_DATESTAMP yields 2 specs");
78 is_deeply([ ds2av($specs[0]) ], [ "h1", "d1", "ds1", undef, undef ], "..first spec is correct");
79 is_deeply([ ds2av($specs[1]) ], [ "h2", "d2", "ds2", undef, undef ], "..second spec is correct");
80
81 @specs = Amanda::Cmdline::parse_dumpspecs(["h1", "d1", "ds1", "h2", "d2", "ds2" ], $Amanda::Cmdline::CMDLINE_PARSE_DATESTAMP | $Amanda::Cmdline::CMDLINE_EXACT_MATCH);
82 is(@specs, 2, "parse of six elements with CMDLINE_PARSE_DATESTAMP and CMDLINE_EXACT_MATCH yields 2 specs");
83 is_deeply([ ds2av($specs[0]) ], [ "=h1", "=d1", "=ds1", undef, undef ], "..first spec is correct");
84 is_deeply([ ds2av($specs[1]) ], [ "=h2", "=d2", "=ds2", undef, undef ], "..second spec is correct");
85
86 @specs = Amanda::Cmdline::parse_dumpspecs(["h1", "d1", "ds1", "lv1", "h2", "d2", "ds2", "lv2" ],
87                 $Amanda::Cmdline::CMDLINE_PARSE_DATESTAMP | $Amanda::Cmdline::CMDLINE_PARSE_LEVEL);
88 is(@specs, 2, "parse of eight elements with CMDLINE_PARSE_DATESTAMP and CMDLINE_PARSE_LEVEL yields 2 specs");
89 is_deeply([ ds2av($specs[0]) ], [ "h1", "d1", "ds1", "lv1", undef ], "..first spec is correct");
90 is_deeply([ ds2av($specs[1]) ], [ "h2", "d2", "ds2", "lv2", undef ], "..second spec is correct");
91
92 @specs = Amanda::Cmdline::parse_dumpspecs(["h1", "d1", "ds1", "lv1", "h2", "d2", "ds2", "lv2" ],
93                 $Amanda::Cmdline::CMDLINE_PARSE_DATESTAMP | $Amanda::Cmdline::CMDLINE_PARSE_LEVEL | $Amanda::Cmdline::CMDLINE_EXACT_MATCH);
94 is(@specs, 2, "parse of eight elements with CMDLINE_PARSE_DATESTAMP, CMDLINE_PARSE_LEVEL and CMDLINE_EXACT_MATCH yields 2 specs");
95 is_deeply([ ds2av($specs[0]) ], [ "=h1", "=d1", "=ds1", "=lv1", undef ], "..first spec is correct");
96 is_deeply([ ds2av($specs[1]) ], [ "=h2", "=d2", "=ds2", "=lv2", undef ], "..second spec is correct");
97
98 @specs = Amanda::Cmdline::parse_dumpspecs(["h1", "d1", "ds1", "lv1" ],
99                 $Amanda::Cmdline::CMDLINE_PARSE_DATESTAMP | $Amanda::Cmdline::CMDLINE_PARSE_LEVEL);
100 is(@specs, 1, "parse of four elements with CMDLINE_PARSE_DATESTAMP and CMDLINE_PARSE_LEVEL yields one spec");
101 is_deeply([ ds2av($specs[0]) ], [ "h1", "d1", "ds1", "lv1", undef ], "..which is correct");
102
103 @specs = Amanda::Cmdline::parse_dumpspecs(["h1", "d1", "ds1", "lv1" ],
104                 $Amanda::Cmdline::CMDLINE_PARSE_DATESTAMP | $Amanda::Cmdline::CMDLINE_PARSE_LEVEL | $Amanda::Cmdline::CMDLINE_EXACT_MATCH);
105 is(@specs, 1, "parse of four elements with CMDLINE_PARSE_DATESTAMP, CMDLINE_PARSE_LEVEL and CMDLINE_EXACT_MATCH yields one spec");
106 is_deeply([ ds2av($specs[0]) ], [ "=h1", "=d1", "=ds1", "=lv1", undef ], "..which is correct");
107
108 @specs = Amanda::Cmdline::parse_dumpspecs(["h1", "d1", "ds1" ],
109                 $Amanda::Cmdline::CMDLINE_PARSE_DATESTAMP | $Amanda::Cmdline::CMDLINE_PARSE_LEVEL);
110 is(@specs, 1, "parse of three elements with CMDLINE_PARSE_DATESTAMP and CMDLINE_PARSE_LEVEL yields one spec");
111 is_deeply([ ds2av($specs[0]) ], [ "h1", "d1", "ds1", undef, undef ], "..which is correct");
112
113 @specs = Amanda::Cmdline::parse_dumpspecs(["h1", "d1" ],
114                 $Amanda::Cmdline::CMDLINE_PARSE_DATESTAMP | $Amanda::Cmdline::CMDLINE_PARSE_LEVEL);
115 is(@specs, 1, "parse of two elements with CMDLINE_PARSE_DATESTAMP and CMDLINE_PARSE_LEVEL yields one spec");
116 is_deeply([ ds2av($specs[0]) ], [ "h1", "d1", undef, undef, undef ], "..which is correct");
117
118 @specs = Amanda::Cmdline::parse_dumpspecs(["h1" ],
119                 $Amanda::Cmdline::CMDLINE_PARSE_DATESTAMP | $Amanda::Cmdline::CMDLINE_PARSE_LEVEL);
120 is(@specs, 1, "parse of one element with CMDLINE_PARSE_DATESTAMP and CMDLINE_PARSE_LEVEL yields one spec");
121 is_deeply([ ds2av($specs[0]) ], [ "h1", undef, undef, undef, undef ], "..which is correct");
122
123 @specs = Amanda::Cmdline::parse_dumpspecs([],
124                 $Amanda::Cmdline::CMDLINE_PARSE_DATESTAMP | $Amanda::Cmdline::CMDLINE_PARSE_LEVEL);
125 is(@specs, 0, "parse of no elements with CMDLINE_PARSE_DATESTAMP and CMDLINE_PARSE_LEVEL yields no specs");
126
127 @specs = Amanda::Cmdline::parse_dumpspecs([],
128                 $Amanda::Cmdline::CMDLINE_PARSE_DATESTAMP | $Amanda::Cmdline::CMDLINE_PARSE_LEVEL
129                 | $Amanda::Cmdline::CMDLINE_EMPTY_TO_WILDCARD);
130 is(@specs, 1, "parse of no elements with CMDLINE_EMPTY_TO_WILDCARD yields one spec");
131
132 # test format_dumpspec_components
133
134 is(Amanda::Cmdline::format_dumpspec_components("h", "di", "ds", "l"),
135    "h di ds l",
136    "format_dumpspec_components works ok");
137
138 # test matching
139 $hdr = Amanda::Header->new();
140 $hdr->{'name'} = 'foo.bar.baz';
141 $hdr->{'disk'} = '/foo/bar/baz';
142 $hdr->{'datestamp'} = '20090102030405';
143 $hdr->{'dumplevel'} = 31;
144 $hdr->{'type'} = $Amanda::Header::F_DUMPFILE;
145
146 ok(!header_matches_dumpspecs($hdr, []), "header doesn't match empty list of dumpspecs");
147
148 ok(header_matches_dumpspecs($hdr, [Amanda::Cmdline::dumpspec_t->new('foo.bar.baz', undef, undef, undef, undef)]),
149    'header matches exact host dumpspec');
150 ok(header_matches_dumpspecs($hdr, [Amanda::Cmdline::dumpspec_t->new('foo', undef, undef, undef, undef)]),
151    'header matches partial host dumpspec');
152 ok(header_matches_dumpspecs($hdr, [Amanda::Cmdline::dumpspec_t->new('?a*', undef, undef, undef, undef)]),
153    'header matches host pattern dumpspec');
154
155 ok(header_matches_dumpspecs($hdr, [Amanda::Cmdline::dumpspec_t->new(undef, '/foo/bar/baz', undef, undef, undef)]),
156    'header matches exact disk dumpspec');
157 ok(header_matches_dumpspecs($hdr, [Amanda::Cmdline::dumpspec_t->new(undef, 'bar', undef, undef, undef)]),
158    'header matches partial disk dumpspec');
159 ok(header_matches_dumpspecs($hdr, [Amanda::Cmdline::dumpspec_t->new(undef, '*a?', undef, undef, undef)]),
160    'header matches disk pattern dumpspec');
161
162 ok(header_matches_dumpspecs($hdr, [Amanda::Cmdline::dumpspec_t->new(undef, undef, '20090102030405', undef, undef)]),
163    'header matches exact datestamp dumpspec');
164 ok(header_matches_dumpspecs($hdr, [Amanda::Cmdline::dumpspec_t->new(undef, undef, '2009', undef, undef)]),
165    'header matches partial datestamp dumpspec');
166 ok(header_matches_dumpspecs($hdr, [Amanda::Cmdline::dumpspec_t->new(undef, undef, '20090102030404-20090102030406', undef, undef)]),
167    'header matches datestamp range dumpspec');
168 ok(header_matches_dumpspecs($hdr, [Amanda::Cmdline::dumpspec_t->new(undef, undef, '2009-2010', undef, undef)]),
169    'header matches datestamp year-only range dumpspec');
170 ok(!header_matches_dumpspecs($hdr, [Amanda::Cmdline::dumpspec_t->new(undef, undef, '20090102030406-20090102030407', undef, undef)]),
171    "header doesn't match datestamp range dumpspec that it's outside of");
172
173 ok(header_matches_dumpspecs($hdr, [Amanda::Cmdline::dumpspec_t->new(undef, undef, undef, '31', undef)]),
174    'header matches exact level dumpspec');
175 ok(header_matches_dumpspecs($hdr, [Amanda::Cmdline::dumpspec_t->new(undef, undef, undef, '30-32', undef)]),
176    'header matches small level range dumpspec');
177 ok(header_matches_dumpspecs($hdr, [Amanda::Cmdline::dumpspec_t->new(undef, undef, undef, '4-50', undef)]),
178    'header matches large level range dumpspec');
179 ok(!header_matches_dumpspecs($hdr, [Amanda::Cmdline::dumpspec_t->new(undef, undef, undef, '32-50', undef)]),
180    "header doesn't match level range it's outside of");
181
182 ok(header_matches_dumpspecs($hdr, [
183     Amanda::Cmdline::dumpspec_t->new('foo.bar.baz', undef, undef, undef, undef),
184     Amanda::Cmdline::dumpspec_t->new(undef, '/foo/bar/baz', undef, undef, undef),
185   ]),
186   'header matches when two dumpspecs are possible matches');
187 ok(!header_matches_dumpspecs($hdr, [
188     Amanda::Cmdline::dumpspec_t->new(undef, undef, '20090102030406-20090102030407', undef, undef),
189     Amanda::Cmdline::dumpspec_t->new(undef, undef, undef, '32-50', undef),
190   ]),
191   'header matches when two dumpspecs are given and neither should match');