1 # Copyright (c) 2005-2008 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 Mathlida Ave, Suite 300
17 # Sunnyvale, CA 94086, USA, or: http://www.zmanda.com
19 use Test::More tests => 78;
21 use lib "@amperldir@";
22 use Installcheck::Config;
23 use Installcheck::Run qw(run run_get run_err);
27 # this is re-created for each test
31 # First, try amgetconf out without a config
33 ok(!run('amgetconf'), "bare amgetconf fails");
34 like($Installcheck::Run::stdout, qr(\AUsage: )i,
35 ".. and gives usage message on stdout");
36 like(run_err('amgetconf', 'this-probably-doesnt-exist', 'tapedev'),
37 qr(could not open conf file)i,
38 "error message when configuration parameter doesn't exist");
41 # Next, work against a basically empty config
43 $testconf = Installcheck::Config->new();
47 is(run_get('amgetconf', 'TESTCONF', "reserve"), "100",
48 "reserve defaults to 100");
49 is(run_get('amgetconf', 'TESTCONF', "tapelist"), "tapelist",
50 "tapelist defaults to 'tapelist'");
51 is(run_get('amgetconf', 'TESTCONF', "usetimestamps"), "yes",
52 "usetimestamps defaults to 'yes'");
53 is(run_get('amgetconf', 'TESTCONF', "send_amreport_on"), "ALL",
54 "send_amreport_on defaults to 'ALL'"); # (enum value is 0)
55 is(run_get('amgetconf', 'TESTCONF', "taperalgo"), "FIRST",
56 "taperalgo defaults to 'ALL'"); # (enum value is 0)
57 is(run_get('amgetconf', 'TESTCONF', "printer"), "",
58 "printer defaults to empty string, which is not an error");
60 # test command-line parsing
61 is(run_get('amgetconf', 'TESTCONF', '--execute-where', 'client', 'amandates'),
62 $Amanda::Constants::DEFAULT_AMANDATES_FILE,
63 "--execute-where client");
64 is(run_get('amgetconf', 'TESTCONF', '--execute-where=client', 'amandates'),
65 $Amanda::Constants::DEFAULT_AMANDATES_FILE,
66 "--execute-where=client");
67 is(run_get('amgetconf', 'TESTCONF', '--client', 'amandates'),
68 $Amanda::Constants::DEFAULT_AMANDATES_FILE,
71 is(run_get('amgetconf', 'TESTCONF', '--execute-where', 'server', 'reserve'), "100",
72 "--execute-where server");
73 is(run_get('amgetconf', 'TESTCONF', '--execute-where=server', 'reserve'), "100",
74 "--execute-where=server");
75 is(run_get('amgetconf', 'TESTCONF', '--execute-where=server', '--execute-where=server', 'reserve'), "100",
76 "--execute-where=server --execute-where=server");
77 is(run_get('amgetconf', 'TESTCONF', '--execute-where=client', '--execute-where=client', 'amandates'),
78 $Amanda::Constants::DEFAULT_AMANDATES_FILE,
79 "--execute-where=client --execute-where=client");
81 like(run_err('amgetconf', 'TESTCONF', '--execute-where=server', '--execute-where=client'),
83 "handles conflict --execute-where=server --execute-where=client");
84 like(run_err('amgetconf', 'TESTCONF', '--execute-where=client', '--execute-where=server'),
86 "handles conflict --execute-where=client --execute-where=server");
87 like(run_err('amgetconf', 'TESTCONF', '--execute-where=server', '--client'),
89 "handles conflict --execute-where=server --client");
90 like(run_err('amgetconf', 'TESTCONF', '--client', '--execute-where=server'),
92 "handles conflict --client --execute-where=server");
94 is(run_get('amgetconf', 'TESTCONF', '-o', 'reserve=50', 'reserve'), "50",
96 is(run_get('amgetconf', 'TESTCONF', '-oreserve=50', 'reserve'), "50",
98 is(run_get('amgetconf', '-o', 'reserve=50', 'TESTCONF', 'reserve'), "50",
99 "-oreserve=50 before config name");
100 is(run_get('amgetconf', 'TESTCONF', 'reserve', 'a', 'table', 'for', 'two', '-o', 'reserve=50'), "50",
101 "extra command-line arguments are ignored");
103 # test a nonexistent parameter
104 like(run_err('amgetconf', 'TESTCONF', "foos_per_bar"), qr/no such parameter/,
105 "handles nonexistent parameters as an error");
106 like(run_err('amgetconf', 'TESTCONF', "build.foos_per_bar"), qr/no such parameter/,
107 "handles nonexistent build parameters as an error");
109 # Test build parameters that we can determine easily. Testing all parameters
110 # would be more of a maintenance bother than a help.
111 is(run_get('amgetconf', 'TESTCONF', "build.bindir"), $bindir,
112 "build.bindir is correct");
113 is(run_get('amgetconf', 'TESTCONF', "build.sbindir"), $sbindir,
114 "build.sbindir is correct");
115 is(run_get('amgetconf', 'TESTCONF', "build.libexecdir"), $libexecdir,
116 "build.libexecdir is correct");
117 is(run_get('amgetconf', 'TESTCONF', "build.amlibexecdir"), $amlibexecdir,
118 "build.amlibexecdir is correct");
119 is(run_get('amgetconf', 'TESTCONF', "build.mandir"), $mandir,
120 "build.mandir is correct");
121 is(run_get('amgetconf', 'TESTCONF', "build.AMANDA_DBGDIR"), $AMANDA_DBGDIR,
122 "build.AMANDA_DBGDIR is correct");
123 is(run_get('amgetconf', 'TESTCONF', "build.AMANDA_TMPDIR"), $AMANDA_TMPDIR,
124 "build.AMANDA_TMPDIR is correct");
125 is(run_get('amgetconf', 'TESTCONF', "build.CONFIG_DIR"), $CONFIG_DIR,
126 "build.CONFIG_DIR is correct");
127 is(run_get('amgetconf', 'TESTCONF', "build.__empty"), "",
128 "empty build variables handled correctly");
130 like(run_err('amgetconf', 'TESTCONF', "build.bogus-param"), qr(no such parameter),
131 "bogus build parameters result in an error");
133 is(run_get('amgetconf', 'TESTCONF', "build.config_dir"), $CONFIG_DIR,
134 "build parameters are case-insensitive");
136 is(run_get('amgetconf', "build.bindir"), $bindir, "build variables are available without a config");
138 # empty --list should return nothing
139 is_deeply([sort(+split(/\n/, run_get('amgetconf', 'TESTCONF', '--list', 'holdingdisk')))], [ ],
140 "--list returns an empty list when there's nothing to return");
143 my $dbfile = run_get('amgetconf', 'TESTCONF', "dbopen.foo");
145 like($dbfile, qr(^\Q$AMANDA_DBGDIR\E/server/foo.[0-9]*.debug$),
146 "'amgetconf dbopen.foo' returns a proper debug filename");
148 skip "dbopen didn't work, so I'll skip the rest", 3
150 ok(!run('amgetconf', 'TESTCONF', "dbclose.foo"),
151 "dbclose without filename fails");
152 is(run_get('amgetconf', 'TESTCONF', "dbclose.foo:$dbfile"), $dbfile,
153 "'amgetconf dbclose.foo:<filename>' returns the debug filename");
155 # sometimes shell scripts pass a full path as appname..
156 $dbfile = run_get('amgetconf', 'TESTCONF', 'dbopen./sbin/foo');
157 like($dbfile, qr(^\Q$AMANDA_DBGDIR\E/server/_sbin_foo.[0-9]*.debug$),
158 "'amgetconf dbopen./sbin/foo' doesn't get confused by the slashes");
162 # Test an invalid config file
164 $testconf = Installcheck::Config->new();
165 $testconf->add_param("foos_per_bar", "10");
168 like(run_err('amgetconf', 'TESTCONF', "foos_per_bar"), qr/errors processing config file/,
169 "gives error on invalid configuration");
172 # Now let's fill in some interesting values
174 $testconf = Installcheck::Config->new();
175 $testconf->add_param("reserved-udp-port", '100,200');
176 $testconf->add_param("printer", '"/dev/lp"');
177 $testconf->add_param("reserve", '27');
180 is(run_get('amgetconf', 'TESTCONF', "reserved-udp-port"), "100,200",
181 "correctly returns intrange parameters from the file");
182 is(run_get('amgetconf', 'TESTCONF', "printer"), "/dev/lp",
183 "correctly returns string parameters from the file");
184 is(run_get('amgetconf', 'TESTCONF', "reserve"), "27",
185 "correctly returns integer parameters from the file");
186 is(run_get('amgetconf', 'TESTCONF', "rEsErVe"), "27",
187 "is case-insensitive");
188 is(run_get('amgetconf', 'TESTCONF', "reserved_udp_port"), "100,200",
189 "treats _ and - identically");
191 # check runs without a config
192 my $olddir = getcwd();
193 chdir("$CONFIG_DIR/TESTCONF") or die("Could not 'cd' to TESTCONF directory");
194 is(run_get('amgetconf', "printer"), "/dev/lp",
195 "uses current directory when no configuration name is given");
196 chdir($olddir) or die("Could not 'cd' back to my original directory");
199 # device_property can appear multiple times
201 $testconf = Installcheck::Config->new();
202 $testconf->add_param("device_property", '"power" "on"');
203 $testconf->add_param("device_property", '"turbo" "engaged"');
206 is_deeply([sort(+split(qr/\n/, run_get('amgetconf', 'TESTCONF', 'device_property')))],
207 [sort('"power" "on"', '"turbo" "engaged"')],
208 "device_property can have multiple values");
213 $testconf = Installcheck::Config->new();
214 $testconf->add_tapetype("cassette", [ length => "32 k" ]);
215 $testconf->add_tapetype("reel2reel", [ length => "1 M" ]);
216 $testconf->add_tapetype("scotch", [ length => "500 bytes" ]); # (use a sharpie)
217 $testconf->add_dumptype("testdump", [ comment => '"testdump-dumptype"' ]);
218 $testconf->add_interface("testiface", [ use => '10' ]);
219 $testconf->add_holdingdisk("hd17", [ chunksize => '128' ]);
220 $testconf->add_application('app_amgtar', [ plugin => '"amgtar"' ]);
221 $testconf->add_application('app_amstar', [ plugin => '"amstar"' ]);
222 $testconf->add_script('my_script', [ "execute-on" => 'pre-dle-amcheck', 'plugin' => '"foo"' ]);
223 $testconf->add_device('my_device', [ "tapedev" => '"foo:/bar"' ]);
226 is_deeply([sort(+split(/\n/, run_get('amgetconf', 'TESTCONF', '--list', 'tapetype')))],
227 [sort("cassette", "reel2reel", "scotch", "TEST-TAPE")],
228 "--list returns correct set of tapetypes");
229 is(run_get('amgetconf', 'TESTCONF', 'tapetype:scotch:length'), '500',
230 "returns tapetype parameter correctly");
232 ok(scalar(grep { $_ eq 'testdump' }
234 run_get('amgetconf', 'TESTCONF', '--list', 'dumptype'))),
235 "--list returns a test dumptype among the default dumptypes");
236 is(run_get('amgetconf', 'TESTCONF', 'dumptype:testdump:comment'), 'testdump-dumptype',
237 "returns dumptype parameter correctly");
239 is_deeply([sort(+split(/\n/, run_get('amgetconf', 'TESTCONF', '--list', 'interface')))],
240 [sort("testiface", "default")],
241 "--list returns correct set of interfaces");
242 is(run_get('amgetconf', 'TESTCONF', 'interface:testiface:use'), '10',
243 "returns interface parameter correctly");
245 is_deeply([sort(+split(/\n/, run_get('amgetconf', 'TESTCONF', '--list', 'holdingdisk')))],
247 "--list returns correct set of holdingdisks");
248 is(run_get('amgetconf', 'TESTCONF', 'holdingdisk:hd17:chunksize'), '128',
249 "returns holdingdisk parameter correctly");
251 like(run_get('amgetconf', 'TESTCONF', '--list', 'build'), qr(.*version.*),
252 "'--list build' lists build variables");
254 is_deeply([sort(+split(/\n/, run_get('amgetconf', 'TESTCONF', '--list', 'application-tool')))],
255 [sort("app_amgtar", "app_amstar")],
256 "--list returns correct set of application-tool");
258 is(run_get('amgetconf', 'TESTCONF', 'application-tool:app_amgtar:plugin'), 'amgtar',
259 "returns application-tool parameter correctly");
261 is_deeply([sort(+split(/\n/, run_get('amgetconf', 'TESTCONF', '--list', 'script-tool')))],
263 "--list returns correct set of script-tool");
265 is(run_get('amgetconf', 'TESTCONF', 'script-tool:my_script:execute-on'), 'PRE-DLE-AMCHECK',
266 "returns script-tool parameter correctly");
267 is(run_get('amgetconf', 'TESTCONF', 'script_tOOl:my_script:execute-on'), 'PRE-DLE-AMCHECK',
268 "insensitive to case in subsec_type");
269 is(run_get('amgetconf', 'TESTCONF', 'script-tool:my_script:execute-on'), 'PRE-DLE-AMCHECK',
270 "insensitive to -/_ in subsec_type");
271 is(run_get('amgetconf', 'TESTCONF', 'script_tOOl:my_script:eXECute-on'), 'PRE-DLE-AMCHECK',
272 "insensitive to case in subsec_key");
273 is(run_get('amgetconf', 'TESTCONF', 'script-tool:my_script:execute_on'), 'PRE-DLE-AMCHECK',
274 "insensitive to -/_ in subsec_key");
276 is_deeply([sort(split(/\n/, run_get('amgetconf', 'TESTCONF', '--list', 'device')))],
278 "--list returns correct set of devices");
280 is(run_get('amgetconf', 'TESTCONF', 'device:my_device:tapedev'), 'foo:/bar',
281 "returns device parameter correctly");
283 # non-existent subsection types, names, and parameters
284 like(run_err('amgetconf', 'TESTCONF', 'NOSUCHTYPE:testiface:comment'), qr/no such parameter/,
285 "handles bad subsection type");
286 like(run_err('amgetconf', 'TESTCONF', 'dumptype:NOSUCHDUMP:comment'), qr/no such parameter/,
287 "handles bad dumptype namek");
288 like(run_err('amgetconf', 'TESTCONF', 'dumptype:testdump:NOSUCHPARAM'), qr/no such parameter/,
289 "handles bad dumptype parameter name");
290 like(run_err('amgetconf', 'TESTCONF', 'application-tool:app_amgtar:NOSUCHPARAM'), qr/no such parameter/,
291 "handles bad application-tool parameter name");
292 like(run_err('amgetconf', 'TESTCONF', 'script-tool:my-script:NOSUCHPARAM'), qr/no such parameter/,
293 "handles bad script-tool parameter name");
295 like(run_err('amgetconf', 'TESTCONF', '--list', 'frogs'), qr/no such parameter/,
296 "--list fails given an invalid subsection name");
299 # exclude lists are a bit funny, too
301 $testconf = Installcheck::Config->new();
302 $testconf->add_dumptype("testdump", [
303 "exclude file optional" => '"f1"', # this optional will have no effect
304 "exclude file append" => '"f2"',
305 "exclude list" => '"l1"',
306 "exclude list append" => '"l2"',
307 "include file" => '"ifo"',
308 "include list optional" => '"ilo"',
312 is_deeply([sort(+split(qr/\n/, run_get('amgetconf', 'TESTCONF', 'dumptype:testdump:exclude')))],
313 [sort('FILE "f1" "f2"',
315 "exclude files and lists displayed correctly; a non-final optional is ignored");
317 is_deeply([sort(+split(qr/\n/, run_get('amgetconf', 'TESTCONF', 'dumptype:testdump:include')))],
318 [sort('FILE OPTIONAL "ifo"',
319 'LIST OPTIONAL "ilo"')],
320 "a final 'OPTIONAL' makes the whole include/exclude optional")