| File: | t/03_plackbench_pm.t |
| Coverage: | 100.0% |
| line | stmt | bran | cond | sub | time | code |
|---|---|---|---|---|---|---|
| 1 | 1 1 1 | 19815 3 43 | use strict; | |||
| 2 | 1 1 1 | 6 2 32 | use warnings; | |||
| 3 | ||||||
| 4 | 1 1 1 | 406 19426 10 | use Test::More; | |||
| 5 | 1 1 1 | 606 7420 197 | use Test::Deep; | |||
| 6 | ||||||
| 7 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | } | |||||