blob: 8738bde90507a2b1fd84cb756605570564d00f61 [file] [log] [blame]
#include "dbus_environment.hpp"
#include "helpers.hpp"
#include "mocks/sensor_listener_mock.hpp"
#include "sensor.hpp"
#include "sensor_cache.hpp"
#include "stubs/dbus_sensor_object.hpp"
#include "utils/clock.hpp"
#include <sdbusplus/asio/property.hpp>
#include <thread>
#include <gmock/gmock.h>
using namespace testing;
using namespace std::chrono_literals;
class TestSensor : public Test
{
public:
void SetUp() override
{
sensorObject->setValue(42.7);
}
void TearDown() override
{
DbusEnvironment::synchronizeIoc();
}
void
registerForUpdates(std::shared_ptr<interfaces::SensorListener> listener)
{
sut->registerForUpdates(listener);
DbusEnvironment::synchronizeIoc();
}
void unregisterFromUpdates(
std::shared_ptr<interfaces::SensorListener> listener)
{
sut->unregisterFromUpdates(listener);
DbusEnvironment::synchronizeIoc();
}
static std::unique_ptr<stubs::DbusSensorObject> makeSensorObject()
{
return std::make_unique<stubs::DbusSensorObject>(
DbusEnvironment::getIoc(), DbusEnvironment::getBus(),
DbusEnvironment::getObjServer());
}
std::unique_ptr<stubs::DbusSensorObject> sensorObject = makeSensorObject();
SensorCache sensorCache;
Milliseconds timestamp = Clock().steadyTimestamp();
std::shared_ptr<Sensor> sut = sensorCache.makeSensor<Sensor>(
DbusEnvironment::serviceName(), sensorObject->path(), "metadata",
DbusEnvironment::getIoc(), DbusEnvironment::getBus());
std::shared_ptr<SensorListenerMock> listenerMock =
std::make_shared<StrictMock<SensorListenerMock>>();
std::shared_ptr<SensorListenerMock> listenerMock2 =
std::make_shared<StrictMock<SensorListenerMock>>();
MockFunction<void()> checkPoint;
};
TEST_F(TestSensor, createsCorretlyViaSensorCache)
{
ASSERT_THAT(sut->id(),
Eq(Sensor::Id("Sensor", DbusEnvironment::serviceName(),
sensorObject->path())));
}
TEST_F(TestSensor, notifiesWithValueAfterRegister)
{
EXPECT_CALL(*listenerMock, sensorUpdated(Ref(*sut), Ge(timestamp), 42.7))
.WillOnce(InvokeWithoutArgs(DbusEnvironment::setPromise("async_read")));
registerForUpdates(listenerMock);
ASSERT_TRUE(DbusEnvironment::waitForFuture("async_read"));
}
TEST_F(TestSensor, notifiesOnceWithValueAfterRegister)
{
EXPECT_CALL(*listenerMock, sensorUpdated(Ref(*sut), Ge(timestamp), 42.7))
.WillOnce(InvokeWithoutArgs(DbusEnvironment::setPromise("async_read")));
EXPECT_CALL(*listenerMock2, sensorUpdated(Ref(*sut), Ge(timestamp), 42.7))
.WillOnce(
InvokeWithoutArgs(DbusEnvironment::setPromise("async_read2")));
DbusEnvironment::synchronizedPost([this] {
sut->registerForUpdates(listenerMock);
sut->registerForUpdates(listenerMock2);
});
ASSERT_TRUE(DbusEnvironment::waitForFuture("async_read"));
ASSERT_TRUE(DbusEnvironment::waitForFuture("async_read2"));
}
TEST_F(TestSensor, getLabeledInfoReturnsCorrectly)
{
auto expected = LabeledSensorInfo(DbusEnvironment::serviceName(),
sensorObject->path(), "metadata");
EXPECT_EQ(sut->getLabeledSensorInfo(), expected);
}
TEST_F(TestSensor, getNameReturnsPathWhenMetadataIsNotSet)
{
static const char* path = "/telemetry/ut/DbusSensorObject2";
sut = sensorCache.makeSensor<Sensor>(DbusEnvironment::serviceName(), path,
"", DbusEnvironment::getIoc(),
DbusEnvironment::getBus());
EXPECT_EQ(sut->getName(), path);
}
TEST_F(TestSensor, getNameReturnsMetadataWhenMetadataIsSet)
{
static const char* path = "/telemetry/ut/DbusSensorObject2";
sut = sensorCache.makeSensor<Sensor>(DbusEnvironment::serviceName(), path,
"metadata2", DbusEnvironment::getIoc(),
DbusEnvironment::getBus());
EXPECT_EQ(sut->getName(), "metadata2");
}
class TestSensorNotification : public TestSensor
{
public:
void SetUp() override
{
EXPECT_CALL(*listenerMock, sensorUpdated(Ref(*sut), Ge(timestamp), 0.))
.WillOnce(
InvokeWithoutArgs(DbusEnvironment::setPromise("async_read")));
registerForUpdates(listenerMock);
ASSERT_TRUE(DbusEnvironment::waitForFuture("async_read"));
}
};
TEST_F(TestSensorNotification, notifiesListenerWithValueWhenChangeOccurs)
{
EXPECT_CALL(*listenerMock, sensorUpdated(Ref(*sut), Ge(timestamp), 42.7))
.WillOnce(InvokeWithoutArgs(DbusEnvironment::setPromise("notify")));
sensorObject->setValue(42.7);
ASSERT_TRUE(DbusEnvironment::waitForFuture("notify"));
}
TEST_F(TestSensorNotification, doesntNotifyListenerWhenNoChangeOccurs)
{
EXPECT_CALL(*listenerMock, sensorUpdated(Ref(*sut), Ge(timestamp), 42.7))
.WillOnce(InvokeWithoutArgs(DbusEnvironment::setPromise("notify")));
sensorObject->setValue(42.7);
sensorObject->setValue(42.7);
ASSERT_TRUE(DbusEnvironment::waitForFuture("notify"));
}
TEST_F(TestSensorNotification, doesntNotifyExpiredListener)
{
InSequence seq;
EXPECT_CALL(*listenerMock2, sensorUpdated(Ref(*sut), Ge(timestamp), 0.));
EXPECT_CALL(*listenerMock2, sensorUpdated(Ref(*sut), Ge(timestamp), 42.7))
.WillOnce(InvokeWithoutArgs(DbusEnvironment::setPromise("notify")));
registerForUpdates(listenerMock2);
listenerMock = nullptr;
sensorObject->setValue(42.7);
ASSERT_TRUE(DbusEnvironment::waitForFuture("notify"));
}
TEST_F(TestSensorNotification, notifiesWithValueDuringRegister)
{
EXPECT_CALL(*listenerMock2, sensorUpdated(Ref(*sut), Ge(timestamp), 0.));
registerForUpdates(listenerMock2);
}
TEST_F(TestSensorNotification, notNotifiesWithValueWhenUnregistered)
{
EXPECT_CALL(*listenerMock2, sensorUpdated(Ref(*sut), Ge(timestamp), 0.));
EXPECT_CALL(*listenerMock, sensorUpdated(Ref(*sut), Ge(timestamp), 42.7))
.Times(0);
EXPECT_CALL(*listenerMock2, sensorUpdated(Ref(*sut), Ge(timestamp), 42.7))
.WillOnce(InvokeWithoutArgs(DbusEnvironment::setPromise("notify")));
registerForUpdates(listenerMock2);
unregisterFromUpdates(listenerMock);
sensorObject->setValue(42.7);
ASSERT_TRUE(DbusEnvironment::waitForFuture("notify"));
}
TEST_F(TestSensorNotification,
dbusSensorIsAddedToSystemAfterSensorIsCreatedThenValueIsUpdated)
{
InSequence seq;
EXPECT_CALL(*listenerMock,
sensorUpdated(Ref(*sut), Ge(timestamp), DoubleEq(42.7)))
.WillOnce(
InvokeWithoutArgs(DbusEnvironment::setPromise("notify-change")));
EXPECT_CALL(checkPoint, Call());
EXPECT_CALL(*listenerMock,
sensorUpdated(Ref(*sut), Ge(timestamp), DoubleEq(0.)))
.WillOnce(
InvokeWithoutArgs(DbusEnvironment::setPromise("notify-create")));
sensorObject->setValue(42.7);
DbusEnvironment::waitForFuture("notify-change");
checkPoint.Call();
sensorObject = nullptr;
sensorObject = makeSensorObject();
DbusEnvironment::waitForFuture("notify-create");
}