
The previous discussion has been moved to
CliRunnerContribDev.
This is a Contrib targeted at TWiki developers. It allows to run
independent TWiki scripts from your TWiki code (mostly unit tests).


This Contrib requires the yet-to-be released TWiki version 4.1!
Note that the detailed documentation has been generated automatically
by the
TWiki:Plugins.BuildContrib
, and would need care to be
comprehensible. For use cases and examples, see the test cases file
provided with this contrib, which are not in the distribution, but
available from SVN.
Summary of Contents
This contrib describes a
$runner object which allows to run TWiki
scripts from your TWiki code in an independent process. The object
methods allow to change the options, configuration, and module
environment for the single request performed by the independent
process. All other simultaneous TWiki operations remain unaffected.
Use Cases
The most important use cases for this contrib are "special" unit
tests - tests which can neither be performed with TWiki's usual test
case mechanisms, nor with LWP or browser tests:
- Test cases where you want to change the set of available CPAN modules: This can't be done from conventional test cases because they all "see" the same Perl libraries, and once a module has been compiled it can't be removed. And it can't be done with browser tests because the browser has no access to your libraries. You could, of course, rename your CPAN library temporarily, but this may affect other users, or other services on the same computer.
- Test cases where you need to run all checks and capture the complete output. Such tests could be done by capturing the output of e.g.
do view; - but this would splatter the namespaces and global variables of the testing environment. That property is interesting for mod_perl like tests, but not for "usual" CGI simulation where every request runs in its own process.
Detailed Documentation
Package TWiki::Contrib::CliRunnerContrib
This package is intended to be used by TWiki developers. It contains
helper functions to fire off daughter processes which invoke one of
TWiki's scripts, with a variety of parameters. This covers the usual
parameters to TWiki scripts as they are available as URL parameters,
but in addition parameters to the Perl interpreter itself, for example
to add extra libraries or modules.
Synopsis
sub test_someUnitTest {
my $this = shift;
my $runner = TWiki::Contrib::CliRunner->new();
$runner->topic('TestCases.MySpecialTestTopic');
$runner->twikiCfg(LogFileName => '/dev/null');
$runner->no('My::Optional::Module');
$runner->addScriptOptions(skin => 'plain');
my $output = $runner->run();
$this->assert_matches(qr/Hey! Where is My::Optional::Module\?/,$output);
}
The CliRunner object
Object Attributes
Calling Convention
TWiki scripts can be called from the command line using two different
calling conventions:
- The "usual" command line convention passes parameters as space-separated key value pairs, indicated by a value of
'CLI'.
- The
CGI.pm convention for calls to the command line passes parameters in a query-string syntax, e.g. ?key=value, appended to the path (topic in case of TWiki). This is indicated by an attribute value of 'CGI'.
Usually TWiki scripts discover their calling convention themselves,
depending on the existence of the environment variable
$ENV{GATEWAY_INTERFACE}. One known exception is
configure, which
does not support TWiki's usual command line convention.
If you chose
'CGI' as calling convention, you have to take care
yourself for setting the environment variables which may be needed by
the script.
$ENV{GATEWAY_INTERFACE} is a
must for all scripts,
with exception of
configure which always assumes
'CGI' conventions.
Others to check out are
$ENV{REMOTE_USER} for running the script under a defined user id, or
$ENV{PATH_INFO} and
$ENV{SCRIPT_NAME}.
- Note to self: Or are they being set by
CGI.pm correctly? Must check.
The calling convention can be queried, and set, with the method
callingConvention.
TODO
- The defaults configuration hash is a crude mixture of site configuration items and mere object defaults - that should be decoupled.
- Documentation and code have gotten slightly out of sync since I've discovered how to use the
Config.spec file.
ClassMethod new([$config]) -> CliRunner object
Purpose: Create a CliRunner object, intended to be fired off one
time, or multiple times, with command line parameters derived from the
object's attributes.
Parameters
$config (optional)
The one and optional parameter to this routine is a reference to a
hash containing parameters to be used for the command line invocation.
The keys, their defaults and meanings are described in the following
table.
| Key |
Default |
Description |
perl |
'perl' |
Location of the Perl interpreter. The default should have been automatically (or manually) set by configure. Otherwise it is assumed that the interpreter is accessible as perl, somewhere on the PATH. |
perlOptions |
'-T' |
Options to pass to the Perl interpreter. The default just switches on taint checking, which is mandatory for most TWiki scripts. |
develOptions |
[] |
Special developer options to pass to the Perl interpreter. |
script |
'view' |
Which of the programs to call |
callingConvention |
'CLI' |
Calling conventions for parameter passing. See #AttributeCallingConvention. |
scriptOptions |
[] |
Options to pass to the script, e.g. an alternate user id. |
topic |
'Main.WebHome' |
The web and topic to act on. |
output_options |
'2>&1' |
Redirection options, e.g. to save output files |
ObjectMethod command -> command_string
Return the command which would be run with the current object (in
fact, the
run method has its command generated with this routine)
Class Method error_missing_module($module) => error_regex
Return a regex suitable for use in an assertion after a module has
been "hidden" using the
no method.
Use in test cases where you do deliberately do not catch errors thrown
as a result of a missing module.
Parameters
Object Method no(@modules
) -> (void)
For the current runner object, pretend that the
CPAN module(s) given
in the parameter list are not available.
Parameters
| Parameter |
Type |
Description |
@modules |
array |
@modules is a list of strings containing module names as you would use them in a use statement, i.e. with :: as separator, and without .pm. |
Example
$runner->no('CGI','Pretty::Strange::Module');
Bugs
The method can not hide modules which are in TWiki's own lib
directories, i.e. those activated in
bin/setlib.cfg and
bin/LocalLib.cfg.
ObjectMethod addScriptOptions(%options) = arrayref to options
Parameters
Bugs/Todo
You can not remove, nor change script options right now.
ObjectMethod callingConvention([$cC]) -> current cC
Gets/sets the calling convention for the runner object (see
#AttributeCallingConvention for a description of the attribute).
Parameters
| Parameter |
Type |
Description |
$cC |
scalar |
Optional. New calling convention to be used by the script. If missing, the calling convention remains unchanged. Valid values are 'CLI' (for command line style) and 'CGI' (for CGI.pm style). |
$currentcC |
scalar |
The current calling convention of the runner object. |
ObjectMethod perlOptions([$optionString]) -> $currentOptions
Parameters
| Parameter |
Type |
Description |
$optionString |
scalar |
Optional. New options to be passed to the Perl interpreter. If missing, the options remain unchanged. |
$currentOptions |
scalar |
The current perl options of the runner object. |
ObjectMethod run([$params]) -> output
Run the current object and capture and return the
intermingled results from both STDOUT and STDERR.
Parameters
$params (optional)
See the
$config parameter of #MethodNew.
TODO
- Separate the output streams for STDOUT and STDERR using
IPC::Open3
- Allow to extend, and not just replace, the configuration options
ObjectMethod script([$script]) -> current script
Gets/sets the script name for the runner object
Parameters
| Parameter |
Type |
Description |
$script |
scalar |
Optional. script to be called. If missing, the script remains unchanged. Defaults to ='view='. |
$current |
scalar |
The current script to be run. |
ObjectMethod topic([$topic]) -> $current
Gets/sets the topic for the runner object
Parameters
| Parameter |
Type |
Description |
$topic |
scalar |
Optional. topic to be operated upon If missing, the topic remains unchanged. Defaults to 'Main.WebHome'. |
$current |
scalar |
The current topic to be run. |
Define configuration items to change in the runner object. Note that,
in contrast to the finalized
%TWiki::cfg hash, our deltas are
lists. This is due to the fact that we need to change individual
entries in multi-level configuration settings, and we need to have
cumulative changes where the ordering matters.
The parameters with even indices (starting with 0) must be array
references, consisting of the keys for each level in the
%TWiki::cfg
hash. The elements with odd indices (starting with 1) are the values
to be used for these configuration items.
Too complicated? Incomprehensible? Yes, of course. Please make a
better description if you can. Or a better code. Or both. Let me
try to explain the current behaviour with some examples:
- Replace a simple configuration item
-
$runner->twikiCfg(MapUserToWikiName => 1);
Note that the => operator is just syntactic Perl sugar to make the first parameter being automatically interpreted as a (bareword) string, or a hash key. Do not try to use this for complex configuration items.
- Enable a plugin
-
$runner->twikiCfg([qw(Plugins TestFixturePlugin Enabled)],1);
Note that in this case the first parameter must not be stringified! $ Equivalent to the previous method, provided that the TestFixturePlugin has no other keys but Enabled:
$runner->twikiCfg([qw(Plugins TestFixturePlugin)],{Enabled=>1});
ObjectMethod twikiCfgFile([$twikiCfgFile]) -> current twikiCfgFile
Gets/sets the twikiCfgFile to be used for the runner object
Package TWiki::Contrib::CliRunnerContrib::HideModule
This package is intended to be used by TWiki developers. It contains
methods to hide
CPAN modules by pretending that they don't return a
true value.
No user-serviceable parts inside.
Package TWiki::Contrib::CliRunnerContrib::TWikiCfg
This package is intended to be used by TWiki developers. It contains
methods to manipulate the
$TWiki::cfg hash for a single run.
No user-serviceable parts inside.
Settings
Settings are stored as preferences variables. To reference a setting write
%<plugin>_<setting>%, e.g.
%CLIRUNNERCONTRIB_STUB%
- One line description:
- Set SHORTDESCRIPTION = Run independent TWiki scripts from your TWiki code (mostly unit tests)
Installation Instructions
- Download the ZIP file from the Plugin web (see below)
- Unzip
CliRunnerContrib.zip in your twiki installation directory. Content: | File: | Description: |
data/TWiki/CliRunnerContrib.txt | Plugin doc page |
lib/TWiki/Contrib/CliRunnerContrib.pm | Plugin Perl module |
lib/TWiki/Contrib/CliRunnerContrib/HideModule.pm | Module to pseudo-hide packages |
lib/TWiki/Contrib/CliRunnerContrib/TWikiCfg.pm | Module to change TWiki configuration |
lib/TWiki/Contrib/CliRunnerContrib/Config.spec | Define configurable options |
- Run
CliRunnerContrib_installer.pl to automatically check and install other modules that this module depends on. You can also do this step manually. Dependencies: None
- Test if the installation was successful:
- Run
WebTestCasesAutoTests.pm in the test/unit directory. If the installation was successful, you see a couple of tests. The tests may not succeed, but this is another matter....
Contrib Info
--
TWiki:Main/HaraldJoerg
- 2026-02-22