blob: 6c685138056c2f9ef4fe46005bf98fe38cf0d6c7 [file] [log] [blame]
#include "helpers.hpp"
#include "metric.hpp"
#include "mocks/sensor_mock.hpp"
#include "params/metric_params.hpp"
#include "utils/conv_container.hpp"
#include "utils/conversion.hpp"
#include "utils/tstring.hpp"
#include <gmock/gmock.h>
using namespace testing;
using namespace std::chrono_literals;
namespace tstring = utils::tstring;
using Timestamp = uint64_t;
class TestMetric : public Test
{
public:
static std::vector<std::shared_ptr<SensorMock>>
makeSensorMocks(size_t amount)
{
std::vector<std::shared_ptr<SensorMock>> result;
for (size_t i = 0; i < amount; ++i)
{
result.emplace_back(std::make_shared<NiceMock<SensorMock>>());
}
return result;
}
std::shared_ptr<Metric> makeSut(const MetricParams& p)
{
return std::make_shared<Metric>(
utils::convContainer<std::shared_ptr<interfaces::Sensor>>(
sensorMocks),
p.operationType(), p.id(), p.metadata(), p.collectionTimeScope(),
p.collectionDuration());
}
MetricParams params =
MetricParams()
.id("id")
.metadata("metadata")
.operationType(OperationType::avg)
.collectionTimeScope(CollectionTimeScope::interval)
.collectionDuration(CollectionDuration(42ms));
std::vector<std::shared_ptr<SensorMock>> sensorMocks = makeSensorMocks(1u);
std::shared_ptr<Metric> sut;
};
TEST_F(TestMetric, subscribesForSensorDuringInitialization)
{
sut = makeSut(params);
EXPECT_CALL(*sensorMocks.front(),
registerForUpdates(Truly([sut = sut.get()](const auto& a0) {
return a0.lock().get() == sut;
})));
sut->initialize();
}
TEST_F(TestMetric, containsEmptyReadingAfterCreated)
{
sut = makeSut(params);
ASSERT_THAT(sut->getReadings(),
ElementsAre(MetricValue({"id", "metadata", 0., 0u})));
}
TEST_F(TestMetric, parsesSensorMetadata)
{
using ReadingMetadata =
utils::LabeledTuple<std::tuple<std::string, std::string>,
utils::tstring::SensorDbusPath,
utils::tstring::SensorRedfishUri>;
nlohmann::json metadata;
metadata["MetricProperties"] = {"sensor1", "sensor2"};
sensorMocks = makeSensorMocks(2);
sut = makeSut(params.metadata(metadata.dump()));
EXPECT_THAT(
sut->getReadings(),
ElementsAre(
MetricValue{"id", ReadingMetadata("", "sensor1").dump(), 0., 0u},
MetricValue{"id", ReadingMetadata("", "sensor2").dump(), 0., 0u}));
}
TEST_F(TestMetric, parsesSensorMetadataWhenMoreMetadataThanSensors)
{
nlohmann::json metadata;
metadata["MetricProperties"] = {"sensor1", "sensor2"};
sensorMocks = makeSensorMocks(1);
sut = makeSut(params.metadata(metadata.dump()));
EXPECT_THAT(sut->getReadings(),
ElementsAre(MetricValue{"id", metadata.dump(), 0., 0u}));
}
TEST_F(TestMetric, parsesSensorMetadataWhenMoreSensorsThanMetadata)
{
nlohmann::json metadata;
metadata["MetricProperties"] = {"sensor1"};
sensorMocks = makeSensorMocks(2);
sut = makeSut(params.metadata(metadata.dump()));
EXPECT_THAT(sut->getReadings(),
ElementsAre(MetricValue{"id", metadata.dump(), 0., 0u},
MetricValue{"id", metadata.dump(), 0., 0u}));
}
class TestMetricAfterInitialization : public TestMetric
{
public:
void SetUp() override
{
sut = makeSut(params);
sut->initialize();
}
};
TEST_F(TestMetricAfterInitialization, containsEmptyReading)
{
ASSERT_THAT(sut->getReadings(),
ElementsAre(MetricValue({"id", "metadata", 0., 0u})));
}
TEST_F(TestMetricAfterInitialization, updatesMetricValuesOnSensorUpdate)
{
sut->sensorUpdated(*sensorMocks.front(), Timestamp{18}, 31.2);
ASSERT_THAT(sut->getReadings(),
ElementsAre(MetricValue{"id", "metadata", 31.2, 18u}));
}
TEST_F(TestMetricAfterInitialization,
throwsWhenUpdateIsPerformedOnUnknownSensor)
{
auto sensor = std::make_shared<StrictMock<SensorMock>>();
EXPECT_THROW(sut->sensorUpdated(*sensor, Timestamp{10}), std::out_of_range);
EXPECT_THROW(sut->sensorUpdated(*sensor, Timestamp{10}, 20.0),
std::out_of_range);
}
TEST_F(TestMetricAfterInitialization, dumpsConfiguration)
{
namespace ts = utils::tstring;
ON_CALL(*sensorMocks.front(), id())
.WillByDefault(Return(SensorMock::makeId("service1", "path1")));
const auto conf = sut->dumpConfiguration();
LabeledMetricParameters expected = {};
expected.at_label<ts::Id>() = "id";
expected.at_label<ts::MetricMetadata>() = "metadata";
expected.at_label<ts::OperationType>() = OperationType::avg;
expected.at_label<ts::CollectionTimeScope>() =
CollectionTimeScope::interval;
expected.at_label<ts::CollectionDuration>() = CollectionDuration(42ms);
expected.at_label<ts::SensorPath>() = {
LabeledSensorParameters("service1", "path1")};
EXPECT_THAT(conf, Eq(expected));
}