Merge pull request #8827 from Icinga/bugfix/perfdata-e-exponent-unit-prefix

Allow using E in perfdata both as exponent and unit prefix
This commit is contained in:
Alexander Aleksandrovič Klimov 2021-06-08 18:00:02 +02:00 committed by GitHub
commit b09d16a385
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 38 additions and 6 deletions

View File

@ -243,23 +243,28 @@ PerfdataValue::Ptr PerfdataValue::Parse(const String& perfdata)
spq = perfdata.GetLength();
String valueStr = perfdata.SubStr(eqp + 1, spq - eqp - 1);
std::vector<String> tokens = valueStr.Split(";");
size_t pos = valueStr.FindFirstNotOf("+-0123456789.eE");
if (pos != String::NPos && valueStr[pos] == ',') {
if (valueStr.FindFirstOf(',') != String::NPos || tokens.empty()) {
BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid performance data value: " + perfdata));
}
double value = Convert::ToDouble(valueStr.SubStr(0, pos));
// Find the position where to split value and unit. Possible values of tokens[0] include:
// "1000", "1.0", "1.", "-.1", "+1", "1e10", "1GB", "1e10GB", "1e10EB", "1E10EB", "1.5GB", "1.GB", "+1.E-1EW"
// Consider everything up to and including the last digit or decimal point as part of the value.
size_t pos = tokens[0].FindLastOf("0123456789.");
if (pos != String::NPos) {
pos++;
}
std::vector<String> tokens = valueStr.Split(";");
double value = Convert::ToDouble(tokens[0].SubStr(0, pos));
bool counter = false;
String unit;
Value warn, crit, min, max;
if (pos != String::NPos)
unit = valueStr.SubStr(pos, tokens[0].GetLength() - pos);
unit = tokens[0].SubStr(pos, String::NPos);
double base;

View File

@ -147,6 +147,7 @@ add_boost_test(base
icinga_perfdata/invalid
icinga_perfdata/multi
icinga_perfdata/scientificnotation
icinga_perfdata/parse_edgecases
remote_url/id_and_path
remote_url/parameters
remote_url/get_and_set

View File

@ -296,6 +296,13 @@ BOOST_AUTO_TEST_CASE(invalid)
{
BOOST_CHECK_THROW(PerfdataValue::Parse("123456"), boost::exception);
BOOST_CHECK_THROW(PerfdataValue::Parse("test=1,23456"), boost::exception);
BOOST_CHECK_THROW(PerfdataValue::Parse("test=123_456"), boost::exception);
BOOST_CHECK_THROW(PerfdataValue::Parse("test="), boost::exception);
BOOST_CHECK_THROW(PerfdataValue::Parse("test=123,456;1;1;1;1"), boost::exception);
BOOST_CHECK_THROW(PerfdataValue::Parse("test=1;123,456;1;1;1"), boost::exception);
BOOST_CHECK_THROW(PerfdataValue::Parse("test=1;1;123,456;1;1"), boost::exception);
BOOST_CHECK_THROW(PerfdataValue::Parse("test=1;1;1;123,456;1"), boost::exception);
BOOST_CHECK_THROW(PerfdataValue::Parse("test=1;1;1;1;123,456"), boost::exception);
}
BOOST_AUTO_TEST_CASE(multi)
@ -354,4 +361,23 @@ BOOST_AUTO_TEST_CASE(scientificnotation)
BOOST_CHECK(str == "test=0.110000;12;0.130000;0.014000;150");
}
BOOST_AUTO_TEST_CASE(parse_edgecases)
{
// Trailing decimal point
PerfdataValue::Ptr pv = PerfdataValue::Parse("test=23.");
BOOST_CHECK(pv);
BOOST_CHECK(pv->GetValue() == 23.0);
// Leading decimal point
pv = PerfdataValue::Parse("test=.42");
BOOST_CHECK(pv);
BOOST_CHECK(pv->GetValue() == 0.42);
// E both as exponent and unit prefix
pv = PerfdataValue::Parse("test=+1.5E-15EB");
BOOST_CHECK(pv);
BOOST_CHECK(pv->GetValue() == 1.5e3);
BOOST_CHECK(pv->GetUnit() == "bytes");
}
BOOST_AUTO_TEST_SUITE_END()