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;
24 use lib "@amperldir@";
25 use Installcheck::Config;
27 use Amanda::Device qw( :constants );
30 use Amanda::Config qw( :init :getconf config_dir_relative );
32 use Amanda::Recovery::Scan;
33 use Installcheck::Run qw(run run_get run_err vtape_dir);
35 # set up debugging so debug output doesn't interfere with test results
36 Amanda::Debug::dbopen("installcheck");
37 Installcheck::log_test_output();
39 # and disable Debug's die() and warn() overrides
40 Amanda::Debug::disable_die_override();
45 package Amanda::Interactive::Installcheck;
47 @ISA = qw( Amanda::Interactive );
52 return bless ($self, $class);
59 Amanda::Debug::debug("Change changer to multi-changer");
60 $params{'finished_cb'}->(undef, "multi-changer");
64 # back to the perl tests..
68 my $testconf = Installcheck::Config->new();
70 my $taperoot_disk = "$Installcheck::TMP/Amanda_Recovery_Scan_Disk";
71 #create a disk changer with 3 slots
73 if (-d $taperoot_disk) {
74 rmtree($taperoot_disk);
76 mkpath($taperoot_disk);
78 for my $slot (1 .. 3) {
79 mkdir("$taperoot_disk/slot$slot")
80 or die("Could not mkdir: $!");
83 $testconf->add_changer("disk-changer", [
84 'tpchanger' => "\"chg-disk:$taperoot_disk\"",
88 my $taperoot_multi = "$Installcheck::TMP/Amanda_Recovery_Scan_Multi";
89 #create a multi changer
91 if (-d $taperoot_multi) {
92 rmtree($taperoot_multi);
94 mkpath($taperoot_multi);
97 for my $slot (1 .. 3) {
98 mkdir("$taperoot_multi/slot$slot")
99 or die("Could not mkdir: $!");
100 mkdir("$taperoot_multi/slot$slot/data")
101 or die("Could not mkdir: $!");
105 my $chg_name = "chg-multi:file:$taperoot_multi/slot{".join(',', @names)."}";
106 $testconf->add_changer("multi-changer", [
107 'tpchanger' => "\"$chg_name\"",
108 'changerfile' => "\"$Installcheck::TMP/Amanda_Recovery_Scan_Multi_status\"",
112 my $taperoot_compat = "$Installcheck::TMP/Amanda_Recovery_Scan_Compat";
113 my $changerfile = "$Installcheck::TMP/scan-changerfile";
115 #create a compat changer
117 if (-d $taperoot_compat) {
118 rmtree($taperoot_compat);
120 mkpath($taperoot_compat);
123 for my $slot (1 .. 3) {
124 mkdir("$taperoot_compat/slot$slot")
125 or die("Could not mkdir: $!");
126 #mkdir("$taperoot_compat/slot$slot/data")
127 # or die("Could not mkdir: $!");
131 open (CONF, ">$changerfile");
132 print CONF "firstslot=1\n";
133 print CONF "lastslot=3\n";
136 $testconf->add_changer("compat-changer", [
137 'tpchanger' => '"chg-disk"',
138 'tapedev' => "\"file:$taperoot_compat\"",
139 'changerfile' => "\"$changerfile\"",
143 my $taperoot_single = "$Installcheck::TMP/Amanda_Recovery_Scan_Single";
144 #create a single changer
146 if (-d $taperoot_single) {
147 rmtree($taperoot_single);
149 mkpath($taperoot_single);
150 mkdir("$taperoot_single/data");
152 $testconf->add_changer("single-changer", [
153 'tpchanger' => "\"chg-single:file:$taperoot_single\"",
159 Amanda::Config::config_init($CONFIG_INIT_EXPLICIT_NAME, "TESTCONF");
161 # sub to label a slot in a changer
163 my ($chg, $chg_name, $slot, $label, $finished_cb) = @_;
166 my $steps = define_steps
167 cb_ref => \$finished_cb;
170 $chg->load(slot => $slot, res_cb => $steps->{'res_cb'});
174 (my $err, $res) = @_;
177 $res->{'device'}->start($ACCESS_WRITE, $label, "20100201010203");
178 $res->set_label(label => $label, finished_cb => $steps->{'set_label_finished'});
181 step set_label_finished => sub {
185 $res->release(finished_cb => $steps->{'finished_cb'});
188 step finished_cb => sub {
191 pass("label slot $slot of $chg_name with label '$label'");
197 my ($chg, $chg_name, $slot, $label) = @_;
199 amlabel($chg, $chg_name, $slot, $label,
200 make_cb(finished_cb => sub { Amanda::MainLoop::quit(); }));
201 Amanda::MainLoop::run();
206 my ($chg, $chg_name, $finished_cb) = @_;
212 my $steps = define_steps
213 cb_ref => \$finished_cb;
216 $scan = Amanda::Recovery::Scan->new(chg => $chg);
217 $steps->{'find_04'}->();
220 step find_04 => sub {
221 $scan->find_volume(label => "TESTCONF04",
222 res_cb => $steps->{'res_cb_04'});
225 step res_cb_04 => sub {
226 my ($err, $res) = @_;
228 ok(!$res, "$chg_name didn't find TESTCONF04");
229 ok($err->notfound, "$chg_name: TESTCONF04 error is notfound");
231 $scan->find_volume(label => "TESTCONF02",
232 res_cb => $steps->{'res_cb_02'});
235 step res_cb_02 => sub {
236 (my $err, $res02) = @_;
238 ok(!$err, "$chg_name found TESTCONF02");
239 ok($res02, "$chg_name: TESTCONF02 give a reservation");
241 $scan->find_volume(label => "TESTCONF02",
242 res_cb => $steps->{'res_cb_02_volinuse'});
245 step res_cb_02_volinuse => sub {
246 my ($err, $res) = @_;
248 ok(!$res, "$chg_name doesn't reserve an already reserved slot");
249 if ($chg_name eq "compat-changer" ||
250 $chg_name eq "single-changer") {
251 ok($err->driveinuse, "$chg_name: TESTCONF02 is driveinuse") ||
252 diag("$chg_name:".Dumper($err));
254 ok($err->volinuse, "$chg_name: TESTCONF02 is volinuse") ||
255 diag("$chg_name:".Dumper($err));
258 $scan->find_volume(label => "TESTCONF03",
259 res_cb => $steps->{'res_cb_03'});
262 step res_cb_03 => sub {
263 (my $err, $res03) = @_;
265 if ($chg_name eq "compat-changer" ||
266 $chg_name eq "single-changer") {
267 ok($err, "$chg_name doesn't found TESTCONF03");
268 ok($err->driveinuse, "$chg_name TESTCONF03 is driveinuse") ||
270 ok(!$res03, "$chg_name: TESTCONF03 give no reservation");
272 ok(!$err, "$chg_name found TESTCONF03");
273 ok($res03, "$chg_name: TESTCONF03 give a reservation");
275 $scan->find_volume(label => "TESTCONF01",
276 res_cb => $steps->{'res_cb_01'});
279 step res_cb_01 => sub {
280 (my $err, $res01) = @_;
282 if ($chg_name eq "compat-changer" ||
283 $chg_name eq "single-changer") {
284 ok($err, "$chg_name doesn't found TESTCONF01");
285 ok($err->driveinuse, "$chg_name TESTCONF01 is driveinuse") ||
287 ok(!$res01, "$chg_name: TESTCONF01 give no reservation");
289 ok(!$err, "$chg_name found TESTCONF01");
290 ok($res01, "$chg_name: TESTCONF01 give a reservation");
292 $scan->find_volume(label => "TESTCONF05",
293 res_cb => $steps->{'res_cb_05'});
296 step res_cb_05 => sub {
297 my ($err, $res) = @_;
299 if ($chg_name eq "compat-changer" ||
300 $chg_name eq "single-changer") {
301 ok($err, "$chg_name doesn't found TESTCONF05");
302 ok($err->driveinuse, "$chg_name TESTCONF05 is driveinuse") ||
304 ok(!$res, "$chg_name: TESTCONF05 give no reservation");
306 ok(!$res, "$chg_name doesn't found TESTCONF05");
307 ok($err->notfound, "$chg_name: TESTCONF05 is notfound");
309 $scan->find_volume(label => "TESTCONF01",
310 res_cb => $steps->{'res_cb_01_volinuse'});
313 step res_cb_01_volinuse => sub {
314 my ($err, $res) = @_;
316 ok($err, "$chg_name doesn't found TESTCONF01");
317 if ($chg_name eq "compat-changer" ||
318 $chg_name eq "single-changer") {
319 ok($err->driveinuse, "$chg_name TESTCONF01 is driveinuse") ||
322 ok($err->volinuse, "$chg_name TESTCONF01 is volinuse") ||
325 ok(!$res, "$chg_name: TESTCONF01 give no reservation");
326 $steps->{'release01'}->();
329 step release01 => sub {
331 $res01->release(finished_cb => $steps->{'release02'});
333 $steps->{'release02'}->();
337 step release02 => sub {
338 $res02->release(finished_cb => $steps->{'release03'});
341 step release03 => sub {
343 $res03->release(finished_cb => $steps->{'done'});
345 $steps->{'done'}->();
350 pass("done with searching test on $chg_name");
355 foreach my $chg_name ("disk-changer", "multi-changer", "compat-changer",
357 # amlabel has to be done outside of Amanda::MainLoop
358 my $chg = Amanda::Changer->new($chg_name);
359 if ($chg_name eq "single-changer") {
360 amlabel_sync($chg, $chg_name, 1, 'TESTCONF02');
362 amlabel_sync($chg, $chg_name, 1, 'TESTCONF01');
363 amlabel_sync($chg, $chg_name, 2, 'TESTCONF02');
364 amlabel_sync($chg, $chg_name, 3, 'TESTCONF03');
367 test_searching($chg, $chg_name, \&Amanda::MainLoop::quit);
368 Amanda::MainLoop::run();
373 my ($chg_name, $finished_cb) = @_;
379 my $steps = define_steps
380 cb_ref => \$finished_cb;
383 $chg = Amanda::Changer->new($chg_name);
384 $scan = Amanda::Recovery::Scan->new(chg => $chg);
385 $scan->{'scan_conf'}->{'notfound'} = Amanda::Recovery::Scan::SCAN_POLL;
386 $scan->{'scan_conf'}->{'volinuse'} = Amanda::Recovery::Scan::SCAN_POLL;
387 $scan->{'scan_conf'}->{'poll_delay'} = 10; # 10 ms
389 $steps->{'find_04'}->();
392 step find_04 => sub {
393 Amanda::MainLoop::call_after(100, $steps->{'label_04'});
394 $scan->find_volume(label => "TESTCONF04",
395 res_cb => $steps->{'res_cb_04'});
396 pass("began searching for TESTCONF04");
399 step label_04 => sub {
400 # this needs to be run on a different process.
401 ok(run('amlabel', '-f', "-otpchanger=$chg_name", 'TESTCONF',
402 'TESTCONF04', 'slot', '3'),
403 "label slot 3 of $chg_name with label TESTCONF04");
404 # note: nothing to do in the amlabel callback
407 step res_cb_04 => sub {
408 (my $err, $res04) = @_;
410 ok(!$err, "$chg_name found TESTCONF04 after POLL");
411 ok($res04, "$chg_name: TESTCONF04 give a reservation after POLL");
413 $res04->release(finished_cb => $steps->{'done'});
417 pass("done with SCAN_POLL on $chg_name");
422 foreach my $chg_name ("disk-changer", "multi-changer") {
423 test_scan_poll($chg_name, \&Amanda::MainLoop::quit);
424 Amanda::MainLoop::run();
427 #test SCAN_ASK_POLL which change the changer.
428 #label TESTCONF05 in multi-changer
429 #start the scan on disk-changer
430 #interactivity module change changer to multi-changer
431 sub test_scan_ask_poll {
432 my ($finished_cb) = @_;
436 my $chg_name = "multi-changer";
437 my $chg = Amanda::Changer->new($chg_name);
438 amlabel_sync($chg, $chg_name, 2, 'TESTCONF05');
439 $chg = Amanda::Changer->new("disk-changer");
441 my $steps = define_steps
442 cb_ref => \$finished_cb;
445 my $interactive = Amanda::Interactive::Installcheck->new();
446 $scan = Amanda::Recovery::Scan->new(chg => $chg,
447 interactive => $interactive);
448 $scan->{'scan_conf'}->{'poll_delay'} = 10; # 10 ms
450 $steps->{'find_05'}->();
453 step find_05 => sub {
454 $scan->find_volume(label => "TESTCONF05",
455 res_cb => $steps->{'res_cb_05'});
458 step res_cb_05 => sub {
459 (my $err, $res05) = @_;
461 ok(!$err, "found TESTCONF05 on changer multi");
462 ok($res05, "TESTCONF05 give a reservation after interactive");
463 is($res05->{'chg'}->{'chg_name'}, $chg_name,
464 "found TESTCONF05 on correct changer: $chg_name");
466 $res05->release(finished_cb => $steps->{'done'});
470 pass("done with SCAN_ASK_POLL");
474 test_scan_ask_poll(\&Amanda::MainLoop::quit);
475 Amanda::MainLoop::run();
477 rmtree($taperoot_disk);
478 rmtree($taperoot_multi);
479 rmtree($taperoot_compat);
480 rmtree($taperoot_single);
481 unlink($changerfile);