1Test2::Tools::Process(3U)ser Contributed Perl DocumentatiToenst2::Tools::Process(3)
2
3
4

NAME

6       Test2::Tools::Process - Unit tests for code that calls exit, exec,
7       system or qx()
8

VERSION

10       version 0.05
11

SYNOPSIS

13        use Test2::V0 -no_srand => 1;
14        use Test2::Tools::Process;
15
16        process {
17          system 'foo', 'bar';
18        } [
19          # check tht the first system call is to
20          # a command foo with any arguments
21          proc_event(system => array {
22            item 'foo';
23            etc;
24          }, sub {
25            # simulate the foo command
26            my($proc, @args) = @_;
27            note "faux bar command: @args";
28            # simulate a notmsl exit
29            $proc->exit(0);
30          }),
31        ];
32
33        process {
34          exit 2;
35          note 'not executed';
36        } [
37          # can use any Test2 checks on the exit status
38          proc_event(exit => match qr/^[2-3]$/),
39        ];
40
41        process {
42          exit 4;
43        } [
44          # or you can just check that the exit status matches numerically
45          proc_event(exit => 4),
46        ];
47
48        process {
49          exit 5;
50        } [
51          # or just check that we called exit.
52          proc_event('exit'),
53        ];
54
55        process {
56          exec 'foo bar';
57          exec 'baz';
58          note 'not executed';
59        } [
60          # emulate first exec as failed
61          proc_event(exec => match qr/^foo\b/, sub {
62            my($return, @command) = @_;
63            $! = 2;
64            return 0;
65          }),
66          # the second exec will be emulated as successful
67          proc_event('exec'),
68        ];
69
70        # just intercept `exit`
71        is intercept_exit { exit 10 }, 10;
72
73        # just intercept `exec`
74        is intercept_exec { exec 'foo', 'bar', 'baz' }, ['foo','bar','baz'];
75
76        done_testing;
77

DESCRIPTION

79       This set of testing tools is intended for writing unit tests for code
80       that interacts with other processes without using real processes that
81       might have unwanted side effects.  It also lets you test code that
82       exits program flow without actually terminating your test.  So far it
83       allows you to test and/or mock "exit", "exec", "system", "readpipe" and
84       "qx//".  Other process related tests will be added in the future.
85
86       This module borrows some ideas from Test::Exit.  In particular it does
87       not use exceptions to simulate "exit" or "exec", so you can freely test
88       code that calls these in an "eval".
89

FUNCTIONS

91   process
92        my $ok = process { ... } \@events, $test_name;
93        my $ok = process { ... } \@events;
94        my $ok = process { ... } $test_name;
95        my $ok = process { ... };
96
97       Runs the block, intercepting "exit", "exec", "system", "readpipe" and
98       "qx//" calls.  The calls are then matched against "\@events" as the
99       expected process events.  See "proc_event" below for defining
100       individual events, and the synopsis above for examples.
101
102   named_signal
103        my $signame = named_signal $name;
104
105       Given a string signal name like "KILL", this will return the integer
106       signal number.  It will throw an exception if the $name is invalid.
107
108   intercept_exit
109        my $status = intercept_exit { ... };
110
111       Intercept any c<exit> calls inside the block, and return the exit
112       status.  Returns "undef" if there were no "exec" calls.
113
114   intercept_exec
115        my $arrayref = intercept_exec { ... };
116
117       Intercept any "exec" calls inside the block and return the command line
118       that a was passed to it.  Returns "undef" if there were no "exec"
119       calls.
120

CHECKS

