Imported Upstream version 2.6.1
[debian/amanda] / installcheck / amgetconf.pl
index 31ea2041366e446f01cf6481b7ca7be2701c6e48..1916a22884ca09249187892bc992c3b4fcdb8e10 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2006 Zmanda Inc.  All Rights Reserved.
+# Copyright (c) 2005-2008 Zmanda Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 2 as published
 # with this program; if not, write to the Free Software Foundation, Inc.,
 # 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 #
-# Contact information: Zmanda Inc, 505 N Mathlida Ave, Suite 120
-# Sunnyvale, CA 94085, USA, or: http://www.zmanda.com
+# Contact information: Zmanda Inc, 465 S Mathlida Ave, Suite 300
+# Sunnyvale, CA 94086, USA, or: http://www.zmanda.com
 
-use Test::More qw(no_plan);
+use Test::More tests => 78;
 
-use Amconfig;
 use lib "@amperldir@";
+use Installcheck::Config;
+use Installcheck::Run qw(run run_get run_err);
 use Amanda::Paths;
-
-# wrapper to call amgetconf and return the results
-sub amgetconf {
-    # open amgetconf and read from it
-    my $cmd = "$sbindir/amgetconf " . join(" ", @_) . " 2>&1";
-    my $result = `$cmd`;
-    chomp $result;
-    return $result;
-}
+use Cwd;
 
 # this is re-created for each test
 my $testconf;
@@ -37,136 +30,275 @@ my $testconf;
 ##
 # First, try amgetconf out without a config
 
