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 => 95;
25 use lib "@amperldir@";
26 use Installcheck::Config;
28 use Amanda::Device qw( :constants );
31 use Amanda::Config qw( :init :getconf config_dir_relative );
33 use Amanda::Recovery::Scan;
34 use Installcheck::Run qw(run run_get run_err vtape_dir);
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();
46 package Amanda::Interactive::Installcheck;
48 @ISA = qw( Amanda::Interactive );
53 return bless ($self, $class);
60 Amanda::Debug::debug("Change changer to multi-changer");
61 $params{'finished_cb'}->(undef, "multi-changer");
65 # back to the perl tests..
69 my $testconf = Installcheck::Config->new();
71 my $taperoot_disk = "$Installcheck::TMP/Amanda_Recovery_Scan_Disk";
72 #create a disk changer with 3 slots
74 if (-d $taperoot_disk) {
75 rmtree($taperoot_disk);
77 mkpath($taperoot_disk);
79 for my $slot (1 .. 3) {
80 mkdir("$taperoot_disk/slot$slot")
81 or die("Could not mkdir: $!");
84 $testconf->add_changer("disk-changer", [
85 'tpchanger' => "\"chg-disk:$taperoot_disk\"",
89 my $taperoot_multi = "$Installcheck::TMP/Amanda_Recovery_Scan_Multi";
90 #create a multi changer
92 if (-d $taperoot_multi) {
93 rmtree($taperoot_multi);
95 mkpath($taperoot_multi);
98 for my $slot (1 .. 3) {
99 mkdir("$taperoot_multi/slot$slot")
100 or die("Could not mkdir: $!");
101 mkdir("$taperoot_multi/slot$slot/data")
102 or die("Could not mkdir: $!");
106 my $chg_name = "chg-multi:file:$taperoot_multi/slot{".join(',', @names)."}";
107 $testconf->add_changer("multi-changer", [
108 'tpchanger' => "\"$chg_name\"",
109 'changerfile' => "\"$Installcheck::TMP/Amanda_Recovery_Scan_Multi_status\"",
113 my $taperoot_compat = "$Installcheck::TMP/Amanda_Recovery_Scan_Compat";
114 my $changerfile = "$Installcheck::TMP/scan-changerfile";
116 #create a compat changer
118 if (-d $taperoot_compat) {
119 rmtree($taperoot_compat);
121 mkpath($taperoot_compat);
124 for my $slot (1 .. 3) {
125 mkdir("$taperoot_compat/slot$slot")
126 or die("Could not mkdir: $!");
127 #mkdir("$taperoot_compat/slot$slot/data")
128 # or die("Could not mkdir: $!");
132 open (CONF, ">$changerfile");
133 print CONF "firstslot=1\n";
134 print CONF "lastslot=3\n";
137 $testconf->add_changer("compat-changer", [
138 'tpchanger' => '"chg-disk"',
139 'tapedev' => "\"file:$taperoot_compat\"",
140 'changerfile' => "\"$changerfile\"",
144 my $taperoot_single = "$Installcheck::TMP/Amanda_Recovery_Scan_Single";
145 #create a single changer
147 if (-d $taperoot_single) {
148 rmtree($taperoot_single);
150 mkpath($taperoot_single);
151 mkdir("$taperoot_single/data");
153 $testconf->add_changer("single-changer", [
154 'tpchanger' => "\"chg-single:file:$taperoot_single\"",
160 Amanda::Config::config_init($CONFIG_INIT_EXPLICIT_NAME, "TESTCONF");
162 # sub to label a slot in a changer
164 my ($chg, $chg_name, $slot, $label, $finished_cb) = @_;
167 my $steps = define_steps
168 cb_ref => \$finished_cb;
171 $chg->load(slot => $slot, res_cb => $steps->{'res_cb'});
175 (my $err, $res) = @_;
178 $res->{'device'}->start($ACCESS_WRITE, $label, "20100201010203");
179 $res->set_label(label => $label, finished_cb => $steps->{'set_label_finished'});
182 step set_label_finished => sub {
186 $res->release(finished_cb => $steps->{'finished_cb'});
189 step finished_cb => sub {
192 pass("label slot $slot of $chg_name with label '$label'");
198 my ($chg, $chg_name, $slot, $label) = @_;
200 amlabel($chg, $chg_name, $slot, $label,
201 make_cb(finished_cb => sub { Amanda::MainLoop::quit(); }));
202 Amanda::MainLoop::run();
207 my ($chg, $chg_name, $finished_cb) = @_;
213 my $steps = define_steps
214 cb_ref => \$finished_cb;
217 $scan = Amanda::Recovery::Scan->new(chg => $chg);
218 $steps->{'find_04'}->();
221 step find_04 => sub {
222 $scan->find_volume(label => "TESTCONF04",
223 res_cb => $steps->{'res_cb_04'});
226 step res_cb_04 => sub {
227 my ($err, $res) = @_;
229 ok(!$res, "$chg_name didn't find TESTCONF04");
230 ok($err->notfound, "$chg_name: TESTCONF04 error is notfound");
232 $scan->find_volume(label => "TESTCONF02",
233 res_cb => $steps->{'res_cb_02'});
236 step res_cb_02 => sub {
237 (my $err, $res02) = @_;
239 ok(!$err, "$chg_name found TESTCONF02");
240 ok($res02, "$chg_name: TESTCONF02 give a reservation");
242 $scan->find_volume(label => "TESTCONF02",
243 res_cb => $steps->{'res_cb_02_volinuse'});
246 step res_cb_02_volinuse => sub {
247 my ($err, $res) = @_;
249 ok(!$res, "$chg_name doesn't reserve an already reserved slot");
250 if ($chg_name eq "compat-changer" ||
251 $chg_name eq "single-changer") {
252 ok($err->driveinuse, "$chg_name: TESTCONF02 is driveinuse") ||
253 diag("$chg_name:".Dumper($err));
255 ok($err->volinuse, "$chg_name: TESTCONF02 is volinuse") ||
256 diag("$chg_name:".Dumper($err));
259 $scan->find_volume(label => "TESTCONF03",
260 res_cb => $steps->{'res_cb_03'});
263 step res_cb_03 => sub {
264 (my $err, $res03) = @_;
266 if ($chg_name eq "compat-changer" ||
267 $chg_name eq "single-changer") {
268 ok($err, "$chg_name doesn't found TESTCONF03");
269 ok($err->driveinuse, "$chg_name TESTCONF03 is driveinuse") ||
271 ok(!$res03, "$chg_name: TESTCONF03 give no reservation");
273 ok(!$err, "$chg_name found TESTCONF03");
274 ok($res03, "$chg_name: TESTCONF03 give a reservation");
276 $scan->find_volume(label => "TESTCONF01",
277 res_cb => $steps->{'res_cb_01'});
280 step res_cb_01 => sub {
281 (my $err, $res01) = @_;
283 if ($chg_name eq "compat-changer" ||
284 $chg_name eq "single-changer") {
285 ok($err, "$chg_name doesn't found TESTCONF01");
286 ok($err->driveinuse, "$chg_name TESTCONF01 is driveinuse") ||
288 ok(!$res01, "$chg_name: TESTCONF01 give no reservation");
290 ok(!$err, "$chg_name found TESTCONF01");
291 ok($res01, "$chg_name: TESTCONF01 give a reservation");
293 $scan->find_volume(label => "TESTCONF05",
294 res_cb => $steps->{'res_cb_05'});
297 step res_cb_05 => sub {
298 my ($err, $res) = @_;
300 if ($chg_name eq "compat-changer" ||
301 $chg_name eq "single-changer") {
302 ok($err, "$chg_name doesn't found TESTCONF05");
303 ok($err->driveinuse, "$chg_name TESTCONF05 is driveinuse") ||
305 ok(!$res, "$chg_name: TESTCONF05 give no reservation");
307 ok(!$res, "$chg_name doesn't found TESTCONF05");
308 ok($err->notfound, "$chg_name: TESTCONF05 is notfound");
310 $scan->find_volume(label => "TESTCONF01",
311 res_cb => $steps->{'res_cb_01_volinuse'});
314 step res_cb_01_volinuse => sub {
315 my ($err, $res) = @_;
317 ok($err, "$chg_name doesn't found TESTCONF01");
318 if ($chg_name eq "compat-changer" ||
319 $chg_name eq "single-changer") {
320 ok($err->driveinuse, "$chg_name TESTCONF01 is driveinuse") ||
323 ok($err->volinuse, "$chg_name TESTCONF01 is volinuse") ||
326 ok(!$res, "$chg_name: TESTCONF01 give no reservation");
327 $steps->{'release01'}->();
330 step release01 => sub {
332 $res01->release(finished_cb => $steps->{'release02'});
334 $steps->{'release02'}->();
338 step release02 => sub {
339 $res02->release(finished_cb => $steps->{'release03'});
342 step release03 => sub {
344 $res03->release(finished_cb => $steps->{'done'});
346 $steps->{'done'}->();
351 pass("done with searching test on $chg_name");
356 foreach my $chg_name ("disk-changer", "multi-changer", "compat-changer",
358 # amlabel has to be done outside of Amanda::MainLoop
359 my $chg = Amanda::Changer->new($chg_name);
360 if ($chg_name eq "single-changer") {
361 amlabel_sync($chg, $chg_name, 1, 'TESTCONF02');
363 amlabel_sync($chg, $chg_name, 1, 'TESTCONF01');
364 amlabel_sync($chg, $chg_name, 2, 'TESTCONF02');
365 amlabel_sync($chg, $chg_name, 3, 'TESTCONF03');
368 test_searching($chg, $chg_name, \&Amanda::MainLoop::quit);
369 Amanda::MainLoop::run();
374 my ($chg_name, $finished_cb) = @_;
380 my $steps = define_steps
381 cb_ref => \$finished_cb;
384 $chg = Amanda::Changer->new($chg_name);
385 $scan = Amanda::Recovery::Scan->new(chg => $chg);
386 $scan->{'scan_conf'}->{'notfound'} = Amanda::Recovery::Scan::SCAN_POLL;
387 $scan->{'scan_conf'}->{'volinuse'} = Amanda::Recovery::Scan::SCAN_POLL;
388 $scan->{'scan_conf'}->{'poll_delay'} = 10; # 10 ms
390 $steps->{'find_04'}->();
393 step find_04 => sub {
394 Amanda::MainLoop::call_after(100, $steps->{'label_04'});
395 $scan->find_volume(label => "TESTCONF04",
396 res_cb => $steps->{'res_cb_04'});
397 pass("began searching for TESTCONF04");
400 step label_04 => sub {
401 # this needs to be run on a different process.
402 ok(run('amlabel', '-f', "-otpchanger=$chg_name", 'TESTCONF',
403 'TESTCONF04', 'slot', '3'),
404 "label slot 3 of $chg_name with label TESTCONF04");
405 # note: nothing to do in the amlabel callback
408 step res_cb_04 => sub {
409 (my $err, $res04) = @_;
411 ok(!$err, "$chg_name found TESTCONF04 after POLL");
412 ok($res04, "$chg_name: TESTCONF04 give a reservation after POLL");
414 $res04->release(finished_cb => $steps->{'done'});
418 pass("done with SCAN_POLL on $chg_name");
423 foreach my $chg_name ("disk-changer", "multi-changer") {
424 test_scan_poll($chg_name, \&Amanda::MainLoop::quit);
425 Amanda::MainLoop::run();
428 #test SCAN_ASK_POLL which change the changer.
429 #label TESTCONF05 in multi-changer
430 #start the scan on disk-changer
431 #interactivity module change changer to multi-changer
432 sub test_scan_ask_poll {
433 my ($finished_cb) = @_;
437 my $chg_name = "multi-changer";
438 my $chg = Amanda::Changer->new($chg_name);
439 amlabel_sync($chg, $chg_name, 2, 'TESTCONF05');
440 $chg = Amanda::Changer->new("disk-changer");
442 my $steps = define_steps
443 cb_ref => \$finished_cb;
446 my $interactive = Amanda::Interactive::Installcheck->new();
447 $scan = Amanda::Recovery::Scan->new(chg => $chg,
448 interactive => $interactive);
449 $scan->{'scan_conf'}->{'poll_delay'} = 10; # 10 ms
451 $steps->{'find_05'}->();
454 step find_05 => sub {
455 $scan->find_volume(label => "TESTCONF05",
456 res_cb => $steps->{'res_cb_05'});
459 step res_cb_05 => sub {
460 (my $err, $res05) = @_;
462 ok(!$err, "found TESTCONF05 on changer multi");
463 ok($res05, "TESTCONF05 give a reservation after interactive");
464 is($res05->{'chg'}->{'chg_name'}, $chg_name,
465 "found TESTCONF05 on correct changer: $chg_name");
467 $res05->release(finished_cb => $steps->{'done'});
471 pass("done with SCAN_ASK_POLL");
475 test_scan_ask_poll(\&Amanda::MainLoop::quit);
476 Amanda::MainLoop::run();
478 rmtree($taperoot_disk);
479 rmtree($taperoot_multi);
480 rmtree($taperoot_compat);
481 rmtree($taperoot_single);
482 unlink($changerfile);