NAME
Test2::Tools::Command - test simple unix commands
SYNOPSIS
use Test2::Tools::Command;
# test some typical unix tools; implicit checks are that status
# is 0, and that stdout and stderr are the empty string, unless
# otherwise specified
command { args => [ 'true' ] };
command { args => [ 'false' ], status => 1 };
command { args => [ 'echo', 'foo' ], stdout => "foo\n" };
# subsequent args are prefixed with this
local @Test2::Tools::Command::command = ( 'perl', '-E' );
# return values and a variety of the options available
my ($result, $exit_status, $stdout_ref, $stderr_ref) =
command { args => [ q{say "out";warn "err";kill TERM => $$} ],
chdir => '/some/dir',
env => { API_KEY => 42 },
stdin => "printed to program\n",
stdout => qr/out/,
stderr => qr/err/,
status => { code => 0, signal => 15, iscore => 0 },
timeout => 7 };
# check on a $? exit status word from somewhere
is_exit $?, 42;
is_exit $?, { code => 0, signal => 9, iscore => 0 };
DESCRIPTION
This module tests that commands given particular arguments result in particular outputs by way of the exit status word, standard output, and standard error. Various parameters to the command function alter exactly how this is done, in addition to variables that can be set.
The commands are expected to be simple, for example filters that maybe accept standard input and respond with some but not too much output. Interactive or otherwise complicated commands will need some other module such as Expect to test them, as will programs that generate too much output.
Also, is_exit is provided to check on the 16-bit exit status word from other code.
VARIABLES
These are not exported.
- @command
-
Custom command to prefix any commands run by command with, for example to specify a test program that will be used in many subsequent tests
local @Test2::Tools::Command::command = ($^X, '--', 'bin/foo'); command { args => [ 'bar', '-c', 'baz' ] };
will result in
perl -- bin/foo bar -c baz
being run.If chdir is used, a command that uses a relative path may need to be fully qualified, e.g. with
rel2abs
of File::Spec::Functions. - $timeout
-
Seconds after which commands will be timed out via
alarm
if a timeout is not given to command. 30 by default.
FUNCTIONS
command is exported by default; this can be disabled by using this module with an empty import list. The test keys are status, stdout, and stderr. The other keys influence how the command is run or change test metadata.
- command hashref
-
Runs a command and executes one or more tests on the results, depending on the contents of hashref, which may contain:
- args => arrayref
-
List of arguments to run the command with. The argument list will be prefixed by the @command variable, if that is set.
- binmode => layer
-
If set, layer will be set on the filehandles wired to the command via the
binmode
function. See also open. - chdir => directory
-
Attempt to
chdir
into directory or failing that will throw an exception, by way of File::chdir.A command that uses a relative path may need to be fully qualified, e.g. with
rel2abs
of File::Spec::Functions. - env => hashref
-
Set the environment for the command to include the keys and values present in hashref. This is additive only; environment variables that must not be set must be deleted from
%ENV
, or the command wrapped with a command that can reset the environment, such as env(1). - name => string
-
Custom name for the tests. Otherwise, the full command executed is used in the test name, which may not be ideal.
- munge_signal => boolean
-
If the signal number of the 16-bit exit status word is not zero, the signal will be munged to have the value
1
. - munge_status => boolean
-
If the exit code of the 16-bit exit status word is not zero, the code will be munged to have the value
1
. Use this where the program being tested is unpredictable as to what non-zero exit code it will use. - status => code-or-hashref
-
Expect the given value as the 16-bit exit status word. By default
0
for the exit code is assumed. This can be specified in two different forms; the following two are equivalent:status => 42 status => { code => 42, iscore => 0, signal => 0 }
Obviously the 16-bit exit status word is decomposed into a hash reference. If the program is instead expected to exit by a SIGPIPE, one might use:
status => { code => 0, iscore => 0, signal => 13 }
See also munge_signal and munge_status.
- stdin => data
-
If present, data will be printed to the command and then standard input will be closed. Otherwise, nothing is done with standard input.
- stdout => qr-or-string
-
Expect that the standard output of the command exactly matches the given string, or if the string is a
qr//
regular expression, that the output matches that expression. - stderr => qr-or-string
-
Expect that the standard err of the command exactly matches the given string, or if the string is a
qr//
regular expression, that the stderr matches that expression. - timeout => seconds
-
Set a custom timeout for the
alarm
call that wraps the command. The variable $timeout will be used if this is unset.
command returns a list consisting of the result of the tests, the original 16-bit exit status word, and scalar references to strings that contain the standard output and standard error of the test program, if any.
my ($result, $status, $out_ref, $err_ref) = command { ...
- is_exit status [ code-or-hashref [ test-name ] ]
-
This routine checks that a 16-bit exit status word (usually by way of the
$?
variable) conforms to some code or hash reference. The hash reference may contain mungle_signal and munge_status that will turn non-zero signal or codes into1
.is_exit $?, 42; is_exit $?, { code => 0, signal => 9, iscore => 0 };
BUGS
None known. There are probably portability problems if you stray from the unix path.
SEE ALSO
Expect may be necessary to test complicated programs.
IPC::Open3 is used to run programs; this may run into portability problems on systems that stray from the way of unix?
COPYRIGHT AND LICENSE
Copyright 2022 Jeremy Mates
This program is distributed under the (Revised) BSD License: https://opensource.org/licenses/BSD-3-Clause