SYNOPSIS
use Test::Quattor qw(test_profile1 test_profile2...);
DESCRIPTION
Test::Quattor
Module preparing the environment for testing Quattor code.
LOADING
When loading this module it will compile any profiles given as arguments. So,
use Test::Quattor qw(foo);
will trigger a compilation of src/test/resources/foo.pan and the
creation of a binary cache for it. The compiled profile will be stored
as target/test/profiles/foo.json, while the cache will be stored in
under target/test/profiles/foo/.
This binary cache may be converted in an
EDG::WP4::CCM::CacheManager::Configuration object using the
get_config_for_profile function.
INTERNAL INFRASTRUCTURE
Module variables
This module provides backup methods for several CAF modules. They
will prevent tests from actually modifying the state of the system,
while allowing an NCM component to follow a realistic execution path.
These backups record what files are being written, what commands are being run, and allow for inspection by a test.
This is done with several functions, see Redefined functions below, that control the following variables:
-
QUATTOR_TEST_LOG_DEBUGLEVEL
If the environment variable QUATTOR_TEST_LOG_DEBUGLEVEL is set, the unittests will run with this debuglevel (0-5). Otherwise the default loglevel is 'verbose'.
To actually see the verbose or debug output, you need to run prove with verbose flag (e.g. by passing
-Dprove.args=-vor by setting-vin the<~/.proverc>). -
$log_cmdA boolean to enable logging of each command that is run via CAF::Process. Can also be set via the QUATTOR_TEST_LOG_CMD environment variable.
-
$log_cmd_missingA boolean to log each cmd that has output mocked but has no output set. Can also be set via the QUATTOR_TEST_LOG_CMD_MISSING environment variable.
-
%files_contentsContents of a file after it is closed. The keys of this hash are the absolute paths to the files.
This hash is a global variable whose contents can be checked in a test, if necessary. But if you want to set the file content before using the Path methods (for example, using
set_file_contents), it is preferable to use%desired_file_contents. -
%commands_runCAF::Process objects being associated to a command execution.
-
%commands_statusDesired exit status for a command. If the command is not present here, it is assumed to succeed.
-
%desired_outputsWhen we know the component will call
CAF::Process::outputand friends, we prepare here an output that the component will have to deal with. -
%desired_errWhen the component may analyse the standard error of a component, we supply it through this hash.
-
%desired_file_contentsInitial contents for a file that should be "edited". The content of this hash (keys are the absolute path names) is managed/updated by all the
CAF::FileWritermethods. It is preferable to use it rather than%files_contents, if you don't need to access its contents directly from another module (CAF::FileWritermethods give access to its contents in fact). -
@command_historyCAF::Process commands that were run.
-
caf_pathA hashref with Path methods and arrayref of reference of used arguments
-
NoActionSet
Test::Quattor::NoActionto overrideCAF::Object::NoActionin any of the mockedTest::Quattormethods (where relevant, e.g. mocked FileWriter and FileEditor).E.g. if you want to run tests with
CAF::Object::NoActionnot set (to test the behaviour of regularCAF::Object::NoAction).Default is 1.
-
%immutableThe content of this hash (keys are the absolute path names) indicates if paths (files, directories, ...) are immutable (or not). Any modification to an immutable path will result in an error.
You can add paths using the
set_immutablefunction.
Redefined functions
In order to achieve this, the following functions are redefined automatically:
-
CAF::Process::{run,execute,output,trun,toutput}Prevent any command from being executed.
-
CAF::FileWriter::openOverriding this function allows us to inspect its contents after the unit under tests has released it.
-
CAF::FileWriter::closeOverriding this function to force noaction and update mocked
%desired_file_contents. -
CAF::FileWriter::_closeMock-only method to make the FileWriter instance not opened (in IO::String sense).
Required for cleanup of filehandles left by eg immutable paths.
-
CAF::FileWriter::_read_contentsUsed to get the original content (for
<CAF::FileWriter-close>>) and/or source (for<CAF::FileEditor-new>>) from the%desired_file_contents. -
CAF::FileEditor::_is_valid_fileMock using
is_filefunction. -
CAF::FileEditor::_is_reference_newerMock using
is_filefunction (but no support for pipes or age test). -
CAF::FileReader::_is_valid_fileMock using
is_filefunction (but no support for pipes). -
CAF::Reporter::debugChecks that each debug() call starts with a debuglevel between 0 and 5.
-
CAF::Reporter::debugChecks that each debug() call starts with a debuglevel between 0 and 5.
-
IO::String::closePrevents the buffers from being released when explicitly closing a file.
-
CAF::Path::file_existsReturn the mocked
is_file -
CAF::Path::directory_existsReturn the mocked
is_directory -
CAF::Path::any_existsReturn the mocked
is_any -
is_symlink
Test if given path is a mocked symlink
-
has_hardlinks
Test if given path is a mocked hardlink
Note that it is not a perfect replacement for the c
has_hardlinksbecause the current implementation of mocked hardlinks does not allow to mimic multiple references to an inode. The differences are : the link used at creation time must be queried, not the target (where in a real hardlink target and link are undistinguishable); if the path is a hardlink the number of references for the inode is always 1. -
is_hardlink
Test if
path1andpath2are hardlinked -
_make_link
Add a mocked
_make_link.This mocked method implements most of the checks done in
LC::Check::link, the function doing the real work in_make_link, and returns the same values as Path_make_link. See Path comments for details.Internally, this mocked symlink/hardlink support uses the file contents to track that a path is a symlink or hardlink. Thus, in addition to the symlink() and hardlink() methods, a link can be created with
set_file_contents($filename, $Test::Quattor::SYMLINK)for a symlink andset_file_contents($filename, $Test::Quattor::HARDLINK)for a hardlink. -
CAF::Path::directoryReturn directory name unless mocked
make_directoryor mockedLC_Checkfail.(The
tempis ignored wrt creating the directory name). -
CAF::Path::LC_CheckStore args in
caf_pathusingadd_caf_path. -
CAF::Path::cleanupremove_anyand store args incaf_pathusingadd_caf_path. -
CAF::Path::moveremove_anyand store args incaf_pathusingadd_caf_path. -
CAF::Path::_listdirMock underlying _listdir method that does the actual opendir/readdir/closedir.
Has 2 args, one directory and one test function. The is no validation of any kind. Do not use this method directly, use
listdirinstead.
FUNCTIONS FOR EXTERNAL USE
The following functions are exported by default:
-
get_fileReturns the object that has manipulated
$filename -
set_file_contentsFor file
$filename, sets the initial$contentsthe component should see.Returns the contents on success, undef otherwise.
-
get_file_contentsFor file
$filename, returns the contents on success, undef otherwise. -
get_commandReturns all the information recorded about the execution of
$cmd, if it has been executed. This is a hash reference in which theobjectelement is the Process object itself, and themethodelement is the function that executed the command. -
set_command_statusSets the "exit status" we'll report for a given command.
-
set_desired_outputSets the standard output we'll return when the caller issues
outputon this command -
set_desired_errSets the standard error we'll receive when the caller issues
executeon this command. -
command_history_resetReset the command history to empty list.
-
command_history_okGiven an arrayref of
required_commands, it checks the@command_historyif all commands were called in the given order (it allows for other commands to exist inbetween). The commands are interpreted as regular expressions.E.g. if
@command_historyis (x1, x2, x3) thencommand_history_ok([x1,X3])returns 1 (Both x1 and x3 were called and in that order, the fact that x2 was also called but not checked is allowed.).command_history_ok([x3,x2])returns 0 (wrong order),command_history_ok([x1,x4])returns 0 (no x4 command).A second arrayref of
forbidden_commandscan be given, and the@command_historyis then first checked that none of those commands occured. If you only want to check the non-occurence of commands, pass an undef as the first argument (and not an empty arrayref). -
set_service_variantSets the Service variant to the one given in the command line:
-
linux_sysvLinux SysV, e.g,
/sbin/service foo start -
linux_systemdLinux, Systemd variant.
-
solarisSolaris and SMF variant.
Test::Quattordefaults tolinux_sysv. -
-
force_service_variantForce the variant by bypassing Service
AUTOLOADmagic and defining the methods via glob assignments in the namespace.The first argument is the
$variantto use.When testing subclassed Service, the second (optional) argument is the subclass, followed by all other arguments as additional non-standard actions.
-
set_immutable
Make path immutable. Pass a false
boolto make the path mutable again (not <undef>, default is to make the path immutable). -
is_mutable
Check if the path and parent path are mutable. (Parent path is not checked when
skip_parentargument is true).Report an error prefixed with
prefixand return 0 when path (and/or parent path) is immutable. -
sane_path
sanitize path by
- squash multiple '/' into one
- remove all trailing '/'
-
is_file
Test if given
$pathis a mocked file -
is_directory
Test if given
$pathis a mocked directory -
is_any Test if given path is known (as file or directory or anything else)
-
make_directory
Add a directory to the mocked directories. If
recis true or undef, also add all underlying directories.If
mutableis true, always create the directory.If directory already exists and is a directory, return SUCCESS (undef otherwise).
-
remove_any
Recursive removal of a path from the files_contents / desired_file_contents
-
move
move
srctodest. Ifbackupis defined and not empty string, movedestto backup (backupis a suffix). -
add_caf_path
Add array of arguments to
caf_pathhashref usingname -
reset_caf_path
Reset
caf_pathref. Ifnameis defined, only reset that cache. -
dump_contents
Debug function to show the entries in
desired_file_contentsandfiles_contents.Options
-
log
Pass a reporter/logger instance, and report with verbose level. By default,
Test::More::diagis used. -
filter
Regex pattern to filter filenames to show (matches are kept).
-
prefix
A message prefix
-
BUGS
Probably many. It does quite a lot of internal black magic to make
your executions safe. Please ensure your component doesn't try to
outsmart the CAF library and everything should be fine.