1Test2::Tools::Process(3U)ser Contributed Perl DocumentatiToenst2::Tools::Process(3)
2
3
4
6 Test2::Tools::Process - Unit tests for code that calls exit, exec,
7 system or qx()
8
10 version 0.06
11
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
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
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
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
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
292 This module is not apparently compatible with IPC::Run3. Use
293 Capture::Tiny instead, which is better maintained in my opinion.
294
296 Test::Exit
297 Simple "exit" emulation for tests. The most recent version does
298 not rely on exceptions.
299
300 Test::Exec
301 Like Test::Exit, but for "exec"
302
303 Test::Mock::Cmd
304 Provides an interface to mocking "system", "qx" and "exec".
305
307 Graham Ollis <plicease@cpan.org>
308
310 This software is copyright (c) 2015-2021 by Graham Ollis.
311
312 This is free software; you can redistribute it and/or modify it under
313 the same terms as the Perl 5 programming language system itself.
314
315
316
317perl v5.34.0 2022-01-21 Test2::Tools::Process(3)