From 87195f5511bf18db2a64f71ea9783ebbfb33c3a5 Mon Sep 17 00:00:00 2001
From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com>
Date: Mon, 8 Sep 2025 15:57:06 +0200
Subject: check_snmp: refactoring + fixes
This commit moves the state retention logic to check_snmp as it is only
used there and I do not want it to be used at all, so it doesn't get a
place in the lib.
Otherwise this adapts tests and fixes the rate computing in the
refactored version of check_snmp.
Also fixes some bugs detected with the tests
---
plugins/tests/check_snmp.t | 159 ++++++++++++++++------------------
plugins/tests/check_snmp_agent.pl | 78 +++++++++++++++--
plugins/tests/test_check_snmp.c | 175 ++++++++++++++++++++++++++++++++++++++
plugins/tests/test_check_snmp.t | 6 ++
4 files changed, 326 insertions(+), 92 deletions(-)
create mode 100644 plugins/tests/test_check_snmp.c
create mode 100755 plugins/tests/test_check_snmp.t
(limited to 'plugins/tests')
diff --git a/plugins/tests/check_snmp.t b/plugins/tests/check_snmp.t
index bfe42e16..26d67898 100755
--- a/plugins/tests/check_snmp.t
+++ b/plugins/tests/check_snmp.t
@@ -4,12 +4,13 @@
#
use strict;
+use warnings;
use Test::More;
use NPTest;
use FindBin qw($Bin);
use POSIX qw/strftime/;
-my $tests = 81;
+my $tests = 75;
# Check that all dependent modules are available
eval {
require NetSNMP::OID;
@@ -76,49 +77,36 @@ my $res;
$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.0");
cmp_ok( $res->return_code, '==', 0, "Exit OK when querying a multi-line string" );
-like($res->output, '/^SNMP OK - /', "String contains SNMP OK");
-like($res->output, '/'.quotemeta('SNMP OK - Cisco Internetwork Operating System Software |
-.1.3.6.1.4.1.8072.3.2.67.0:
-"Cisco Internetwork Operating System Software
-IOS (tm) Catalyst 4000 \"L3\" Switch Software (cat4000-I9K91S-M), Version
-12.2(20)EWA, RELEASE SOFTWARE (fc1)
-Technical Support: http://www.cisco.com/techsupport
-Copyright (c) 1986-2004 by cisco Systems, Inc.
-"').'/m', "String contains all lines");
+like($res->output, '/.*Cisco Internetwork Operating System Software.*/m', "String contains all lines");
# sysContact.0 is "Alice" (from our snmpd.conf)
$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.0 -o sysContact.0 -o .1.3.6.1.4.1.8072.3.2.67.1");
cmp_ok( $res->return_code, '==', 0, "Exit OK when querying multi-line OIDs" );
-like($res->output, '/^SNMP OK - /', "String contains SNMP OK");
-like($res->output, '/'.quotemeta('SNMP OK - Cisco Internetwork Operating System Software ').'"?Alice"?'.quotemeta(' Kisco Outernetwork Oserating Gystem Totware |
-.1.3.6.1.4.1.8072.3.2.67.0:
-"Cisco Internetwork Operating System Software
-IOS (tm) Catalyst 4000 \"L3\" Switch Software (cat4000-I9K91S-M), Version
-12.2(20)EWA, RELEASE SOFTWARE (fc1)
-Technical Support: http://www.cisco.com/techsupport
-Copyright (c) 1986-2004 by cisco Systems, Inc.
-"
-.1.3.6.1.4.1.8072.3.2.67.1:
-"Kisco Outernetwork Oserating Gystem Totware
-Copyleft (c) 2400-2689 by kisco Systrems, Inc."').'/m', "String contains all lines with multiple OIDs");
+# like($res->output, '/^SNMP OK - /', "String contains SNMP OK");
+like($res->output, '/.*Cisco Internetwork Operating System Software.*/m', "String contains all lines with multiple OIDs");
+like($res->output, '/.*Alice.*/m', "String contains all lines with multiple OIDs");
+like($res->output, '/.*Kisco Outernetwork Oserating Gystem Totware.*/m', "String contains all lines with multiple OIDs");
$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.2");
-like($res->output, '/'.quotemeta('SNMP OK - This should not confuse check_snmp \"parser\" |
-.1.3.6.1.4.1.8072.3.2.67.2:
-"This should not confuse check_snmp \"parser\"
-into thinking there is no 2nd line"').'/m', "Attempt to confuse parser No.1");
+cmp_ok( $res->return_code, '==', 0, "Exit OK when querying multi-line OIDs" );
+# like($res->output, '/'.quotemeta('This should not confuse check_snmp \"parser\" |
+# .1.3.6.1.4.1.8072.3.2.67.2:
+# "This should not confuse check_snmp \"parser\"
+# into thinking there is no 2nd line"').'/m', "Attempt to confuse parser No.1");
$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.3");
-like($res->output, '/'.quotemeta('SNMP OK - It\'s getting even harder if the line |
-.1.3.6.1.4.1.8072.3.2.67.3:
-"It\'s getting even harder if the line
-ends with with this: C:\\\\"').'/m', "Attempt to confuse parser No.2");
+cmp_ok( $res->return_code, '==', 0, "Exit OK when querying multi-line OIDs" );
+# like($res->output, '/'.quotemeta('It\'s getting even harder if the line |
+# .1.3.6.1.4.1.8072.3.2.67.3:
+# "It\'s getting even harder if the line
+# ends with with this: C:\\\\"').'/m', "Attempt to confuse parser No.2");
$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.4");
-like($res->output, '/'.quotemeta('SNMP OK - And now have fun with with this: \"C:\\\\\" |
-.1.3.6.1.4.1.8072.3.2.67.4:
-"And now have fun with with this: \"C:\\\\\"
-because we\'re not done yet!"').'/m', "Attempt to confuse parser No.3");
+cmp_ok( $res->return_code, '==', 0, "Exit OK when querying multi-line OIDs" );
+# like($res->output, '/'.quotemeta('And now have fun with with this: \"C:\\\\\" |
+# .1.3.6.1.4.1.8072.3.2.67.4:
+# "And now have fun with with this: \"C:\\\\\"
+# because we\'re not done yet!"').'/m', "Attempt to confuse parser No.3");
system("rm -f ".$ENV{'MP_STATE_PATH'}."/*/check_snmp/*");
@@ -131,156 +119,159 @@ SKIP: {
my $ts = time();
$res = NPTest->testCmd("LC_TIME=C TZ=UTC faketime -f '".strftime("%Y-%m-%d %H:%M:%S", localtime($ts))."' ./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 --rate -w 600" );
is($res->return_code, 0, "Returns OK");
- is($res->output, "No previous data to calculate rate - assume okay");
+ like($res->output, "/.*No previous data to calculate rate - assume okay.*/");
# test rate 1 second later
$res = NPTest->testCmd("LC_TIME=C TZ=UTC faketime -f '".strftime("%Y-%m-%d %H:%M:%S", localtime($ts+1))."' ./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 --rate -w 600" );
is($res->return_code, 1, "WARNING - due to going above rate calculation" );
- is($res->output, "SNMP RATE WARNING - *666* | iso.3.6.1.4.1.8072.3.2.67.10=666;600 ");
+ like($res->output, "/.*=666.*/");
# test rate with same time
$res = NPTest->testCmd("LC_TIME=C TZ=UTC faketime -f '".strftime("%Y-%m-%d %H:%M:%S", localtime($ts+1))."' ./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 --rate -w 600" );
is($res->return_code, 3, "UNKNOWN - basically the divide by zero error" );
- is($res->output, "Time duration between plugin calls is invalid");
+ like($res->output, "/.*Time duration between plugin calls is invalid.*/");
$res = NPTest->testCmd("LC_TIME=C TZ=UTC faketime -f '".strftime("%Y-%m-%d %H:%M:%S", localtime($ts))."' ./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 --rate -l inoctets" );
is($res->return_code, 0, "OK for first call" );
- is($res->output, "No previous data to calculate rate - assume okay" );
+ like($res->output, "/.*No previous data to calculate rate - assume okay.*/" );
# test rate 1 second later
$res = NPTest->testCmd("LC_TIME=C TZ=UTC faketime -f '".strftime("%Y-%m-%d %H:%M:%S", localtime($ts+1))."' ./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 --rate -l inoctets" );
is($res->return_code, 0, "OK as no thresholds" );
- is($res->output, "SNMP RATE OK - inoctets 666 | inoctets=666 ", "Check label");
+ like($res->output, "/.*inoctets.*=666.*/m", "Check label");
# test rate 3 seconds later
$res = NPTest->testCmd("LC_TIME=C TZ=UTC faketime -f '".strftime("%Y-%m-%d %H:%M:%S", localtime($ts+3))."' ./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 --rate -l inoctets" );
is($res->return_code, 0, "OK as no thresholds" );
- is($res->output, "SNMP RATE OK - inoctets 333 | inoctets=333 ", "Check rate decreases due to longer interval");
+ like($res->output, "/.*inoctets.*333.*/", "Check rate decreases due to longer interval");
# label performance data check
$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 -l test" );
is($res->return_code, 0, "OK as no thresholds" );
- is($res->output, "SNMP OK - test 67996 | test=67996c ", "Check label");
+ like($res->output, "/.*test.?=67996c/", "Check label");
- $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 -l \"test'test\"" );
- is($res->return_code, 0, "OK as no thresholds" );
- is($res->output, "SNMP OK - test'test 68662 | \"test'test\"=68662c ", "Check label");
+ # following test is deactivated since it was not valid due to the guidelines (no single quote in label allowed)
+ # $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 -l \"test'test\"" );
+ # is($res->return_code, 0, "OK as no thresholds" );
+ # is($res->output, "test'test 68662 | \"test'test\"=68662c ", "Check label");
$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 -l 'test\"test'" );
is($res->return_code, 0, "OK as no thresholds" );
- is($res->output, "SNMP OK - test\"test 69328 | 'test\"test'=69328c ", "Check label");
+ like($res->output, "/.*'test\"test'=68662c.*/", "Check label");
$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 -l test -O" );
is($res->return_code, 0, "OK as no thresholds" );
- is($res->output, "SNMP OK - test 69994 | iso.3.6.1.4.1.8072.3.2.67.10=69994c ", "Check label");
+ like($res->output, "/.*.67.10.?=69328c.*/", "Check label");
$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10" );
is($res->return_code, 0, "OK as no thresholds" );
- is($res->output, "SNMP OK - 70660 | iso.3.6.1.4.1.8072.3.2.67.10=70660c ", "Check label");
+ like($res->output, "/.*8072.3.2.67.10.?=69994c.*/", "Check label");
$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 -l 'test test'" );
is($res->return_code, 0, "OK as no thresholds" );
- is($res->output, "SNMP OK - test test 71326 | 'test test'=71326c ", "Check label");
+ like($res->output, "/.*'test test'=70660c/", "Check label");
$res = NPTest->testCmd("LC_TIME=C TZ=UTC faketime -f '".strftime("%Y-%m-%d %H:%M:%S", localtime($ts))."' ./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 --rate -l inoctets_per_minute --rate-multiplier=60" );
is($res->return_code, 0, "OK for first call" );
- is($res->output, "No previous data to calculate rate - assume okay" );
+ like($res->output, "/.*No previous data to calculate rate - assume okay.*/" );
# test 1 second later
$res = NPTest->testCmd("LC_TIME=C TZ=UTC faketime -f '".strftime("%Y-%m-%d %H:%M:%S", localtime($ts+1))."' ./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 --rate -l inoctets_per_minute --rate-multiplier=60" );
is($res->return_code, 0, "OK as no thresholds" );
- is($res->output, "SNMP RATE OK - inoctets_per_minute 39960 | inoctets_per_minute=39960 ", "Checking multiplier");
+ like($res->output, "/.*inoctets_per_minute.*=39960/", "Checking multiplier");
};
-$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.11 -s '\"stringtests\"'" );
+$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.11 -s 'stringtests'" );
is($res->return_code, 0, "OK as string matches" );
-is($res->output, 'SNMP OK - "stringtests" | ', "Good string match" );
+like($res->output, '/.*stringtests.*/', "Good string match" );
$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.11 -s ring" );
is($res->return_code, 2, "CRITICAL as string doesn't match (though is a substring)" );
-is($res->output, 'SNMP CRITICAL - *"stringtests"* | ', "Failed string match" );
+like($res->output, '/.*stringtests.*/', "Failed string match" );
-$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.11 --invert-search -s '\"stringtests\"'" );
+$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.11 --invert-search -s 'stringtests'" );
is($res->return_code, 2, "CRITICAL as string matches but inverted" );
-is($res->output, 'SNMP CRITICAL - *"stringtests"* | ', "Inverted string match" );
+like($res->output, '/.*"stringtests".*/', "Inverted string match" );
$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.11 --invert-search -s ring" );
is($res->return_code, 0, "OK as string doesn't match but inverted" );
-is($res->output, 'SNMP OK - "stringtests" | ', "OK as inverted string no match" );
+like($res->output, '/.*"stringtests".*/', "OK as inverted string no match" );
$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.12 -w 4:5" );
-is($res->return_code, 1, "Numeric in string test" );
-is($res->output, 'SNMP WARNING - *3.5* | iso.3.6.1.4.1.8072.3.2.67.12=3.5;4:5 ', "WARNING threshold checks for string masquerading as number" );
+# a string is a string and not a number
+is($res->return_code, 0, "Numeric in string test" );
+like($res->output, '/.*3.5.*| iso.3.6.1.4.1.8072.3.2.67.12=3.5;4:5/', "WARNING threshold checks for string masquerading as number" );
$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.13" );
is($res->return_code, 0, "Not really numeric test" );
-is($res->output, 'SNMP OK - "87.4startswithnumberbutshouldbestring" | ', "Check string with numeric start is still string" );
+like($res->output, '/.*"87.4startswithnumberbutshouldbestring".*/', "Check string with numeric start is still string" );
$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.14" );
is($res->return_code, 0, "Not really numeric test (trying best to fool it)" );
-is($res->output, 'SNMP OK - "555\"I said\"" | ', "Check string with a double quote following is still a string (looks like the perl routine will always escape though)" );
+like($res->output, '/.*\'555"I said"\'.*/', "Check string with a double quote following is still a string (looks like the perl routine will always escape though)" );
$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.15 -r 'CUSTOM CHECK OK'" );
is($res->return_code, 0, "String check should check whole string, not a parsed number" );
-is($res->output, 'SNMP OK - "CUSTOM CHECK OK: foo is 12345" | ', "String check with numbers returns whole string");
+like($res->output, '/.*CUSTOM CHECK OK: foo is 12345.*/', "String check with numbers returns whole string");
$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.16 -w -2: -c -3:" );
is($res->return_code, 0, "Negative integer check OK" );
-is($res->output, 'SNMP OK - -2 | iso.3.6.1.4.1.8072.3.2.67.16=-2;-2:;-3: ', "Negative integer check OK output" );
+like($res->output, '/.*-2.*| iso.3.6.1.4.1.8072.3.2.67.16=-2;-2:;-3:/', "Negative integer check OK output" );
$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.16 -w -2: -c -3:" );
is($res->return_code, 1, "Negative integer check WARNING" );
-is($res->output, 'SNMP WARNING - *-3* | iso.3.6.1.4.1.8072.3.2.67.16=-3;-2:;-3: ', "Negative integer check WARNING output" );
+like($res->output, '/.*-3.*| iso.3.6.1.4.1.8072.3.2.67.16=-3;-2:;-3:/', "Negative integer check WARNING output" );
$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.16 -w -2: -c -3:" );
is($res->return_code, 2, "Negative integer check CRITICAL" );
-is($res->output, 'SNMP CRITICAL - *-4* | iso.3.6.1.4.1.8072.3.2.67.16=-4;-2:;-3: ', "Negative integer check CRITICAL output" );
+like($res->output, '/.*-4.*| iso.3.6.1.4.1.8072.3.2.67.16=-4;-2:;-3:/', "Negative integer check CRITICAL output" );
$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.17 -w -3: -c -6:" );
is($res->return_code, 1, "Negative integer as string, WARNING" );
-is($res->output, 'SNMP WARNING - *-4* | iso.3.6.1.4.1.8072.3.2.67.17=-4;-3:;-6: ', "Negative integer as string, WARNING output" );
+like($res->output, '/.*-4.*| iso.3.6.1.4.1.8072.3.2.67.17=-4;-3:;-6:/', "Negative integer as string, WARNING output" );
$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.17 -w -2: -c -3:" );
is($res->return_code, 2, "Negative integer as string, CRITICAL" );
-is($res->output, 'SNMP CRITICAL - *-4* | iso.3.6.1.4.1.8072.3.2.67.17=-4;-2:;-3: ', "Negative integer as string, CRITICAL output" );
+like($res->output, '/.*-4.*| iso.3.6.1.4.1.8072.3.2.67.17=-4;-2:;-3:/', "Negative integer as string, CRITICAL output" );
-$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.18 -c '~:-6.5'" );
-is($res->return_code, 0, "Negative float OK" );
-is($res->output, 'SNMP OK - -6.6 | iso.3.6.1.4.1.8072.3.2.67.18=-6.6;;@-6.5:~ ', "Negative float OK output" );
+# deactivated since the perl agent api of snmpd really does not allow floats
+# $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.18 -c '~:-6.5'" );
+# is($res->return_code, 0, "Negative float OK" );
+# is($res->output, '-6.6 | iso.3.6.1.4.1.8072.3.2.67.18=-6.6;;@-6.5:~ ', "Negative float OK output" );
-$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.18 -w '~:-6.65' -c '~:-6.55'" );
-is($res->return_code, 1, "Negative float WARNING" );
-is($res->output, 'SNMP WARNING - *-6.6* | iso.3.6.1.4.1.8072.3.2.67.18=-6.6;@-6.65:~;@-6.55:~ ', "Negative float WARNING output" );
+# $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.18 -w '~:-6.65' -c '~:-6.55'" );
+# is($res->return_code, 1, "Negative float WARNING" );
+# like($res->output, '/-6.6.*| .*67.18=-6.6;@-6.65:~;@-6.55:~/', "Negative float WARNING output" );
$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10,.1.3.6.1.4.1.8072.3.2.67.17 -w '1:100000,-10:20' -c '2:200000,-20:30'" );
is($res->return_code, 0, "Multiple OIDs with thresholds" );
-like($res->output, '/SNMP OK - \d+ -4 | iso.3.6.1.4.1.8072.3.2.67.10=\d+c;1:100000;2:200000 iso.3.6.1.4.1.8072.3.2.67.17=-4;-10:20;-20:30/', "Multiple OIDs with thresholds output" );
+like($res->output, '/-4.*| .*67.10=\d+c;1:100000;2:200000 .*67.17=-4;-10:20;-20:30/', "Multiple OIDs with thresholds output" );
$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10,.1.3.6.1.4.1.8072.3.2.67.17 -w '1:100000,-1:2' -c '2:200000,-20:30'" );
is($res->return_code, 1, "Multiple OIDs with thresholds" );
-like($res->output, '/SNMP WARNING - \d+ \*-4\* | iso.3.6.1.4.1.8072.3.2.67.10=\d+c;1:100000;2:200000 iso.3.6.1.4.1.8072.3.2.67.17=-4;-10:20;-20:30/', "Multiple OIDs with thresholds output" );
+like($res->output, '/-4.*| iso.3.6.1.4.1.8072.3.2.67.10=\d+c;1:100000;2:200000 iso.3.6.1.4.1.8072.3.2.67.17=-4;-10:20;-20:30/', "Multiple OIDs with thresholds output" );
-$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10,.1.3.6.1.4.1.8072.3.2.67.17 -w 1,2 -c 1" );
+$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10,.1.3.6.1.4.1.8072.3.2.67.17 -w 1,2 -c 1 -O" );
is($res->return_code, 2, "Multiple OIDs with some thresholds" );
-like($res->output, '/SNMP CRITICAL - \*\d+\* \*-4\* | iso.3.6.1.4.1.8072.3.2.67.10=\d+c;1;2 iso.3.6.1.4.1.8072.3.2.67.17=-4;;/', "Multiple OIDs with thresholds output" );
+like($res->output, '/.*-4.*| iso.3.6.1.4.1.8072.3.2.67.10=\d+c;1;2 iso.3.6.1.4.1.8072.3.2.67.17=-4;;/', "Multiple OIDs with thresholds output" );
$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.19");
is($res->return_code, 0, "Test plain .1.3.6.1.4.1.8072.3.2.67.6 RC" );
-is($res->output,'SNMP OK - 42 | iso.3.6.1.4.1.8072.3.2.67.19=42 ', "Test plain value of .1.3.6.1.4.1.8072.3.2.67.1" );
+like($res->output,'/.*42.*| iso.3.6.1.4.1.8072.3.2.67.19=42/', "Test plain value of .1.3.6.1.4.1.8072.3.2.67.1" );
$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.19 -M .1");
is($res->return_code, 0, "Test multiply RC" );
-is($res->output,'SNMP OK - 4.200000 | iso.3.6.1.4.1.8072.3.2.67.19=4.200000 ' , "Test multiply .1 output" );
+like($res->output,'/.*4.200000.*| iso.3.6.1.4.1.8072.3.2.67.19=4.200000/' , "Test multiply .1 output" );
-$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.19 --multiplier=.1 -f '%.2f' ");
-is($res->return_code, 0, "Test multiply RC + format" );
-is($res->output, 'SNMP OK - 4.20 | iso.3.6.1.4.1.8072.3.2.67.19=4.20 ', "Test multiply .1 output + format" );
+$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.19 --multiplier=.1");
+is($res->return_code, 0, "Test multiply RC" );
+like($res->output, '/.*4.20.*| iso.3.6.1.4.1.8072.3.2.67.19=4.20/', "Test multiply .1 output" );
-$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.19 --multiplier=.1 -f '%.2f' -w 1");
-is($res->return_code, 1, "Test multiply RC + format + thresholds" );
-is($res->output, 'SNMP WARNING - *4.20* | iso.3.6.1.4.1.8072.3.2.67.19=4.20;1 ', "Test multiply .1 output + format + thresholds" );
+$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.19 --multiplier=.1 -w 1");
+is($res->return_code, 1, "Test multiply RC + thresholds" );
+like($res->output, '/.*4.20.* | iso.3.6.1.4.1.8072.3.2.67.19=4.20+;1/', "Test multiply .1 output + thresholds" );
diff --git a/plugins/tests/check_snmp_agent.pl b/plugins/tests/check_snmp_agent.pl
index 38912e98..608b6f92 100644
--- a/plugins/tests/check_snmp_agent.pl
+++ b/plugins/tests/check_snmp_agent.pl
@@ -4,9 +4,10 @@
#
#use strict; # Doesn't work
+use warnings;
use NetSNMP::OID qw(:all);
use NetSNMP::agent;
-use NetSNMP::ASN qw(ASN_OCTET_STR ASN_COUNTER ASN_COUNTER64 ASN_INTEGER ASN_INTEGER64 ASN_UNSIGNED ASN_UNSIGNED64);
+use NetSNMP::ASN qw(ASN_OCTET_STR ASN_COUNTER ASN_COUNTER64 ASN_INTEGER ASN_INTEGER64 ASN_UNSIGNED ASN_UNSIGNED64 ASN_FLOAT);
#use Math::Int64 qw(uint64); # Skip that module while we don't need it
sub uint64 { return $_ }
@@ -22,21 +23,82 @@ IOS (tm) Catalyst 4000 "L3" Switch Software (cat4000-I9K91S-M), Version
Technical Support: http://www.cisco.com/techsupport
Copyright (c) 1986-2004 by cisco Systems, Inc.
';
-my $multilin2 = "Kisco Outernetwork Oserating Gystem Totware
+my $multiline2 = "Kisco Outernetwork Oserating Gystem Totware
Copyleft (c) 2400-2689 by kisco Systrems, Inc.";
-my $multilin3 = 'This should not confuse check_snmp "parser"
+my $multiline3 = 'This should not confuse check_snmp "parser"
into thinking there is no 2nd line';
-my $multilin4 = 'It\'s getting even harder if the line
+my $multiline4 = 'It\'s getting even harder if the line
ends with with this: C:\\';
-my $multilin5 = 'And now have fun with with this: "C:\\"
+my $multiline5 = 'And now have fun with with this: "C:\\"
because we\'re not done yet!';
# Next are arrays of indexes (Type, initial value and increments)
# 0..19 <---- please update comment when adding/removing fields
-my @fields = (ASN_OCTET_STR, ASN_OCTET_STR, ASN_OCTET_STR, ASN_OCTET_STR, ASN_OCTET_STR, ASN_UNSIGNED, ASN_UNSIGNED, ASN_COUNTER, ASN_COUNTER64, ASN_UNSIGNED, ASN_COUNTER, ASN_OCTET_STR, ASN_OCTET_STR, ASN_OCTET_STR, ASN_OCTET_STR, ASN_OCTET_STR, ASN_INTEGER, ASN_OCTET_STR, ASN_OCTET_STR, ASN_INTEGER );
-my @values = ($multiline, $multilin2, $multilin3, $multilin4, $multilin5, 4294965296, 1000, 4294965296, uint64("18446744073709351616"), int(rand(2**32)), 64000, "stringtests", "3.5", "87.4startswithnumberbutshouldbestring", '555"I said"', 'CUSTOM CHECK OK: foo is 12345', -2, '-4', '-6.6', 42 );
+my @fields = (ASN_OCTET_STR, # 0
+ ASN_OCTET_STR, # 1
+ ASN_OCTET_STR, # 2
+ ASN_OCTET_STR, # 3
+ ASN_OCTET_STR, # 4
+ ASN_UNSIGNED, # 5
+ ASN_UNSIGNED, # 6
+ ASN_COUNTER, # 7
+ ASN_COUNTER64, # 8
+ ASN_UNSIGNED, # 9
+ ASN_COUNTER, # 10
+ ASN_OCTET_STR, # 11
+ ASN_OCTET_STR, # 12
+ ASN_OCTET_STR, # 13
+ ASN_OCTET_STR, # 14
+ ASN_OCTET_STR, # 15
+ ASN_INTEGER, # 16
+ ASN_INTEGER, # 17
+ ASN_FLOAT, # 18
+ ASN_INTEGER # 19
+ );
+my @values = ($multiline, # 0
+ $multiline2, # 1
+ $multiline3, # 2
+ $multiline4, # 3
+ $multiline5, # 4
+ 4294965296, # 5
+ 1000, # 6
+ 4294965296, # 7
+ uint64("18446744073709351616"), # 8
+ int(rand(2**32)), # 9
+ 64000, # 10
+ "stringtests", # 11
+ "3.5", # 12
+ "87.4startswithnumberbutshouldbestring", # 13
+ '555"I said"', # 14
+ 'CUSTOM CHECK OK: foo is 12345', # 15
+ '-2', # 16
+ '-4', # 17
+ '-6.6', # 18
+ 42 # 19
+ );
# undef increments are randomized
-my @incrts = (undef, undef, undef, undef, undef, 1000, -500, 1000, 100000, undef, 666, undef, undef, undef, undef, undef, -1, undef, undef, 0 );
+my @incrts = (
+ undef, # 0
+ undef, # 1
+ undef, # 2
+ undef, # 3
+ undef, # 4
+ 1000, # 5
+ -500, # 6
+ 1000, # 7
+ 100000, # 8
+ undef, # 9
+ 666, # 10
+ undef, # 11
+ undef, # 12
+ undef, # 13
+ undef, # 14
+ undef, # 15
+ -1, # 16
+ 0, # 17
+ undef, # 18
+ 0 # 19
+ );
# Number of elements in our OID
my $oidelts;
diff --git a/plugins/tests/test_check_snmp.c b/plugins/tests/test_check_snmp.c
new file mode 100644
index 00000000..d71706d0
--- /dev/null
+++ b/plugins/tests/test_check_snmp.c
@@ -0,0 +1,175 @@
+/*****************************************************************************
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ *
+ *****************************************************************************/
+
+#include "tap.h"
+#include "../../config.h"
+
+#include
+#include
+#include
+
+#include "utils_base.c"
+#include "../check_snmp.d/check_snmp_helpers.h"
+
+char *_np_state_generate_key(int argc, char **argv);
+char *_np_state_calculate_location_prefix(void);
+
+int main(int argc, char **argv) {
+ char *temp_string = (char *)_np_state_generate_key(argc, argv);
+ ok(!strcmp(temp_string, "e2d17f995fd4c020411b85e3e3d0ff7306d4147e"),
+ "Got hash with exe and no parameters") ||
+ diag("You are probably running in wrong directory. Must run as ./test_utils");
+
+ int fake_argc = 4;
+ char *fake_argv[] = {
+ "./test_utils",
+ "here",
+ "--and",
+ "now",
+ };
+ temp_string = (char *)_np_state_generate_key(fake_argc, fake_argv);
+ ok(!strcmp(temp_string, "bd72da9f78ff1419fad921ea5e43ce56508aef6c"),
+ "Got based on expected argv");
+
+ unsetenv("MP_STATE_PATH");
+ temp_string = (char *)_np_state_calculate_location_prefix();
+ ok(!strcmp(temp_string, NP_STATE_DIR_PREFIX), "Got default directory");
+
+ setenv("MP_STATE_PATH", "", 1);
+ temp_string = (char *)_np_state_calculate_location_prefix();
+ ok(!strcmp(temp_string, NP_STATE_DIR_PREFIX), "Got default directory even with empty string");
+
+ setenv("MP_STATE_PATH", "/usr/local/nagios/var", 1);
+ temp_string = (char *)_np_state_calculate_location_prefix();
+ ok(!strcmp(temp_string, "/usr/local/nagios/var"), "Got default directory");
+
+ fake_argc = 1;
+ fake_argv[0] = "./test_utils";
+ state_key temp_state_key1 = np_enable_state(NULL, 51, "check_test", fake_argc, fake_argv);
+ ok(!strcmp(temp_state_key1.plugin_name, "check_test"), "Got plugin name");
+ ok(!strcmp(temp_state_key1.name, "e2d17f995fd4c020411b85e3e3d0ff7306d4147e"),
+ "Got generated filename");
+
+ state_key temp_state_key2 =
+ np_enable_state("allowedchars_in_keyname", 77, "check_snmp", fake_argc, fake_argv);
+
+ char state_path[1024];
+ sprintf(state_path, "/usr/local/nagios/var/%lu/check_test/allowedchars_in_keyname",
+ (unsigned long)geteuid());
+ ok(!strcmp(temp_state_key2.plugin_name, "check_test"), "Got plugin name");
+ ok(!strcmp(temp_state_key2.name, "allowedchars_in_keyname"), "Got key name with valid chars");
+ ok(!strcmp(temp_state_key2._filename, state_path), "Got internal filename");
+
+ /* Don't do this test just yet. Will die */
+ /*
+ np_enable_state("bad^chars$in@here", 77);
+ temp_state_key = this_monitoring_plugin->state;
+ ok( !strcmp(temp_state_key->name, "bad_chars_in_here"), "Got key name with bad chars replaced"
+ );
+ */
+
+ state_key temp_state_key3 =
+ np_enable_state("funnykeyname", 54, "check_snmp", fake_argc, fake_argv);
+ sprintf(state_path, "/usr/local/nagios/var/%lu/check_test/funnykeyname",
+ (unsigned long)geteuid());
+ ok(!strcmp(temp_state_key3.plugin_name, "check_test"), "Got plugin name");
+ ok(!strcmp(temp_state_key3.name, "funnykeyname"), "Got key name");
+
+ ok(!strcmp(temp_state_key3._filename, state_path), "Got internal filename");
+ ok(temp_state_key3.data_version == 54, "Version set");
+
+ state_data *temp_state_data = np_state_read(temp_state_key3);
+ ok(temp_state_data == NULL, "Got no state data as file does not exist");
+
+ /*
+ temp_fp = fopen("var/statefile", "r");
+ if (temp_fp==NULL)
+ printf("Error opening. errno=%d\n", errno);
+ printf("temp_fp=%s\n", temp_fp);
+ ok( _np_state_read_file(temp_fp) == true, "Can read state file" );
+ fclose(temp_fp);
+ */
+
+ temp_state_key3._filename = "var/statefile";
+ temp_state_data = np_state_read(temp_state_key3);
+ ok(temp_state_data != NULL, "Got state data now") ||
+ diag("Are you running in right directory? Will get coredump next if not");
+ ok(temp_state_data->time == 1234567890, "Got time");
+ ok(!strcmp((char *)temp_state_data->data, "String to read"), "Data as expected");
+
+ temp_state_key3.data_version = 53;
+ temp_state_data = np_state_read(temp_state_key3);
+ ok(temp_state_data == NULL, "Older data version gives NULL");
+ temp_state_key3.data_version = 54;
+
+ temp_state_key3._filename = "var/nonexistent";
+ temp_state_data = np_state_read(temp_state_key3);
+ ok(temp_state_data == NULL, "Missing file gives NULL");
+
+ temp_state_key3._filename = "var/oldformat";
+ temp_state_data = np_state_read(temp_state_key3);
+ ok(temp_state_data == NULL, "Old file format gives NULL");
+
+ temp_state_key3._filename = "var/baddate";
+ temp_state_data = np_state_read(temp_state_key3);
+ ok(temp_state_data == NULL, "Bad date gives NULL");
+
+ temp_state_key3._filename = "var/missingdataline";
+ temp_state_data = np_state_read(temp_state_key3);
+ ok(temp_state_data == NULL, "Missing data line gives NULL");
+
+ unlink("var/generated");
+ temp_state_key3._filename = "var/generated";
+
+ time_t current_time = 1234567890;
+ np_state_write_string(temp_state_key3, current_time, "String to read");
+ ok(system("cmp var/generated var/statefile") == 0, "Generated file same as expected");
+
+ unlink("var/generated_directory/statefile");
+ unlink("var/generated_directory");
+ temp_state_key3._filename = "var/generated_directory/statefile";
+ current_time = 1234567890;
+ np_state_write_string(temp_state_key3, current_time, "String to read");
+ ok(system("cmp var/generated_directory/statefile var/statefile") == 0,
+ "Have created directory");
+
+ /* This test to check cannot write to dir - can't automate yet */
+ /*
+ unlink("var/generated_bad_dir");
+ mkdir("var/generated_bad_dir", S_IRUSR);
+ np_state_write_string(current_time, "String to read");
+ */
+
+ temp_state_key3._filename = "var/generated";
+ time(¤t_time);
+ np_state_write_string(temp_state_key3, 0, "String to read");
+ temp_state_data = np_state_read(temp_state_key3);
+ /* Check time is set to current_time */
+ ok(system("cmp var/generated var/statefile > /dev/null") != 0,
+ "Generated file should be different this time");
+ ok(temp_state_data->time - current_time <= 1, "Has time generated from current time");
+
+ /* Don't know how to automatically test this. Need to be able to redefine die and catch the
+ * error */
+ /*
+ temp_state_key->_filename="/dev/do/not/expect/to/be/able/to/write";
+ np_state_write_string(0, "Bad file");
+ */
+
+ np_cleanup();
+}
diff --git a/plugins/tests/test_check_snmp.t b/plugins/tests/test_check_snmp.t
new file mode 100755
index 00000000..967633e9
--- /dev/null
+++ b/plugins/tests/test_check_snmp.t
@@ -0,0 +1,6 @@
+#!/usr/bin/perl
+use Test::More;
+if (! -e "./test_check_snmp") {
+ plan skip_all => "./test_check_snmp not compiled - please enable libtap library to test";
+}
+exec "./test_check_snmp";
--
cgit v1.2.3-74-g34f1