File Coverage

blib/lib/HTTP/WebTest/SelfTest.pm
Criterion Covered Total %
statement 92 96 95.8
branch 15 22 68.1
condition 5 8 62.5
subroutine 17 17 100.0
pod 8 8 100.0
total 137 151 90.7


line stmt bran cond sub pod time code
1             # $Id: SelfTest.pm,v 1.8 2003/07/03 11:22:01 m_ilya Exp $
2              
3             package HTTP::WebTest::SelfTest;
4              
5             =head1 NAME
6              
7             HTTP::WebTest::SelfTest - Helper package for HTTP::WebTest test suite
8              
9             =head1 SYNOPSIS
10              
11             use HTTP::WebTest::SelfTest;
12              
13             =head1 DESCRIPTION
14              
15             This module provides helper routines used by L self
16             test suite. Plugin writers may find this module useful for
17             implementation of test suites for their plugins.
18              
19             =cut
20              
21 21     21   29351 use strict;
  21         53  
  21         1098  
22              
23 21     21   114 use base qw(Exporter);
  21         44  
  21         2911  
24              
25             =head1 GLOBAL VARIABLES
26              
27             This module imports in namespace of test script following global
28             variables.
29              
30             =cut
31              
32 21     21   114 use vars qw(@EXPORT $HOSTNAME $PORT $URL);
  21         39  
  21         2386  
33              
34             @EXPORT = qw($HOSTNAME $PORT $URL
35             abs_url
36             check_webtest
37             read_file write_file
38             generate_testfile canonical_output compare_output
39             parse_basic_credentials
40             start_webserver stop_webserver);
41              
42 21     21   28574 use Algorithm::Diff qw(diff);
  21         172779  
  21         2222  
43 21     21   34133 use MIME::Base64;
  21         22697  
  21         1636  
44 21     21   168 use URI;
  21         41  
  21         659  
45              
46 21     21   125 use HTTP::WebTest::Utils qw(find_port start_webserver stop_webserver);
  21         42  
  21         38966  
