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