line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Test::More::Fork; |
2
|
6
|
|
|
6
|
|
641166
|
use strict; |
|
6
|
|
|
|
|
18
|
|
|
6
|
|
|
|
|
696
|
|
3
|
6
|
|
|
6
|
|
36
|
use warnings; |
|
6
|
|
|
|
|
6
|
|
|
6
|
|
|
|
|
672
|
|
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
#{{{ POD |
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
=pod |
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
=head1 NAME |
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
Test::More::Fork - Test forking capabilities hacked on to Test::More |
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
=head1 DESCRIPTION |
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
Test::More::Fork allows you to run tests seperately. This is useful for |
16
|
|
|
|
|
|
|
returning to a known or pristine state between tests. Test::Seperate seperates |
17
|
|
|
|
|
|
|
tests into different forked processes. You can do whatever you want in a test |
18
|
|
|
|
|
|
|
set without fear that something you do will effect a test in another set. |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
This is a better option than local when dealing with complex meta-structures |
21
|
|
|
|
|
|
|
and testing class-construction in disperate conditions. |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
=head1 SYNOPSYS |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
# Should be used in place of Test::More, will import all of the functions |
26
|
|
|
|
|
|
|
# from Test::More, and accept all the same arguments. |
27
|
|
|
|
|
|
|
use Test::More::Fork tests => 5; |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
ok( 1, "Runs in the main process" ); |
30
|
|
|
|
|
|
|
# ok 1 - Runs in the main process |
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
fork_tests { |
33
|
|
|
|
|
|
|
ok( 1, "Runs in a forked process" |
34
|
|
|
|
|
|
|
} "Forked tests were run", 1; |
35
|
|
|
|
|
|
|
# ok 2 - Runs in a forked process |
36
|
|
|
|
|
|
|
# ok 3 - Forked tests were run |
37
|
|
|
|
|
|
|
# ok 4 - verify test count |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
#message and coutn are optional: |
40
|
|
|
|
|
|
|
fork_tests { ok( 1, "another test" )}; |
41
|
|
|
|
|
|
|
# ok 5 - another test |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
#create your own test that is safe to run in a forked process: |
44
|
|
|
|
|
|
|
fork_sub 'new_sub' => sub { ... }; |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
=head1 EXPORTED FUNCTIONS |
47
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
See the docs for L, all functions exported by Test::More are |
49
|
|
|
|
|
|
|
exported by Test::More::Fork as well. |
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
=over 4 |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
=cut |
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
#}}} |
56
|
|
|
|
|
|
|
|
57
|
6
|
|
|
6
|
|
36
|
use base 'Test::More'; |
|
6
|
|
|
|
|
84
|
|
|
6
|
|
|
|
|
8256
|
|
58
|
6
|
|
|
6
|
|
56766
|
use Data::Dumper; |
|
6
|
|
|
|
|
18
|
|
|
6
|
|
|
|
|
1122
|
|
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
our @EXPORT = ( 'fork_tests', 'fork_sub', @Test::More::EXPORT ); |
61
|
|
|
|
|
|
|
our $VERSION = "0.007"; |
62
|
|
|
|
|
|
|
our $CHILD; |
63
|
|
|
|
|
|
|
our $SEPERATOR = 'EODATA'; |
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
pipe( READ, WRITE ) || die( $! ); |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
=item fork_sub $name => sub { ... } |
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
Create a new sub defined in both the current package and Test::More::Fork. This |
70
|
|
|
|
|
|
|
sub will be safe to run in a forked test. |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
=cut |
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
sub fork_sub { |
75
|
178
|
|
|
178
|
1
|
2834
|
my ( $sub, $code ) = @_; |
76
|
|
|
|
|
|
|
my $new = sub { |
77
|
6
|
|
|
6
|
|
42
|
no strict 'refs'; |
|
6
|
|
|
|
|
18
|
|
|
6
|
|
|
|
|
1632
|
|
78
|
107
|
100
|
|
107
|
|
56461
|
goto &$code unless $CHILD; |
79
|
|
|
|
|
|
|
|
80
|
17
|
|
|
|
|
234
|
push @$CHILD => { |
81
|
|
|
|
|
|
|
'caller' => [ caller()], |
82
|
|
|
|
|
|
|
'sub' => $sub, |
83
|
|
|
|
|
|
|
'params' => [@_], |
84
|
|
|
|
|
|
|
}; |
85
|
17
|
|
|
|
|
1397
|
"$sub() delayed"; |
86
|
178
|
|
|
|
|
722
|
}; |
87
|
|
|
|
|
|
|
{ |
88
|
6
|
|
|
6
|
|
36
|
no strict 'refs'; |
|
6
|
|
|
|
|
12
|
|
|
6
|
|
|
|
|
852
|
|
|
178
|
|
|
|
|
244
|
|
89
|
178
|
|
|
|
|
698
|
*$sub = $new; |
90
|
178
|
|
|
|
|
488
|
my ( $caller ) = caller(); |
91
|
178
|
100
|
|
|
|
6540
|
return if $caller eq __PACKAGE__; |
92
|
10
|
|
|
|
|
20
|
*{ $caller . '::' . $sub } = $new; |
|
10
|
|
|
|
|
62
|
|
93
|
|
|
|
|
|
|
} |
94
|
|
|
|
|
|
|
} |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
BEGIN { |
97
|
6
|
|
|
6
|
|
24
|
for my $sub ( @Test::More::EXPORT ) { |
98
|
6
|
|
|
6
|
|
36
|
no strict 'refs'; |
|
6
|
|
|
|
|
12
|
|
|
6
|
|
|
|
|
288
|
|
99
|
168
|
|
|
|
|
198
|
fork_sub $sub => \&{'Test::More::' . $sub} |
|
168
|
|
|
|
|
642
|
|
100
|
|
|
|
|
|
|
} |
101
|
|
|
|
|
|
|
} |
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
=item fork_tests( sub { ... }, $message, $count ) |
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
Forks, then runs the provided sub in a child process. |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
$message and $count are optional, and each add an extra test to the count. |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
=cut |
110
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
sub fork_tests(&;$$) { |
112
|
20
|
|
|
20
|
1
|
12355
|
my ($sub, $message, $count) = @_; |
113
|
|
|
|
|
|
|
|
114
|
20
|
100
|
|
|
|
25394
|
if ( my $pid = fork()) { |
115
|
15
|
|
|
|
|
819
|
my $data = _read(); |
116
|
15
|
|
|
|
|
126102
|
waitpid( $pid, 0 ); |
117
|
15
|
|
|
|
|
265
|
my $out = !$?; |
118
|
15
|
|
|
|
|
147
|
my $tests = _run_tests( $data ); |
119
|
14
|
100
|
|
|
|
173
|
Test::More::ok( $out, $message ) if $message; |
120
|
14
|
100
|
|
|
|
4733
|
Test::More::is( @$tests, $count, "Verify test count" ) if $count; |
121
|
|
|
|
|
|
|
} |
122
|
|
|
|
|
|
|
else { |
123
|
5
|
|
|
|
|
509
|
$CHILD = []; |
124
|
5
|
|
|
|
|
170
|
eval { $sub->() }; |
|
5
|
|
|
|
|
392
|
|
125
|
5
|
100
|
|
|
|
726
|
if ( $@ ) { |
126
|
1
|
|
|
|
|
55
|
_write( $@ . $SEPERATOR ); |
127
|
|
|
|
|
|
|
} |
128
|
|
|
|
|
|
|
else { |
129
|
4
|
|
|
|
|
263
|
_write( Dumper( $CHILD ) . $SEPERATOR ); |
130
|
|
|
|
|
|
|
} |
131
|
5
|
|
|
|
|
2808
|
exit; |
132
|
|
|
|
|
|
|
} |
133
|
|
|
|
|
|
|
} |
134
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
sub _run_tests { |
136
|
31
|
|
|
31
|
|
5687
|
my $data = shift; |
137
|
31
|
100
|
|
|
|
1239
|
die( $data ) unless( $data =~ m/^\$VAR1/ ); |
138
|
30
|
|
|
|
|
99
|
my $tests = _deserialize_data( $data ); |
139
|
30
|
|
|
|
|
292
|
for my $test ( @$tests ) { |
140
|
35
|
|
|
|
|
527
|
my $caller = $test->{ 'caller' }; |
141
|
35
|
|
|
|
|
62
|
my $sub = $test->{ 'sub' }; |
142
|
35
|
|
|
|
|
61
|
my $params = $test->{ params }; |
143
|
6
|
|
|
6
|
|
42
|
no strict 'refs'; |
|
6
|
|
|
|
|
18
|
|
|
6
|
|
|
|
|
2088
|
|
144
|
35
|
|
|
|
|
340
|
my $tb = Test::More->builder; |
145
|
35
|
|
|
|
|
808
|
my $number = $tb->current_test; |
146
|
35
|
|
|
|
|
427
|
eval { &$sub( @$params ) }; |
|
35
|
|
|
|
|
380
|
|
147
|
35
|
|
|
|
|
14191
|
my @summary = $tb->summary; |
148
|
35
|
100
|
100
|
|
|
1144
|
if ( $tb->current_test != $number && !$summary[$number] ) { |
149
|
5
|
|
|
|
|
170
|
Test::More::diag( "Problem at: " . $caller->[1] . " line: " . $caller->[2] ); |
150
|
|
|
|
|
|
|
} |
151
|
35
|
100
|
|
|
|
543
|
Test::More::diag $@ if $@; |
152
|
|
|
|
|
|
|
} |
153
|
30
|
|
|
|
|
232
|
return $tests; |
154
|
|
|
|
|
|
|
} |
155
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
sub _deserialize_data { |
157
|
36
|
|
|
36
|
|
1554
|
my $data = shift; |
158
|
6
|
|
|
6
|
|
42
|
no strict; |
|
6
|
|
|
|
|
12
|
|
|
6
|
|
|
|
|
876
|
|
159
|
36
|
|
|
|
|
409
|
$data =~ s/$SEPERATOR//; |
160
|
36
|
|
|
|
|
6710
|
return eval $data; |
161
|
|
|
|
|
|
|
} |
162
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
sub _read { |
164
|
15
|
|
|
15
|
|
1088
|
local $/ = $SEPERATOR; |
165
|
15
|
|
|
|
|
6616798
|
my $data = ; |
166
|
15
|
|
|
|
|
248
|
return $data; |
167
|
|
|
|
|
|
|
} |
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
sub _write { |
170
|
5
|
|
|
5
|
|
3010
|
print WRITE $_ for @_; |
171
|
|
|
|
|
|
|
} |
172
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
1; |
174
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
__END__ |