From 7e65a60a5d69c59921a0a8fbf7866fb484a32e9f Mon Sep 17 00:00:00 2001 From: Alvar Penning Date: Fri, 9 May 2025 09:11:42 +0200 Subject: [PATCH] Fix PerfdataValue Counter Parsing Ensure that the counter unit of measurement, "c", is parsed correctly for performance data values again. A prior refactoring in 720a88c29a489cec91815af49755413202802d7a changed the parsing logic, resulting in an incorrect behavior for counter units. By passing the raw input into the l_CsUoMs map first, the "c" UoM is removed. Moving the explicit counter check before passing the raw unit into the map resolves this issue. Fixes #9540. --- lib/base/perfdatavalue.cpp | 9 +++++---- test/icinga-perfdata.cpp | 13 +++++++++++++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/lib/base/perfdatavalue.cpp b/lib/base/perfdatavalue.cpp index 217167e01..5c7c7622f 100644 --- a/lib/base/perfdatavalue.cpp +++ b/lib/base/perfdatavalue.cpp @@ -270,6 +270,11 @@ PerfdataValue::Ptr PerfdataValue::Parse(const String& perfdata) if (pos != String::NPos) unit = tokens[0].SubStr(pos, String::NPos); + // UoM.Out is an empty string for "c". So set counter before parsing. + if (unit == "c") { + counter = true; + } + double base; { @@ -295,10 +300,6 @@ PerfdataValue::Ptr PerfdataValue::Parse(const String& perfdata) } } - if (unit == "c") { - counter = true; - } - warn = ParseWarnCritMinMaxToken(tokens, 1, "warning"); crit = ParseWarnCritMinMaxToken(tokens, 2, "critical"); min = ParseWarnCritMinMaxToken(tokens, 3, "minimum"); diff --git a/test/icinga-perfdata.cpp b/test/icinga-perfdata.cpp index 68d0ea277..8bc97d4fa 100644 --- a/test/icinga-perfdata.cpp +++ b/test/icinga-perfdata.cpp @@ -285,6 +285,19 @@ BOOST_AUTO_TEST_CASE(uom) str = pv->Format(); BOOST_CHECK_EQUAL(str, "test=1W"); + + pv = PerfdataValue::Parse("test=42c"); + BOOST_CHECK(pv); + BOOST_CHECK_EQUAL(pv->GetValue(), 42); + BOOST_CHECK(pv->GetCounter()); + BOOST_CHECK_EQUAL(pv->GetUnit(), ""); + BOOST_CHECK_EQUAL(pv->GetCrit(), Empty); + BOOST_CHECK_EQUAL(pv->GetWarn(), Empty); + BOOST_CHECK_EQUAL(pv->GetMin(), Empty); + BOOST_CHECK_EQUAL(pv->GetMax(), Empty); + + str = pv->Format(); + BOOST_CHECK_EQUAL(str, "test=42c"); } BOOST_AUTO_TEST_CASE(warncritminmax)