File Coverage: t/03_plackbench_pm.t

# File Coverage

File: | t/03_plackbench_pm.t
Coverage: | 100.0%

line | stmt | bran | cond | sub | time | code
--- | --- | --- | --- | --- | --- | ---
1 | 1 1 1 |  |  | 1 | 19815 3 43 | use strict;
2 | 1 1 1 |  |  | 1 | 6 2 32 | use warnings;
3 |
4 | 1 1 1 |  |  | 1 | 406 19426 10 | use Test::More;
5 | 1 1 1 |  |  | 1 | 606 7420 197 | use Test::Deep;
6 |
7 | 1 1 1 |  |  | 1 | 264 1055 155 | use FindBin qw( $Bin );
8 | 1 |  |  |  | 118031 | my $psgi_path = "$Bin/test_app.psgi";
9 |
10 | 1 1 1 |  |  | 1 | 282 3 2512 | use App::plackbench;
11 |
12 | 1 |  |  |  | 4 | subtest 'attribute' => \&test_attributes;
13 | 1 |  |  |  | 501 | subtest 'run' => \&test_run;
14 | 1 |  |  |  | 499 | subtest 'fixup' => \&test_fixup;
15 | 1 |  |  |  | 485 | subtest 'POST' => \&test_post_data;
16 | 1 |  |  |  | 477 | subtest 'warm' => \&test_warm;
17 | 1 |  |  |  | 488 | subtest 'fixup_from_file' => \&test_fixup_from_file;
18 | 1 |  |  |  | 478 | done_testing();
19 |
20 |  |  |  |  |  | sub test_attributes {
21 | 1 |  |  | 1 | 549 | my $bench = App::plackbench->new( psgi_path => $psgi_path );
22 |
23 | 1 |  |  |  | 4 | ok( !$bench->warm(), 'warm() should default to false' );
24 |
25 | 1 |  |  |  | 289 | $bench->warm(1);
26 | 1 |  |  |  | 3 | ok( $bench->warm(), 'warm() should be setable' );
27 |
28 | 1 |  |  |  | 259 | ok(
29 |  |  |  |  |  | App::plackbench->new( warm => 1 )->warm(),
30 |  |  |  |  |  | 'warm() should be setable in the constructor'
31 |  |  |  |  |  | );
32 |
33 | 1 |  |  |  | 289 | ok( $bench->app(), 'lazy-built attributes should work' );
34 |
35 | 1 |  |  |  | 303 | return;
36 |  |  |  |  |  | }
37 |
38 |  |  |  |  |  | sub test_run {
39 | 1 |  |  | 1 | 461 | my $bench = App::plackbench->new(
40 |  |  |  |  |  | psgi_path => $psgi_path,
41 |  |  |  |  |  | count => 5,
42 |  |  |  |  |  | uri => '/ok',
43 |  |  |  |  |  | );
44 | 1 |  |  |  | 5 | my $stats = $bench->run();
45 | 1 |  |  |  | 10 | ok( $stats->isa('App::plackbench::Stats'),
46 |  |  |  |  |  | 'run() should return App::plackbench::Stats object' );
47 |
48 | 1 |  |  |  | 339 | is( $stats->count(), $bench->count(),
49 |  |  |  |  |  | 'the stats object should have the correct number of times' );
50 |
51 | 1 |  |  |  | 271 | cmp_ok( $stats->mean(), '<', 1,
52 |  |  |  |  |  | 'the returned times should be within reason' );
53 |
54 | 1 |  |  |  | 282 | return;
55 |  |  |  |  |  | }
56 |
57 |  |  |  |  |  | sub test_fixup {
58 | 1 |  |  | 1 | 459 | my $counter = 0;
59 |
60 |  |  |  |  |  | my $bench = App::plackbench->new(
61 |  |  |  |  |  | psgi_path => $psgi_path,
62 |  |  |  |  |  | count => 5,
63 |  |  |  |  |  | uri => '/ok',
64 |  |  |  |  |  | fixup => [
65 |  |  |  |  |  | sub {
66 | 1 |  |  | 1 | 2 | $counter++;
67 | 1 |  |  |  | 5 | shift->header( FooBar => '1.0' );
68 |  |  |  |  |  | }
69 | 1 |  |  |  | 12 | ],
70 |  |  |  |  |  | );
71 |
72 | 1 |  |  |  | 5 | $bench->run();
73 | 1 |  |  |  | 5 | is( $counter, 1, 'fixup subs should be called once per unique request' );
74 | 1 |  |  |  | 292 | is( $bench->app->_get_requests()->[-1]->{HTTP_FOOBAR},
75 |  |  |  |  |  | '1.0', 'changes made to the request should be kept' );
76 |
77 | 1 |  |  |  | 255 | $bench->fixup([{}]);
78 | 1 1 |  |  |  | 2 4 | eval { $bench->run(); };
79 | 1 |  |  |  | 5 | ok( !$@, 'should ignore non-coderefs and non-strings in fixup()' );
80 |
81 | 1 |  |  |  | 277 | return;
82 |  |  |  |  |  | }
83 |
84 |  |  |  |  |  | sub test_post_data {
85 | 1 |  |  | 1 | 471 | my $bench = App::plackbench->new(
86 |  |  |  |  |  | psgi_path => $psgi_path,
87 |  |  |  |  |  | count => 5,
88 |  |  |  |  |  | uri => '/ok',
89 |  |  |  |  |  | post_data => [ 'a', 'bb', 'ccc' ],
90 |  |  |  |  |  | );
91 | 1 |  |  |  | 4 | $bench->app()->_clear_requests();
92 | 1 |  |  |  | 3 | $bench->run();
93 |
94 | 5 |  |  |  | 12 | my @non_post = grep {
95 | 1 |  |  |  | 3 | $_->{REQUEST_METHOD} ne 'POST'
96 | 1 |  |  |  | 3 | } @{ $bench->app()->_get_requests() };
97 | 1 |  |  |  | 6 | ok(!@non_post, 'all requests should be POST requests when post data is specified');
98 |
99 | 1 5 1 |  |  |  | 270 14 4 | my @lengths = map { $_->{CONTENT_LENGTH} } @{ $bench->app()->_get_requests() };
100 | 1 |  |  |  | 7 | cmp_deeply(\@lengths,
101 |  |  |  |  |  | [1, 2, 3, 1, 2], 'should cycle through POST data in order');
102 | 1 |  |  |  | 7372 | return;
103 |  |  |  |  |  | }
104 |
105 |  |  |  |  |  | sub test_warm {
106 | 1 |  |  | 1 | 460 | my $count = 5;
107 | 1 |  |  |  | 7 | my $bench = App::plackbench->new(
108 |  |  |  |  |  | psgi_path => $psgi_path,
109 |  |  |  |  |  | count => $count,
110 |  |  |  |  |  | uri => '/ok',
111 |  |  |  |  |  | warm => 1,
112 |  |  |  |  |  | );
113 | 1 |  |  |  | 4 | $bench->app()->_clear_requests();
114 | 1 |  |  |  | 5 | my $stats = $bench->run();
115 |
116 | 1 |  |  |  | 4 | is($stats->count(), $count, 'should put as many requests into the stats as asked for');
117 | 1 1 |  |  |  | 291 4 | is(scalar(@{$bench->app()->_get_requests()}), $count + 1, 'should make an extra request when "warm" is enabled');
118 |
119 | 1 |  |  |  | 255 | $bench->warm(0);
120 | 1 |  |  |  | 4 | $bench->app()->_clear_requests();
121 | 1 |  |  |  | 4 | $stats = $bench->run();
122 |
123 | 1 |  |  |  | 4 | is($stats->count(), $count, 'should put as many requests into the stats as asked for');
124 | 1 1 |  |  |  | 261 3 | is(scalar(@{$bench->app()->_get_requests()}), $count, 'should not make an extra request when "warm" is disabled');
125 |
126 | 1 |  |  |  | 265 | return;
127 |  |  |  |  |  | }
128 |
129 |  |  |  |  |  | sub test_fixup_from_file {
130 | 1 |  |  | 1 | 466 | my $bench = App::plackbench->new(
131 |  |  |  |  |  | psgi_path => $psgi_path,
132 |  |  |  |  |  | uri => '/ok',
133 |  |  |  |  |  | );
134 |
135 | 1 |  |  |  | 4 | ok($bench->run()->mean(), 'should run ok to begin with');
136 |
137 | 1 |  |  |  | 277 | $bench->add_fixup_from_file("$Bin/fail_redirect");
138 |
139 | 1 |  |  |  | 3 | eval {
140 | 1 |  |  |  | 3 | $bench->run();
141 |  |  |  |  |  | };
142 | 1 |  |  |  | 100 | like($@, qr/failed/, 'should eval the file and use it\'s sub');
143 |
144 | 1 |  |  |  | 280 | $bench->fixup(undef);
145 | 1 |  |  |  | 6 | $bench->add_fixup_from_file("$Bin/fail_redirect");
146 | 1 |  |  |  | 4 | is(Scalar::Util::reftype($bench->fixup()->[0]), 'CODE', 'should initialize fixup() if necessary');
147 |
148 | 1 |  |  |  | 253 | eval {
149 | 1 |  |  |  | 5 | $bench->add_fixup_from_file("$Bin/does_not_exist");
150 |  |  |  |  |  | };
151 |
152 |  |  |  |  |  | # Don't try and check that the error contains "No such file", cause that's
153 |  |  |  |  |  | # a different error in German (just sayin', it's not it came up or
154 |  |  |  |  |  | # anything...)
155 | 1 |  |  |  | 5 | ok($@, 'should die when file doesn\'t exist');
156 |
157 | 1 |  |  |  | 260 | eval {
158 | 1 |  |  |  | 5 | $bench->add_fixup_from_file("$Bin/syntax_error");
159 |  |  |  |  |  | };
160 | 1 |  |  |  | 22 | like($@, qr#\Q$Bin/syntax_error#, 'should die when file doesn\'t compile');
161 |
162 | 1 |  |  |  | 248 | eval {
163 | 1 |  |  |  | 5 | $bench->add_fixup_from_file("$Bin/non_sub");
164 |  |  |  |  |  | };
165 | 1 |  |  |  | 7 | like($@, qr/does not return a subroutine/, 'should die when file doesn\'t return a subroutine reference');
166 |
167 | 1 |  |  |  | 275 | return;
168 |  |  |  |  |  | }