our $VERBOSE = $opt{verbose} || 0;
-our $OUTPUT = lc $opt{output} || '';
+our $OUTPUT = lc($opt{output} || '');
## Allow the optimization of the get_methods list by an argument
if ($opt{get_method}) {
}
elsif ($type =~ /integer/) {
$warning =~ s/_//g;
- if (length $warning and $warning !~ /^\d+$/) {
+ if (length $warning and $warning !~ /^[-+]?\d+$/) {
ndie $type =~ /positive/ ? msg('range-int-pos', 'warning') : msg('range-int', 'warning');
}
elsif (length $warning && $type =~ /positive/ && $warning <= 0) {
}
$critical =~ s/_//g;
- if (length $critical and $critical !~ /^\d+$/) {
+ if (length $critical and $critical !~ /^[-+]?\d+$/) {
ndie $type =~ /positive/ ? msg('range-int-pos', 'critical') : msg('range-int', 'critical');
}
elsif (length $critical && $type =~ /positive/ && $critical <= 0) {
) {
ndie msg('range-warnbig');
}
+ $warning = int $warning if length $warning;
+ $critical = int $critical if length $warning;
}
elsif ('restringex' eq $type) {
if (! length $critical and ! length $warning) {
ndie msg('range-badpercent', 'warning');
}
}
+ $warning = int $warning if length $warning;
+ $critical = int $critical if length $warning;
}
elsif ('size or percent' eq $type) {
if (length $critical) {
} ## end of validate_range
+sub validate_size_or_percent_with_oper {
+
+ my $arg = shift || {};
+ ndie qq{validate_range must be called with a hashref\n}
+ unless ref $arg eq 'HASH';
+
+ my $warning = exists $opt{warning} ? $opt{warning} :
+ exists $opt{critical} ? '' : $arg->{default_warning} || '';
+ my $critical = exists $opt{critical} ? $opt{critical} :
+ exists $opt{warning} ? '' : $arg->{default_critical} || '';
+
+ ndie msg('range-noopt-size') unless length $critical || length $warning;
+ my @subs;
+ for my $val ($warning, $critical) {
+ if ($val =~ /^([^&|]+)\s([&|]{2}|and|or)\s([^&|]+)$/i) {
+ my ($l, $op, $r) = ($1, $2, $3);
+ local $opt{warning} = $l;
+ local $opt{critical} = 0;
+ ($l) = validate_range({ type => 'size or percent' });
+ $opt{warning} = $r;
+ ($r) = validate_range({ type => 'size or percent' });
+ if ($l =~ s/%$//) {
+ ($l, $r) = ($r, $l);
+ } else {
+ $r =~ s/%$//;
+ }
+ push @subs, $op eq '&&' || lc $op eq 'and' ? sub {
+ $_[0] >= $l && $_[1] >= $r;
+ } : sub {
+ $_[0] >= $l || $_[1] >= $r;
+ };
+ }
+ else {
+ local $opt{warning} = $val;
+ local $opt{critical} = 0;
+ my ($v) = validate_range({ type => 'size or percent' });
+ push @subs, !length $v ? sub { 0 }
+ : $v =~ s/%$// ? sub { $_[1] >= $v }
+ : sub { $_[0] >= $v };
+ }
+ }
+
+ return @subs;
+
+} ## end of validate_size_or_percent_with_oper
+
+
sub check_autovac_freeze {
## Check how close all databases are to autovacuum_freeze_max_age
$LIMIT = $opt{perflimit};
}
- my ($warning, $critical) = validate_range
+ my ($warning, $critical) = validate_size_or_percent_with_oper
({
- type => 'size or percent',
default_warning => '1 GB',
default_critical => '5 GB',
});
$stats{table}{"DB=$dbname TABLE=$schema.$table"} = [$wb, $bloat];
next;
}
- if (length $critical) {
- if (index($critical,'%')>=0) {
- (my $critical2 = $critical) =~ s/\%//;
- if ($perbloat >= $critical2) {
- add_critical $msg;
- $ok = 0;
- }
- }
- elsif ($wb >= $critical) {
- add_critical $msg;
- $ok = 0;
- }
+ if ($critical->($wb, $perbloat)) {
+ add_critical $msg;
+ $ok = 0;
}
- if (length $warning and $ok) {
- if (index($warning,'%')>=0) {
- (my $warning2 = $warning) =~ s/\%//;
- if ($perbloat >= $warning2) {
- add_warning $msg;
- $ok = 0;
- }
- }
- elsif ($wb >= $warning) {
- add_warning $msg;
- $ok = 0;
- }
+ if ($ok && $warning->($wb, $perbloat)) {
+ add_warning $msg;
+ $ok = 0;
}
($max = $wb, $maxmsg = $msg) if $wb > $max and $ok;
}
$stats{index}{"DB=$dbname INDEX=$index"} = [$iwb, $ibloat];
next;
}
- if (length $critical) {
- if (index($critical,'%')>=0) {
- (my $critical2 = $critical) =~ s/\%//;
- if ($iperbloat >= $critical2) {
- add_critical $msg;
- $ok = 0;
- }
- }
- elsif ($iwb >= $critical) {
- add_critical $msg;
- $ok = 0;
- }
+ if ($critical->($iwb, $iperbloat)) {
+ add_critical $msg;
+ $ok = 0;
}
- if (length $warning and $ok) {
- if (index($warning,'%')>=0) {
- (my $warning2 = $warning) =~ s/\%//;
- if ($iperbloat >= $warning2) {
- add_warning $msg;
- $ok = 0;
- }
- }
- elsif ($iwb >= $warning) {
- add_warning $msg;
- $ok = 0;
- }
+ if ($ok && $warning->($iwb, $iperbloat)) {
+ add_warning $msg;
+ $ok = 0;
}
-
($max = $iwb, $maxmsg = $msg) if $iwb > $max and $ok;
}
}
## NOTE: Needs to run on the same system (for now)
## XXX Allow custom ssh commands for remote df and the like
- my ($warning, $critical) = validate_range
+ my ($warning, $critical) = validate_size_or_percent_with_oper
({
- type => 'size or percent',
default_warning => '90%',
default_critical => '95%',
});
$db->{perf} = "$fs=$used";
my $ok = 1;
- if (length $critical) {
- if (index($critical,'%')>=0) {
- (my $critical2 = $critical) =~ s/\%//;
- if ($percent >= $critical2) {
- add_critical $msg;
- $ok = 0;
- }
- }
- elsif ($used >= $critical) {
- add_critical $msg;
- $ok = 0;
- }
+ if ($critical->($used, $percent)) {
+ add_critical $msg;
+ $ok = 0;
}
- if (length $warning and $ok) {
- if (index($warning,'%')>=0) {
- (my $warning2 = $warning) =~ s/\%//;
- if ($percent >= $warning2) {
- add_warning $msg;
- $ok = 0;
- }
- }
- elsif ($used >= $warning) {
- add_warning $msg;
- $ok = 0;
- }
+
+ if ($ok && $warning->($used, $percent)) {
+ add_warning $msg;
+ $ok = 0;
}
+
if ($ok) {
add_ok $msg;
}
The I<--include> and I<--exclude> options can be used to filter out which tables
to look at. See the L</"BASIC FILTERING"> section for more details.
-The I<--warning> and I<--critical> options can be specified as sizes or percents.
+The I<--warning> and I<--critical> options can be specified as sizes, percents, or both.
Valid size units are bytes, kilobytes, megabytes, gigabytes, terabytes, exabytes,
petabytes, and zettabytes. You can abbreviate all of those with the first letter. Items
without units are assumed to be 'bytes'. The default values are '1 GB' and '5 GB'. The value
Example 1: Warn if any table on port 5432 is over 100 MB bloated, and critical if over 200 MB
- check_postgres_bloat --port=5432 --warning='100 M', --critical='200 M'
+ check_postgres_bloat --port=5432 --warning='100 M' --critical='200 M'
Example 2: Give a critical if table 'orders' on host 'sami' has more than 10 megs of bloat
check_postgres_bloat --db=sales --include=q4 --critical='50%'
+Example 4: Give a critical any table is over 20% bloated I<and> has over 150
+MB of bloat:
+
+ check_postgres_bloat --port=5432 --critical='20% and 150 M'
+
+Example 5: Give a critical any table is over 40% bloated I<or> has over 500 MB
+of bloat:
+
+ check_postgres_bloat --port=5432 --warning='500 M or 40%'
+
For MRTG output, the first line gives the highest number of wasted bytes for the tables, and the
second line gives the highest number of wasted bytes for the indexes. The fourth line gives the database
name, table name, and index name information. If you want to output the bloat ratio instead (how many
that you have the executable "/bin/df" available to report on disk sizes, and it
also needs to be run as a superuser, so it can examine the B<data_directory>
setting inside of Postgres. The I<--warning> and I<--critical> options are
-given in either sizes or percentages. If using sizes, the standard unit types
+given in either sizes or percentages or both. If using sizes, the standard unit types
are allowed: bytes, kilobytes, gigabytes, megabytes, gigabytes, terabytes, or
exabytes. Each may be abbreviated to the first letter only; no units at all
indicates 'bytes'. The default values are '90%' and '95%'.
check_postgres_disk_space --port=5432 --warning='10 GB' --critical='11 GB' --include="~^/dev/sda"
+Example 4: Make sure that no file system is both over 50% I<and> has over 15 GB
+
+ check_postgres_disk_space --critical='50% and 15 GB'
+
+Example 5: Issue a warning if any file system is either over 70% full I<or> has
+more than 1T
+
+ check_postgres_disk_space --warning='1T or 75'
+
For MRTG output, returns the size in bytes of the file system on the first line,
and the name of the file system on the fourth line.
--- /dev/null
+#!perl
+
+## Test the "validate_range" function
+
+use 5.006;
+use strict;
+use warnings;
+use Test::More tests => 139;
+
+eval {
+ local @ARGV = qw(--action nonexistent);
+ require 'check_postgres.pl'; ## no critic (RequireBarewordIncludes)
+};
+like($@, qr{\-\-help}, 'check_postgres.pl compiles')
+ or BAIL_OUT "Script did not compile, cancelling rest of tests.\n";
+
+SECONDS: {
+ local %check_postgres::opt = (
+ warning => '1s',
+ critical => '42 seconds'
+ );
+ my ($w, $c) = check_postgres::validate_range({ type => 'seconds' });
+ is $w, 1, 'Should have warning == 1 seconds';
+ is $c, 42, 'Should have critical == 42 seconds';
+}
+
+TIME: {
+ local %check_postgres::opt = (
+ warning => '1s',
+ critical => '42 seconds'
+ );
+ my ($w, $c) = check_postgres::validate_range({ type => 'time' });
+ is $w, 1, 'Should have warning == 1 second';
+ is $c, 42, 'Should have critical == 42 seconds';
+
+ %check_postgres::opt = (
+ warning => '1m',
+ critical => '42 minutes'
+ );
+ ($w, $c) = check_postgres::validate_range({ type => 'time' });
+ is $w, 60, 'Should have warning == 1 minute';
+ is $c, 2520, 'Should have critical == 42 minutes';
+
+ %check_postgres::opt = (
+ warning => '1h',
+ critical => '42 hours'
+ );
+ ($w, $c) = check_postgres::validate_range({ type => 'time' });
+ is $w, 3600, 'Should have warning == 1 hour';
+ is $c, 151200, 'Should have critical == 42 hours';
+
+ %check_postgres::opt = (
+ warning => '1d',
+ critical => '42 days'
+ );
+ ($w, $c) = check_postgres::validate_range({ type => 'time' });
+ is $w, 86400, 'Should have warning == 1 day';
+ is $c, 3628800, 'Should have critical == 42 days';
+
+ %check_postgres::opt = (
+ warning => '1w',
+ critical => '4 weeks'
+ );
+ ($w, $c) = check_postgres::validate_range({ type => 'time' });
+ is $w, 604800, 'Should have warning == 1 week';
+ is $c, 2419200, 'Should have critical == 4 weeks';
+
+ %check_postgres::opt = (
+ warning => '1y',
+ critical => '4 years'
+ );
+ ($w, $c) = check_postgres::validate_range({ type => 'time' });
+ is $w, 31536000, 'Should have warning == 1 year';
+ is $c, 126144000, 'Should have critical == 4 years';
+
+ %check_postgres::opt = (
+ warning => '1',
+ critical => '42'
+ );
+ ($w, $c) = check_postgres::validate_range({ type => 'time' });
+ is $w, 1, 'Should have warning == 1';
+ is $c, 42, 'Should have critical == 42';
+}
+
+VERSION: {
+ local %check_postgres::opt = (
+ warning => '8.4.2',
+ critical => '9.0beta1'
+ );
+ my ($w, $c) = check_postgres::validate_range({ type => 'version' });
+ is $w, '8.4.2', 'Should have warning == 8.4.2';
+ is $c, '9.0beta1', 'Should have critical == 9.0beta1';
+}
+
+SIZE: {
+ local %check_postgres::opt = (
+ warning => '1',
+ critical => '42 bytes'
+ );
+ my ($w, $c) = check_postgres::validate_range({ type => 'size' });
+ is $w, 1, 'Should have warning == 1 byte';
+ is $c, 42, 'Should have critical == 42 bytes';
+
+ %check_postgres::opt = (
+ warning => '1k',
+ critical => '42 kilobytes'
+ );
+ ($w, $c) = check_postgres::validate_range({ type => 'size' });
+ is $w, 1024, 'Should have warning == 1 kilobytes';
+ is $c, 43008, 'Should have critical == 42 kilobytes';
+
+ %check_postgres::opt = (
+ warning => '1m',
+ critical => '42 megabytes'
+ );
+ ($w, $c) = check_postgres::validate_range({ type => 'size' });
+ is $w, 1048576, 'Should have warning == 1 megabytes';
+ is $c, 44040192, 'Should have critical == 42 megabytes';
+
+ %check_postgres::opt = (
+ warning => '1g',
+ critical => '42 gigabytes'
+ );
+ ($w, $c) = check_postgres::validate_range({ type => 'size' });
+ is $w, 1073741824, 'Should have warning == 1 gigabytes';
+ is $c, 45097156608, 'Should have critical == 42 gigabytes';
+
+ %check_postgres::opt = (
+ warning => '1t',
+ critical => '42 terabytes'
+ );
+ ($w, $c) = check_postgres::validate_range({ type => 'size' });
+ is $w, 1099511627776, 'Should have warning == 1 terabytes';
+ is $c, 46179488366592, 'Should have critical == 42 terabytes';
+
+ %check_postgres::opt = (
+ warning => '1p',
+ critical => '42 petabytes'
+ );
+ ($w, $c) = check_postgres::validate_range({ type => 'size' });
+ is $w, 1125899906842624, 'Should have warning == 1 petabytes';
+ is $c, 47287796087390208, 'Should have critical == 42 petaytes';
+
+ %check_postgres::opt = (
+ warning => '1e',
+ critical => '42 exobytes'
+ );
+ ($w, $c) = check_postgres::validate_range({ type => 'size' });
+ is $w, 1.15292150460685e+18, 'Should have warning == 1 exobytes';
+ is $c, 4.84227031934876e+19, 'Should have critical == 42 exobytes';
+
+ %check_postgres::opt = (
+ warning => '1z',
+ critical => '42 zettabytes'
+ );
+ ($w, $c) = check_postgres::validate_range({ type => 'size' });
+ is $w, 1.18059162071741e+21, 'Should have warning == 1 zettabytes';
+ is $c, 4.95848480701313e+22, 'Should have critical == 42 zettaytes';
+}
+
+INTEGER: {
+ local %check_postgres::opt = (
+ warning => '1',
+ critical => '42'
+ );
+ my ($w, $c) = check_postgres::validate_range({ type => 'integer' });
+ is $w, 1, 'Should have warning == 1';
+ is $c, 42, 'Should have critical == 42';
+
+ %check_postgres::opt = (
+ warning => '1_0',
+ critical => '42_1'
+ );
+ ($w, $c) = check_postgres::validate_range({ type => 'integer' });
+ is $w, 10, 'Should have warning == 10';
+ is $c, 421, 'Should have critical == 421';
+
+ %check_postgres::opt = (
+ warning => -1,
+ critical => '+42'
+ );
+ ($w, $c) = check_postgres::validate_range({ type => 'integer' });
+ is $w, -1, 'Should have warning == -1';
+ is $c, +42, 'Should have critical == +42';
+
+ %check_postgres::opt = (
+ warning => '+1',
+ critical => '+42'
+ );
+ ($w, $c) = check_postgres::validate_range({ type => 'positive_integer' });
+ is $w, +1, 'Should have warning == +1';
+ is $c, +42, 'Should have critical == +42';
+}
+
+RESTRINGEX: {
+ local %check_postgres::opt = (
+ warning => '~bucardo',
+ );
+ my ($w, $c) = check_postgres::validate_range({ type => 'restringex' });
+ is $w, '~bucardo', 'Should have warning == "~bucardo"';
+ is $c, '', 'Should have critical == ""';
+
+ %check_postgres::opt = (
+ critical => 'whatever',
+ );
+ ($w, $c) = check_postgres::validate_range({ type => 'restringex' });
+ is $w, '', 'Should have warning == ""';
+ is $c, 'whatever', 'Should have critical == "whatever"';
+}
+
+PERCENT: {
+ local %check_postgres::opt = (
+ critical => '90%',
+ warning => '5%',
+ );
+ my ($w, $c) = check_postgres::validate_range({ type => 'percent' });
+ is $w, '5%', 'Should have warning == 5%';
+ is $c, '90%', 'Should have critical == 90%';
+}
+
+SIZEORPERCENT: {
+ local %check_postgres::opt = (
+ critical => '95%',
+ warning => '7%',
+ );
+ my ($w, $c) = check_postgres::validate_range({ type => 'size or percent' });
+ is $w, '7%', 'Should have warning == 7%';
+ is $c, '95%', 'Should have critical == 95%';
+
+ %check_postgres::opt = (
+ critical => '1024k',
+ warning => '10%',
+ );
+ ($w, $c) = check_postgres::validate_range({ type => 'size or percent' });
+ is $w, '10%', 'Should have warning == 10%';
+ is $c, '1048576', 'Should have critical == 1024K';
+
+ %check_postgres::opt = (
+ warning => '1m',
+ critical => '42 megabytes'
+ );
+ ($w, $c) = check_postgres::validate_range({ type => 'size or percent' });
+ is $w, 1048576, 'Should have warning == 1 megabytes';
+ is $c, 44040192, 'Should have critical == 42 megabytes';
+}
+
+CHECKSUM: {
+ local %check_postgres::opt = (
+ critical => '3d9442fc242f11e09b7e001e52fffe51',
+ warning => '7367ff2379b947d9b637f69494b2f3fc',
+ );
+ my ($w, $c) = check_postgres::validate_range({ type => 'checksum' });
+ is $w, '7367ff2379b947d9b637f69494b2f3fc',
+ 'Should have warning == 7367ff2379b947d9b637f69494b2f3fc';
+ is $c, '3d9442fc242f11e09b7e001e52fffe51',
+ 'Should have critical == 3d9442fc242f11e09b7e001e52fffe51';
+}
+
+CACTI: {
+ local %check_postgres::opt;
+ my ($w, $c) = check_postgres::validate_range({ type => 'cacti' });
+ is $w, '', 'Should have warning == ""';
+ is $c, '', 'Should have critical == ""';
+}
+
+RANGEOP: {
+ # Try size.
+ local %check_postgres::opt = (
+ warning => '1k',
+ critical => '42 kilobytes'
+ );
+ my ($w, $c) = check_postgres::validate_size_or_percent_with_oper();
+ isa_ok $w, 'CODE', 'warning';
+ isa_ok $c, 'CODE', 'critical';
+
+ ok !$c->(43), '43b is less than 43kb';
+ ok $c->(43008), '43008b is 43kb';
+ ok $c->(90210), '90210b is greater than 43kb';
+
+ ok !$w->(10), '10b is less than 1kb';
+ ok $w->(1024), '1024b is 1kb';
+ ok $w->(2048), '2048 is greater than 1kb';
+
+ # Try percentages.
+ %check_postgres::opt = (
+ critical => '95%',
+ warning => '7%',
+ );
+ ($w, $c) = check_postgres::validate_size_or_percent_with_oper();
+ isa_ok $w, 'CODE', 'warning';
+ isa_ok $c, 'CODE', 'critical';
+
+ ok !$c->(undef, 20), '20 is less than 95';
+ ok $c->(undef, 95), '95 is 95';
+ ok $c->(undef, 98), '98 is greater than 95';
+
+ ok !$w->(undef, 5), '5 is less than 7';
+ ok $w->(undef, 7), '7 is 7';
+ ok $w->(undef, 10), '10 is greater than 7';
+
+ # Try both.
+ %check_postgres::opt = (
+ warning => '1k && 20%',
+ critical => '42 kilobytes and 30%'
+ );
+ ($w, $c) = check_postgres::validate_size_or_percent_with_oper();
+ isa_ok $w, 'CODE', 'warning';
+ isa_ok $c, 'CODE', 'critical';
+
+ ok !$c->(42, 20), 'Should get false for critical 42, 20';
+ ok !$c->(44000, 20), 'Should get false for critical 44000, 20';
+ ok $c->(44000, 30), 'Should get true for critical 44000, 30';
+
+ ok !$w->(42, 10), 'Should get false for warning 42, 10';
+ ok !$w->(1024, 10), 'Should get false for warning 1024, 10';
+ ok $w->(44000, 20), 'Should get true for warning 1024, 20';
+
+ # Reverse them.
+ %check_postgres::opt = (
+ warning => '20% AND 1k',
+ critical => '30% && 42 kilobytes'
+ );
+ ($w, $c) = check_postgres::validate_size_or_percent_with_oper();
+ isa_ok $w, 'CODE', 'reversed warning';
+ isa_ok $c, 'CODE', 'reversed critical';
+
+ ok !$c->(42, 20), 'Should get false for critical 42, 20';
+ ok !$c->(44000, 20), 'Should get false for critical 44000, 20';
+ ok $c->(44000, 30), 'Should get true for critical 44000, 30';
+
+ ok !$w->(42, 10), 'Should get false for warning 42, 10';
+ ok !$w->(1024, 10), 'Should get false for warning 1024, 10';
+ ok $w->(44000, 20), 'Should get true for warning 1024, 20';
+
+ # Try either.
+ %check_postgres::opt = (
+ warning => '1k || 20%',
+ critical => '42 kilobytes or 30%'
+ );
+ ($w, $c) = check_postgres::validate_size_or_percent_with_oper();
+ isa_ok $w, 'CODE', 'or warning';
+ isa_ok $c, 'CODE', 'or critical';
+
+ ok !$c->(42, 20), 'Should get false for critical 42, 20';
+ ok $c->(44000, 20), 'Should get true for critical 44000, 20';
+ ok $c->(42, 30), 'Should get true for critical 42, 30';
+ ok $c->(44000, 30), 'Should get true for critical 44000, 30';
+
+ ok !$w->(42, 10), 'Should get false for warning 42, 10';
+ ok $w->(1024, 10), 'Should get true for warning 1024, 10';
+ ok $w->(42, 20), 'Should get true for warning 42, 20';
+ ok $w->(1024, 20), 'Should get true for warning 1024, 20';
+
+ # Reverse them.
+ %check_postgres::opt = (
+ warning => '20% OR 1k',
+ critical => '30% || 42 kilobytes'
+ );
+ ($w, $c) = check_postgres::validate_size_or_percent_with_oper();
+ isa_ok $w, 'CODE', 'reversed or warning';
+ isa_ok $c, 'CODE', 'reversed or critical';
+
+ ok !$c->(42, 20), 'Should get false for critical 42, 20';
+ ok $c->(44000, 20), 'Should get true for critical 44000, 20';
+ ok $c->(42, 30), 'Should get true for critical 42, 30';
+ ok $c->(44000, 30), 'Should get true for critical 44000, 30';
+
+ ok !$w->(42, 10), 'Should get false for warning 42, 10';
+ ok $w->(1024, 10), 'Should get true for warning 1024, 10';
+ ok $w->(42, 20), 'Should get true for warning 42, 20';
+ ok $w->(1024, 20), 'Should get true for warning 1024, 20';
+
+ # Try with defaults.
+ %check_postgres::opt = ();
+ ($w, $c) = check_postgres::validate_size_or_percent_with_oper({
+ default_warning => '20% or 1k',
+ default_critical => '30% || 42 kilobytes'
+ });
+ isa_ok $w, 'CODE', 'default warning';
+ isa_ok $c, 'CODE', 'default critical';
+
+ ok !$c->(42, 20), 'Should get false for critical 42, 20';
+ ok $c->(44000, 20), 'Should get true for critical 44000, 20';
+ ok $c->(42, 30), 'Should get true for critical 42, 30';
+ ok $c->(44000, 30), 'Should get true for critical 44000, 30';
+
+ ok !$w->(42, 10), 'Should get false for warning 42, 10';
+ ok $w->(1024, 10), 'Should get true for warning 1024, 10';
+ ok $w->(42, 20), 'Should get true for warning 42, 20';
+ ok $w->(1024, 20), 'Should get true for warning 1024, 20';
+
+ # Try with just critical.
+ %check_postgres::opt = ( critical => '20% or 1k');
+ ($w, $c) = check_postgres::validate_size_or_percent_with_oper();
+ isa_ok $w, 'CODE', 'missing warning';
+ isa_ok $c, 'CODE', 'critical';
+
+ ok !$c->(42, 10), 'Should get false for critical 42, 10';
+ ok $c->(1024, 10), 'Should get true for critical 1024, 10';
+ ok $c->(42, 20), 'Should get true for critical 42, 20';
+ ok $c->(1024, 20), 'Should get true for critical 1024, 20';
+
+ ok !$w->(0), 'Warning should return false';
+ ok !$w->(undef), 'Warning should always return false';
+ ok !$w->('whatever'), 'Warning should really always return false';
+
+ # Try with just warning.
+ %check_postgres::opt = ( warning => '20% or 1k');
+ ($w, $c) = check_postgres::validate_size_or_percent_with_oper();
+ isa_ok $w, 'CODE', 'warning';
+ isa_ok $c, 'CODE', 'missing critical';
+
+ ok !$c->(0), 'Critical should return false';
+ ok !$c->(undef), 'Critical should always return false';
+ ok !$c->('whatever'), 'Critical should really always return false';
+
+ ok !$w->(42, 10), 'Should get false for warning 42, 10';
+ ok $w->(1024, 10), 'Should get true for warning 1024, 10';
+ ok $w->(42, 20), 'Should get true for warning 42, 20';
+ ok $w->(1024, 20), 'Should get true for warning 1024, 20';
+}