xref: /openbmc/phosphor-pid-control/test/dbus_passive_unittest.cpp (revision 6b9f59991b7f694866c98775b4179ae97c5e69a8)
175eb769dSJames Feist #include "conf.hpp"
20ef1faf7SPatrick Venture #include "dbus/dbuspassive.hpp"
3da4a5dd1SPatrick Venture #include "test/dbushelper_mock.hpp"
40ef1faf7SPatrick Venture 
5*6b9f5999SPatrick Venture #include <functional>
60ef1faf7SPatrick Venture #include <sdbusplus/test/sdbus_mock.hpp>
70ef1faf7SPatrick Venture #include <string>
81f802f5eSJames Feist #include <variant>
90ef1faf7SPatrick Venture 
10da4a5dd1SPatrick Venture #include <gmock/gmock.h>
11da4a5dd1SPatrick Venture #include <gtest/gtest.h>
120ef1faf7SPatrick Venture 
13da4a5dd1SPatrick Venture using ::testing::_;
140ef1faf7SPatrick Venture using ::testing::InSequence;
150ef1faf7SPatrick Venture using ::testing::Invoke;
160ef1faf7SPatrick Venture using ::testing::IsNull;
170ef1faf7SPatrick Venture using ::testing::NotNull;
180ef1faf7SPatrick Venture using ::testing::Return;
190ef1faf7SPatrick Venture using ::testing::StrEq;
200ef1faf7SPatrick Venture 
210ef1faf7SPatrick Venture std::string SensorIntf = "xyz.openbmc_project.Sensor.Value";
220ef1faf7SPatrick Venture 
23da4a5dd1SPatrick Venture TEST(DbusPassiveTest, FactoryFailsWithInvalidType)
24da4a5dd1SPatrick Venture {
250ef1faf7SPatrick Venture     // Verify the type is checked by the factory.
260ef1faf7SPatrick Venture 
270ef1faf7SPatrick Venture     sdbusplus::SdBusMock sdbus_mock;
280ef1faf7SPatrick Venture     auto bus_mock = sdbusplus::get_mocked_new(&sdbus_mock);
290ef1faf7SPatrick Venture     std::string type = "invalid";
300ef1faf7SPatrick Venture     std::string id = "id";
310ef1faf7SPatrick Venture 
320ef1faf7SPatrick Venture     DbusHelperMock helper;
33f81f2886SJames Feist     auto info = conf::SensorConfig();
340ef1faf7SPatrick Venture 
3598b704e1SJames Feist     std::unique_ptr<ReadInterface> ri = DbusPassive::createDbusPassive(
3698b704e1SJames Feist         bus_mock, type, id, &helper, &info, nullptr);
370ef1faf7SPatrick Venture 
380ef1faf7SPatrick Venture     EXPECT_EQ(ri, nullptr);
390ef1faf7SPatrick Venture }
400ef1faf7SPatrick Venture 
41da4a5dd1SPatrick Venture TEST(DbusPassiveTest, BoringConstructorTest)
42da4a5dd1SPatrick Venture {
43f8cb4644SPatrick Venture     // Simply build the object, does no error checking.
440ef1faf7SPatrick Venture 
450ef1faf7SPatrick Venture     sdbusplus::SdBusMock sdbus_mock;
460ef1faf7SPatrick Venture     auto bus_mock = sdbusplus::get_mocked_new(&sdbus_mock);
470ef1faf7SPatrick Venture     std::string type = "invalid";
480ef1faf7SPatrick Venture     std::string id = "id";
490ef1faf7SPatrick Venture     std::string path = "/xyz/openbmc_project/sensors/unknown/id";
500ef1faf7SPatrick Venture 
510ef1faf7SPatrick Venture     DbusHelperMock helper;
52f8cb4644SPatrick Venture     struct SensorProperties properties;
530ef1faf7SPatrick Venture 
5498b704e1SJames Feist     DbusPassive(bus_mock, type, id, &helper, properties, false, path, nullptr);
550ef1faf7SPatrick Venture     // Success
560ef1faf7SPatrick Venture }
570ef1faf7SPatrick Venture 
58da4a5dd1SPatrick Venture class DbusPassiveTestObj : public ::testing::Test
59da4a5dd1SPatrick Venture {
600ef1faf7SPatrick Venture   protected:
61da4a5dd1SPatrick Venture     DbusPassiveTestObj() :
62da4a5dd1SPatrick Venture         sdbus_mock(),
63da4a5dd1SPatrick Venture         bus_mock(std::move(sdbusplus::get_mocked_new(&sdbus_mock))), helper()
640ef1faf7SPatrick Venture     {
65563a356fSPatrick Venture         EXPECT_CALL(helper, getService(_, StrEq(SensorIntf), StrEq(path)))
660ef1faf7SPatrick Venture             .WillOnce(Return("asdf"));
670ef1faf7SPatrick Venture 
68da4a5dd1SPatrick Venture         EXPECT_CALL(helper,
69563a356fSPatrick Venture                     getProperties(_, StrEq("asdf"), StrEq(path), NotNull()))
70da4a5dd1SPatrick Venture             .WillOnce(Invoke(
71da4a5dd1SPatrick Venture                 [&](sdbusplus::bus::bus& bus, const std::string& service,
72da4a5dd1SPatrick Venture                     const std::string& path, struct SensorProperties* prop) {
730ef1faf7SPatrick Venture                     prop->scale = _scale;
740ef1faf7SPatrick Venture                     prop->value = _value;
750ef1faf7SPatrick Venture                     prop->unit = "x";
76*6b9f5999SPatrick Venture                     prop->min = 0;
77*6b9f5999SPatrick Venture                     prop->max = 0;
780ef1faf7SPatrick Venture                 }));
79563a356fSPatrick Venture         EXPECT_CALL(helper, thresholdsAsserted(_, StrEq("asdf"), StrEq(path)))
8036b7d8ebSJames Feist             .WillOnce(Return(false));
810ef1faf7SPatrick Venture 
82f81f2886SJames Feist         auto info = conf::SensorConfig();
8398b704e1SJames Feist         ri = DbusPassive::createDbusPassive(bus_mock, type, id, &helper, &info,
8498b704e1SJames Feist                                             nullptr);
850ef1faf7SPatrick Venture         passive = reinterpret_cast<DbusPassive*>(ri.get());
860ef1faf7SPatrick Venture         EXPECT_FALSE(passive == nullptr);
870ef1faf7SPatrick Venture     }
880ef1faf7SPatrick Venture 
890ef1faf7SPatrick Venture     sdbusplus::SdBusMock sdbus_mock;
900ef1faf7SPatrick Venture     sdbusplus::bus::bus bus_mock;
910ef1faf7SPatrick Venture     DbusHelperMock helper;
920ef1faf7SPatrick Venture     std::string type = "temp";
930ef1faf7SPatrick Venture     std::string id = "id";
940ef1faf7SPatrick Venture     std::string path = "/xyz/openbmc_project/sensors/temperature/id";
950ef1faf7SPatrick Venture     int64_t _scale = -3;
960ef1faf7SPatrick Venture     int64_t _value = 10;
970ef1faf7SPatrick Venture 
980ef1faf7SPatrick Venture     std::unique_ptr<ReadInterface> ri;
990ef1faf7SPatrick Venture     DbusPassive* passive;
1000ef1faf7SPatrick Venture };
1010ef1faf7SPatrick Venture 
102da4a5dd1SPatrick Venture TEST_F(DbusPassiveTestObj, ReadReturnsExpectedValues)
103da4a5dd1SPatrick Venture {
1040ef1faf7SPatrick Venture     // Verify read is returning the values.
1050ef1faf7SPatrick Venture     ReadReturn v;
1060ef1faf7SPatrick Venture     v.value = 0.01;
1070ef1faf7SPatrick Venture     // TODO: updated is set when the value is created, so we can range check
1080ef1faf7SPatrick Venture     // it.
1090ef1faf7SPatrick Venture     ReadReturn r = passive->read();
1100ef1faf7SPatrick Venture     EXPECT_EQ(v.value, r.value);
1110ef1faf7SPatrick Venture }
1120ef1faf7SPatrick Venture 
113da4a5dd1SPatrick Venture TEST_F(DbusPassiveTestObj, SetValueUpdatesValue)
114da4a5dd1SPatrick Venture {
1150ef1faf7SPatrick Venture     // Verify setvalue does as advertised.
1160ef1faf7SPatrick Venture 
1170ef1faf7SPatrick Venture     double value = 0.01;
1180ef1faf7SPatrick Venture     passive->setValue(value);
1190ef1faf7SPatrick Venture 
1200ef1faf7SPatrick Venture     // TODO: updated is set when the value is set, so we can range check it.
1210ef1faf7SPatrick Venture     ReadReturn r = passive->read();
1220ef1faf7SPatrick Venture     EXPECT_EQ(value, r.value);
1230ef1faf7SPatrick Venture }
1240ef1faf7SPatrick Venture 
125da4a5dd1SPatrick Venture TEST_F(DbusPassiveTestObj, GetScaleReturnsExpectedValue)
126da4a5dd1SPatrick Venture {
1270ef1faf7SPatrick Venture     // Verify the scale is returned as expected.
1280ef1faf7SPatrick Venture     EXPECT_EQ(_scale, passive->getScale());
1290ef1faf7SPatrick Venture }
1300ef1faf7SPatrick Venture 
131563a356fSPatrick Venture TEST_F(DbusPassiveTestObj, getIDReturnsExpectedValue)
132da4a5dd1SPatrick Venture {
133563a356fSPatrick Venture     // Verify getID returns the expected value.
134563a356fSPatrick Venture     EXPECT_EQ(id, passive->getID());
1350ef1faf7SPatrick Venture }
1360ef1faf7SPatrick Venture 
137*6b9f5999SPatrick Venture TEST_F(DbusPassiveTestObj, GetMinValueReturnsExpectedValue)
138*6b9f5999SPatrick Venture {
139*6b9f5999SPatrick Venture     EXPECT_DOUBLE_EQ(0, passive->getMin());
140*6b9f5999SPatrick Venture }
141*6b9f5999SPatrick Venture 
142da4a5dd1SPatrick Venture TEST_F(DbusPassiveTestObj, VerifyHandlesDbusSignal)
143da4a5dd1SPatrick Venture {
1440ef1faf7SPatrick Venture     // The dbus passive sensor listens for updates and if it's the Value
1450ef1faf7SPatrick Venture     // property, it needs to handle it.
1460ef1faf7SPatrick Venture 
1470ef1faf7SPatrick Venture     EXPECT_CALL(sdbus_mock, sd_bus_message_ref(IsNull()))
1480ef1faf7SPatrick Venture         .WillOnce(Return(nullptr));
1490ef1faf7SPatrick Venture     sdbusplus::message::message msg(nullptr, &sdbus_mock);
1500ef1faf7SPatrick Venture 
1510ef1faf7SPatrick Venture     const char* Value = "Value";
1520ef1faf7SPatrick Venture     int64_t xValue = 10000;
1530ef1faf7SPatrick Venture     const char* intf = "xyz.openbmc_project.Sensor.Value";
1541f802f5eSJames Feist     // string, std::map<std::string, std::variant<int64_t>>
1550ef1faf7SPatrick Venture     // msg.read(msgSensor, msgData);
1560ef1faf7SPatrick Venture 
157da4a5dd1SPatrick Venture     EXPECT_CALL(sdbus_mock, sd_bus_message_read_basic(IsNull(), 's', NotNull()))
1580ef1faf7SPatrick Venture         .WillOnce(Invoke([&](sd_bus_message* m, char type, void* p) {
1590ef1faf7SPatrick Venture             const char** s = static_cast<const char**>(p);
1600ef1faf7SPatrick Venture             // Read the first parameter, the string.
1610ef1faf7SPatrick Venture             *s = intf;
1620ef1faf7SPatrick Venture             return 0;
1630ef1faf7SPatrick Venture         }))
1640ef1faf7SPatrick Venture         .WillOnce(Invoke([&](sd_bus_message* m, char type, void* p) {
1650ef1faf7SPatrick Venture             const char** s = static_cast<const char**>(p);
1660ef1faf7SPatrick Venture             *s = Value;
1670ef1faf7SPatrick Venture             // Read the string in the pair (dictionary).
1680ef1faf7SPatrick Venture             return 0;
1690ef1faf7SPatrick Venture         }));
1700ef1faf7SPatrick Venture 
1710ef1faf7SPatrick Venture     // std::map
1720ef1faf7SPatrick Venture     EXPECT_CALL(sdbus_mock,
1730ef1faf7SPatrick Venture                 sd_bus_message_enter_container(IsNull(), 'a', StrEq("{sv}")))
1740ef1faf7SPatrick Venture         .WillOnce(Return(0));
1750ef1faf7SPatrick Venture 
1760ef1faf7SPatrick Venture     // while !at_end()
1770ef1faf7SPatrick Venture     EXPECT_CALL(sdbus_mock, sd_bus_message_at_end(IsNull(), 0))
1780ef1faf7SPatrick Venture         .WillOnce(Return(0))
1790ef1faf7SPatrick Venture         .WillOnce(Return(1)); // So it exits the loop after reading one pair.
1800ef1faf7SPatrick Venture 
1810ef1faf7SPatrick Venture     // std::pair
1820ef1faf7SPatrick Venture     EXPECT_CALL(sdbus_mock,
1830ef1faf7SPatrick Venture                 sd_bus_message_enter_container(IsNull(), 'e', StrEq("sv")))
1840ef1faf7SPatrick Venture         .WillOnce(Return(0));
1850ef1faf7SPatrick Venture 
1860ef1faf7SPatrick Venture     EXPECT_CALL(sdbus_mock,
1870ef1faf7SPatrick Venture                 sd_bus_message_verify_type(IsNull(), 'v', StrEq("x")))
1880ef1faf7SPatrick Venture         .WillOnce(Return(1));
1890ef1faf7SPatrick Venture     EXPECT_CALL(sdbus_mock,
1900ef1faf7SPatrick Venture                 sd_bus_message_enter_container(IsNull(), 'v', StrEq("x")))
1910ef1faf7SPatrick Venture         .WillOnce(Return(0));
1920ef1faf7SPatrick Venture 
193da4a5dd1SPatrick Venture     EXPECT_CALL(sdbus_mock, sd_bus_message_read_basic(IsNull(), 'x', NotNull()))
1940ef1faf7SPatrick Venture         .WillOnce(Invoke([&](sd_bus_message* m, char type, void* p) {
1950ef1faf7SPatrick Venture             int64_t* s = static_cast<int64_t*>(p);
1960ef1faf7SPatrick Venture             *s = xValue;
1970ef1faf7SPatrick Venture             return 0;
1980ef1faf7SPatrick Venture         }));
1990ef1faf7SPatrick Venture 
2000ef1faf7SPatrick Venture     EXPECT_CALL(sdbus_mock, sd_bus_message_exit_container(IsNull()))
2010ef1faf7SPatrick Venture         .WillOnce(Return(0))  /* variant. */
2020ef1faf7SPatrick Venture         .WillOnce(Return(0))  /* std::pair */
2030ef1faf7SPatrick Venture         .WillOnce(Return(0)); /* std::map */
2040ef1faf7SPatrick Venture 
2057af157b1SPatrick Venture     int rv = handleSensorValue(msg, passive);
2060ef1faf7SPatrick Venture     EXPECT_EQ(rv, 0); // It's always 0.
2070ef1faf7SPatrick Venture 
2080ef1faf7SPatrick Venture     ReadReturn r = passive->read();
2090ef1faf7SPatrick Venture     EXPECT_EQ(10, r.value);
2100ef1faf7SPatrick Venture }
2110ef1faf7SPatrick Venture 
212da4a5dd1SPatrick Venture TEST_F(DbusPassiveTestObj, VerifyIgnoresOtherPropertySignal)
213da4a5dd1SPatrick Venture {
2140ef1faf7SPatrick Venture     // The dbus passive sensor listens for updates and if it's the Value
2150ef1faf7SPatrick Venture     // property, it needs to handle it.  In this case, it won't be.
2160ef1faf7SPatrick Venture 
2170ef1faf7SPatrick Venture     EXPECT_CALL(sdbus_mock, sd_bus_message_ref(IsNull()))
2180ef1faf7SPatrick Venture         .WillOnce(Return(nullptr));
2190ef1faf7SPatrick Venture     sdbusplus::message::message msg(nullptr, &sdbus_mock);
2200ef1faf7SPatrick Venture 
2210ef1faf7SPatrick Venture     const char* Scale = "Scale";
2220ef1faf7SPatrick Venture     int64_t xScale = -6;
2230ef1faf7SPatrick Venture     const char* intf = "xyz.openbmc_project.Sensor.Value";
2241f802f5eSJames Feist     // string, std::map<std::string, std::variant<int64_t>>
2250ef1faf7SPatrick Venture     // msg.read(msgSensor, msgData);
2260ef1faf7SPatrick Venture 
227da4a5dd1SPatrick Venture     EXPECT_CALL(sdbus_mock, sd_bus_message_read_basic(IsNull(), 's', NotNull()))
2280ef1faf7SPatrick Venture         .WillOnce(Invoke([&](sd_bus_message* m, char type, void* p) {
2290ef1faf7SPatrick Venture             const char** s = static_cast<const char**>(p);
2300ef1faf7SPatrick Venture             // Read the first parameter, the string.
2310ef1faf7SPatrick Venture             *s = intf;
2320ef1faf7SPatrick Venture             return 0;
2330ef1faf7SPatrick Venture         }))
2340ef1faf7SPatrick Venture         .WillOnce(Invoke([&](sd_bus_message* m, char type, void* p) {
2350ef1faf7SPatrick Venture             const char** s = static_cast<const char**>(p);
2360ef1faf7SPatrick Venture             *s = Scale;
2370ef1faf7SPatrick Venture             // Read the string in the pair (dictionary).
2380ef1faf7SPatrick Venture             return 0;
2390ef1faf7SPatrick Venture         }));
2400ef1faf7SPatrick Venture 
2410ef1faf7SPatrick Venture     // std::map
2420ef1faf7SPatrick Venture     EXPECT_CALL(sdbus_mock,
2430ef1faf7SPatrick Venture                 sd_bus_message_enter_container(IsNull(), 'a', StrEq("{sv}")))
2440ef1faf7SPatrick Venture         .WillOnce(Return(0));
2450ef1faf7SPatrick Venture 
2460ef1faf7SPatrick Venture     // while !at_end()
2470ef1faf7SPatrick Venture     EXPECT_CALL(sdbus_mock, sd_bus_message_at_end(IsNull(), 0))
2480ef1faf7SPatrick Venture         .WillOnce(Return(0))
2490ef1faf7SPatrick Venture         .WillOnce(Return(1)); // So it exits the loop after reading one pair.
2500ef1faf7SPatrick Venture 
2510ef1faf7SPatrick Venture     // std::pair
2520ef1faf7SPatrick Venture     EXPECT_CALL(sdbus_mock,
2530ef1faf7SPatrick Venture                 sd_bus_message_enter_container(IsNull(), 'e', StrEq("sv")))
2540ef1faf7SPatrick Venture         .WillOnce(Return(0));
2550ef1faf7SPatrick Venture 
2560ef1faf7SPatrick Venture     EXPECT_CALL(sdbus_mock,
2570ef1faf7SPatrick Venture                 sd_bus_message_verify_type(IsNull(), 'v', StrEq("x")))
2580ef1faf7SPatrick Venture         .WillOnce(Return(1));
2590ef1faf7SPatrick Venture     EXPECT_CALL(sdbus_mock,
2600ef1faf7SPatrick Venture                 sd_bus_message_enter_container(IsNull(), 'v', StrEq("x")))
2610ef1faf7SPatrick Venture         .WillOnce(Return(0));
2620ef1faf7SPatrick Venture 
263da4a5dd1SPatrick Venture     EXPECT_CALL(sdbus_mock, sd_bus_message_read_basic(IsNull(), 'x', NotNull()))
2640ef1faf7SPatrick Venture         .WillOnce(Invoke([&](sd_bus_message* m, char type, void* p) {
2650ef1faf7SPatrick Venture             int64_t* s = static_cast<int64_t*>(p);
2660ef1faf7SPatrick Venture             *s = xScale;
2670ef1faf7SPatrick Venture             return 0;
2680ef1faf7SPatrick Venture         }));
2690ef1faf7SPatrick Venture 
2700ef1faf7SPatrick Venture     EXPECT_CALL(sdbus_mock, sd_bus_message_exit_container(IsNull()))
2710ef1faf7SPatrick Venture         .WillOnce(Return(0))  /* variant. */
2720ef1faf7SPatrick Venture         .WillOnce(Return(0))  /* std::pair */
2730ef1faf7SPatrick Venture         .WillOnce(Return(0)); /* std::map */
2740ef1faf7SPatrick Venture 
2757af157b1SPatrick Venture     int rv = handleSensorValue(msg, passive);
2760ef1faf7SPatrick Venture     EXPECT_EQ(rv, 0); // It's always 0.
2770ef1faf7SPatrick Venture 
2780ef1faf7SPatrick Venture     ReadReturn r = passive->read();
2790ef1faf7SPatrick Venture     EXPECT_EQ(0.01, r.value);
2800ef1faf7SPatrick Venture }
28136b7d8ebSJames Feist TEST_F(DbusPassiveTestObj, VerifyCriticalThresholdAssert)
28236b7d8ebSJames Feist {
28336b7d8ebSJames Feist 
28436b7d8ebSJames Feist     // Verifies when a threshold is crossed the sensor goes into error state
28536b7d8ebSJames Feist     EXPECT_CALL(sdbus_mock, sd_bus_message_ref(IsNull()))
28636b7d8ebSJames Feist         .WillOnce(Return(nullptr));
28736b7d8ebSJames Feist     sdbusplus::message::message msg(nullptr, &sdbus_mock);
28836b7d8ebSJames Feist 
28936b7d8ebSJames Feist     const char* criticalAlarm = "CriticalAlarmHigh";
29036b7d8ebSJames Feist     bool alarm = true;
29136b7d8ebSJames Feist     const char* intf = "xyz.openbmc_project.Sensor.Threshold.Critical";
29236b7d8ebSJames Feist 
29336b7d8ebSJames Feist     passive->setFailed(false);
29436b7d8ebSJames Feist 
29536b7d8ebSJames Feist     EXPECT_CALL(sdbus_mock, sd_bus_message_read_basic(IsNull(), 's', NotNull()))
29636b7d8ebSJames Feist         .WillOnce(Invoke([&](sd_bus_message* m, char type, void* p) {
29736b7d8ebSJames Feist             const char** s = static_cast<const char**>(p);
29836b7d8ebSJames Feist             // Read the first parameter, the string.
29936b7d8ebSJames Feist             *s = intf;
30036b7d8ebSJames Feist             return 0;
30136b7d8ebSJames Feist         }))
30236b7d8ebSJames Feist         .WillOnce(Invoke([&](sd_bus_message* m, char type, void* p) {
30336b7d8ebSJames Feist             const char** s = static_cast<const char**>(p);
30436b7d8ebSJames Feist             *s = criticalAlarm;
30536b7d8ebSJames Feist             // Read the string in the pair (dictionary).
30636b7d8ebSJames Feist             return 0;
30736b7d8ebSJames Feist         }));
30836b7d8ebSJames Feist 
30936b7d8ebSJames Feist     // std::map
31036b7d8ebSJames Feist     EXPECT_CALL(sdbus_mock,
31136b7d8ebSJames Feist                 sd_bus_message_enter_container(IsNull(), 'a', StrEq("{sv}")))
31236b7d8ebSJames Feist         .WillOnce(Return(0));
31336b7d8ebSJames Feist 
31436b7d8ebSJames Feist     // while !at_end()
31536b7d8ebSJames Feist     EXPECT_CALL(sdbus_mock, sd_bus_message_at_end(IsNull(), 0))
31636b7d8ebSJames Feist         .WillOnce(Return(0))
31736b7d8ebSJames Feist         .WillOnce(Return(1)); // So it exits the loop after reading one pair.
31836b7d8ebSJames Feist 
31936b7d8ebSJames Feist     // std::pair
32036b7d8ebSJames Feist     EXPECT_CALL(sdbus_mock,
32136b7d8ebSJames Feist                 sd_bus_message_enter_container(IsNull(), 'e', StrEq("sv")))
32236b7d8ebSJames Feist         .WillOnce(Return(0));
32336b7d8ebSJames Feist 
32436b7d8ebSJames Feist     EXPECT_CALL(sdbus_mock,
32536b7d8ebSJames Feist                 sd_bus_message_verify_type(IsNull(), 'v', StrEq("x")))
32636b7d8ebSJames Feist         .WillOnce(Return(0));
32736b7d8ebSJames Feist     EXPECT_CALL(sdbus_mock,
32836b7d8ebSJames Feist                 sd_bus_message_verify_type(IsNull(), 'v', StrEq("d")))
32936b7d8ebSJames Feist         .WillOnce(Return(0));
33036b7d8ebSJames Feist     EXPECT_CALL(sdbus_mock,
33136b7d8ebSJames Feist                 sd_bus_message_verify_type(IsNull(), 'v', StrEq("b")))
33236b7d8ebSJames Feist         .WillOnce(Return(1));
33336b7d8ebSJames Feist     EXPECT_CALL(sdbus_mock,
33436b7d8ebSJames Feist                 sd_bus_message_enter_container(IsNull(), 'v', StrEq("b")))
33536b7d8ebSJames Feist         .WillOnce(Return(0));
33636b7d8ebSJames Feist 
33736b7d8ebSJames Feist     EXPECT_CALL(sdbus_mock, sd_bus_message_read_basic(IsNull(), 'b', NotNull()))
33836b7d8ebSJames Feist         .WillOnce(Invoke([&](sd_bus_message* m, char type, void* p) {
33936b7d8ebSJames Feist             bool* s = static_cast<bool*>(p);
34036b7d8ebSJames Feist             *s = alarm;
34136b7d8ebSJames Feist             return 0;
34236b7d8ebSJames Feist         }));
34336b7d8ebSJames Feist 
34436b7d8ebSJames Feist     EXPECT_CALL(sdbus_mock, sd_bus_message_exit_container(IsNull()))
34536b7d8ebSJames Feist         .WillOnce(Return(0))  /* variant. */
34636b7d8ebSJames Feist         .WillOnce(Return(0))  /* std::pair */
34736b7d8ebSJames Feist         .WillOnce(Return(0)); /* std::map */
34836b7d8ebSJames Feist 
3497af157b1SPatrick Venture     int rv = handleSensorValue(msg, passive);
35036b7d8ebSJames Feist     EXPECT_EQ(rv, 0); // It's always 0.
35136b7d8ebSJames Feist     bool failed = passive->getFailed();
35236b7d8ebSJames Feist     EXPECT_EQ(failed, true);
35336b7d8ebSJames Feist }
35436b7d8ebSJames Feist 
35536b7d8ebSJames Feist TEST_F(DbusPassiveTestObj, VerifyCriticalThresholdDeassert)
35636b7d8ebSJames Feist {
35736b7d8ebSJames Feist 
35836b7d8ebSJames Feist     // Verifies when a threshold is deasserted a failed sensor goes back into
35936b7d8ebSJames Feist     // the normal state
36036b7d8ebSJames Feist     EXPECT_CALL(sdbus_mock, sd_bus_message_ref(IsNull()))
36136b7d8ebSJames Feist         .WillOnce(Return(nullptr));
36236b7d8ebSJames Feist     sdbusplus::message::message msg(nullptr, &sdbus_mock);
36336b7d8ebSJames Feist 
36436b7d8ebSJames Feist     const char* criticalAlarm = "CriticalAlarmHigh";
36536b7d8ebSJames Feist     bool alarm = false;
36636b7d8ebSJames Feist     const char* intf = "xyz.openbmc_project.Sensor.Threshold.Critical";
36736b7d8ebSJames Feist 
36836b7d8ebSJames Feist     passive->setFailed(true);
36936b7d8ebSJames Feist 
37036b7d8ebSJames Feist     EXPECT_CALL(sdbus_mock, sd_bus_message_read_basic(IsNull(), 's', NotNull()))
37136b7d8ebSJames Feist         .WillOnce(Invoke([&](sd_bus_message* m, char type, void* p) {
37236b7d8ebSJames Feist             const char** s = static_cast<const char**>(p);
37336b7d8ebSJames Feist             // Read the first parameter, the string.
37436b7d8ebSJames Feist             *s = intf;
37536b7d8ebSJames Feist             return 0;
37636b7d8ebSJames Feist         }))
37736b7d8ebSJames Feist         .WillOnce(Invoke([&](sd_bus_message* m, char type, void* p) {
37836b7d8ebSJames Feist             const char** s = static_cast<const char**>(p);
37936b7d8ebSJames Feist             *s = criticalAlarm;
38036b7d8ebSJames Feist             // Read the string in the pair (dictionary).
38136b7d8ebSJames Feist             return 0;
38236b7d8ebSJames Feist         }));
38336b7d8ebSJames Feist 
38436b7d8ebSJames Feist     // std::map
38536b7d8ebSJames Feist     EXPECT_CALL(sdbus_mock,
38636b7d8ebSJames Feist                 sd_bus_message_enter_container(IsNull(), 'a', StrEq("{sv}")))
38736b7d8ebSJames Feist         .WillOnce(Return(0));
38836b7d8ebSJames Feist 
38936b7d8ebSJames Feist     // while !at_end()
39036b7d8ebSJames Feist     EXPECT_CALL(sdbus_mock, sd_bus_message_at_end(IsNull(), 0))
39136b7d8ebSJames Feist         .WillOnce(Return(0))
39236b7d8ebSJames Feist         .WillOnce(Return(1)); // So it exits the loop after reading one pair.
39336b7d8ebSJames Feist 
39436b7d8ebSJames Feist     // std::pair
39536b7d8ebSJames Feist     EXPECT_CALL(sdbus_mock,
39636b7d8ebSJames Feist                 sd_bus_message_enter_container(IsNull(), 'e', StrEq("sv")))
39736b7d8ebSJames Feist         .WillOnce(Return(0));
39836b7d8ebSJames Feist 
39936b7d8ebSJames Feist     EXPECT_CALL(sdbus_mock,
40036b7d8ebSJames Feist                 sd_bus_message_verify_type(IsNull(), 'v', StrEq("x")))
40136b7d8ebSJames Feist         .WillOnce(Return(0));
40236b7d8ebSJames Feist     EXPECT_CALL(sdbus_mock,
40336b7d8ebSJames Feist                 sd_bus_message_verify_type(IsNull(), 'v', StrEq("d")))
40436b7d8ebSJames Feist         .WillOnce(Return(0));
40536b7d8ebSJames Feist     EXPECT_CALL(sdbus_mock,
40636b7d8ebSJames Feist                 sd_bus_message_verify_type(IsNull(), 'v', StrEq("b")))
40736b7d8ebSJames Feist         .WillOnce(Return(1));
40836b7d8ebSJames Feist     EXPECT_CALL(sdbus_mock,
40936b7d8ebSJames Feist                 sd_bus_message_enter_container(IsNull(), 'v', StrEq("b")))
41036b7d8ebSJames Feist         .WillOnce(Return(0));
41136b7d8ebSJames Feist 
41236b7d8ebSJames Feist     EXPECT_CALL(sdbus_mock, sd_bus_message_read_basic(IsNull(), 'b', NotNull()))
41336b7d8ebSJames Feist         .WillOnce(Invoke([&](sd_bus_message* m, char type, void* p) {
41436b7d8ebSJames Feist             bool* s = static_cast<bool*>(p);
41536b7d8ebSJames Feist             *s = alarm;
41636b7d8ebSJames Feist             return 0;
41736b7d8ebSJames Feist         }));
41836b7d8ebSJames Feist 
41936b7d8ebSJames Feist     EXPECT_CALL(sdbus_mock, sd_bus_message_exit_container(IsNull()))
42036b7d8ebSJames Feist         .WillOnce(Return(0))  /* variant. */
42136b7d8ebSJames Feist         .WillOnce(Return(0))  /* std::pair */
42236b7d8ebSJames Feist         .WillOnce(Return(0)); /* std::map */
42336b7d8ebSJames Feist 
4247af157b1SPatrick Venture     int rv = handleSensorValue(msg, passive);
42536b7d8ebSJames Feist     EXPECT_EQ(rv, 0); // It's always 0.
42636b7d8ebSJames Feist     bool failed = passive->getFailed();
42736b7d8ebSJames Feist     EXPECT_EQ(failed, false);
42836b7d8ebSJames Feist }
429*6b9f5999SPatrick Venture 
430*6b9f5999SPatrick Venture void GetPropertiesMax3k(sdbusplus::bus::bus& bus, const std::string& service,
431*6b9f5999SPatrick Venture                         const std::string& path, SensorProperties* prop)
432*6b9f5999SPatrick Venture {
433*6b9f5999SPatrick Venture     prop->scale = -3;
434*6b9f5999SPatrick Venture     prop->value = 10;
435*6b9f5999SPatrick Venture     prop->unit = "x";
436*6b9f5999SPatrick Venture     prop->min = 0;
437*6b9f5999SPatrick Venture     prop->max = 3000;
438*6b9f5999SPatrick Venture }
439*6b9f5999SPatrick Venture 
440*6b9f5999SPatrick Venture using GetPropertiesFunction =
441*6b9f5999SPatrick Venture     std::function<void(sdbusplus::bus::bus&, const std::string&,
442*6b9f5999SPatrick Venture                        const std::string&, SensorProperties*)>;
443*6b9f5999SPatrick Venture 
444*6b9f5999SPatrick Venture // TODO: There is definitely a cleaner way to do this.
445*6b9f5999SPatrick Venture class DbusPassiveTest3kMaxObj : public ::testing::Test
446*6b9f5999SPatrick Venture {
447*6b9f5999SPatrick Venture   protected:
448*6b9f5999SPatrick Venture     DbusPassiveTest3kMaxObj() :
449*6b9f5999SPatrick Venture         sdbus_mock(),
450*6b9f5999SPatrick Venture         bus_mock(std::move(sdbusplus::get_mocked_new(&sdbus_mock))), helper()
451*6b9f5999SPatrick Venture     {
452*6b9f5999SPatrick Venture         EXPECT_CALL(helper, getService(_, StrEq(SensorIntf), StrEq(path)))
453*6b9f5999SPatrick Venture             .WillOnce(Return("asdf"));
454*6b9f5999SPatrick Venture 
455*6b9f5999SPatrick Venture         EXPECT_CALL(helper,
456*6b9f5999SPatrick Venture                     getProperties(_, StrEq("asdf"), StrEq(path), NotNull()))
457*6b9f5999SPatrick Venture             .WillOnce(_getProps);
458*6b9f5999SPatrick Venture         EXPECT_CALL(helper, thresholdsAsserted(_, StrEq("asdf"), StrEq(path)))
459*6b9f5999SPatrick Venture             .WillOnce(Return(false));
460*6b9f5999SPatrick Venture 
461*6b9f5999SPatrick Venture         auto info = conf::SensorConfig();
462*6b9f5999SPatrick Venture         ri = DbusPassive::createDbusPassive(bus_mock, type, id, &helper, &info,
463*6b9f5999SPatrick Venture                                             nullptr);
464*6b9f5999SPatrick Venture         passive = reinterpret_cast<DbusPassive*>(ri.get());
465*6b9f5999SPatrick Venture         EXPECT_FALSE(passive == nullptr);
466*6b9f5999SPatrick Venture     }
467*6b9f5999SPatrick Venture 
468*6b9f5999SPatrick Venture     sdbusplus::SdBusMock sdbus_mock;
469*6b9f5999SPatrick Venture     sdbusplus::bus::bus bus_mock;
470*6b9f5999SPatrick Venture     DbusHelperMock helper;
471*6b9f5999SPatrick Venture     std::string type = "temp";
472*6b9f5999SPatrick Venture     std::string id = "id";
473*6b9f5999SPatrick Venture     std::string path = "/xyz/openbmc_project/sensors/temperature/id";
474*6b9f5999SPatrick Venture     int64_t _scale = -3;
475*6b9f5999SPatrick Venture     int64_t _value = 10;
476*6b9f5999SPatrick Venture 
477*6b9f5999SPatrick Venture     std::unique_ptr<ReadInterface> ri;
478*6b9f5999SPatrick Venture     DbusPassive* passive;
479*6b9f5999SPatrick Venture     GetPropertiesFunction _getProps = &GetPropertiesMax3k;
480*6b9f5999SPatrick Venture };
481*6b9f5999SPatrick Venture 
482*6b9f5999SPatrick Venture TEST_F(DbusPassiveTest3kMaxObj, ReadMinAndMaxReturnsExpected)
483*6b9f5999SPatrick Venture {
484*6b9f5999SPatrick Venture     EXPECT_DOUBLE_EQ(0, passive->getMin());
485*6b9f5999SPatrick Venture     EXPECT_DOUBLE_EQ(3, passive->getMax());
486*6b9f5999SPatrick Venture }
487*6b9f5999SPatrick Venture 
488*6b9f5999SPatrick Venture class DbusPassiveTest3kMaxIgnoredObj : public ::testing::Test
489*6b9f5999SPatrick Venture {
490*6b9f5999SPatrick Venture   protected:
491*6b9f5999SPatrick Venture     DbusPassiveTest3kMaxIgnoredObj() :
492*6b9f5999SPatrick Venture         sdbus_mock(),
493*6b9f5999SPatrick Venture         bus_mock(std::move(sdbusplus::get_mocked_new(&sdbus_mock))), helper()
494*6b9f5999SPatrick Venture     {
495*6b9f5999SPatrick Venture         EXPECT_CALL(helper, getService(_, StrEq(SensorIntf), StrEq(path)))
496*6b9f5999SPatrick Venture             .WillOnce(Return("asdf"));
497*6b9f5999SPatrick Venture 
498*6b9f5999SPatrick Venture         EXPECT_CALL(helper,
499*6b9f5999SPatrick Venture                     getProperties(_, StrEq("asdf"), StrEq(path), NotNull()))
500*6b9f5999SPatrick Venture             .WillOnce(_getProps);
501*6b9f5999SPatrick Venture         EXPECT_CALL(helper, thresholdsAsserted(_, StrEq("asdf"), StrEq(path)))
502*6b9f5999SPatrick Venture             .WillOnce(Return(false));
503*6b9f5999SPatrick Venture 
504*6b9f5999SPatrick Venture         auto info = conf::SensorConfig();
505*6b9f5999SPatrick Venture         info.ignoreDbusMinMax = true;
506*6b9f5999SPatrick Venture         ri = DbusPassive::createDbusPassive(bus_mock, type, id, &helper, &info,
507*6b9f5999SPatrick Venture                                             nullptr);
508*6b9f5999SPatrick Venture         passive = reinterpret_cast<DbusPassive*>(ri.get());
509*6b9f5999SPatrick Venture         EXPECT_FALSE(passive == nullptr);
510*6b9f5999SPatrick Venture     }
511*6b9f5999SPatrick Venture 
512*6b9f5999SPatrick Venture     sdbusplus::SdBusMock sdbus_mock;
513*6b9f5999SPatrick Venture     sdbusplus::bus::bus bus_mock;
514*6b9f5999SPatrick Venture     DbusHelperMock helper;
515*6b9f5999SPatrick Venture     std::string type = "temp";
516*6b9f5999SPatrick Venture     std::string id = "id";
517*6b9f5999SPatrick Venture     std::string path = "/xyz/openbmc_project/sensors/temperature/id";
518*6b9f5999SPatrick Venture     int64_t _scale = -3;
519*6b9f5999SPatrick Venture     int64_t _value = 10;
520*6b9f5999SPatrick Venture 
521*6b9f5999SPatrick Venture     std::unique_ptr<ReadInterface> ri;
522*6b9f5999SPatrick Venture     DbusPassive* passive;
523*6b9f5999SPatrick Venture     GetPropertiesFunction _getProps = &GetPropertiesMax3k;
524*6b9f5999SPatrick Venture };
525*6b9f5999SPatrick Venture 
526*6b9f5999SPatrick Venture TEST_F(DbusPassiveTest3kMaxIgnoredObj, ReadMinAndMaxReturnsExpected)
527*6b9f5999SPatrick Venture {
528*6b9f5999SPatrick Venture     EXPECT_DOUBLE_EQ(0, passive->getMin());
529*6b9f5999SPatrick Venture     EXPECT_DOUBLE_EQ(0, passive->getMax());
530*6b9f5999SPatrick Venture }
531