1 # Copyright (c) 2010 Zmanda Inc. All Rights Reserved.
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.
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
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
16 # Contact information: Zmanda Inc, 465 S. Mathilda Ave., Suite 300
17 # Sunnyvale, CA 94086, USA, or: http://www.zmanda.com
19 use Test::More tests => 27;
25 use lib "@amperldir@";
27 use Installcheck::Config;
28 use Installcheck::Changer;
29 use Amanda::Device qw( :constants );
32 use Amanda::Config qw( :init :getconf config_dir_relative );
34 use Amanda::Taper::Scan;
36 # set up debugging so debug output doesn't interfere with test results
37 Amanda::Debug::dbopen("installcheck");
38 Installcheck::log_test_output();
40 # and disable Debug's die() and warn() overrides
41 Amanda::Debug::disable_die_override();
43 my $taperoot = "$Installcheck::TMP/Amanda_Taper_Scan_oldest";
44 my $tapelist_filename = "$Installcheck::TMP/tapelist";
45 `cat /dev/null > $Installcheck::TMP/tapelist`;
46 my $tapelist = Amanda::Tapelist->new($tapelist_filename);
59 for my $slot (1 .. $nslots) {
60 mkdir("$taperoot/slot$slot")
61 or die("Could not mkdir: $!");
64 # clear out the tapefile
65 open(my $fh, ">", $tapelist_filename) or die("opening tapelist_filename: $!");
70 my ($slot, $label, $stamp, $reuse, $update_tapelist) = @_;
72 my $drivedir = "$taperoot/tmp";
73 -d $drivedir and rmtree($drivedir);
75 symlink("$taperoot/slot$slot", "$drivedir/data");
77 my $dev = Amanda::Device->new("file:$drivedir");
78 die $dev->error_or_status() unless $dev->status == $DEVICE_STATUS_SUCCESS;
81 if (!$dev->start($ACCESS_WRITE, $label, $stamp)) {
82 die $dev->error_or_status();
90 if ($update_tapelist) {
91 if (exists $slot_label{$slot}) {
92 $tapelist->remove_tapelabel($slot_label{$slot});
93 delete $slot_label{$slot};
95 # tapelist uses '0' for new tapes; devices use 'X'..
96 $stamp = '0' if ($stamp eq 'X');
97 $reuse = $reuse ne 'no-reuse';
98 $tapelist->remove_tapelabel($label);
99 $tapelist->add_tapelabel($stamp, $label, "", $reuse);
101 $slot_label{$slot} = $label;
102 #open(my $fh, ">>", $tapelist_filename) or die("opening tapelist_filename: $!");
103 #print $fh "$stamp $label $reuse\n";
108 # run the mainloop around a scan
111 my ($error, $res, $label, $mode);
113 my $result_cb = make_cb(result_cb => sub {
114 ($error, $res, $label, $mode) = @_;
116 $error = "$error" if defined $error;
118 $res->release(finished_cb => sub {
119 Amanda::MainLoop::quit();
122 Amanda::MainLoop::quit();
126 $ts->scan(result_cb => $result_cb);
127 Amanda::MainLoop::run();
128 return $error, $label, $mode;
131 # set the current slot on the changer
132 sub set_current_slot {
135 unlink("$taperoot/data");
136 symlink("slot$slot", "$taperoot/data");
139 # set up and load a config
140 my $testconf = Installcheck::Config->new();
141 $testconf->add_param("tapelist", "\"$tapelist\"");
142 $testconf->add_param("labelstr", "\"TEST-[0-9]+\"");
144 my $cfg_result = config_init($CONFIG_INIT_EXPLICIT_NAME, 'TESTCONF');
145 if ($cfg_result != $CFGERR_OK) {
146 my ($level, @errors) = Amanda::Config::config_errors();
147 die(join "\n", @errors);
151 $tapelist->clear_tapelist();
153 label_slot(1, "TEST-10", "20090424173011", "reuse", 1);
154 label_slot(2, "TEST-20", "20090424173022", "reuse", 1);
155 label_slot(3, "TEST-30", "20090424173033", "reuse", 1);
161 # set up a oldest taperscan
162 $chg = Amanda::Changer->new("chg-disk:$taperoot", tapelist => $tapelist);
163 $taperscan = Amanda::Taper::Scan->new(
164 tapelist => $tapelist,
165 algorithm => "oldest",
168 @results = run_scan($taperscan);
169 is_deeply([ @results ],
170 [ "No acceptable volumes found", undef, undef ],
171 "no reusable tapes -> error")
172 or diag(Dumper(\@results));
175 $chg = Amanda::Changer->new("chg-disk:$taperoot", tapelist => $tapelist);
176 $taperscan = Amanda::Taper::Scan->new(
177 tapelist => $tapelist,
178 algorithm => "oldest",
181 @results = run_scan($taperscan);
182 is_deeply([ @results ],
183 [ undef, "TEST-10", $ACCESS_WRITE ],
184 "finds the best reusable tape")
185 or diag(Dumper(\@results));
188 $chg = Amanda::Changer->new("chg-disk:$taperoot", tapelist => $tapelist);
190 $taperscan = Amanda::Taper::Scan->new(
191 tapelist => $tapelist,
192 algorithm => "oldest",
195 @results = run_scan($taperscan);
196 is_deeply([ @results ],
197 [ undef, "TEST-10", $ACCESS_WRITE ],
198 "finds the first reusable tape")
199 or diag(Dumper(\@results));
202 label_slot(4, "TEST-40", "20090424173030", "reuse", 1);
203 $chg = Amanda::Changer->new("chg-disk:$taperoot", tapelist => $tapelist);
204 $taperscan = Amanda::Taper::Scan->new(
205 tapelist => $tapelist,
206 algorithm => "oldest",
209 @results = run_scan($taperscan);
210 is_deeply([ @results ],
211 [ undef, "TEST-10", $ACCESS_WRITE ],
212 "finds the first reusable tape")
213 or diag(Dumper(\@results));
216 label_slot(4, "TEST-40", "X", "reuse", 1);
217 label_slot(5, "TEST-35", "X", "reuse", 1);
218 $chg = Amanda::Changer->new("chg-disk:$taperoot", tapelist => $tapelist);
219 $taperscan = Amanda::Taper::Scan->new(
220 tapelist => $tapelist,
221 algorithm => "oldest",
224 @results = run_scan($taperscan);
225 is_deeply([ @results ],
226 [ undef, "TEST-35", $ACCESS_WRITE ],
227 "finds the first reusable tape")
228 or diag(Dumper(\@results));
231 $chg = Amanda::Changer->new("chg-disk:$taperoot",
232 tapelist => $tapelist,
233 autolabel => { 'template' => "TEST-%0",
235 'volume_error' => 1});
236 $taperscan = Amanda::Taper::Scan->new(
237 tapelist => $tapelist,
238 algorithm => "oldest",
241 $taperscan->{'scan_conf'}->{'new_labeled'} = 'order';
242 $taperscan->{'scan_conf'}->{'new_volume'} = 'soon';
243 @results = run_scan($taperscan);
244 is_deeply([ @results ],
245 [ undef, "TEST-50", $ACCESS_WRITE ],
246 "labels new tapes in blank slots")
247 or diag(Dumper(\@results));
250 $chg = Amanda::Changer->new("chg-disk:$taperoot",
251 tapelist => $tapelist);
252 $taperscan->{'scan_conf'}->{'new_labeled'} = 'order';
253 $taperscan->{'scan_conf'}->{'new_volume'} = 'soon';
255 label_slot(1, "TEST-60", "X", "reuse", 1);
256 $taperscan = Amanda::Taper::Scan->new(
257 tapelist => $tapelist,
258 algorithm => "oldest",
262 @results = run_scan($taperscan);
263 is_deeply([ @results ],
264 [ undef, "TEST-35", $ACCESS_WRITE ],
265 "scans for volumes, even with a newly labeled volume available")
266 or diag(Dumper(\@results));
269 # test new_labeled with autolabel
271 $tapelist->clear_tapelist();
273 label_slot(1, "TEST-10", "20090424173011", "reuse", 1);
274 label_slot(2, "TEST-20", "20090424173033", "reuse", 1);
275 label_slot(4, "TEST-30", "20090424173022", "reuse", 1);
276 label_slot(3, "TEST-15", "X", "reuse", 1);
277 label_slot(5, "TEST-25", "X", "reuse", 1);
280 $chg = Amanda::Changer->new("chg-disk:$taperoot", tapelist => $tapelist,
281 autolabel => { 'template' => "TEST-%0",
283 'volume_error' => 1});
286 $taperscan = Amanda::Taper::Scan->new(
287 tapelist => $tapelist,
288 algorithm => "oldest",
291 $taperscan->{'scan_conf'}->{'new_labeled'} = 'soon';
292 $taperscan->{'scan_conf'}->{'new_volume'} = 'soon';
293 @results = run_scan($taperscan);
294 is_deeply([ @results ],
295 [ undef, "TEST-25", $ACCESS_WRITE ],
297 or diag(Dumper(\@results));
299 $taperscan->{'scan_conf'}->{'new_labeled'} = 'order';
300 $taperscan->{'scan_conf'}->{'new_volume'} = 'order';
301 @results = run_scan($taperscan);
302 is_deeply([ @results ],
303 [ undef, "TEST-25", $ACCESS_WRITE ],
305 or diag(Dumper(\@results));
307 $taperscan->{'scan_conf'}->{'new_labeled'} = 'last';
308 $taperscan->{'scan_conf'}->{'new_volume'} = 'last';
309 @results = run_scan($taperscan);
310 is_deeply([ @results ],
311 [ undef, "TEST-10", $ACCESS_WRITE ],
313 or diag(Dumper(\@results));
316 # test new_labeled with autolabel
318 $tapelist->clear_tapelist();
320 label_slot(1, "TEST-10", "20090424173011", "reuse", 1);
321 label_slot(2, "TEST-20", "20090424173033", "reuse", 1);
322 label_slot(4, "TEST-30", "20090424173022", "reuse", 1);
323 label_slot(3, "TEST-15", "X", "reuse", 1);
326 $chg = Amanda::Changer->new("chg-disk:$taperoot", tapelist => $tapelist,
327 autolabel => { 'template' => "TEST-%0",
329 'volume_error' => 1});
332 $taperscan = Amanda::Taper::Scan->new(
333 tapelist => $tapelist,
334 algorithm => "oldest",
337 $taperscan->{'scan_conf'}->{'new_labeled'} = 'soon';
338 $taperscan->{'scan_conf'}->{'new_volume'} = 'soon';
339 @results = run_scan($taperscan);
340 is_deeply([ @results ],
341 [ undef, "TEST-15", $ACCESS_WRITE ],
343 or diag(Dumper(\@results));
345 $taperscan->{'scan_conf'}->{'new_labeled'} = 'order';
346 $taperscan->{'scan_conf'}->{'new_volume'} = 'order';
347 @results = run_scan($taperscan);
348 is_deeply([ @results ],
349 [ undef, "TEST-40", $ACCESS_WRITE ],
351 or diag(Dumper(\@results));
353 $taperscan->{'scan_conf'}->{'new_labeled'} = 'last';
354 $taperscan->{'scan_conf'}->{'new_volume'} = 'last';
355 @results = run_scan($taperscan);
356 is_deeply([ @results ],
357 [ undef, "TEST-10", $ACCESS_WRITE ],
359 or diag(Dumper(\@results));
361 $taperscan->{'scan_conf'}->{'new_labeled'} = 'last';
362 $taperscan->{'scan_conf'}->{'new_volume'} = 'order';
363 @results = run_scan($taperscan);
364 is_deeply([ @results ],
365 [ undef, "TEST-40", $ACCESS_WRITE ],
367 or diag(Dumper(\@results));
369 $taperscan->{'scan_conf'}->{'new_labeled'} = 'order';
370 $taperscan->{'scan_conf'}->{'new_volume'} = 'soon';
371 @results = run_scan($taperscan);
372 is_deeply([ @results ],
373 [ undef, "TEST-40", $ACCESS_WRITE ],
375 or diag(Dumper(\@results));
378 # test new_labeled with autolabel
380 $tapelist->clear_tapelist();
382 label_slot(1, "TEST-10", "20090424173011", "reuse", 1);
383 label_slot(2, "TEST-20", "20090424173022", "reuse", 1);
384 label_slot(4, "TEST-30", "20090424173033", "reuse", 1);
385 label_slot(3, "TEST-15", "X", "reuse", 1);
388 $chg = Amanda::Changer->new("chg-disk:$taperoot", tapelist => $tapelist,
389 autolabel => { 'template' => "TEST-%0",
391 'volume_error' => 1});
394 $taperscan = Amanda::Taper::Scan->new(
395 tapelist => $tapelist,
396 algorithm => "oldest",
399 $taperscan->{'scan_conf'}->{'new_labeled'} = 'soon';
400 $taperscan->{'scan_conf'}->{'new_volume'} = 'soon';
401 @results = run_scan($taperscan);
402 is_deeply([ @results ],
403 [ undef, "TEST-15", $ACCESS_WRITE ],
405 or diag(Dumper(\@results));
407 $taperscan->{'scan_conf'}->{'new_labeled'} = 'order';
408 $taperscan->{'scan_conf'}->{'new_volume'} = 'order';
409 @results = run_scan($taperscan);
410 is_deeply([ @results ],
411 [ undef, "TEST-40", $ACCESS_WRITE ],
413 or diag(Dumper(\@results));
415 $taperscan->{'scan_conf'}->{'new_labeled'} = 'last';
416 $taperscan->{'scan_conf'}->{'new_volume'} = 'last';
417 @results = run_scan($taperscan);
418 is_deeply([ @results ],
419 [ undef, "TEST-10", $ACCESS_WRITE ],
421 or diag(Dumper(\@results));
423 $taperscan->{'scan_conf'}->{'new_labeled'} = 'last';
424 $taperscan->{'scan_conf'}->{'new_volume'} = 'order';
425 @results = run_scan($taperscan);
426 is_deeply([ @results ],
427 [ undef, "TEST-40", $ACCESS_WRITE ],
429 or diag(Dumper(\@results));
431 $taperscan->{'scan_conf'}->{'new_labeled'} = 'order';
432 $taperscan->{'scan_conf'}->{'new_volume'} = 'soon';
433 @results = run_scan($taperscan);
434 is_deeply([ @results ],
435 [ undef, "TEST-40", $ACCESS_WRITE ],
437 or diag(Dumper(\@results));
440 # test new_volume with autolabel
442 $tapelist->clear_tapelist();
444 label_slot(1, "TEST-10", "20090424173011", "reuse", 1);
445 label_slot(2, "TEST-20", "20090424173033", "reuse", 1);
446 label_slot(4, "TEST-30", "20090424173022", "reuse", 1);
449 $chg = Amanda::Changer->new("chg-disk:$taperoot", tapelist => $tapelist,
450 autolabel => { 'template' => "TEST-%0",
452 'volume_error' => 1});
455 $taperscan = Amanda::Taper::Scan->new(
456 tapelist => $tapelist,
457 algorithm => "oldest",
460 $taperscan->{'scan_conf'}->{'new_labeled'} = 'soon';
461 $taperscan->{'scan_conf'}->{'new_volume'} = 'soon';
462 @results = run_scan($taperscan);
463 is_deeply([ @results ],
464 [ undef, "TEST-40", $ACCESS_WRITE ],
466 or diag(Dumper(\@results));
468 $taperscan->{'scan_conf'}->{'new_labeled'} = 'order';
469 $taperscan->{'scan_conf'}->{'new_volume'} = 'order';
470 @results = run_scan($taperscan);
471 is_deeply([ @results ],
472 [ undef, "TEST-40", $ACCESS_WRITE ],
474 or diag(Dumper(\@results));
476 $taperscan->{'scan_conf'}->{'new_labeled'} = 'last';
477 $taperscan->{'scan_conf'}->{'new_volume'} = 'last';
478 @results = run_scan($taperscan);
479 is_deeply([ @results ],
480 [ undef, "TEST-10", $ACCESS_WRITE ],
482 or diag(Dumper(\@results));
485 $chg = Amanda::Changer->new("chg-disk:$taperoot", tapelist => $tapelist,
486 autolabel => { 'template' => "TEST-%0",
488 'volume_error' => 1});
489 $taperscan = Amanda::Taper::Scan->new(
490 tapelist => $tapelist,
491 algorithm => "oldest",
494 $taperscan->{'scan_conf'}->{'new_labeled'} = 'soon';
495 $taperscan->{'scan_conf'}->{'new_volume'} = 'soon';
496 @results = run_scan($taperscan);
497 is_deeply([ @results ],
498 [ undef, "TEST-40", $ACCESS_WRITE ],
500 or diag(Dumper(\@results));
502 $taperscan->{'scan_conf'}->{'new_labeled'} = 'order';
503 $taperscan->{'scan_conf'}->{'new_volume'} = 'order';
504 @results = run_scan($taperscan);
505 is_deeply([ @results ],
506 [ undef, "TEST-40", $ACCESS_WRITE ],
508 or diag(Dumper(\@results));
510 $taperscan->{'scan_conf'}->{'new_labeled'} = 'last';
511 $taperscan->{'scan_conf'}->{'new_volume'} = 'last';
512 @results = run_scan($taperscan);
513 is_deeply([ @results ],
514 [ undef, "TEST-40", $ACCESS_WRITE ],
516 or diag(Dumper(\@results));
519 # test skipping no-reuse tapes
521 $tapelist->clear_tapelist();
523 label_slot(1, "TEST-1", "20090424173001", "no-reuse", 1);
524 label_slot(2, "TEST-2", "20090424173002", "reuse", 1);
525 label_slot(3, "TEST-3", "20090424173003", "reuse", 1);
526 label_slot(4, "TEST-4", "20090424173004", "reuse", 1);
528 $chg = Amanda::Changer->new("chg-disk:$taperoot", tapelist => $tapelist);
531 $taperscan = Amanda::Taper::Scan->new(
532 tapelist => $tapelist,
533 algorithm => "oldest",
537 @results = run_scan($taperscan);
538 is_deeply([ @results ],
539 [ undef, "TEST-2", $ACCESS_WRITE ],
540 "skips a no-reuse volume")
541 or diag(Dumper(\@results));