122   proc_event
123        process { ... } [
124          proc_event($type => $check, $callback),
125          proc_event($type => $check),
126          proc_event($type => $callback),
127          proc_event($type),
128
129          # additional result checks for `system` events
130          proc_event('system' => $check, \%result_check, $callback),
131          proc_event('system' => \%result_check, $callback),
132          proc_event('system' => $check, \%result_check),
133          proc_event('system' => \%result_check),
134        ];
135
136       The "proc_event" function creates a process event, with an optional
137       check and callback.  How the $check works depends on the $type.  If no
138       $check is provided then it will only check that the $type matches.  Due
139       to their nature, "exit" and "exec" events are emulated.  "system"
140       events will actually make a system call, unless a $callback is
141       provided.
142
143       exit
144           A process event for an "exit" call.  The check is against the
145           status value passed to "exit".  This value will always be an
146           integer.  If no status value was passed to "exit", 0 will be used
147           as the status value.
148
149           If no callback is provided then an "exit" will be emulated by
150           terminating the process block without executing any more code.  The
151           rest of the test will then proceed.
152
153            proc_event( exit => sub {
154              my($proc, $status) = @_;
155              $proc->terminate;
156            });
157
158           The callback takes a $proc object and a $status value.  Normally
159           "exit" should never return, so what you want to do is call the
160           "terminate" method on the $proc object.
161
162       exec
163           A process event for an "exec" call.  The check is against the
164           command passed to "exec".  If "exec" is called with a single
165           argument this will be a string, otherwise it will be an array
166           reference.  This way you can differentiate between the SCALAR and
167           LIST modes of "exec".
168
169           If no callback is provided then a (successful) "exec" will be
170           emulated by terminating the process block without executing any
171           more code.  The rest of the test will then proceed.
172
173            proc_event( exec => sub {
174              my($proc, @command) = @_;
175              ...;
176            });
177
178           The callback takes a $proc object and the arguments passed to
179           "exec" as @command.  You can emulate a failed "exec" by using the
180           "errno" method on the $proc object:
181
182            proc_event( exec => sub {
183              my($proc, @command) = @_;
184              $proc->errno(2); # this is the errno value
185            });
186
187           To emulate a successful "exec" call you want to just remember to
188           call the "terminate" method on the $proc object.
189
190            proc_event( exec => sub {
191              my($proc, @command) = @_;
192              $proc->terminate;
193            });
194
195       system
196           A process event for "system", "piperead" and "qx//".  The first
197           check (as with "exec") is against the command string passed to
198           "system".  The second is a hash reference with result checks.
199
200           status
201                proc_event( system => { status => $check } );
202
203               The normal termination status.  This is usually the value
204               passed to "exit" in the program called.  Typically a program
205               that succeeded will return zero (0) and a failed on will return
206               non-zero.
207
208           errno
209                proc_event( system => { errno => $check } );
210
211               The "errno" or $! value if the system call failed.  Most
212               commonly this is for bad command names, but it could be
213               something else like running out of memory or other system
214               resources.
215
216           signal
217                proc_event( system => { signal => $check } );
218
219               Set if the process was killed by a signal.
220
221           Only one check should be included because only one of these is
222           usually valid.  If you do not provide this check, then it will
223           check that the status code is zero only.
224
225           By default the actual system call will be made, but if you provide
226           a callback you can simulate commands, which is helpful in unit
227           testing your script without having to call external programs which
228           may have unwanted side effects.
229
230            proc_event( system => sub {
231              my($proc, @command) = @_;
232              ...
233            });
234
235           Like the "exec" event, @command contains the full command passed to
236           the "system" call.  You can use the $proc object to simulate one of
237           three different results:
238
239           exit
240                $proc->exit($status);
241                $proc->exit;
242
243               Exit with the given status.  A status of zero (0) will be used
244               if not provided.  If no result is specified in the callback at
245               all then a status of zero (0) will also be used.
246
247           signal
248                $proc->signal($signal);
249
250               Terminate with the given signal.  $signal can be either an
251               integer value (in which case no validation that it is a real
252               signal is done), or a string signal name like "KILL", "HUP" or
253               any signal supported by your operating system.  If you provide
254               an invalid signal name an exception will be thrown.
255
256                proc_event( system => { signal => 9 } => sub {
257                  my($proc, @args) = @_;
258                  $proc->signal('KILL');
259                });
260
261               Note that when you kill one of these faux processes with a
262               signal you will want to update the expected signal check, as in
263               the example above.
264
265           errno
266                $proc->errno($errno);
267
268               Simulate a failed "system" call.  Most often "system" will fail
269               if the command is not found.  The $errno passed in should be a
270               valid "errno" value.  On my system 2 is the error code for
271               command not found.  Example:
272
273                proc_event( system => { errno => number(2) } => sub {
274                  my($proc, @args) = @_;
275                  $proc->errno(2);
276                });
277
278           type
279                my $type = $proc->type;
280
281               Returns "system" or "readpipe" depending on the Perl function
282               that triggered the system call.
283

CAVEATS

285       The "exit" emulation, doesn't call "END" callbacks or other
286       destructors, since you aren't really terminating the process.
287
288       This module installs handlers for "exec", "exit", "system" and
289       "readpipe", in the "CORE::GLOBAL" namespace, so if your code is also
290       installing handlers there then things might not work.
291

SEE ALSO

293       Test::Exit
294           Simple "exit" emulation for tests.  The most recent version does
295           not rely on exceptions.
296
297       Test::Exec
298           Like Test::Exit, but for "exec"
299
300       Test::Mock::Cmd
301           Provides an interface to mocking "system", "qx" and "exec".
302

AUTHOR

304       Graham Ollis <plicease@cpan.org>
305
307       This software is copyright (c) 2015-2021 by Graham Ollis.
308
309       This is free software; you can redistribute it and/or modify it under
310       the same terms as the Perl 5 programming language system itself.
311
312
313
314perl v5.34.0                      2021-07-23          Test2::Tools::Process(3)
Impressum