1 # Copyright (c) 2010-2012 Zmanda Inc. All Rights Reserved.
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.
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
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
17 # Contact information: Zmanda Inc, 465 S. Mathilda Ave., Suite 300
18 # Sunnyvale, CA 94086, USA, or: http://www.zmanda.com
20 use Test::More tests => 27;
26 use lib "@amperldir@";
28 use Installcheck::Config;
29 use Installcheck::Changer;
30 use Amanda::Device qw( :constants );
33 use Amanda::Config qw( :init :getconf config_dir_relative );
35 use Amanda::Taper::Scan;
37 # set up debugging so debug output doesn't interfere with test results
38 Amanda::Debug::dbopen("installcheck");
39 Installcheck::log_test_output();
41 # and disable Debug's die() and warn() overrides
42 Amanda::Debug::disable_die_override();
44 my $taperoot = "$Installcheck::TMP/Amanda_Taper_Scan_lexical";
45 my $tapelist_filename = "$Installcheck::TMP/tapelist";
46 `cat /dev/null > $Installcheck::TMP/tapelist`;
47 my $tapelist = Amanda::Tapelist->new($tapelist_filename);
60 for my $slot (1 .. $nslots) {
61 mkdir("$taperoot/slot$slot")
62 or die("Could not mkdir: $!");
65 # clear out the tapefile
66 open(my $fh, ">", $tapelist_filename) or die("opening tapelist_filename: $!");
71 my ($slot, $label, $stamp, $reuse, $update_tapelist) = @_;
73 my $drivedir = "$taperoot/tmp";
74 -d $drivedir and rmtree($drivedir);
76 symlink("$taperoot/slot$slot", "$drivedir/data");
78 my $dev = Amanda::Device->new("file:$drivedir");
79 die $dev->error_or_status() unless $dev->status == $DEVICE_STATUS_SUCCESS;
82 if (!$dev->start($ACCESS_WRITE, $label, $stamp)) {
83 die $dev->error_or_status();
91 if ($update_tapelist) {
92 if (exists $slot_label{$slot}) {
93 $tapelist->remove_tapelabel($slot_label{$slot});
94 delete $slot_label{$slot};
96 # tapelist uses '0' for new tapes; devices use 'X'..
97 $stamp = '0' if ($stamp eq 'X');
98 $reuse = $reuse ne 'no-reuse';
99 $tapelist->remove_tapelabel($label);
100 $tapelist->add_tapelabel($stamp, $label, "", $reuse);
102 $slot_label{$slot} = $label;
103 #open(my $fh, ">>", $tapelist_filename) or die("opening tapelist_filename: $!");
104 #print $fh "$stamp $label $reuse\n";
109 # run the mainloop around a scan
112 my ($error, $res, $label, $mode);
114 my $result_cb = make_cb(result_cb => sub {
115 ($error, $res, $label, $mode) = @_;
117 $error = "$error" if defined $error;
119 $res->release(finished_cb => sub {
120 Amanda::MainLoop::quit();
123 Amanda::MainLoop::quit();
127 $ts->scan(result_cb => $result_cb);
128 Amanda::MainLoop::run();
129 return $error, $label, $mode;
132 # set the current slot on the changer
133 sub set_current_slot {
136 unlink("$taperoot/data");
137 symlink("slot$slot", "$taperoot/data");
140 # set up and load a config
141 my $testconf = Installcheck::Config->new();
142 $testconf->add_param("tapelist", "\"$tapelist\"");
143 $testconf->add_param("labelstr", "\"TEST-[0-9]+\"");
145 my $cfg_result = config_init($CONFIG_INIT_EXPLICIT_NAME, 'TESTCONF');
146 if ($cfg_result != $CFGERR_OK) {
147 my ($level, @errors) = Amanda::Config::config_errors();
148 die(join "\n", @errors);
152 $tapelist->clear_tapelist();
154 label_slot(1, "TEST-10", "20090424173011", "reuse", 1);
155 label_slot(2, "TEST-20", "20090424173022", "reuse", 1);
156 label_slot(3, "TEST-30", "20090424173033", "reuse", 1);
162 # set up a lexical taperscan
163 $chg = Amanda::Changer->new("chg-disk:$taperoot", tapelist => $tapelist);
164 $taperscan = Amanda::Taper::Scan->new(
165 tapelist => $tapelist,
166 algorithm => "lexical",
169 @results = run_scan($taperscan);
170 is_deeply([ @results ],
171 [ "No acceptable volumes found", undef, undef ],
172 "no reusable tapes -> error")
173 or diag(Dumper(\@results));
176 $chg = Amanda::Changer->new("chg-disk:$taperoot", tapelist => $tapelist);
177 $taperscan = Amanda::Taper::Scan->new(
178 tapelist => $tapelist,
179 algorithm => "lexical",
182 @results = run_scan($taperscan);
183 is_deeply([ @results ],
184 [ undef, "TEST-10", $ACCESS_WRITE ],
185 "finds the best reusable tape")
186 or diag(Dumper(\@results));
189 $chg = Amanda::Changer->new("chg-disk:$taperoot", tapelist => $tapelist);
191 $taperscan = Amanda::Taper::Scan->new(
192 tapelist => $tapelist,
193 algorithm => "lexical",
196 @results = run_scan($taperscan);
197 is_deeply([ @results ],
198 [ undef, "TEST-10", $ACCESS_WRITE ],
199 "finds the first reusable tape")
200 or diag(Dumper(\@results));
203 label_slot(4, "TEST-40", "20090424173030", "reuse", 1);
204 $chg = Amanda::Changer->new("chg-disk:$taperoot", tapelist => $tapelist);
205 $taperscan = Amanda::Taper::Scan->new(
206 tapelist => $tapelist,
207 algorithm => "lexical",
210 @results = run_scan($taperscan);
211 is_deeply([ @results ],
212 [ undef, "TEST-40", $ACCESS_WRITE ],
213 "finds the first reusable tape")
214 or diag(Dumper(\@results));
217 label_slot(4, "TEST-40", "X", "reuse", 1);
218 label_slot(5, "TEST-35", "X", "reuse", 1);
219 $chg = Amanda::Changer->new("chg-disk:$taperoot", tapelist => $tapelist);
220 $taperscan = Amanda::Taper::Scan->new(
221 tapelist => $tapelist,
222 algorithm => "lexical",
225 @results = run_scan($taperscan);
226 is_deeply([ @results ],
227 [ undef, "TEST-35", $ACCESS_WRITE ],
228 "finds the first reusable tape")
229 or diag(Dumper(\@results));
232 $chg = Amanda::Changer->new("chg-disk:$taperoot",
233 tapelist => $tapelist,
234 autolabel => { 'template' => "TEST-%0",
236 'volume_error' => 1});
237 $taperscan = Amanda::Taper::Scan->new(
238 tapelist => $tapelist,
239 algorithm => "lexical",
242 $taperscan->{'scan_conf'}->{'new_labeled'} = 'order';
243 $taperscan->{'scan_conf'}->{'new_volume'} = 'soon';
244 @results = run_scan($taperscan);
245 is_deeply([ @results ],
246 [ undef, "TEST-50", $ACCESS_WRITE ],
247 "labels new tapes in blank slots")
248 or diag(Dumper(\@results));
251 $chg = Amanda::Changer->new("chg-disk:$taperoot",
252 tapelist => $tapelist);
253 $taperscan->{'scan_conf'}->{'new_labeled'} = 'order';
254 $taperscan->{'scan_conf'}->{'new_volume'} = 'soon';
256 label_slot(1, "TEST-60", "X", "reuse", 1);
257 $taperscan = Amanda::Taper::Scan->new(
258 tapelist => $tapelist,
259 algorithm => "lexical",
263 @results = run_scan($taperscan);
264 is_deeply([ @results ],
265 [ undef, "TEST-35", $ACCESS_WRITE ],
266 "scans for volumes, even with a newly labeled volume available")
267 or diag(Dumper(\@results));
270 # test new_labeled with autolabel
272 $tapelist->clear_tapelist();
274 label_slot(1, "TEST-10", "20090424173011", "reuse", 1);
275 label_slot(2, "TEST-20", "20090424173033", "reuse", 1);
276 label_slot(4, "TEST-30", "20090424173022", "reuse", 1);
277 label_slot(3, "TEST-15", "X", "reuse", 1);
278 label_slot(5, "TEST-25", "X", "reuse", 1);
281 $chg = Amanda::Changer->new("chg-disk:$taperoot", tapelist => $tapelist,
282 autolabel => { 'template' => "TEST-%0",
284 'volume_error' => 1});
287 $taperscan = Amanda::Taper::Scan->new(
288 tapelist => $tapelist,
289 algorithm => "lexical",
292 $taperscan->{'scan_conf'}->{'new_labeled'} = 'soon';
293 $taperscan->{'scan_conf'}->{'new_volume'} = 'soon';
294 @results = run_scan($taperscan);
295 is_deeply([ @results ],
296 [ undef, "TEST-25", $ACCESS_WRITE ],
298 or diag(Dumper(\@results));
300 $taperscan->{'scan_conf'}->{'new_labeled'} = 'order';
301 $taperscan->{'scan_conf'}->{'new_volume'} = 'order';
302 @results = run_scan($taperscan);
303 is_deeply([ @results ],
304 [ undef, "TEST-25", $ACCESS_WRITE ],
306 or diag(Dumper(\@results));
308 $taperscan->{'scan_conf'}->{'new_labeled'} = 'last';
309 $taperscan->{'scan_conf'}->{'new_volume'} = 'last';
310 @results = run_scan($taperscan);
311 is_deeply([ @results ],
312 [ undef, "TEST-30", $ACCESS_WRITE ],
314 or diag(Dumper(\@results));
317 # test new_labeled with autolabel
319 $tapelist->clear_tapelist();
321 label_slot(1, "TEST-10", "20090424173011", "reuse", 1);
322 label_slot(2, "TEST-20", "20090424173033", "reuse", 1);
323 label_slot(4, "TEST-30", "20090424173022", "reuse", 1);
324 label_slot(3, "TEST-15", "X", "reuse", 1);
327 $chg = Amanda::Changer->new("chg-disk:$taperoot", tapelist => $tapelist,
328 autolabel => { 'template' => "TEST-%0",
330 'volume_error' => 1});
333 $taperscan = Amanda::Taper::Scan->new(
334 tapelist => $tapelist,
335 algorithm => "lexical",
338 $taperscan->{'scan_conf'}->{'new_labeled'} = 'soon';
339 $taperscan->{'scan_conf'}->{'new_volume'} = 'soon';
340 @results = run_scan($taperscan);
341 is_deeply([ @results ],
342 [ undef, "TEST-15", $ACCESS_WRITE ],
344 or diag(Dumper(\@results));
346 $taperscan->{'scan_conf'}->{'new_labeled'} = 'order';
347 $taperscan->{'scan_conf'}->{'new_volume'} = 'order';
348 @results = run_scan($taperscan);
349 is_deeply([ @results ],
350 [ undef, "TEST-30", $ACCESS_WRITE ],
352 or diag(Dumper(\@results));
354 $taperscan->{'scan_conf'}->{'new_labeled'} = 'last';
355 $taperscan->{'scan_conf'}->{'new_volume'} = 'last';
356 @results = run_scan($taperscan);
357 is_deeply([ @results ],
358 [ undef, "TEST-30", $ACCESS_WRITE ],
360 or diag(Dumper(\@results));
362 $taperscan->{'scan_conf'}->{'new_labeled'} = 'last';
363 $taperscan->{'scan_conf'}->{'new_volume'} = 'order';
364 @results = run_scan($taperscan);
365 is_deeply([ @results ],
366 [ undef, "TEST-30", $ACCESS_WRITE ],
368 or diag(Dumper(\@results));
370 $taperscan->{'scan_conf'}->{'new_labeled'} = 'order';
371 $taperscan->{'scan_conf'}->{'new_volume'} = 'soon';
372 @results = run_scan($taperscan);
373 is_deeply([ @results ],
374 [ undef, "TEST-40", $ACCESS_WRITE ],
376 or diag(Dumper(\@results));
379 # test new_labeled with autolabel
381 $tapelist->clear_tapelist();
383 label_slot(1, "TEST-10", "20090424173011", "reuse", 1);
384 label_slot(2, "TEST-20", "20090424173022", "reuse", 1);
385 label_slot(4, "TEST-30", "20090424173033", "reuse", 1);
386 label_slot(3, "TEST-15", "X", "reuse", 1);
389 $chg = Amanda::Changer->new("chg-disk:$taperoot", tapelist => $tapelist,
390 autolabel => { 'template' => "TEST-%0",
392 'volume_error' => 1});
395 $taperscan = Amanda::Taper::Scan->new(
396 tapelist => $tapelist,
397 algorithm => "lexical",
400 $taperscan->{'scan_conf'}->{'new_labeled'} = 'soon';
401 $taperscan->{'scan_conf'}->{'new_volume'} = 'soon';
402 @results = run_scan($taperscan);
403 is_deeply([ @results ],
404 [ undef, "TEST-15", $ACCESS_WRITE ],
406 or diag(Dumper(\@results));
408 $taperscan->{'scan_conf'}->{'new_labeled'} = 'order';
409 $taperscan->{'scan_conf'}->{'new_volume'} = 'order';
410 @results = run_scan($taperscan);
411 is_deeply([ @results ],
412 [ undef, "TEST-40", $ACCESS_WRITE ],
414 or diag(Dumper(\@results));
416 $taperscan->{'scan_conf'}->{'new_labeled'} = 'last';
417 $taperscan->{'scan_conf'}->{'new_volume'} = 'last';
418 @results = run_scan($taperscan);
419 is_deeply([ @results ],
420 [ undef, "TEST-10", $ACCESS_WRITE ],
422 or diag(Dumper(\@results));
424 $taperscan->{'scan_conf'}->{'new_labeled'} = 'last';
425 $taperscan->{'scan_conf'}->{'new_volume'} = 'order';
426 @results = run_scan($taperscan);
427 is_deeply([ @results ],
428 [ undef, "TEST-40", $ACCESS_WRITE ],
430 or diag(Dumper(\@results));
432 $taperscan->{'scan_conf'}->{'new_labeled'} = 'order';
433 $taperscan->{'scan_conf'}->{'new_volume'} = 'soon';
434 @results = run_scan($taperscan);
435 is_deeply([ @results ],
436 [ undef, "TEST-40", $ACCESS_WRITE ],
438 or diag(Dumper(\@results));
441 # test new_volume with autolabel
443 $tapelist->clear_tapelist();
445 label_slot(1, "TEST-10", "20090424173011", "reuse", 1);
446 label_slot(2, "TEST-20", "20090424173033", "reuse", 1);
447 label_slot(4, "TEST-30", "20090424173022", "reuse", 1);
450 $chg = Amanda::Changer->new("chg-disk:$taperoot", tapelist => $tapelist,
451 autolabel => { 'template' => "TEST-%0",
453 'volume_error' => 1});
456 $taperscan = Amanda::Taper::Scan->new(
457 tapelist => $tapelist,
458 algorithm => "lexical",
461 $taperscan->{'scan_conf'}->{'new_labeled'} = 'soon';
462 $taperscan->{'scan_conf'}->{'new_volume'} = 'soon';
463 @results = run_scan($taperscan);
464 is_deeply([ @results ],
465 [ undef, "TEST-40", $ACCESS_WRITE ],
467 or diag(Dumper(\@results));
469 $taperscan->{'scan_conf'}->{'new_labeled'} = 'order';
470 $taperscan->{'scan_conf'}->{'new_volume'} = 'order';
471 @results = run_scan($taperscan);
472 is_deeply([ @results ],
473 [ undef, "TEST-30", $ACCESS_WRITE ],
475 or diag(Dumper(\@results));
477 $taperscan->{'scan_conf'}->{'new_labeled'} = 'last';
478 $taperscan->{'scan_conf'}->{'new_volume'} = 'last';
479 @results = run_scan($taperscan);
480 is_deeply([ @results ],
481 [ undef, "TEST-30", $ACCESS_WRITE ],
483 or diag(Dumper(\@results));
486 $chg = Amanda::Changer->new("chg-disk:$taperoot", tapelist => $tapelist,
487 autolabel => { 'template' => "TEST-%0",
489 'volume_error' => 1});
490 $taperscan = Amanda::Taper::Scan->new(
491 tapelist => $tapelist,
492 algorithm => "lexical",
495 $taperscan->{'scan_conf'}->{'new_labeled'} = 'soon';
496 $taperscan->{'scan_conf'}->{'new_volume'} = 'soon';
497 @results = run_scan($taperscan);
498 is_deeply([ @results ],
499 [ undef, "TEST-40", $ACCESS_WRITE ],
501 or diag(Dumper(\@results));
503 $taperscan->{'scan_conf'}->{'new_labeled'} = 'order';
504 $taperscan->{'scan_conf'}->{'new_volume'} = 'order';
505 @results = run_scan($taperscan);
506 is_deeply([ @results ],
507 [ undef, "TEST-40", $ACCESS_WRITE ],
509 or diag(Dumper(\@results));
511 $taperscan->{'scan_conf'}->{'new_labeled'} = 'last';
512 $taperscan->{'scan_conf'}->{'new_volume'} = 'last';
513 @results = run_scan($taperscan);
514 is_deeply([ @results ],
515 [ undef, "TEST-40", $ACCESS_WRITE ],
517 or diag(Dumper(\@results));
520 # test skipping no-reuse tapes
522 $tapelist->clear_tapelist();
524 label_slot(1, "TEST-1", "20090424173001", "no-reuse", 1);
525 label_slot(2, "TEST-2", "20090424173002", "reuse", 1);
526 label_slot(3, "TEST-3", "20090424173003", "reuse", 1);
527 label_slot(4, "TEST-4", "20090424173004", "reuse", 1);
529 $chg = Amanda::Changer->new("chg-disk:$taperoot", tapelist => $tapelist);
532 $taperscan = Amanda::Taper::Scan->new(
533 tapelist => $tapelist,
534 algorithm => "lexical",
538 @results = run_scan($taperscan);
539 is_deeply([ @results ],
540 [ undef, "TEST-2", $ACCESS_WRITE ],
541 "skips a no-reuse volume")
542 or diag(Dumper(\@results));