Imported Upstream version 3.2.1
[debian/amanda] / installcheck / Amanda_Tapelist.pl
1 # Copyright (c) 2008, 2010 Zmanda, Inc.  All Rights Reserved.
2 #
3 # This program is free software; you can redistribute it and/or modify it
4 # under the terms of the GNU General Public License version 2 as published
5 # by the Free Software Foundation.
6 #
7 # This program is distributed in the hope that it will be useful, but
8 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
9 # or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
10 # for more details.
11 #
12 # You should have received a copy of the GNU General Public License along
13 # with this program; if not, write to the Free Software Foundation, Inc.,
14 # 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
15 #
16 # Contact information: Zmanda Inc, 465 S. Mathilda Ave., Suite 300
17 # Sunnyvale, CA 94086, USA, or: http://www.zmanda.com
18
19 use Test::More tests => 24;
20 use strict;
21 use warnings;
22
23 use lib "@amperldir@";
24 use Installcheck::Config;
25 use Amanda::Tapelist;
26 use Amanda::Config qw( :init :getconf config_dir_relative );
27 use POSIX ":sys_wait_h";
28
29 # put the debug messages somewhere
30 Amanda::Debug::dbopen("installcheck");
31 Installcheck::log_test_output();
32
33 my $tl;
34 my $tl_ok;
35 my $line;
36 my @lines;
37
38 # First try reading a tapelist
39
40 my $testconf = Installcheck::Config->new();
41 $testconf->write();
42
43 config_init($CONFIG_INIT_EXPLICIT_NAME, "TESTCONF") == $CFGERR_OK
44     or die("config_init failed");
45 my $tapelist = config_dir_relative("tapelist");
46
47 sub mktapelist {
48     my ($filename, @lines) = @_;
49     open(my $fh, ">", $filename) or die("Could not make tapelist '$filename'");
50     for my $line (@lines) {
51         print $fh $line;
52     }
53     close($fh);
54 }
55
56 sub readtapelist {
57     my ($filename) = @_;
58     open(my $fh, "<", $filename) or die("Could not read tapelist '$filename'");
59     my @reread_lines = <$fh>;
60     close($fh);
61     return @reread_lines;
62 }
63
64 @lines = (
65     "20071111010002 TESTCONF004 reuse\n",
66     "20071110010002 TESTCONF003 reuse BARCODE:BAR-003\n",
67     "20071109010002 TESTCONF002 reuse BARCODE:BAR-002 #comment 2\n",
68     "20071108010001 TESTCONF001 no-reuse #comment 1\n",
69 );
70 mktapelist($tapelist, @lines);
71
72 $tl = Amanda::Tapelist->new($tapelist);
73 $tl_ok = is_deeply($tl, {
74  filename => $tapelist,
75  lockname => $tapelist . ".lock",
76  tles => [
77   { 'datestamp' => '20071111010002', 'label' => 'TESTCONF004',
78     'reuse' => 1, 'position' => 1, 'barcode' => undef, 'comment' => undef },
79   { 'datestamp' => '20071110010002', 'label' => 'TESTCONF003',
80     'reuse' => 1, 'position' => 2, 'barcode' => 'BAR-003', 'comment' => undef },
81   { 'datestamp' => '20071109010002', 'label' => 'TESTCONF002',
82     'reuse' => 1, 'position' => 3, 'barcode' => 'BAR-002', 'comment' => 'comment 2' },
83   { 'datestamp' => '20071108010001', 'label' => 'TESTCONF001',
84     'reuse' => '', 'position' => 4, 'barcode' => undef, 'comment' => 'comment 1' },
85 ] }, "A simple tapelist is parsed correctly");
86
87 SKIP: {
88     skip "Tapelist is parsed incorrectly, so these tests are unlikely to work", 15,
89         unless $tl_ok;
90
91     # now try writing it out and check that the results are the same
92     $tl->write("$tapelist-new");
93     my @reread_lines = readtapelist("$tapelist-new");
94     is_deeply(\@reread_lines, \@lines, "Lines of freshly written tapelist match the original");
95
96     is_deeply($tl->lookup_tapelabel('TESTCONF002'),
97         { 'datestamp' => '20071109010002', 'label' => 'TESTCONF002',
98           'reuse' => 1, 'position' => 3, 'barcode' => 'BAR-002', 'comment' => 'comment 2' },
99         "lookup_tapelabel works");
100
101     is_deeply($tl->lookup_tapelabel('TESTCONF009'), undef,
102         "lookup_tapelabel returns undef on an unknown label");
103
104     is_deeply($tl->lookup_tapepos(4),
105         { 'datestamp' => '20071108010001', 'label' => 'TESTCONF001',
106           'reuse' => '', 'position' => 4, 'barcode' => undef, 'comment' => 'comment 1' },
107         "lookup_tapepos works");
108
109     is_deeply($tl->lookup_tapepos(9), undef,
110         "lookup_tapepos returns undef on an unknown position");
111
112     is_deeply($tl->lookup_tapedate('20071110010002'),
113         { 'datestamp' => '20071110010002', 'label' => 'TESTCONF003',
114           'reuse' => 1, 'position' => 2, 'barcode' => 'BAR-003', 'comment' => undef },
115         "lookup_tapedate works");
116
117     is_deeply($tl->lookup_tapedate('12345678'), undef,
118         "lookup_tapedate returns undef on an unknown datestamp");
119
120     # try some edits
121     $tl->add_tapelabel("20080112010203", "TESTCONF007", "seven", 1, undef, 'BAR-007');
122     is(scalar @{$tl->{'tles'}}, 5, "add_tapelabel adds a new element to the tapelist");
123
124     is_deeply($tl->lookup_tapepos(1),
125         { 'datestamp' => '20080112010203', 'label' => 'TESTCONF007',
126           'reuse' => 1, 'position' => 1, 'barcode' => 'BAR-007', 'comment' => 'seven' },
127         ".. lookup_tapepos finds it at the beginning");
128
129     is_deeply($tl->lookup_tapelabel("TESTCONF007"),
130         { 'datestamp' => '20080112010203', 'label' => 'TESTCONF007',
131           'reuse' => 1, 'position' => 1, 'barcode' => 'BAR-007', 'comment' => 'seven' },
132         ".. lookup_tapelabel finds it");
133
134     is_deeply($tl->lookup_tapedate("20080112010203"),
135         { 'datestamp' => '20080112010203', 'label' => 'TESTCONF007',
136           'reuse' => 1, 'position' => 1, 'barcode' => 'BAR-007', 'comment' => 'seven' },
137         ".. lookup_tapedate finds it");
138
139     # try some edits
140     $tl->add_tapelabel("20080112010204", "TESTCONF008", "eight", 0);
141     is(scalar @{$tl->{'tles'}}, 6, "add_tapelabel adds a new element to the tapelist no-reuse");
142
143     is_deeply($tl->lookup_tapelabel("TESTCONF008"),
144         { 'datestamp' => '20080112010204', 'label' => 'TESTCONF008',
145           'reuse' => 0, 'position' => 1, 'barcode' => undef, 'comment' => 'eight' },
146         ".. lookup_tapelabel finds it no-reuse");
147
148     $tl->remove_tapelabel("TESTCONF008");
149     is(scalar @{$tl->{'tles'}}, 5, "remove_tapelabel removes an element from the tapelist, no-reuse");
150
151     $tl->remove_tapelabel("TESTCONF002");
152     is(scalar @{$tl->{'tles'}}, 4, "remove_tapelabel removes an element from the tapelist");
153
154     is_deeply($tl->lookup_tapepos(4), # used to be in position 5
155         { 'datestamp' => '20071108010001', 'label' => 'TESTCONF001',
156           'reuse' => '', 'position' => 4, 'barcode' => undef, 'comment' => 'comment 1' },
157         ".. tape positions are adjusted correctly");
158
159     is_deeply($tl->lookup_tapelabel("TESTCONF002"), undef,
160         ".. lookup_tapelabel no longer finds it");
161
162     is_deeply($tl->lookup_tapedate("20071109010002"), undef,
163         ".. lookup_tapedate no longer finds it");
164
165     ## set tapecycle to 0 to perform the next couple tests
166     config_uninit();
167     my $cor = new_config_overrides(1);
168     add_config_override_opt($cor, "tapecycle=1");
169     set_config_overrides($cor);
170     config_init($CONFIG_INIT_EXPLICIT_NAME, "TESTCONF") == $CFGERR_OK
171         or die("config_init failed");
172
173     is( Amanda::Tapelist::get_last_reusable_tape_label(0),
174         'TESTCONF002', ".. get_last_reusable_tape_labe for skip=0" );
175
176     is( Amanda::Tapelist::get_last_reusable_tape_label(2),
177         'TESTCONF004', ".. get_last_reusable_tape_labe for skip=2" );
178 }
179
180 # try parsing various invalid lines
181 @lines = (
182     "2006123456 FOO reuse\n", # valid
183     "TESTCONF003 290385098 reuse\n", # invalid
184     "20071109010002 TESTCONF002 re-use\n", # invalid
185     "20071108010001 TESTCONF001\n", # invalid
186     "20071108010001 TESTCONF001 #comment\n", # invalid
187     "#comment\n", # invalid
188 );
189 mktapelist($tapelist, @lines);
190
191 $tl = Amanda::Tapelist->new($tapelist);
192 is_deeply($tl, {
193   filename => $tapelist,
194   lockname => $tapelist . ".lock",
195   tles => [
196   { 'datestamp' => '2006123456', 'label' => 'FOO',
197     'reuse' => 1, 'position' => 1, 'barcode' => undef, 'comment' => undef },
198 ] }, "Invalid lines are ignored");
199
200 # make sure clear_tapelist is empty
201 $tl->clear_tapelist();
202 is_deeply($tl,  { filename => $tapelist,
203                   lockname => $tapelist . ".lock",
204                   tles => [] }, "clear_tapelist returns an empty tapelist");
205
206 $tl->reload();
207 is_deeply($tl, {
208   filename => $tapelist,
209   lockname => $tapelist . ".lock",
210   tles => [
211   { 'datestamp' => '2006123456', 'label' => 'FOO',
212     'reuse' => 1, 'position' => 1, 'barcode' => undef, 'comment' => undef },
213 ] }, "reload works");
214