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 => 11;
23 use lib "@amperldir@";
27 use Installcheck::Dumpcache;
28 use Installcheck::Config;
29 use Installcheck::Mock;
30 use Installcheck::Run qw(run run_err run_get $diskname);
31 use Amanda::DB::Catalog;
33 use Amanda::Config qw( :init );
37 Amanda::Debug::dbopen("installcheck");
39 my $vtape_root = "$Installcheck::TMP/tertiary";
41 rmtree $vtape_root if -d $vtape_root;
42 mkpath "$vtape_root/slot1";
43 return "chg-disk:$vtape_root";
47 Installcheck::Dumpcache::load("basic");
49 config_init($CONFIG_INIT_EXPLICIT_NAME, "TESTCONF");
50 my ($cfgerr_level, @cfgerr_errors) = config_errors();
51 if ($cfgerr_level >= $CFGERR_WARNINGS) {
52 config_print_errors();
56 # and then set up a new vtape to vault onto
57 my $tertiary_chg = setup_chg_disk();
59 # try a few failures first
60 like(run_err("$sbindir/amvault",
62 '--label-template', "TESTCONF%%",
63 '--src-timestamp', 'latest',
64 '--dst-changer', $tertiary_chg,
65 'TESTCONF', 'someotherhost'),
66 qr/No dumps to vault/,
67 "amvault with a non-matching dumpspec dumps nothing")
68 or diag($Installcheck::Run::stderr);
70 like(run_err("$sbindir/amvault",
72 '--label-template', "TESTCONF%%",
73 '--src-timestamp', 'latest',
75 '--dst-changer', $tertiary_chg,
76 'TESTCONF', '*', '*', '*', '1-3'),
77 qr/No dumps to vault/,
78 "amvault with --fulls-only but specifying non-full dumpspecs dumps nothing")
79 or diag($Installcheck::Run::stderr);
81 like(run_err("$sbindir/amvault",
83 '--label-template', "TESTCONF%%",
84 '--dst-changer', $tertiary_chg,
86 qr/specify something to select/,
87 "amvault without any limiting factors is an error"),
88 or diag($Installcheck::Run::stderr);
90 # now a successful vaulting
91 ok(run("$sbindir/amvault",
93 '--label-template', "TESTCONF%%",
94 '--src-timestamp', 'latest',
95 '--dst-changer', $tertiary_chg,
98 or diag($Installcheck::Run::stderr);
99 my @tert_files = glob("$vtape_root/slot1/0*");
101 "..and files appear on the tertiary volume!");
103 my @dumps = Amanda::DB::Catalog::sort_dumps([ 'write_timestamp' ],
104 Amanda::DB::Catalog::get_dumps());
107 "now there are two dumps in the catalog");
112 map { $_ => $dump->{$_} }
113 qw(diskname hostname level dump_timestamp kb orig_kb)
116 is_deeply(summarize($dumps[1]), summarize($dumps[0]),
117 "and they match in all the right ways")
118 or diag(Dumper(@dumps));
120 # clean up the tertiary vtapes before moving on
122 Installcheck::Run::cleanup();
124 # try the multi dump, to get a better idea of the filtering possibilities
125 Installcheck::Dumpcache::load("multi");
126 config_init($CONFIG_INIT_EXPLICIT_NAME, "TESTCONF");
127 ($cfgerr_level, @cfgerr_errors) = config_errors();
128 if ($cfgerr_level >= $CFGERR_WARNINGS) {
129 config_print_errors();
134 my $stdout = run_get(@_);
136 diag($Installcheck::Run::stderr);
141 for my $line (split /\n/, $stdout) {
142 next if ($line =~ /^Total Size:/);
143 my ($tape, $file, $host, $disk, $datestamp, $level) =
144 ($line =~ /^(\S+) (\d*) (\S+) (.+) (\d+) (\d+)$/);
145 $tape = 'holding' if $file eq '';
146 push @rv, [$tape, $file, $host, $disk, $level]; # note: no datestamp
151 is_deeply([ get_dry_run("$sbindir/amvault",
154 '--label-template', "TESTCONF%%",
156 '--dst-changer', $tertiary_chg,
158 [ "TESTCONF01", "1", "localhost", "$diskname/dir", "0" ],
159 [ "TESTCONF01", "2", "localhost", "$diskname", "0" ],
160 [ "TESTCONF02", "2", "localhost", "$diskname", "0" ]
161 ], "amvault with --fulls-only only dumps fulls");
163 is_deeply([ get_dry_run("$sbindir/amvault",
166 '--label-template', "TESTCONF%%",
167 '--dst-changer', $tertiary_chg,
168 'TESTCONF', "localhost", "$diskname/dir") ], [
169 [ "holding", "", "localhost", "$diskname/dir", "1" ],
170 [ "TESTCONF01", "1", "localhost", "$diskname/dir", "0" ],
171 [ "TESTCONF02", "1", "localhost", "$diskname/dir", "1" ]
172 ], "amvault with a disk expression dumps only that disk");
174 # Test NDMP-to-NDMP vaulting. This will test all manner of goodness:
175 # - specifying a named changer on the amvault command line
177 # - directtcp vaulting (well, not really, since we don't support connecting yet)
179 skip "not built with ndmp and server", 2 unless
180 Amanda::Util::built_with_component("ndmp") and Amanda::Util::built_with_component("server");
182 Installcheck::Dumpcache::load("ndmp");
184 my $ndmp = Installcheck::Mock::NdmpServer->new(no_reset => 1);
185 $ndmp->edit_config();
187 # append a tertiary changer to the config file - it's just too hard to
188 # specify a full ndmp changer on the command line
190 my $ndmp_port = $ndmp->{'port'};
191 my $chg_dir = "$Installcheck::TMP/vtapes/ndmjob-tert";
192 my $chg_spec = "chg-ndmp:127.0.0.1:$ndmp_port\@$chg_dir";
193 my $drive_root = "ndmp:127.0.0.1:$ndmp_port\@$chg_dir";
195 -d $chg_dir && rmtree($chg_dir);
198 my $amanda_conf_filename = "$CONFIG_DIR/TESTCONF/amanda.conf";
199 open(my $fh, ">>", $amanda_conf_filename);
201 define changer "tertiary" {
202 tpchanger "$chg_spec"
203 property "tape-device" "0=$drive_root/drive0"
204 property append "tape-device" "1=$drive_root/drive1"
205 changerfile "$chg_dir-changerfile"
209 $tertiary_chg = "tertiary";
210 ok(run("$sbindir/amvault",
213 '--label-template', "TESTCONF%%",
214 '--src-timestamp', 'latest',
215 '--dst-changer', $tertiary_chg,
217 "amvault runs with an NDMP device as secondary and tertiary, with --export")
218 or diag($Installcheck::Run::stderr);
220 config_init($CONFIG_INIT_EXPLICIT_NAME, "TESTCONF");
221 ($cfgerr_level, @cfgerr_errors) = config_errors();
222 if ($cfgerr_level >= $CFGERR_WARNINGS) {
223 config_print_errors();
227 # query the tertiary changer to see where that dump ended up
228 my $chg = Amanda::Changer->new($tertiary_chg);
230 my $inventory_cb = sub {
231 my ($err, $inv) = @_;
235 Amanda::MainLoop::quit();
237 Amanda::MainLoop::call_later(sub { $chg->inventory(inventory_cb => $inventory_cb); });
238 Amanda::MainLoop::run();
241 # find TESTCONF02 in the inventory, and check that it is in an i/e slot
242 my $notfound = "tertiary volume not found";
243 for my $i (@$inventory) {
244 if ($i->{'label'} && $i->{'label'} eq 'TESTCONF02') {
245 if ($i->{'import_export'}) {
248 $notfound = "tertiary volume not properly exported";
254 ok(!$notfound, "tertiary volume exists and was properly exported");
257 diag("amvault stderr:");
258 diag($Installcheck::Run::stderr);
264 Installcheck::Run::cleanup();