File Coverage

lib/Test/Memory/Usage.pm
Criterion Covered Total %
statement 53 53 100.0
branch 3 4 75.0
condition 4 4 100.0
subroutine 17 17 100.0
pod 5 5 100.0
total 82 83 98.8


line stmt bran cond sub pod time code
1             package Test::Memory::Usage;
2             {
3             $Test::Memory::Usage::VERSION = '0.0.5';
4             }
5             {
6             $Test::Memory::Usage::DIST = 'Test-Memory-Usage';
7             }
8             # ABSTRACT: make sure code doesn't unexpectedly eat all your memory
9 5     5   487692 use strict;
  5         15  
  5         200  
10 5     5   30 use warnings;
  5         9  
  5         156  
11              
12 5     5   19149 use Memory::Usage;
  5         11337  
  5         142  
13 5     5   39 use Test::Builder;
  5         17  
  5         122  
14 5     5   886 use Sub::Uplevel qw( uplevel );
  5         1117  
  5         45  
15 5     5   225 use base qw( Exporter );
  5         11  
  5         572  
16 5     5   29 use vars qw( $Tester $mu $first_state_index);
  5         9  
  5         836  
17             our @EXPORT = qw(memory_virtual_ok memory_rss_ok memory_stack_ok memory_usage_ok memory_usage_start);
18              
19              
20             sub import {
21 5     5   49 my $self = shift;
22             $self->export_to_level( 1, $self, $_ )
23 5         10063 foreach @EXPORT;
24             }
25              
26             BEGIN {
27 5     5   40 $Tester = Test::Builder->new;
28 5         45 $mu = Memory::Usage->new;
29 5         58 $mu->record('Memory::Usage test starting');
30             };
31              
32              
33             sub memory_usage_start {
34 13     13 1 643454 $mu->record('Memory::Usage start-marker');
35             # the state to use as our base point is one fewer than the number of
36             # states we have
37 13         1140 $first_state_index = @{$mu->state} - 1;
  13         49  
38             }
39              
40             sub memory_usage_ok {
41 15     15 1 2666334 my $percentage_allowed = shift;
42 15         55 memory_virtual_ok($percentage_allowed);
43 15         45 memory_rss_ok($percentage_allowed);
44 15         48 memory_stack_ok($percentage_allowed);
45             }
46              
47             sub memory_virtual_ok {
48 15     15 1 64 return _growth_ok('virtual', 2, shift);
49             }
50              
51             sub memory_rss_ok {
52 15     15 1 40 return _growth_ok('RSS', 3, shift);
53             }
54              
55             sub memory_stack_ok {
56 15     15 1 40 return _growth_ok('data/stack', 2, shift);
57             }
58              
59             sub _percentage_growth {
60 24     24   52 my ($start, $end) = @_;
61 24         366 return sprintf('%.1f%%',( ($end * 1.0) / ($start * 1.0) ) * 100);
62             }
63              
64             sub _growth_ok {
65 45     45   181 my ($memory_name, $state_index, $percentage_allowed) = @_;
66             # which item in the state list to use for comparison; defaults to the
67             # first one (when the module starts)
68             # can be altered by calling memory_usage_start() in the test script
69 45   100     134 $first_state_index ||= 0;
70              
71             # how much can the usage grow by?
72 45   100     132 $percentage_allowed ||= 10;
73             # turn the [user friendly] percentage into a number we can more easily
74             # work with
75 45         117 my $multiplier = 1 + ($percentage_allowed / 100.0);
76              
77             # make sure we record our (current) state; if we don't do this we might be
78             # in the position where we've only got the first recorded state and it
79             # looks like there's been no growth
80 45         181 my $sub = [caller(1)]->[3];
81 45         1234 $mu->record("Memory::Usage $sub()");
82              
83             # grab some useful values
84 45         3922 my $state = $mu->state;
85 45         222 my $start = $state->[$first_state_index]->[$state_index];
86 45         80 my $end = $state->[-1]->[$state_index];
87              
88             # we're 'ok' as long as we haven't grown more than 10%
89 45         117 my $ok = $end < ($start * $multiplier);
90              
91             # 'run' the test; feedback if required
92 45         279 $Tester->ok($ok, "${memory_name} memory usage grows less than $percentage_allowed%");
93 45 100       26985 $ok or $Tester->diag(
94             "${memory_name} memory usage grew from $start to $end ("
95             . _percentage_growth($start, $end)
96             . ')'
97             );
98 45         2234 return $ok;
99             }
100              
101              
102             END {
103 5     5   148969 $mu->record('Memory::Usage test completed');
104 5 50       29654 memory_usage_ok
105             if (not $Tester->has_plan);
106             }
107              
108              
109             1;
110             # vim: ts=8 sts=4 et sw=4 sr sta
111              
112             __END__