From b17b2421987bb8a7606948333e75f990b35852b8 Mon Sep 17 00:00:00 2001 From: Ton Voon Date: Wed, 19 Mar 2008 14:42:12 +0000 Subject: 1st pass at check_procs with multiple threshold checks git-svn-id: https://nagiosplug.svn.sourceforge.net/svnroot/nagiosplug/nagiosplug/branches/new_threshold_syntax@1958 f882894a-f735-0410-b71e-b25c423dba1c --- lib/tests/test_utils.c | 158 ++++++++++++++++++++++++++++++++++++++++++++++++- lib/utils_base.c | 135 +++++++++++++++++++++++++++++++++++++++++- lib/utils_base.h | 21 +++++-- 3 files changed, 306 insertions(+), 8 deletions(-) (limited to 'lib') diff --git a/lib/tests/test_utils.c b/lib/tests/test_utils.c index 278f526e..a5189cea 100644 --- a/lib/tests/test_utils.c +++ b/lib/tests/test_utils.c @@ -30,7 +30,7 @@ main (int argc, char **argv) thresholds *thresholds = NULL; int rc; - plan_tests(82); + plan_tests(172); range = parse_range_string("6"); ok( range != NULL, "'6' is valid range"); @@ -40,6 +40,32 @@ main (int argc, char **argv) ok( range->end_infinity == FALSE, "Not using infinity"); free(range); + range = _parse_range_string_v2("6"); + ok( range == NULL, "Missing colon in range" ); + ok( utils_errno == NP_RANGE_MISSING_COLON, "Right error code" ); + + range = _parse_range_string_v2("6:"); + ok( range != NULL, "'6:' is valid range"); + ok( range->start == 6, "Start correct"); + ok( range->start_infinity == FALSE, "Not using negative infinity"); + ok( range->end_infinity == TRUE, "Using infinity"); + free(range); + + range = _parse_range_string_v2("6:6"); + ok( range != NULL, "'6:6' is valid range"); + ok( range->start == 6, "Start correct"); + ok( range->start_infinity == FALSE, "Not using negative infinity"); + ok( range->end == 6, "End correct"); + ok( range->end_infinity == FALSE, "Not using infinity"); + free(range); + + range = _parse_range_string_v2(":6"); + ok( range != NULL, "':6' is valid range"); + ok( range->start_infinity == TRUE, "Using negative infinity"); + ok( range->end == 6, "End correct"); + ok( range->end_infinity == FALSE, "Not using infinity"); + free(range); + range = parse_range_string("1:12%%"); ok( range != NULL, "'1:12%%' is valid - percentages are ignored"); ok( range->start == 1, "Start correct"); @@ -48,6 +74,14 @@ main (int argc, char **argv) ok( range->end_infinity == FALSE, "Not using infinity"); free(range); + range = _parse_range_string_v2("1:12%%"); + ok( range != NULL, "'1:12%%' is valid - percentages are ignored"); + ok( range->start == 1, "Start correct"); + ok( range->start_infinity == FALSE, "Not using negative infinity"); + ok( range->end == 12, "End correct"); + ok( range->end_infinity == FALSE, "Not using infinity"); + free(range); + range = parse_range_string("-7:23"); ok( range != NULL, "'-7:23' is valid range"); ok( range->start == -7, "Start correct"); @@ -56,6 +90,14 @@ main (int argc, char **argv) ok( range->end_infinity == FALSE, "Not using infinity"); free(range); + range = _parse_range_string_v2("-7:23"); + ok( range != NULL, "'-7:23' is valid range"); + ok( range->start == -7, "Start correct"); + ok( range->start_infinity == FALSE, "Not using negative infinity"); + ok( range->end == 23, "End correct"); + ok( range->end_infinity == FALSE, "Not using infinity"); + free(range); + range = parse_range_string(":5.75"); ok( range != NULL, "':5.75' is valid range"); ok( range->start == 0, "Start correct"); @@ -64,6 +106,14 @@ main (int argc, char **argv) ok( range->end_infinity == FALSE, "Not using infinity"); free(range); + range = _parse_range_string_v2(":5.75"); + ok( range != NULL, "':5.75' is valid range"); + ok( range->start == 0, "Start correct"); + ok( range->start_infinity == TRUE, "Using negative infinity"); + ok( range->end == 5.75, "End correct"); + ok( range->end_infinity == FALSE, "Not using infinity"); + free(range); + range = parse_range_string("~:-95.99"); ok( range != NULL, "~:-95.99' is valid range"); ok( range->start_infinity == TRUE, "Using negative infinity"); @@ -71,6 +121,26 @@ main (int argc, char **argv) ok( range->end_infinity == FALSE, "Not using infinity"); free(range); + range = _parse_range_string_v2("~:-95.99"); + ok( range == NULL, "~:-95.99' is invalid range"); + ok( utils_errno == NP_RANGE_UNPARSEABLE, "Correct error code" ); + + /* + * This is currently parseable. This is because ~ is interpreted as a 0 + * and then 95.99 is the end, so we get 0:95.99. Should validate the characters before + * passing to strtod + range = _parse_range_string_v2("~:95.99"); + ok( range == NULL, "~:95.99' is invalid range"); + ok( utils_errno == NP_RANGE_UNPARSEABLE, "Correct error code" ); + */ + + range = _parse_range_string_v2(":-95.99"); + ok( range != NULL, ":-95.99' is valid range"); + ok( range->start_infinity == TRUE, "Using negative infinity"); + ok( range->end == -95.99, "End correct (with rounding errors)"); + ok( range->end_infinity == FALSE, "Not using infinity"); + free(range); + range = parse_range_string("12345678901234567890:"); temp = atof("12345678901234567890"); /* Can't just use this because number too large */ ok( range != NULL, "'12345678901234567890:' is valid range"); @@ -83,6 +153,14 @@ main (int argc, char **argv) ok( check_range(temp*2, range) == FALSE, "12345678901234567890*2 - no alert"); free(range); + range = _parse_range_string_v2("12345678901234567890:"); + temp = atof("12345678901234567890"); + ok( range != NULL, "'12345678901234567890:' is valid range"); + ok( range->start == temp, "Start correct"); + ok( range->start_infinity == FALSE, "Not using negative infinity"); + ok( range->end_infinity == TRUE, "Using infinity"); + free(range); + range = parse_range_string("~:0"); ok( range != NULL, "'~:0' is valid range"); ok( range->start_infinity == TRUE, "Using negative infinity"); @@ -94,8 +172,16 @@ main (int argc, char **argv) ok( check_range(0, range) == FALSE, "0 - no alert"); free(range); + range = _parse_range_string_v2("-4.33:-4.33"); + ok( range != NULL, "'-4.33:-4.33' is valid range"); + ok( range->start_infinity == FALSE, "Not using negative infinity"); + ok( range->start == -4.33, "Start right"); + ok( range->end == -4.33, "End correct"); + ok( range->end_infinity == FALSE, "Not using infinity"); + free(range); + range = parse_range_string("@0:657.8210567"); - ok( range != 0, "@0:657.8210567' is a valid range"); + ok( range != NULL, "@0:657.8210567' is a valid range"); ok( range->start == 0, "Start correct"); ok( range->start_infinity == FALSE, "Not using negative infinity"); ok( range->end == 657.8210567, "End correct"); @@ -107,6 +193,14 @@ main (int argc, char **argv) ok( check_range(0, range) == TRUE, "0 - alert"); free(range); + range = parse_range_string("^0:657.8210567"); + ok( range != NULL, "^0:657.8210567' is a valid range"); + ok( range->start == 0, "Start correct"); + ok( range->start_infinity == FALSE, "Not using negative infinity"); + ok( range->end == 657.8210567, "End correct"); + ok( range->end_infinity == FALSE, "Not using infinity"); + free(range); + range = parse_range_string("1:1"); ok( range != NULL, "'1:1' is a valid range"); ok( range->start == 1, "Start correct"); @@ -121,22 +215,71 @@ main (int argc, char **argv) range = parse_range_string("2:1"); ok( range == NULL, "'2:1' rejected"); + range = _parse_range_string_v2("2:1"); + ok( range == NULL, "'2:1' rejected"); + ok( utils_errno == NP_RANGE_UNPARSEABLE, "Errno correct" ); + rc = _set_thresholds(&thresholds, NULL, NULL); ok( rc == 0, "Thresholds (NULL, NULL) set"); ok( thresholds->warning == NULL, "Warning not set"); ok( thresholds->critical == NULL, "Critical not set"); + thresholds = _parse_thresholds_string(NULL); + ok( thresholds != NULL, "Threshold still set, even though NULL"); + ok( thresholds->warning == NULL, "Warning set to NULL"); + ok( thresholds->critical == NULL, "Critical set to NULL"); + + thresholds = _parse_thresholds_string(""); + ok( thresholds != NULL, "Threshold still set, even though ''"); + ok( thresholds->warning == NULL, "Warning set to NULL"); + ok( thresholds->critical == NULL, "Critical set to NULL"); + + thresholds = _parse_thresholds_string("/"); + ok( thresholds != NULL, "Threshold still set, even though '/'"); + ok( thresholds->warning == NULL, "Warning set to NULL"); + ok( thresholds->critical == NULL, "Critical set to NULL"); + rc = _set_thresholds(&thresholds, NULL, "80"); ok( rc == 0, "Thresholds (NULL, '80') set"); ok( thresholds->warning == NULL, "Warning not set"); ok( thresholds->critical->end == 80, "Critical set correctly"); + thresholds = _parse_thresholds_string(":80/"); + ok( thresholds != NULL, "Threshold set for ':80/'"); + ok( thresholds->warning == NULL, "Warning set to NULL"); + ok( thresholds->critical->start_infinity == TRUE, "Start is right" ); + ok( thresholds->critical->end == 80, "Critical set to 80"); + + thresholds = _parse_thresholds_string(":80"); + ok( thresholds != NULL, "Threshold set for ':80'"); + ok( thresholds->warning == NULL, "Warning set to NULL"); + ok( thresholds->critical->start_infinity == TRUE, "Start is right" ); + ok( thresholds->critical->end == 80, "Critical set to 80"); + + thresholds = _parse_thresholds_string("80"); + ok( thresholds == NULL, "Threshold not set because of single value '80'"); + ok( utils_errno == NP_RANGE_MISSING_COLON, "Correct error message"); + rc = _set_thresholds(&thresholds, "5:33", NULL); ok( rc == 0, "Thresholds ('5:33', NULL) set"); ok( thresholds->warning->start == 5, "Warning start set"); ok( thresholds->warning->end == 33, "Warning end set"); ok( thresholds->critical == NULL, "Critical not set"); + thresholds = _parse_thresholds_string("5:33"); + ok( thresholds != NULL, "Threshold set for '5:33'"); + ok( thresholds->warning == NULL, "Warning set to NULL"); + ok( thresholds->critical->start_infinity == FALSE, "Start is right" ); + ok( thresholds->critical->start == 5, "Critical set to 5"); + ok( thresholds->critical->end == 33, "Critical set to 33"); + + thresholds = _parse_thresholds_string("/5:33"); + ok( thresholds != NULL, "Threshold set for '/5:33'"); + ok( thresholds->critical == NULL, "Critical set to NULL"); + ok( thresholds->warning->start_infinity == FALSE, "Start is right" ); + ok( thresholds->warning->start == 5, "Warning start set to 5"); + ok( thresholds->warning->end == 33, "Warning end set to 33"); + rc = _set_thresholds(&thresholds, "30", "60"); ok( rc == 0, "Thresholds ('30', '60') set"); ok( thresholds->warning->end == 30, "Warning set correctly"); @@ -145,6 +288,17 @@ main (int argc, char **argv) ok( get_status(30.0001, thresholds) == STATE_WARNING, "30.0001 - warning"); ok( get_status(69, thresholds) == STATE_CRITICAL, "69 - critical"); + thresholds = _parse_thresholds_string("-6.7:29 / 235.4:3333.33"); + ok( thresholds != NULL, "Threshold set for '-6.7:29 / 235.4:3333.33'"); + ok( thresholds->critical->start_infinity == FALSE, "Critical not starting at infinity"); + ok( thresholds->critical->start == -6.7, "Critical start right" ); + ok( thresholds->critical->end_infinity == FALSE, "Critical not ending at infinity"); + ok( thresholds->critical->end == 29, "Critical end right" ); + ok( thresholds->warning->start_infinity == FALSE, "Start is right" ); + ok( thresholds->warning->start == 235.4, "Warning set to 5"); + ok( thresholds->warning->end_infinity == FALSE, "End is right" ); + ok( thresholds->warning->end == 3333.33, "Warning set to 33"); + char *test; test = np_escaped_string("bob\\n"); ok( strcmp(test, "bob\n") == 0, "bob\\n ok"); diff --git a/lib/utils_base.c b/lib/utils_base.c index d1453c67..1320b712 100644 --- a/lib/utils_base.c +++ b/lib/utils_base.c @@ -98,6 +98,138 @@ range return NULL; } +/* New range string parsing routines, for the v2 thresholds syntax */ +/* Returns range if OK, otherwise errors. Sets utils_errno if error */ +int utils_errno; +range * +_parse_range_string_v2 (char *str) { + range *temp_range; + double start; + double end; + char *end_str; + + temp_range = (range *) malloc(sizeof(range)); + + /* Initialise */ + temp_range->start = 0; + temp_range->start_infinity = FALSE; + temp_range->end = 0; + temp_range->end_infinity = FALSE; + temp_range->alert_on = INSIDE; + + if (str[0] == '^') { + temp_range->alert_on = OUTSIDE; + str++; + } + + end_str = index(str, ':'); + if (end_str == NULL) { + utils_errno = NP_RANGE_MISSING_COLON; + free(temp_range); + temp_range = NULL; + return NULL; + } + end_str++; + if (str[0] == ':') { + temp_range->start_infinity = TRUE; + } else { + start = strtod(str, NULL); /* Will stop at ':' */ + set_range_start(temp_range, start); + } + if (strcmp(end_str, "") != 0) { + end = strtod(end_str, NULL); + set_range_end(temp_range, end); + } else { + temp_range->end_infinity = TRUE; + } + + if (temp_range->start_infinity == TRUE || + temp_range->end_infinity == TRUE || + temp_range->start <= temp_range->end) { + return temp_range; + } + free(temp_range); + temp_range = NULL; + utils_errno = NP_RANGE_UNPARSEABLE; + return NULL; +} + +void +_die_on_parse_error(int errorcode) { + switch (errorcode) { + case NP_RANGE_UNPARSEABLE: + die(STATE_UNKNOWN, _("Range format incorrect\n")); + case NP_WARN_WITHIN_CRIT: + die(STATE_UNKNOWN, _("Warning level is a subset of critical and will not be alerted\n")); + case NP_RANGE_MISSING_COLON: + die(STATE_UNKNOWN, _("Range is missing a colon\n")); + case NP_MEMORY_ERROR: + die(STATE_UNKNOWN, _("Memory error\n")); + } +} + +thresholds +*_parse_thresholds_string(char *string) { + thresholds *temp_thresholds = NULL; + char *separator = NULL; + char *temp_string = NULL; + range *temp_range = NULL; + int rc; + + temp_thresholds = malloc(sizeof(temp_thresholds)); + if (temp_thresholds == NULL) { + utils_errno = NP_MEMORY_ERROR; + return NULL; + } + + temp_thresholds->warning = NULL; + temp_thresholds->critical = NULL; + + if (string == NULL || strcmp(string, "") == 0) + return temp_thresholds; + + if((temp_string = strdup(string)) == NULL) { + free(temp_thresholds); + utils_errno = NP_MEMORY_ERROR; + return NULL; + } + + /* Find critical part and parse the range */ + separator = index(temp_string, '/'); + if (separator) { + *separator = '\0'; + separator++; + } + if ((strcmp(temp_string, "") != 0) && (temp_range = _parse_range_string_v2( temp_string )) == NULL) { + free(temp_thresholds); + free(temp_string); + /* utils_errno already set */ + return NULL; + } + temp_thresholds->critical = temp_range; + + if (separator == NULL || strcmp(separator, "") == 0) { + return temp_thresholds; + } + /* UOM not processed yet */ + if(( temp_range = _parse_range_string_v2( separator )) == NULL) { + free(temp_thresholds); + free(temp_string); + return NULL; + } + temp_thresholds->warning = temp_range; + return temp_thresholds; +} + +thresholds +*parse_thresholds_string(char *string) +{ + thresholds *my_threshold; + if ((my_threshold = _parse_thresholds_string(string)) == NULL) + _die_on_parse_error(utils_errno); + return my_threshold; +} + /* returns 0 if okay, otherwise 1 */ int _set_thresholds(thresholds **my_thresholds, char *warn_string, char *critical_string) @@ -139,8 +271,7 @@ set_thresholds(thresholds **my_thresholds, char *warn_string, char *critical_str } } -void print_thresholds(const char *threshold_name, thresholds *my_threshold) { - printf("%s - ", threshold_name); +void print_thresholds(thresholds *my_threshold) { if (! my_threshold) { printf("Threshold not set"); } else { diff --git a/lib/utils_base.h b/lib/utils_base.h index bda76595..c616c5bd 100644 --- a/lib/utils_base.h +++ b/lib/utils_base.h @@ -31,7 +31,7 @@ typedef struct thresholds_struct { range *parse_range_string (char *); int _set_thresholds(thresholds **, char *, char *); void set_thresholds(thresholds **, char *, char *); -void print_thresholds(const char *, thresholds *); +void print_thresholds(thresholds *); int check_range(double, range *); int get_status(double, thresholds *); @@ -39,9 +39,22 @@ char *np_escaped_string (const char *); void die (int, const char *, ...) __attribute__((noreturn,format(printf, 2, 3))); -/* Return codes for _set_thresholds */ -#define NP_RANGE_UNPARSEABLE 1 -#define NP_WARN_WITHIN_CRIT 2 + +/* Parses a threshold string, as entered from command line */ +/* Returns a malloc'd threshold* which can be freed */ +thresholds *parse_thresholds_string(char *); +thresholds * _parse_thresholds_string(char *); +void free_thresholds(thresholds *); +range * _parse_range_string_v2(char *); +int utils_errno; + + +/* Error codes */ +#define NP_RANGE_UNPARSEABLE 1 +#define NP_WARN_WITHIN_CRIT 2 +#define NP_RANGE_MISSING_COLON 3 +#define NP_THRESHOLD_UNPARSEABLE 4 +#define NP_MEMORY_ERROR 5 /* a simple check to see if we're running as root. * returns zero on failure, nonzero on success */ -- cgit v1.2.3-74-g34f1