1Apache::TestUtil(3) User Contributed Perl Documentation Apache::TestUtil(3)
2
3
4
6 Apache::TestUtil - Utility functions for writing tests
7
9 use Apache::Test;
10 use Apache::TestUtil;
11
12 ok t_cmp("foo", "foo", "sanity check");
13 t_write_file("filename", @content);
14 my $fh = t_open_file($filename);
15 t_mkdir("/foo/bar");
16 t_rmtree("/foo/bar");
17 t_is_equal($a, $b);
18
20 "Apache::TestUtil" automatically exports a number of functions useful
21 in writing tests.
22
23 All the files and directories created using the functions from this
24 package will be automatically destroyed at the end of the program
25 execution (via END block). You should not use these functions other
26 than from within tests which should cleanup all the created directories
27 and files at the end of the test.
28
30 t_cmp()
31 t_cmp($received, $expected, $comment);
32
33 t_cmp() prints the values of $comment, $expected and $received.
34 e.g.:
35
36 t_cmp(1, 1, "1 == 1?");
37
38 prints:
39
40 # testing : 1 == 1?
41 # expected: 1
42 # received: 1
43
44 then it returns the result of comparison of the $expected and the
45 $received variables. Usually, the return value of this function is
46 fed directly to the ok() function, like this:
47
48 ok t_cmp(1, 1, "1 == 1?");
49
50 the third argument ($comment) is optional, mostly useful for
51 telling what the comparison is trying to do.
52
53 It is valid to use "undef" as an expected value. Therefore:
54
55 my $foo;
56 t_cmp(undef, $foo, "undef == undef?");
57
58 will return a true value.
59
60 You can compare any two data-structures with t_cmp(). Just make
61 sure that if you pass non-scalars, you have to pass their
62 references. The datastructures can be deeply nested. For example
63 you can compare:
64
65 t_cmp({1 => [2..3,{5..8}], 4 => [5..6]},
66 {1 => [2..3,{5..8}], 4 => [5..6]},
67 "hash of array of hashes");
68
69 You can also compare the second argument against the first as a
70 regex. Use the "qr//" function in the second argument. For example:
71
72 t_cmp("abcd", qr/^abc/, "regex compare");
73
74 will do:
75
76 "abcd" =~ /^abc/;
77
78 This function is exported by default.
79
80 t_filepath_cmp()
81 This function is used to compare two filepaths via t_cmp(). For
82 non-Win32, it simply uses t_cmp() for the comparison, but for
83 Win32, Win32::GetLongPathName() is invoked to convert the first two
84 arguments to their DOS long pathname. This is useful when there is
85 a possibility the two paths being compared are not both represented
86 by their long or short pathname.
87
88 This function is exported by default.
89
90 t_debug()
91 t_debug("testing feature foo");
92 t_debug("test", [1..3], 5, {a=>[1..5]});
93
94 t_debug() prints out any datastructure while prepending "#" at the
95 beginning of each line, to make the debug printouts comply with
96 "Test::Harness"'s requirements. This function should be always used
97 for debug prints, since if in the future the debug printing will
98 change (e.g. redirected into a file) your tests won't need to be
99 changed.
100
101 the special global variable $Apache::TestUtil::DEBUG_OUTPUT can be
102 used to redirect the output from t_debug() and related calls such
103 as t_write_file(). for example, from a server-side test you would
104 probably need to redirect it to STDERR:
105
106 sub handler {
107 plan $r, tests => 1;
108
109 local $Apache::TestUtil::DEBUG_OUTPUT = \*STDERR;
110
111 t_write_file('/tmp/foo', 'bar');
112 ...
113 }
114
115 left to its own devices, t_debug() will collide with the standard
116 HTTP protocol during server-side tests, resulting in a situation
117 both confusing difficult to debug. but STDOUT is left as the
118 default, since you probably don't want debug output under normal
119 circumstances unless running under verbose mode.
120
121 This function is exported by default.
122
123 t_write_test_lib()
124 t_write_test_lib($filename, @lines)
125
126 t_write_test_lib() creates a new file at $filename or overwrites
127 the existing file with the content passed in @lines. The file is
128 created in a temporary directory which is added to @INC at test
129 configuration time. It is intended to be used for creating
130 temporary packages for testing which can be modified at run time,
131 see the Apache::Reload unit tests for an example.
132
133 t_write_file()
134 t_write_file($filename, @lines);
135
136 t_write_file() creates a new file at $filename or overwrites the
137 existing file with the content passed in @lines. If only the
138 $filename is passed, an empty file will be created.
139
140 If parent directories of $filename don't exist they will be
141 automagically created.
142
143 The generated file will be automatically deleted at the end of the
144 program's execution.
145
146 This function is exported by default.
147
148 t_append_file()
149 t_append_file($filename, @lines);
150
151 t_append_file() is similar to t_write_file(), but it doesn't
152 clobber existing files and appends @lines to the end of the file.
153 If the file doesn't exist it will create it.
154
155 If parent directories of $filename don't exist they will be
156 automagically created.
157
158 The generated file will be registered to be automatically deleted
159 at the end of the program's execution, only if the file was created
160 by t_append_file().
161
162 This function is exported by default.
163
164 t_write_shell_script()
165 Apache::TestUtil::t_write_shell_script($filename, @lines);
166
167 Similar to t_write_file() but creates a portable shell/batch
168 script. The created filename is constructed from $filename and an
169 appropriate extension automatically selected according to the
170 platform the code is running under.
171
172 It returns the extension of the created file.
173
174 t_write_perl_script()
175 Apache::TestUtil::t_write_perl_script($filename, @lines);
176
177 Similar to t_write_file() but creates a executable Perl script with
178 correctly set shebang line.
179
180 t_open_file()
181 my $fh = t_open_file($filename);
182
183 t_open_file() opens a file $filename for writing and returns the
184 file handle to the opened file.
185
186 If parent directories of $filename don't exist they will be
187 automagically created.
188
189 The generated file will be automatically deleted at the end of the
190 program's execution.
191
192 This function is exported by default.
193
194 t_mkdir()
195 t_mkdir($dirname);
196
197 t_mkdir() creates a directory $dirname. The operation will fail if
198 the parent directory doesn't exist.
199
200 If parent directories of $dirname don't exist they will be
201 automagically created.
202
203 The generated directory will be automatically deleted at the end of
204 the program's execution.
205
206 This function is exported by default.
207
208 t_rmtree()
209 t_rmtree(@dirs);
210
211 t_rmtree() deletes the whole directories trees passed in @dirs.
212
213 This function is exported by default.
214
215 t_chown()
216 Apache::TestUtil::t_chown($file);
217
218 Change ownership of $file to the test's User/Group. This function
219 is noop on platforms where chown(2) is unsupported (e.g. Win32).
220
221 t_is_equal()
222 t_is_equal($a, $b);
223
224 t_is_equal() compares any two datastructures and returns 1 if they
225 are exactly the same, otherwise 0. The datastructures can be nested
226 hashes, arrays, scalars, undefs or a combination of any of these.
227 See t_cmp() for an example.
228
229 If $b is a regex reference, the regex comparison "$a =~ $b" is
230 performed. For example:
231
232 t_is_equal($server_version, qr{^Apache});
233
234 If comparing non-scalars make sure to pass the references to the
235 datastructures.
236
237 This function is exported by default.
238
239 t_server_log_error_is_expected()
240 If the handler's execution results in an error or a warning logged
241 to the error_log file which is expected, it's a good idea to have a
242 disclaimer printed before the error itself, so one can tell real
243 problems with tests from expected errors. For example when testing
244 how the package behaves under error conditions the error_log file
245 might be loaded with errors, most of which are expected.
246
247 For example if a handler is about to generate a run-time error,
248 this function can be used as:
249
250 use Apache::TestUtil;
251 ...
252 sub handler {
253 my $r = shift;
254 ...
255 t_server_log_error_is_expected();
256 die "failed because ...";
257 }
258
259 After running this handler the error_log file will include:
260
261 *** The following error entry is expected and harmless ***
262 [Tue Apr 01 14:00:21 2003] [error] failed because ...
263
264 When more than one entry is expected, an optional numerical
265 argument, indicating how many entries to expect, can be passed. For
266 example:
267
268 t_server_log_error_is_expected(2);
269
270 will generate:
271
272 *** The following 2 error entries are expected and harmless ***
273
274 If the error is generated at compile time, the logging must be done
275 in the BEGIN block at the very beginning of the file:
276
277 BEGIN {
278 use Apache::TestUtil;
279 t_server_log_error_is_expected();
280 }
281 use DOES_NOT_exist;
282
283 After attempting to run this handler the error_log file will
284 include:
285
286 *** The following error entry is expected and harmless ***
287 [Tue Apr 01 14:04:49 2003] [error] Can't locate "DOES_NOT_exist.pm"
288 in @INC (@INC contains: ...
289
290 Also see t_server_log_warn_is_expected() which is similar but used
291 for warnings.
292
293 This function is exported by default.
294
295 t_server_log_warn_is_expected()
296 t_server_log_warn_is_expected() generates a disclaimer for expected
297 warnings.
298
299 See the explanation for t_server_log_error_is_expected() for more
300 details.
301
302 This function is exported by default.
303
304 t_client_log_error_is_expected()
305 t_client_log_error_is_expected() generates a disclaimer for
306 expected errors. But in contrast to
307 t_server_log_error_is_expected() called by the client side of the
308 script.
309
310 See the explanation for t_server_log_error_is_expected() for more
311 details.
312
313 For example the following client script fails to find the handler:
314
315 use Apache::Test;
316 use Apache::TestUtil;
317 use Apache::TestRequest qw(GET);
318
319 plan tests => 1;
320
321 t_client_log_error_is_expected();
322 my $url = "/error_document/cannot_be_found";
323 my $res = GET($url);
324 ok t_cmp(404, $res->code, "test 404");
325
326 After running this test the error_log file will include an entry
327 similar to the following snippet:
328
329 *** The following error entry is expected and harmless ***
330 [Tue Apr 01 14:02:55 2003] [error] [client 127.0.0.1]
331 File does not exist: /tmp/test/t/htdocs/error
332
333 When more than one entry is expected, an optional numerical
334 argument, indicating how many entries to expect, can be passed. For
335 example:
336
337 t_client_log_error_is_expected(2);
338
339 will generate:
340
341 *** The following 2 error entries are expected and harmless ***
342
343 This function is exported by default.
344
345 t_client_log_warn_is_expected()
346 t_client_log_warn_is_expected() generates a disclaimer for expected
347 warnings on the client side.
348
349 See the explanation for t_client_log_error_is_expected() for more
350 details.
351
352 This function is exported by default.
353
354 t_catfile('a', 'b', 'c')
355 This function is essentially "File::Spec->catfile", but on Win32
356 will use Win32::GetLongpathName() to convert the result to a long
357 path name (if the result is an absolute file). The function is not
358 exported by default.
359
360 t_catfile_apache('a', 'b', 'c')
361 This function is essentially "File::Spec::Unix->catfile", but on
362 Win32 will use Win32::GetLongpathName() to convert the result to a
363 long path name (if the result is an absolute file). It is useful
364 when comparing something to that returned by Apache, which uses a
365 Unix-style specification with forward slashes for directory
366 separators. The function is not exported by default.
367
368 t_start_error_log_watch(), t_finish_error_log_watch()
369 This pair of functions provides an easy interface for checking the
370 presence or absense of any particular message or messages in the
371 httpd error_log that were generated by the httpd daemon as part of
372 a test suite. It is likely, that you should proceed this with a
373 call to one of the t_*_is_expected() functions.
374
375 t_start_error_log_watch();
376 do_it;
377 ok grep {...} t_finish_error_log_watch();
378
379 Another usage case could be a handler that emits some debugging
380 messages to the error_log. Now, if this handler is called in a
381 series of other test cases it can be hard to find the relevant
382 messages manually. In such cases the following sequence in the test
383 file may help:
384
385 t_start_error_log_watch();
386 GET '/this/or/that';
387 t_debug t_finish_error_log_watch();
388
389 t_start_file_watch()
390 Apache::TestUtil::t_start_file_watch('access_log');
391
392 This function is similar to t_start_error_log_watch() but allows
393 for other files than "error_log" to be watched. It opens the given
394 file and positions the file pointer at its end. Subsequent calls to
395 t_read_file_watch() or t_finish_file_watch() will read lines that
396 have been appended after this call.
397
398 A file name can be passed as parameter. If omitted or undefined the
399 "error_log" is opened. Relative file name are evaluated relative to
400 the directory containing "error_log".
401
402 If the specified file does not exist (yet) no error is returned. It
403 is assumed that it will appear soon. In this case
404 "t_{read,finish}_file_watch()" will open the file silently and read
405 from the beginning.
406
407 t_read_file_watch(), t_finish_file_watch()
408 local $/ = "\n";
409 $line1=Apache::TestUtil::t_read_file_watch('access_log');
410 $line2=Apache::TestUtil::t_read_file_watch('access_log');
411
412 @lines=Apache::TestUtil::t_finish_file_watch('access_log');
413
414 This pair of functions reads the file opened by
415 t_start_error_log_watch().
416
417 As does the core "readline" function, they return one line if
418 called in scalar context, otherwise all lines until end of file.
419
420 Before calling "readline" these functions do not set $/ as does
421 "t_finish_error_log_watch". So, if the file has for example a fixed
422 record length use this:
423
424 {
425 local $/=\$record_length;
426 @lines=t_finish_file_watch($name);
427 }
428
429 t_file_watch_for()
430 @lines=Apache::TestUtil::t_file_watch_for('access_log',
431 qr/condition/,
432 $timeout);
433
434 This function reads the file from the current position and looks
435 for the first line that matches "qr/condition/". If no such line
436 could be found until end of file the function pauses and retries
437 until either such a line is found or the timeout (in seconds) is
438 reached.
439
440 In scalar or void context only the matching line is returned. In
441 list context all read lines are returned with the matching one in
442 last position.
443
444 The function uses "\n" and end-of-line marker and waits for
445 complete lines.
446
447 The timeout although it can be specified with sub-second precision
448 is not very accurate. It is simply multiplied by 10. The result is
449 used as a maximum loop count. For the intented purpose this should
450 be good enough.
451
452 Use this function to check for logfile entries when you cannot be
453 sure that they are already written when the test program reaches
454 the point, for example to check for messages that are written in a
455 PerlCleanupHandler or a PerlLogHandler.
456
457 ok t_file_watch_for 'access_log', qr/expected log entry/, 2;
458
459 This call reads the "access_log" and waits for maximum 2 seconds
460 for the expected entry to appear.
461
463 Stas Bekman <stas@stason.org>, Torsten Förtsch
464 <torsten.foertsch@gmx.net>
465
467 perl(1)
468
469
470
471perl v5.38.0 2023-07-20 Apache::TestUtil(3)