-like(amgetconf(), qr(\AUsage: )i, 
-    "bare 'amgetconf' gives usage message");
-like(amgetconf("this-probably-doesnt-exist"), qr(could not open conf file)i, 
+ok(!run('amgetconf'), "bare amgetconf fails");
+like($Installcheck::Run::stdout, qr(\AUsage: )i, 
+    ".. and gives usage message on stdout");
+like(run_err('amgetconf', 'this-probably-doesnt-exist', 'tapedev'),
+    qr(could not open conf file)i, 
     "error message when configuration parameter doesn't exist");
 
 ##
 # Next, work against a basically empty config
 
-$testconf = Amconfig->new();
+$testconf = Installcheck::Config->new();
 $testconf->write();
 
 # test some defaults
-is(amgetconf('TESTCONF', "reserve"), "100", 
+is(run_get('amgetconf', 'TESTCONF', "reserve"), "100", 
     "reserve defaults to 100");
-is(amgetconf('TESTCONF', "tapelist"), "tapelist", 
+is(run_get('amgetconf', 'TESTCONF', "tapelist"), "tapelist", 
     "tapelist defaults to 'tapelist'");
-is(amgetconf('TESTCONF', "usetimestamps"), "yes", 
+is(run_get('amgetconf', 'TESTCONF', "usetimestamps"), "yes", 
     "usetimestamps defaults to 'yes'");
+is(run_get('amgetconf', 'TESTCONF', "send_amreport_on"), "ALL",
+    "send_amreport_on defaults to 'ALL'"); # (enum value is 0)
+is(run_get('amgetconf', 'TESTCONF', "taperalgo"), "FIRST",
+    "taperalgo defaults to 'ALL'"); # (enum value is 0)
+is(run_get('amgetconf', 'TESTCONF', "printer"), "",
+    "printer defaults to empty string, which is not an error");
+
+# test command-line parsing
+is(run_get('amgetconf', 'TESTCONF', '--execute-where', 'client', 'amandates'),
+   $Amanda::Constants::DEFAULT_AMANDATES_FILE,
+    "--execute-where client");
+is(run_get('amgetconf', 'TESTCONF', '--execute-where=client', 'amandates'),
+   $Amanda::Constants::DEFAULT_AMANDATES_FILE,
+    "--execute-where=client");
+is(run_get('amgetconf', 'TESTCONF', '--client', 'amandates'),
+   $Amanda::Constants::DEFAULT_AMANDATES_FILE,
+    "--client");
+
+is(run_get('amgetconf', 'TESTCONF', '--execute-where', 'server', 'reserve'), "100",
+    "--execute-where server");
+is(run_get('amgetconf', 'TESTCONF', '--execute-where=server', 'reserve'), "100",
+    "--execute-where=server");
+is(run_get('amgetconf', 'TESTCONF', '--execute-where=server', '--execute-where=server', 'reserve'), "100",
+    "--execute-where=server --execute-where=server");
+is(run_get('amgetconf', 'TESTCONF', '--execute-where=client', '--execute-where=client', 'amandates'),
+   $Amanda::Constants::DEFAULT_AMANDATES_FILE,
+    "--execute-where=client --execute-where=client");
+
+like(run_err('amgetconf', 'TESTCONF', '--execute-where=server', '--execute-where=client'),
+    qr/conflicts with/,
+    "handles conflict --execute-where=server --execute-where=client");
+like(run_err('amgetconf', 'TESTCONF', '--execute-where=client', '--execute-where=server'),
+    qr/conflicts with/,
+    "handles conflict --execute-where=client --execute-where=server");
+like(run_err('amgetconf', 'TESTCONF', '--execute-where=server', '--client'),
+     qr/conflicts with/,
+    "handles conflict --execute-where=server --client");
+like(run_err('amgetconf', 'TESTCONF', '--client', '--execute-where=server'),
+    qr/conflicts with/, 
+    "handles conflict --client --execute-where=server");
+
+is(run_get('amgetconf', 'TESTCONF', '-o', 'reserve=50', 'reserve'), "50",
+    "-o reserve=50");
+is(run_get('amgetconf', 'TESTCONF', '-oreserve=50', 'reserve'), "50",
+    "-oreserve=50");
+is(run_get('amgetconf', '-o', 'reserve=50', 'TESTCONF', 'reserve'), "50",
+    "-oreserve=50 before config name");
+is(run_get('amgetconf', 'TESTCONF', 'reserve', 'a', 'table', 'for', 'two', '-o', 'reserve=50'), "50",
+    "extra command-line arguments are ignored");
 
 # test a nonexistent parameter
-like(amgetconf('TESTCONF', "foos_per_bar"), qr/no such parameter/, 
-    "handles nonexistent parameters");
-
-# test build parameters (just the most common)
-is(amgetconf('TESTCONF', "build.bindir"), $bindir, "build.bindir is correct");
-is(amgetconf('TESTCONF', "build.sbindir"), $sbindir, "build.sbindir is correct");
-is(amgetconf('TESTCONF', "build.amlibexecdir"), $amlibexecdir, "build.amlibexecdir is correct");
-is(amgetconf('TESTCONF', "build.mandir"), $mandir, "build.mandir is correct");
-is(amgetconf('TESTCONF', "build.AMANDA_DBGDIR"), $AMANDA_DBGDIR, "build.AMANDA_DBGDIR is correct");
-is(amgetconf('TESTCONF', "build.AMANDA_TMPDIR"), $AMANDA_TMPDIR, "build.AMANDA_TMPDIR is correct");
-is(amgetconf('TESTCONF', "build.CONFIG_DIR"), $CONFIG_DIR, "build.CONFIG_DIR is correct");
+like(run_err('amgetconf', 'TESTCONF', "foos_per_bar"), qr/no such parameter/, 
+    "handles nonexistent parameters as an error");
+like(run_err('amgetconf', 'TESTCONF', "build.foos_per_bar"), qr/no such parameter/, 
+    "handles nonexistent build parameters as an error");
+
+# Test build parameters that we can determine easily.  Testing all parameters
+# would be more of a maintenance bother than a help.
+is(run_get('amgetconf', 'TESTCONF', "build.bindir"), $bindir,
+    "build.bindir is correct");
+is(run_get('amgetconf', 'TESTCONF', "build.sbindir"), $sbindir,
+    "build.sbindir is correct");
+is(run_get('amgetconf', 'TESTCONF', "build.libexecdir"), $libexecdir,
+    "build.libexecdir is correct");
+is(run_get('amgetconf', 'TESTCONF', "build.amlibexecdir"), $amlibexecdir,
+    "build.amlibexecdir is correct");
+is(run_get('amgetconf', 'TESTCONF', "build.mandir"), $mandir,
+    "build.mandir is correct");
+is(run_get('amgetconf', 'TESTCONF', "build.AMANDA_DBGDIR"), $AMANDA_DBGDIR,
+    "build.AMANDA_DBGDIR is correct");
+is(run_get('amgetconf', 'TESTCONF', "build.AMANDA_TMPDIR"), $AMANDA_TMPDIR,
+    "build.AMANDA_TMPDIR is correct");
+is(run_get('amgetconf', 'TESTCONF', "build.CONFIG_DIR"), $CONFIG_DIR,
+    "build.CONFIG_DIR is correct");
+is(run_get('amgetconf', 'TESTCONF', "build.__empty"), "",
+    "empty build variables handled correctly");
+
+like(run_err('amgetconf', 'TESTCONF', "build.bogus-param"), qr(no such parameter),
+    "bogus build parameters result in an error");
+
+is(run_get('amgetconf', 'TESTCONF', "build.config_dir"), $CONFIG_DIR, 
+    "build parameters are case-insensitive");
+
+is(run_get('amgetconf', "build.bindir"), $bindir, "build variables are available without a config");
+
+# empty --list should return nothing
+is_deeply([sort(+split(/\n/, run_get('amgetconf', 'TESTCONF', '--list', 'holdingdisk')))], [ ],
+       "--list returns an empty list when there's nothing to return");
 
 # dbopen, dbclose
-my $dbfile = amgetconf('TESTCONF', "dbopen.foo");
-like($dbfile, qr(^$AMANDA_DBGDIR/server/foo.[0-9]*.debug$),
+my $dbfile = run_get('amgetconf', 'TESTCONF', "dbopen.foo");
+chomp $dbfile;
+like($dbfile, qr(^\Q$AMANDA_DBGDIR\E/server/foo.[0-9]*.debug$),
     "'amgetconf dbopen.foo' returns a proper debug filename");
-ok(-f $dbfile,
-    "'amgetconf dbopen.foo' creates the debug file");
-like(amgetconf('TESTCONF', "dbclose.foo"), qr/cannot parse/,
-    "dbclose without filename fails");
-is(amgetconf('TESTCONF', "dbclose.foo:$dbfile"), $dbfile, 
-    "'amgetconf dbclose.foo:<filename>' returns the debug filename");
+SKIP: {
+    skip "dbopen didn't work, so I'll skip the rest", 3
+       unless (-f $dbfile);
+    ok(!run('amgetconf', 'TESTCONF', "dbclose.foo"),
+       "dbclose without filename fails");
+    is(run_get('amgetconf', 'TESTCONF', "dbclose.foo:$dbfile"), $dbfile, 
+       "'amgetconf dbclose.foo:<filename>' returns the debug filename");
+
+    # sometimes shell scripts pass a full path as appname..
+    $dbfile = run_get('amgetconf', 'TESTCONF', 'dbopen./sbin/foo');
+    like($dbfile, qr(^\Q$AMANDA_DBGDIR\E/server/_sbin_foo.[0-9]*.debug$),
+       "'amgetconf dbopen./sbin/foo' doesn't get confused by the slashes");
+}
 
 ##
 # Test an invalid config file
 
-$testconf = Amconfig->new();
+$testconf = Installcheck::Config->new();
 $testconf->add_param("foos_per_bar", "10");
 $testconf->write();
 
-like(amgetconf('TESTCONF', "foos_per_bar"), qr/errors processing config file/, 
+like(run_err('amgetconf', 'TESTCONF', "foos_per_bar"), qr/errors processing config file/, 
     "gives error on invalid configuration");
 
 ##
 # Now let's fill in some interesting values
 
-$testconf = Amconfig->new();
+$testconf = Installcheck::Config->new();
 $testconf->add_param("reserved-udp-port", '100,200');
 $testconf->add_param("printer", '"/dev/lp"');
 $testconf->add_param("reserve", '27');
 $testconf->write();
 
-is(amgetconf('TESTCONF', "reserved-udp-port"), "100,200", 
+is(run_get('amgetconf', 'TESTCONF', "reserved-udp-port"), "100,200", 
     "correctly returns intrange parameters from the file");
-is(amgetconf('TESTCONF', "printer"), "/dev/lp", 
+is(run_get('amgetconf', 'TESTCONF', "printer"), "/dev/lp", 
     "correctly returns string parameters from the file");
-is(amgetconf('TESTCONF', "reserve"), "27", 
+is(run_get('amgetconf', 'TESTCONF', "reserve"), "27", 
     "correctly returns integer parameters from the file");
-is(amgetconf('TESTCONF', "rEsErVe"), "27", 
+is(run_get('amgetconf', 'TESTCONF', "rEsErVe"), "27", 
     "is case-insensitive");
+is(run_get('amgetconf', 'TESTCONF', "reserved_udp_port"), "100,200", 
+    "treats _ and - identically");
+
+# check runs without a config
+my $olddir = getcwd();
+chdir("$CONFIG_DIR/TESTCONF") or die("Could not 'cd' to TESTCONF directory");
+is(run_get('amgetconf', "printer"), "/dev/lp", 
+    "uses current directory when no configuration name is given");
+chdir($olddir) or die("Could not 'cd' back to my original directory");
 
 ##
 # device_property can appear multiple times
 
-$testconf = Amconfig->new();
+$testconf = Installcheck::Config->new();
 $testconf->add_param("device_property", '"power" "on"');
 $testconf->add_param("device_property", '"turbo" "engaged"');
 $testconf->write();
 
-is_deeply([sort(+split(qr/\n/, amgetconf('TESTCONF', 'device_property')))],
+is_deeply([sort(+split(qr/\n/, run_get('amgetconf', 'TESTCONF', 'device_property')))],
          [sort('"power" "on"', '"turbo" "engaged"')],
     "device_property can have multiple values");
 
 ##
 # Subsections
 
-$testconf = Amconfig->new();
+$testconf = Installcheck::Config->new();
 $testconf->add_tapetype("cassette", [ length => "32 k" ]);
 $testconf->add_tapetype("reel2reel", [ length => "1 M" ]);
 $testconf->add_tapetype("scotch", [ length => "500 bytes" ]); # (use a sharpie)
 $testconf->add_dumptype("testdump", [ comment => '"testdump-dumptype"' ]);
 $testconf->add_interface("testiface", [ use => '10' ]);
 $testconf->add_holdingdisk("hd17", [ chunksize => '128' ]);
+$testconf->add_application('app_amgtar', [ plugin => '"amgtar"' ]);
+$testconf->add_application('app_amstar', [ plugin => '"amstar"' ]);
+$testconf->add_script('my_script', [ "execute-on" => 'pre-dle-amcheck', 'plugin' => '"foo"' ]);
+$testconf->add_device('my_device', [ "tapedev" => '"foo:/bar"' ]);
 $testconf->write();
 
-is_deeply([sort(+split(/\n/, amgetconf('TESTCONF', '--list', 'tapetype')))],
+is_deeply([sort(+split(/\n/, run_get('amgetconf', 'TESTCONF', '--list', 'tapetype')))],
          [sort("cassette", "reel2reel", "scotch", "TEST-TAPE")],
        "--list returns correct set of tapetypes");
-is(amgetconf('TESTCONF', 'tapetype:scotch:length'), '500', 
+is(run_get('amgetconf', 'TESTCONF', 'tapetype:scotch:length'), '500', 
     "returns tapetype parameter correctly");
 
-ok(grep { $_ eq 'testdump' } split(/\n/, amgetconf('TESTCONF', '--list', 'dumptype')),
+ok(scalar(grep { $_ eq 'testdump' } 
+       split(/\n/, 
+           run_get('amgetconf', 'TESTCONF', '--list', 'dumptype'))),
        "--list returns a test dumptype among the default dumptypes");
-is(amgetconf('TESTCONF', 'dumptype:testdump:comment'), 'testdump-dumptype', 
+is(run_get('amgetconf', 'TESTCONF', 'dumptype:testdump:comment'), 'testdump-dumptype', 
     "returns dumptype parameter correctly");
 
-is_deeply([sort(+split(/\n/, amgetconf('TESTCONF', '--list', 'interface')))],
+is_deeply([sort(+split(/\n/, run_get('amgetconf', 'TESTCONF', '--list', 'interface')))], 
           [sort("testiface", "default")],
        "--list returns correct set of interfaces");
-is(amgetconf('TESTCONF', 'interface:testiface:use'), '10', 
+is(run_get('amgetconf', 'TESTCONF', 'interface:testiface:use'), '10', 
     "returns interface parameter correctly");
 
-is_deeply([sort(+split(/\n/, amgetconf('TESTCONF', '--list', 'holdingdisk')))],
-         [sort("hd17")],
+is_deeply([sort(+split(/\n/, run_get('amgetconf', 'TESTCONF', '--list', 'holdingdisk')))], 
+         [sort("hd17")], 
        "--list returns correct set of holdingdisks");
-is(amgetconf('TESTCONF', 'holdingdisk:hd17:chunksize'), '128',
+is(run_get('amgetconf', 'TESTCONF', 'holdingdisk:hd17:chunksize'), '128',
     "returns holdingdisk parameter correctly");
 
+like(run_get('amgetconf', 'TESTCONF', '--list', 'build'), qr(.*version.*),
+       "'--list build' lists build variables");
+
+is_deeply([sort(+split(/\n/, run_get('amgetconf', 'TESTCONF', '--list', 'application-tool')))],
+          [sort("app_amgtar", "app_amstar")],
+        "--list returns correct set of application-tool");
+
+is(run_get('amgetconf', 'TESTCONF', 'application-tool:app_amgtar:plugin'), 'amgtar',
+    "returns application-tool parameter correctly");
+
+is_deeply([sort(+split(/\n/, run_get('amgetconf', 'TESTCONF', '--list', 'script-tool')))],
+          [sort("my_script")],
+        "--list returns correct set of script-tool");
+
+is(run_get('amgetconf', 'TESTCONF', 'script-tool:my_script:execute-on'), 'PRE-DLE-AMCHECK',
+    "returns script-tool parameter correctly");
+is(run_get('amgetconf', 'TESTCONF', 'script_tOOl:my_script:execute-on'), 'PRE-DLE-AMCHECK',
+    "insensitive to case in subsec_type");
+is(run_get('amgetconf', 'TESTCONF', 'script-tool:my_script:execute-on'), 'PRE-DLE-AMCHECK',
+    "insensitive to -/_ in subsec_type");
+is(run_get('amgetconf', 'TESTCONF', 'script_tOOl:my_script:eXECute-on'), 'PRE-DLE-AMCHECK',
+    "insensitive to case in subsec_key");
+is(run_get('amgetconf', 'TESTCONF', 'script-tool:my_script:execute_on'), 'PRE-DLE-AMCHECK',
+    "insensitive to -/_ in subsec_key");
+
+is_deeply([sort(split(/\n/, run_get('amgetconf', 'TESTCONF', '--list', 'device')))],
+          [sort("my_device")],
+        "--list returns correct set of devices");
+
+is(run_get('amgetconf', 'TESTCONF', 'device:my_device:tapedev'), 'foo:/bar',
+    "returns device parameter correctly");
+
 # non-existent subsection types, names, and parameters
-like(amgetconf('TESTCONF', 'NOSUCHTYPE:testiface:comment'), qr/no such parameter/, 
+like(run_err('amgetconf', 'TESTCONF', 'NOSUCHTYPE:testiface:comment'), qr/no such parameter/, 
     "handles bad subsection type");
-like(amgetconf('TESTCONF', 'dumptype:NOSUCHDUMP:comment'), qr/no such parameter/, 
+like(run_err('amgetconf', 'TESTCONF', 'dumptype:NOSUCHDUMP:comment'), qr/no such parameter/, 
     "handles bad dumptype namek");
-like(amgetconf('TESTCONF', 'dumptype:testdump:NOSUCHPARAM'), qr/no such parameter/, 
+like(run_err('amgetconf', 'TESTCONF', 'dumptype:testdump:NOSUCHPARAM'), qr/no such parameter/, 
     "handles bad dumptype parameter name");
+like(run_err('amgetconf', 'TESTCONF', 'application-tool:app_amgtar:NOSUCHPARAM'), qr/no such parameter/, 
+    "handles bad application-tool parameter name");
+like(run_err('amgetconf', 'TESTCONF', 'script-tool:my-script:NOSUCHPARAM'), qr/no such parameter/, 
+    "handles bad script-tool parameter name");
+
+like(run_err('amgetconf', 'TESTCONF', '--list', 'frogs'), qr/no such parameter/,
+        "--list fails given an invalid subsection name");
 
 ##
 # exclude lists are a bit funny, too
 
-$testconf = Amconfig->new();
+$testconf = Installcheck::Config->new();
 $testconf->add_dumptype("testdump", [
     "exclude file optional" => '"f1"', # this optional will have no effect
     "exclude file append" => '"f2"',
@@ -177,13 +309,14 @@ $testconf->add_dumptype("testdump", [
     ]);
 $testconf->write();
 
-is_deeply([sort(+split(qr/\n/, amgetconf('TESTCONF', 'dumptype:testdump:exclude')))],
+is_deeply([sort(+split(qr/\n/, run_get('amgetconf', 'TESTCONF', 'dumptype:testdump:exclude')))],
          [sort('FILE "f1" "f2"',
                'LIST "l1" "l2"')],
     "exclude files and lists displayed correctly; a non-final optional is ignored");
 
-is_deeply([sort(+split(qr/\n/, amgetconf('TESTCONF', 'dumptype:testdump:include')))],
+is_deeply([sort(+split(qr/\n/, run_get('amgetconf', 'TESTCONF', 'dumptype:testdump:include')))],
          [sort('FILE OPTIONAL "ifo"',
                'LIST OPTIONAL "ilo"')],
     "a final 'OPTIONAL' makes the whole include/exclude optional")
 
+