47              
48             =head2 $HOSTNAME
49              
50             The hostname of the test webserver.
51              
52             =cut
53              
54             $HOSTNAME = $ENV{TEST_HOSTNAME} || '127.0.0.1';
55              
56             =head2 $PORT
57              
58             The port of the test webserver.
59              
60             =cut
61              
62             $PORT = find_port();
63             die "Can't find free port" unless defined $PORT;
64              
65             =head2 $URL
66              
67             The URL of the test webserer.
68              
69             =cut
70              
71             $URL = "http://$HOSTNAME:$PORT/";
72              
73             =head1 SUBROUTINES
74              
75             This module imports in namespace of test script following helper
76             subroutines.
77              
78             =head2 abs_url($base, $rel)
79              
80             =head3 Return
81              
82             Returns absolute URL based on pair of base and relative URLs.
83              
84             =cut
85              
86             sub abs_url {
87 207     207 1 143001 my $abs = shift;
88 207         721 my $rel = shift;
89              
90 207         2655 return URI->new_abs($rel, $abs);
91             }
92              
93             =head2 read_file($filename, $ignore_errors)
94              
95             Reads a file.
96              
97             =head3 Parameters
98              
99             =over 4
100              
101             =item $filename
102              
103             Name of the file.
104              
105             =item $ignore_errors
106              
107             (Optional) If true then open file errors are ignored, otherwise they
108             raise an exception. If omit defaults to true.
109              
110             =back
111              
112             =head3 Returns
113              
114             Whole content of the file as a string.
115              
116             =cut
117              
118             sub read_file {
119 116     116 1 16288 my $filename = shift;
120 116         215 my $ignore_errors = shift;
121              
122 116         388 local *FILE;
123 116 100       9311 if(open FILE, "< $filename") {
124 115         21523 my $data = join '', ;
125 115         2543 close FILE;
126              
127 115         686 return $data;
128             } else {
129 1 50       5 die "Can't open file '$filename': $!" unless $ignore_errors;
130             }
131              
132 1         117 return '';
133             }
134              
135             =head2 write_file($filename, $data)
136              
137             Writes into a file.
138              
139             =head3 Parameters
140              
141             =over 4
142              
143             =item $filename
144              
145             Name of the file.
146              
147             =item $data
148              
149             Data to write into the file.
150              
151             =back
152              
153             =cut
154              
155             sub write_file {
156 26     26 1 2271 my $file = shift;
157 26         98 my $data = shift;
158              
159 26         90 local *FILE;
160 26 50       3467 open FILE, "> $file" or die "Can't open file '$file': $!";
161 26         201 print FILE $data;
162 26         1773 close FILE;
163             }
164              
165             =head2 check_webtest(%params)
166              
167             Runs a test sequence and compares output with a reference file.
168              
169             =head3 Parameters
170              
171             =over 4
172              
173             =item webtest => $webtest
174              
175             L object to be used for running the test sequence.
176              
177             =item tests => $tests
178              
179             The test sequence.
180              
181             =item tests => $opts
182              
183             The global parameters for the test sequence.
184              
185             =item out_filter => $out_filter
186              
187             =back
188              
189             =cut
190              
191             sub check_webtest {
192 55     55 1 43733 my %param = @_;
193              
194 55         154 my $webtest = $param{webtest};
195 55         112 my $tests = $param{tests};
196 55   100     388 my $opts = $param{opts} || {};
197              
198 55         155 my $output = '';
199              
200 55         1166 $webtest->run_tests($tests, { %$opts, output_ref => \$output });
201 55         4196 canonical_output(%param, output_ref => \$output);
202 55         325 compare_output(%param, output_ref => \$output);
203             }
204              
205             =head2 generate_testfile(%params)
206              
207             Generates test file from template file. I.e. it replaces substring
208             '<>' with value of named parameter C.
209              
210             =head3 Parameters
211              
212             =over 4
213              
214             =item file => $file
215              
216             Filename of test file. Template file is expected to be in file named
217             "$file.in".
218              
219             =item server_url => $server_url
220              
221             Test webserver URL.
222              
223             =back
224              
225             =cut
226              
227             sub generate_testfile {
228 4     4 1 2333 my %param = @_;
229              
230 4         24 my $file = $param{file};
231 4         32 my $in_file = $file . '.in';
232              
233             # prepare wt script file
234 4         27 my $data = read_file($in_file);
235 4         105 $data =~ s/<>/$param{server_url}/g;
236              
237 4         34 $data = <
238             # Note: $file is autogenerated from $in_file. DO NOT EDIT $file.
239             # Your changes will be lost. Edit $in_file instead.
240              
241             WARNING
242              
243 4         32 write_file($file, $data);
244             }
245              
246             =head2 canonical_output(%params)
247              
248             Some substrings in test output are unique for each test run. This
249             subroutine "fixes" test output so it becomes repeatable (unless tests
250             get broken).
251              
252             =head3 Parameters
253              
254             =over 4
255              
256             =item output_ref => $output_ref
257              
258             A reference on scalar which contains test output as whole string.
259              
260             =item out_filter => $out_filter
261              
262             An optional reference on subroutine which can be used as additional
263             filter. It gets passed test output as its first parameter.
264              
265             =item server_url => $server_url
266              
267             Test webserver URL. Normally it is unique for each test run so it gets
268             replaced with C.
269              
270             =item server_hostname => $server_hostname
271              
272             Test webserver URL. Normally it is unique for each machine where test
273             is run so it gets replaced with C.
274              
275             =back
276              
277             =cut
278              
279             sub canonical_output {
280 72     72 1 644 my %param = @_;
281              
282 72         177 my $output_ref = $param{output_ref};
283 72         157 my $out_filter = $param{out_filter};
284 72         138 my $server_url = $param{server_url};
285 72         132 my $server_hostname = $param{server_hostname};
286              
287             # run test filter if defined
288 72 100       223 if(defined $out_filter) {
289 14         73 $out_filter->($$output_ref);
290             }
291              
292             # change urls on some canonical in test output
293 72 100       808 if(defined $server_url) {
294 60         292 my $url = abs_url($server_url, '/')->as_string;
295 60         25240 $$output_ref =~ s|\Q$url\E
296             |http://http.web.test/|xg;
297             }
298              
299             # change urls on some canonical in test output
300 72 50       403 if(defined $server_hostname) {
301 0         0 $$output_ref =~ s|http://\Q$server_hostname\E:\d+/
302             |http://http.web.test/|xg;
303             }
304             }
305              
306             =head2 compare_output(%params)
307              
308             Tests if a test output matches content of specified reference file. If
309             environment variable C is set then the test is always
310             succeed and the content of the reference file is overwritten with
311             current test output.
312              
313             =head3 Parameters
314              
315             =over 4
316              
317             =item output_ref => $output_ref
318              
319             A reference on scalar which contains test output as whole string.
320              
321             =item check_file => $check_file
322              
323             Filename of the reference file.
324              
325             =back
326              
327             =cut
328              
329             sub compare_output {
330 73     73 1 407 my %param = @_;
331              
332 73         174 my $check_file = $param{check_file};
333 73         122 my $output2 = ${$param{output_ref}};
  73         201  
334              
335 73         248 my $output1 = read_file($check_file, 1);
336 73         361 _print_diff($output1, $output2);
337 73   66     442 _ok(($output1 eq $output2) or defined $ENV{TEST_FIX});
338              
339 73 50 33     66844 if(defined $ENV{TEST_FIX} and $output1 ne $output2) {
340             # special mode for writting test report output files
341              
342 0         0 write_file($check_file, $output2);
343             }
344             }
345              
346             # ok compatible with Test and Test::Builder
347             sub _ok {
348             # if Test is already loaded use its ok
349 73 50   73   854 if(Test->can('ok')) {
350 0         0 @_ = $_[0];
351 0         0 goto \&Test::ok;
352             } else {
353 73         782 require Test::Builder;
354 73         257 local $Test::Builder::Level = $Test::Builder::Level + 1;
355 73         738 Test::Builder->new->ok(@_);
356             }
357             }
358              
359             # print diff of outputs
360             sub _print_diff {
361 73     73   163 my $output1 = shift;
362 73         155 my $output2 = shift;
363              
364 73         2669 my @diff = diff([split /\n/, $output1], [split /\n/, $output2]);
365              
366 73         64115 for my $hunk (@diff) {
367 13         117 for my $diff_str (@$hunk) {
368 34         6347 printf "%s %03d %s\n", @$diff_str;
369             }
370             }
371             }
372              
373             =head2 parse_basic_credentials($credentials)
374              
375             Decodes credentials for Basic authorization scheme according RFC2617.
376              
377             =head3 Returns
378              
379             Returns user/password pair.
380              
381             =cut
382              
383             sub parse_basic_credentials {
384 8     8 1 703 my $credentials = shift;
385              
386 8 100       36 return () unless defined $credentials;
387 6         52 $credentials =~ m|^ \s* Basic \s+ ([A-Za-z0-9+/=]+) \s* $|x;
388 6         24 my $basic_credentials = $1;
389 6 50       23 return () unless defined $basic_credentials;
390 6         58 my $user_pass = decode_base64($basic_credentials);
391 6         38 my($user, $password) = $user_pass =~ /^ (.*) : (.*) $/x;
392 6 50       22 return () unless defined $password;
393              
394 6         25 return ($user, $password);
395             }
396              
397             =head1 DEPRECATED SUBROUTINES
398              
399             This module imports in namespace of test script following helper
400             subroutines but they are deprecated and may be removed in the future
401             from this module.
402              
403             =head2 start_webserver
404              
405             This subroutine was moved into
406             L but for backward
407             compatibility purposes can be exported from this module.
408              
409             =head2 stop_webserver
410              
411             This subroutine was moved into
412             L but for backward
413             compatibility purposes can be exported from this module.
414              
415             =head1 COPYRIGHT
416              
417             Copyright (c) 2001-2003 Ilya Martynov. All rights reserved.
418              
419             This program is free software; you can redistribute it and/or modify
420             it under the same terms as Perl itself.
421              
422             =head1 SEE ALSO
423              
424             L
425              
426             L
427              
428             L
429              
430             =cut
431              
432             1;