Imported Upstream version 3.3.3
[debian/amanda] / installcheck / Amanda_Tapelist.pl
1 # Copyright (c) 2008-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 => 26;
21 use strict;
22 use warnings;
23
24 use lib "@amperldir@";
25 use Installcheck::Config;
26 use Amanda::Tapelist;
27 use Amanda::Config qw( :init :getconf config_dir_relative );
28 use POSIX ":sys_wait_h";
29 use Data::Dumper;
30
31 # put the debug messages somewhere
32 Amanda::Debug::dbopen("installcheck");
33 Installcheck::log_test_output();
34
35 my $tl;
36 my $tl_ok;
37 my $line;
38 my @lines;
39
40 # First try reading a tapelist
41
42 my $testconf = Installcheck::Config->new();
43 $testconf->write();
44
45 config_init($CONFIG_INIT_EXPLICIT_NAME, "TESTCONF") == $CFGERR_OK
46     or die("config_init failed");
47 my $tapelist = config_dir_relative("tapelist");
48
49 sub mktapelist {
50     my ($filename, @lines) = @_;
51     open(my $fh, ">", $filename) or die("Could not make tapelist '$filename'");
52     for my $line (@lines) {
53         print $fh $line;
54     }
55     close($fh);
56 }
57
58 sub readtapelist {
59     my ($filename) = @_;
60     open(my $fh, "<", $filename) or die("Could not read tapelist '$filename'");
61     my @reread_lines = <$fh>;
62     close($fh);
63     return @reread_lines;
64 }
65
66 @lines = (
67     "20071111010002 TESTCONF004 reuse META:META1\n",
68     "20071110010002 TESTCONF003 reuse BARCODE:BAR-003 BLOCKSIZE:32\n",
69     "20071109010002 TESTCONF002 reuse BARCODE:BAR-002 META:META2 BLOCKSIZE:64 #comment 2\n",
70     "20071108010001 TESTCONF001 no-reuse #comment 1\n",
71     "20071107110002 TESTCONF015\n",
72     "20071107010002 TESTCONF006 no-reuse\n",
73     "20071106010002 TESTCONF005 reuse\n",
74 );
75 mktapelist($tapelist, @lines);
76
77 $tl = Amanda::Tapelist->new($tapelist);
78 $tl_ok = is_deeply($tl, {
79  filename => $tapelist,
80  lockname => $tapelist . ".lock",
81  tles => [
82   { 'datestamp' => '20071111010002', 'label' => 'TESTCONF004',
83     'reuse' => 1, 'position' => 1, 'blocksize' => undef,
84     'barcode' => undef, 'meta' => 'META1', 'comment' => undef },
85   { 'datestamp' => '20071110010002', 'label' => 'TESTCONF003',
86     'reuse' => 1, 'position' => 2, 'blocksize' => '32',
87     'barcode' => 'BAR-003', 'meta' => undef, 'comment' => undef },
88   { 'datestamp' => '20071109010002', 'label' => 'TESTCONF002',
89     'reuse' => 1, 'position' => 3, 'blocksize' => '64',
90     'barcode' => 'BAR-002', 'meta' => 'META2', 'comment' => 'comment 2' },
91   { 'datestamp' => '20071108010001', 'label' => 'TESTCONF001',
92     'reuse' => '', 'position' => 4, 'blocksize' => undef,
93     'barcode' => undef, 'meta' => undef, 'comment' => 'comment 1' },
94   { 'datestamp' => '20071107110002', 'label' => 'TESTCONF015',
95     'reuse' => 1, 'position' => 5, 'blocksize' => undef,
96     'barcode' => undef, 'meta' => undef, 'comment' => undef },
97   { 'datestamp' => '20071107010002', 'label' => 'TESTCONF006',
98     'reuse' => '', 'position' => 6, 'blocksize' => undef,
99     'barcode' => undef, 'meta' => undef, 'comment' => undef },
100   { 'datestamp' => '20071106010002', 'label' => 'TESTCONF005',
101     'reuse' => 1, 'position' => 7, 'blocksize' => undef,
102     'barcode' => undef, 'meta' => undef, 'comment' => undef },
103 ] }, "A simple tapelist is parsed correctly");
104
105 SKIP: {
106     skip "Tapelist is parsed incorrectly, so these tests are unlikely to work", 15,
107         unless $tl_ok;
108
109     # now try writing it out and check that the results are the same
110     $tl->write("$tapelist-new");
111     my @reread_lines = readtapelist("$tapelist-new");
112     chomp($lines[4]);
113     $lines[4] .= " reuse\n"; #'reuse' is automatically written
114     is_deeply(\@reread_lines, \@lines, "Lines of freshly written tapelist match the original");
115
116     is_deeply($tl->lookup_tapelabel('TESTCONF002'),
117         { 'datestamp' => '20071109010002', 'label' => 'TESTCONF002',
118           'reuse' => 1, 'position' => 3, 'blocksize' => '64',
119           'barcode' => 'BAR-002', 'meta' => 'META2', 'comment' => 'comment 2' },
120         "lookup_tapelabel works");
121
122     is_deeply($tl->lookup_tapelabel('TESTCONF009'), undef,
123         "lookup_tapelabel returns undef on an unknown label");
124
125     is_deeply($tl->lookup_tapepos(4),
126         { 'datestamp' => '20071108010001', 'label' => 'TESTCONF001',
127           'reuse' => '', 'position' => 4, 'blocksize' => undef,
128           'barcode' => undef, 'meta' => undef, 'comment' => 'comment 1' },
129         "lookup_tapepos works");
130
131     is_deeply($tl->lookup_tapepos(9), undef,
132         "lookup_tapepos returns undef on an unknown position");
133
134     is_deeply($tl->lookup_tapedate('20071110010002'),
135         { 'datestamp' => '20071110010002', 'label' => 'TESTCONF003',
136           'reuse' => 1, 'position' => 2, 'blocksize' => '32',
137           'barcode' => 'BAR-003', 'meta' => undef, 'comment' => undef },
138         "lookup_tapedate works");
139
140     is_deeply($tl->lookup_tapedate('12345678'), undef,
141         "lookup_tapedate returns undef on an unknown datestamp");
142
143     # try some edits
144     $tl->add_tapelabel("20080112010203", "TESTCONF007", "seven", 1, 'META3', 'BAR-007');
145     is(scalar @{$tl->{'tles'}}, 8, "add_tapelabel adds a new element to the tapelist");
146
147     is_deeply($tl->lookup_tapepos(1),
148         { 'datestamp' => '20080112010203', 'label' => 'TESTCONF007',
149           'reuse' => 1, 'position' => 1, 'blocksize' => undef,
150           'barcode' => 'BAR-007', 'meta' => 'META3', 'comment' => 'seven' },
151         ".. lookup_tapepos finds it at the beginning");
152
153     is_deeply($tl->lookup_tapelabel("TESTCONF007"),
154         { 'datestamp' => '20080112010203', 'label' => 'TESTCONF007',
155           'reuse' => 1, 'position' => 1, 'blocksize' => undef,
156           'barcode' => 'BAR-007', 'meta' => 'META3' , 'comment' => 'seven' },
157         ".. lookup_tapelabel finds it");
158
159     is_deeply($tl->lookup_tapedate("20080112010203"),
160         { 'datestamp' => '20080112010203', 'label' => 'TESTCONF007',
161           'reuse' => 1, 'position' => 1, 'blocksize' => undef,
162           'barcode' => 'BAR-007', 'meta' => 'META3', 'comment' => 'seven' },
163         ".. lookup_tapedate finds it");
164
165     # try some edits
166     $tl->add_tapelabel("20080112010204", "TESTCONF008", "eight", 0, undef, undef, 128);
167     is(scalar @{$tl->{'tles'}}, 9, "add_tapelabel adds a new element to the tapelist no-reuse");
168
169     is_deeply($tl->lookup_tapelabel("TESTCONF008"),
170         { 'datestamp' => '20080112010204', 'label' => 'TESTCONF008',
171           'reuse' => 0, 'position' => 1, 'blocksize' => '128',
172            'barcode' => undef, 'meta' => undef, 'comment' => 'eight' },
173         ".. lookup_tapelabel finds it no-reuse");
174
175     $tl->remove_tapelabel("TESTCONF008");
176     is(scalar @{$tl->{'tles'}}, 8, "remove_tapelabel removes an element from the tapelist, no-reuse");
177
178     $tl->remove_tapelabel("TESTCONF002");
179     is(scalar @{$tl->{'tles'}}, 7, "remove_tapelabel removes an element from the tapelist");
180
181     is_deeply($tl->lookup_tapepos(4), # used to be in position 5
182         { 'datestamp' => '20071108010001', 'label' => 'TESTCONF001',
183           'reuse' => '', 'position' => 4, 'blocksize' => undef,
184           'barcode' => undef, 'meta' => undef, 'comment' => 'comment 1' },
185         ".. tape positions are adjusted correctly");
186
187     is_deeply($tl->lookup_tapelabel("TESTCONF002"), undef,
188         ".. lookup_tapelabel no longer finds it");
189
190     is_deeply($tl->lookup_tapedate("20071109010002"), undef,
191         ".. lookup_tapedate no longer finds it");
192
193     # insert in the middle of the list.
194     $tl->add_tapelabel("20071109010204", "TESTCONF009", "nine", 1);
195
196     is_deeply($tl->lookup_tapepos(4),
197         { 'datestamp' => '20071109010204', 'label' => 'TESTCONF009',
198           'reuse' => '1', 'position' => 4, 'blocksize' => undef,
199           'barcode' => undef, 'meta' => undef, 'comment' => 'nine' },
200         ".. tape positions are adjusted correctly");
201
202     is_deeply($tl->lookup_tapelabel('TESTCONF009'),
203         { 'datestamp' => '20071109010204', 'label' => 'TESTCONF009',
204           'reuse' => '1', 'position' => 4, 'blocksize' => undef,
205           'barcode' => undef, 'meta' => undef, 'comment' => 'nine' },
206         ".. tape positions are adjusted correctly");
207
208     ## set tapecycle to 0 to perform the next couple tests
209     config_uninit();
210     my $cor = new_config_overrides(1);
211     add_config_override_opt($cor, "tapecycle=1");
212     set_config_overrides($cor);
213     config_init($CONFIG_INIT_EXPLICIT_NAME, "TESTCONF") == $CFGERR_OK
214         or die("config_init failed");
215
216     is( Amanda::Tapelist::get_last_reusable_tape_label(0),
217         'TESTCONF005', ".. get_last_reusable_tape_labe for skip=0" );
218
219     is( Amanda::Tapelist::get_last_reusable_tape_label(2),
220         'TESTCONF002', ".. get_last_reusable_tape_labe for skip=2" );
221 }
222
223 # try parsing various invalid lines
224 @lines = (
225     "2006123456 FOO reuse\n", # valid
226 #    "TESTCONF003 290385098 reuse\n", # invalid
227 #    "20071109010002 TESTCONF002 re-use\n", # invalid
228 #    "20071108010001 TESTCONF001\n", # invalid
229 #    "20071108010001 TESTCONF001 #comment\n", # invalid
230 #    "#comment\n", # invalid
231 );
232 mktapelist($tapelist, @lines);
233
234 $tl = Amanda::Tapelist->new($tapelist);
235 is_deeply($tl, {
236   filename => $tapelist,
237   lockname => $tapelist . ".lock",
238   tles => [
239   { 'datestamp' => '2006123456', 'label' => 'FOO',
240     'reuse' => 1, 'position' => 1, 'blocksize' => undef,
241     'barcode' => undef, 'meta' => undef, 'comment' => undef },
242 ] }, "Invalid lines are ignored");
243
244 # make sure clear_tapelist is empty
245 $tl->clear_tapelist();
246 is_deeply($tl,  { filename => $tapelist,
247                   lockname => $tapelist . ".lock",
248                   tles => [] }, "clear_tapelist returns an empty tapelist");
249
250 $tl->reload();
251 is_deeply($tl, {
252   filename => $tapelist,
253   lockname => $tapelist . ".lock",
254   tles => [
255   { 'datestamp' => '2006123456', 'label' => 'FOO',
256     'reuse' => 1, 'position' => 1, 'blocksize' => undef,
257     'barcode' => undef, 'meta' => undef, 'comment' => undef },
258 ] }, "reload works");
259