diff --git a/src/telemetry/aggregator/aggMinMax.cpp b/src/telemetry/aggregator/aggMinMax.cpp index 09f1cb3..e6bc19e 100644 --- a/src/telemetry/aggregator/aggMinMax.cpp +++ b/src/telemetry/aggregator/aggMinMax.cpp @@ -177,3 +177,7 @@ Content AggMethodMinMax::aggregate(const std::vector& contents) } } // namespace telemetry + +#ifdef TELEMETRY_ENABLE_TESTS +#include "tests/testAggMinMax.cpp" +#endif diff --git a/src/telemetry/aggregator/tests/testAggMinMax.cpp b/src/telemetry/aggregator/tests/testAggMinMax.cpp new file mode 100644 index 0000000..6559554 --- /dev/null +++ b/src/telemetry/aggregator/tests/testAggMinMax.cpp @@ -0,0 +1,292 @@ +/** + * @file + * @author Pavel Siska + * @brief Unit tests of Telemetry::AggMethodMinMax + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include + +namespace telemetry { + +/** + * @test Test find min of scalar values + */ +TEST(AggMinMaxTest, TestFindMin) +{ + // Test find min of uint64_t scalar + { + Scalar result = uint64_t(10); + findMin(uint64_t(1), result); + EXPECT_EQ(uint64_t(1), std::get(result)); + } + + // Test find min of int64_t scalar + { + Scalar result = int64_t(10); + findMin(int64_t(5), result); + EXPECT_EQ(int64_t(5), std::get(result)); + } + + // Test find min of double scalar + { + Scalar result = double(1.0); + findMin(double(5.0), result); + EXPECT_EQ(double(1.0), std::get(result)); + } + + // Test find min of scalar types with different types (expect failure) + { + Scalar result = uint64_t(5); + EXPECT_THROW(findMin(int64_t(5), result), std::exception); + } +} + +/** + * @test Test find max of scalar values + */ +TEST(AggMinMaxTest, TestFindMax) +{ + // Test find max of uint64_t scalar + { + Scalar result = uint64_t(1); + findMax(uint64_t(10), result); + EXPECT_EQ(uint64_t(10), std::get(result)); + } + + // Test find max of int64_t scalar + { + Scalar result = int64_t(1); + findMax(int64_t(5), result); + EXPECT_EQ(int64_t(5), std::get(result)); + } + + // Test find max of double scalar + { + Scalar result = double(1.0); + findMax(double(5.0), result); + EXPECT_EQ(double(5.0), std::get(result)); + } + + // Test find max of scalar types with different types (expect failure) + { + Scalar result = uint64_t(5); + EXPECT_THROW(findMax(int64_t(5), result), std::exception); + } +} + +/** + * @test Test aggregation of scalar values + */ +TEST(AggMinMaxTest, TestAggregateScalar) +{ + const AggMethodMinMax::AggMethod minMethod = findMin; + const AggMethodMinMax::AggMethod maxMethod = findMax; + + // Test aggregation of scalar values (min) + { + std::vector values = {Scalar {5.0}, Scalar {10.0}, Scalar {15.0}}; + Scalar result = aggregateScalar(values, minMethod); + EXPECT_EQ(Scalar {5.0}, result); + } + + // Test aggregation of scalar values (max) + { + std::vector values = {Scalar {5.0}, Scalar {15.0}, Scalar {10.0}}; + Scalar result = aggregateScalar(values, maxMethod); + EXPECT_EQ(Scalar {15.0}, result); + } + + // Test aggregation of ScalarWithUnit values (expect failure) + { + std::vector values = {ScalarWithUnit {5.0, "unit"}}; + EXPECT_THROW(aggregateScalar(values, minMethod), TelemetryException); + } + + // Test aggregation of empty vector + { + std::vector values = {}; + Scalar result = aggregateScalar(values, maxMethod); + EXPECT_TRUE(std::holds_alternative(result)); + } +} + +/** + * @test Test aggregation of scalar values with units + */ +TEST(AggMinMaxTest, TestAggregateScalarWithUnit) +{ + const AggMethodMinMax::AggMethod minMethod = findMin; + const AggMethodMinMax::AggMethod maxMethod = findMax; + + // Test aggregation of scalar values with unit (min) + { + std::vector values + = {ScalarWithUnit {5.0, "unit"}, + ScalarWithUnit {-10.0, "unit"}, + ScalarWithUnit {15.0, "unit"}}; + const auto& [scalar, unit] = aggregateScalarWithUnit(values, minMethod); + EXPECT_EQ(std::get(scalar), -10.0); + EXPECT_EQ(unit, "unit"); + } + + // Test aggregation of scalar values with unit (max) + { + std::vector values + = {ScalarWithUnit {5.0, "unit"}, + ScalarWithUnit {10.0, "unit"}, + ScalarWithUnit {150.0, "unit"}}; + const auto& [scalar, unit] = aggregateScalarWithUnit(values, maxMethod); + EXPECT_EQ(std::get(scalar), 150.0); + EXPECT_EQ(unit, "unit"); + } + + // Test aggregation of Scalar values (expect failure) + { + std::vector values = {Scalar {5.0}}; + EXPECT_THROW(aggregateScalarWithUnit(values, maxMethod), TelemetryException); + } + + // Test aggregation of empty vector + { + std::vector values = {}; + const auto& [scalar, unit] = aggregateScalarWithUnit(values, maxMethod); + EXPECT_TRUE(std::holds_alternative(scalar)); + EXPECT_EQ(unit, ""); + } +} + +/** + * @test Test creation of dictionary content + */ +TEST(AggMinMaxTest, TestCreateDictContent) +{ + ResultType result = Scalar {uint64_t(30)}; + Content content = createDictContent("min", result); + + EXPECT_TRUE(std::holds_alternative(content)); + + Dict& contentDict = std::get(content); + EXPECT_EQ(1, contentDict.size()); + + auto iter = contentDict.cbegin(); + { + const auto& [key, value] = *(iter++); + EXPECT_EQ("min", key); + EXPECT_TRUE(std::holds_alternative(value)); + const auto& scalar = std::get(value); + EXPECT_TRUE(std::holds_alternative(scalar)); + EXPECT_EQ(uint64_t(30), std::get(scalar)); + } +} + +/** + * @test Test aggregation method for sum + */ +TEST(AggMinMaxTest, TestAggregate) +{ + // Test aggregation of scalar values (min) + { + AggMethodMinMax aggMethodMin(AggMethodType::MIN); + std::vector contents = {Scalar {5.0}, Scalar {100.0}, Scalar {-105.0}}; + Content content = aggMethodMin.aggregate(contents); + EXPECT_TRUE(std::holds_alternative(content)); + Scalar& scalar = std::get(content); + EXPECT_TRUE(std::holds_alternative(scalar)); + double result = std::get(scalar); + EXPECT_EQ(-105.0, result); + } + + // Test aggregation of scalar values (max) + { + AggMethodMinMax aggMethodMax(AggMethodType::MAX); + std::vector contents = {Scalar {5.0}, Scalar {100.0}, Scalar {-105.0}}; + Content content = aggMethodMax.aggregate(contents); + EXPECT_TRUE(std::holds_alternative(content)); + Scalar& scalar = std::get(content); + EXPECT_TRUE(std::holds_alternative(scalar)); + double result = std::get(scalar); + EXPECT_EQ(100.0, result); + } + + // Test aggregation of ScalarWithUnit values (min) + { + AggMethodMinMax aggMethodMin(AggMethodType::MIN); + std::vector contents = {ScalarWithUnit {5.0, "unit"}}; + Content content = aggMethodMin.aggregate(contents); + EXPECT_TRUE(std::holds_alternative(content)); + const auto& [scalar, unit] = std::get(content); + EXPECT_EQ(5.0, std::get(scalar)); + EXPECT_EQ("unit", unit); + } + + // Test aggregation of mixed types (expect failure) + { + AggMethodMinMax aggMethodMin(AggMethodType::MIN); + std::vector contents = {ScalarWithUnit {5.0, "unit"}, Scalar {5.0}}; + EXPECT_THROW(aggMethodMin.aggregate(contents), TelemetryException); + } + + // Test aggregation of incompatible types (expect failure) + { + AggMethodMinMax aggMethodMin(AggMethodType::MIN); + std::vector contents = {Scalar {true}, Scalar {5.0}}; + EXPECT_THROW(aggMethodMin.aggregate(contents), TelemetryException); + } + + // Test aggregation of incompatible scalar types (expect failure) + { + AggMethodMinMax aggMethodMin(AggMethodType::MIN); + std::vector contents = {Scalar {uint64_t(20)}, Scalar {5.0}}; + EXPECT_THROW(aggMethodMin.aggregate(contents), TelemetryException); + } + + // Test aggregation of scalar and uint64_t types + { + AggMethodMinMax aggMethodMax(AggMethodType::MAX); + std::vector contents = {Scalar {uint64_t(20)}, uint64_t {5}}; + Content content = aggMethodMax.aggregate(contents); + EXPECT_TRUE(std::holds_alternative(content)); + const auto& scalar = std::get(content); + EXPECT_EQ(20, std::get(scalar)); + } + + // Test aggregation of dictionary values (min) + { + AggMethodMinMax aggMethodMin(AggMethodType::MIN); + aggMethodMin.setDictField("packets", "packetsSum"); + std::vector contents + = {Dict({{"packets", Scalar {uint64_t(1)}}}), + Dict({{"packets", Scalar {uint64_t(5)}}})}; + Content content = aggMethodMin.aggregate(contents); + EXPECT_TRUE(std::holds_alternative(content)); + + const Dict& dict = std::get(content); + EXPECT_EQ(1, dict.size()); + + const Scalar& scalarValueSum = std::get(dict.at("packetsSum")); + EXPECT_EQ(uint64_t(1), std::get(scalarValueSum)); + } + + // Test aggregation of dictionary values (max) + { + AggMethodMinMax aggMethodMax(AggMethodType::MAX); + aggMethodMax.setDictField("packets", "packetsSum"); + std::vector contents + = {Dict({{"packets", Scalar {uint64_t(1)}}}), + Dict({{"packets", Scalar {uint64_t(5)}}})}; + Content content = aggMethodMax.aggregate(contents); + EXPECT_TRUE(std::holds_alternative(content)); + + const Dict& dict = std::get(content); + EXPECT_EQ(1, dict.size()); + + const Scalar& scalarValueSum = std::get(dict.at("packetsSum")); + EXPECT_EQ(uint64_t(5), std::get(scalarValueSum)); + } +} + +} // namespace telemetry