xref: /openbmc/phosphor-pid-control/test/dbus_passive_unittest.cpp (revision f81f28860b91727b03845381f7afcc5c93274d57)
175eb769dSJames Feist #include "conf.hpp"
20ef1faf7SPatrick Venture #include "dbus/dbuspassive.hpp"
3da4a5dd1SPatrick Venture #include "test/dbushelper_mock.hpp"
40ef1faf7SPatrick Venture 
50ef1faf7SPatrick Venture #include <sdbusplus/test/sdbus_mock.hpp>
60ef1faf7SPatrick Venture #include <string>
71f802f5eSJames Feist #include <variant>
80ef1faf7SPatrick Venture 
9da4a5dd1SPatrick Venture #include <gmock/gmock.h>
10da4a5dd1SPatrick Venture #include <gtest/gtest.h>
110ef1faf7SPatrick Venture 
12da4a5dd1SPatrick Venture using ::testing::_;
130ef1faf7SPatrick Venture using ::testing::InSequence;
140ef1faf7SPatrick Venture using ::testing::Invoke;
150ef1faf7SPatrick Venture using ::testing::IsNull;
160ef1faf7SPatrick Venture using ::testing::NotNull;
170ef1faf7SPatrick Venture using ::testing::Return;
180ef1faf7SPatrick Venture using ::testing::StrEq;
190ef1faf7SPatrick Venture 
200ef1faf7SPatrick Venture std::string SensorIntf = "xyz.openbmc_project.Sensor.Value";
210ef1faf7SPatrick Venture 
22da4a5dd1SPatrick Venture TEST(DbusPassiveTest, FactoryFailsWithInvalidType)
23da4a5dd1SPatrick Venture {
240ef1faf7SPatrick Venture     // Verify the type is checked by the factory.
250ef1faf7SPatrick Venture 
260ef1faf7SPatrick Venture     sdbusplus::SdBusMock sdbus_mock;
270ef1faf7SPatrick Venture     auto bus_mock = sdbusplus::get_mocked_new(&sdbus_mock);
280ef1faf7SPatrick Venture     std::string type = "invalid";
290ef1faf7SPatrick Venture     std::string id = "id";
300ef1faf7SPatrick Venture 
310ef1faf7SPatrick Venture     DbusHelperMock helper;
32*f81f2886SJames Feist     auto info = conf::SensorConfig();
330ef1faf7SPatrick Venture 
340ef1faf7SPatrick Venture     std::unique_ptr<ReadInterface> ri =
3575eb769dSJames Feist         DbusPassive::createDbusPassive(bus_mock, type, id, &helper, &info);
360ef1faf7SPatrick Venture 
370ef1faf7SPatrick Venture     EXPECT_EQ(ri, nullptr);
380ef1faf7SPatrick Venture }
390ef1faf7SPatrick Venture 
40da4a5dd1SPatrick Venture TEST(DbusPassiveTest, BoringConstructorTest)
41da4a5dd1SPatrick Venture {
42f8cb4644SPatrick Venture     // Simply build the object, does no error checking.
430ef1faf7SPatrick Venture 
440ef1faf7SPatrick Venture     sdbusplus::SdBusMock sdbus_mock;
450ef1faf7SPatrick Venture     auto bus_mock = sdbusplus::get_mocked_new(&sdbus_mock);
460ef1faf7SPatrick Venture     std::string type = "invalid";
470ef1faf7SPatrick Venture     std::string id = "id";
480ef1faf7SPatrick Venture     std::string path = "/xyz/openbmc_project/sensors/unknown/id";
490ef1faf7SPatrick Venture 
500ef1faf7SPatrick Venture     DbusHelperMock helper;
51f8cb4644SPatrick Venture     struct SensorProperties properties;
520ef1faf7SPatrick Venture 
53f8cb4644SPatrick Venture     DbusPassive(bus_mock, type, id, &helper, properties, false);
540ef1faf7SPatrick Venture     // Success
550ef1faf7SPatrick Venture }
560ef1faf7SPatrick Venture 
57da4a5dd1SPatrick Venture class DbusPassiveTestObj : public ::testing::Test
58da4a5dd1SPatrick Venture {
590ef1faf7SPatrick Venture   protected:
60da4a5dd1SPatrick Venture     DbusPassiveTestObj() :
61da4a5dd1SPatrick Venture         sdbus_mock(),
62da4a5dd1SPatrick Venture         bus_mock(std::move(sdbusplus::get_mocked_new(&sdbus_mock))), helper()
630ef1faf7SPatrick Venture     {
64563a356fSPatrick Venture         EXPECT_CALL(helper, getService(_, StrEq(SensorIntf), StrEq(path)))
650ef1faf7SPatrick Venture             .WillOnce(Return("asdf"));
660ef1faf7SPatrick Venture 
67da4a5dd1SPatrick Venture         EXPECT_CALL(helper,
68563a356fSPatrick Venture                     getProperties(_, StrEq("asdf"), StrEq(path), NotNull()))
69da4a5dd1SPatrick Venture             .WillOnce(Invoke(
70da4a5dd1SPatrick Venture                 [&](sdbusplus::bus::bus& bus, const std::string& service,
71da4a5dd1SPatrick Venture                     const std::string& path, struct SensorProperties* prop) {
720ef1faf7SPatrick Venture                     prop->scale = _scale;
730ef1faf7SPatrick Venture                     prop->value = _value;
740ef1faf7SPatrick Venture                     prop->unit = "x";
750ef1faf7SPatrick Venture                 }));
76563a356fSPatrick Venture         EXPECT_CALL(helper, thresholdsAsserted(_, StrEq("asdf"), StrEq(path)))
7736b7d8ebSJames Feist             .WillOnce(Return(false));
780ef1faf7SPatrick Venture 
79*f81f2886SJames Feist         auto info = conf::SensorConfig();
8075eb769dSJames Feist         ri = DbusPassive::createDbusPassive(bus_mock, type, id, &helper, &info);
810ef1faf7SPatrick Venture         passive = reinterpret_cast<DbusPassive*>(ri.get());
820ef1faf7SPatrick Venture         EXPECT_FALSE(passive == nullptr);
830ef1faf7SPatrick Venture     }
840ef1faf7SPatrick Venture 
850ef1faf7SPatrick Venture     sdbusplus::SdBusMock sdbus_mock;
860ef1faf7SPatrick Venture     sdbusplus::bus::bus bus_mock;
870ef1faf7SPatrick Venture     DbusHelperMock helper;
880ef1faf7SPatrick Venture     std::string type = "temp";
890ef1faf7SPatrick Venture     std::string id = "id";
900ef1faf7SPatrick Venture     std::string path = "/xyz/openbmc_project/sensors/temperature/id";
910ef1faf7SPatrick Venture     int64_t _scale = -3;
920ef1faf7SPatrick Venture     int64_t _value = 10;
930ef1faf7SPatrick Venture 
940ef1faf7SPatrick Venture     std::unique_ptr<ReadInterface> ri;
950ef1faf7SPatrick Venture     DbusPassive* passive;
960ef1faf7SPatrick Venture };
970ef1faf7SPatrick Venture 
98da4a5dd1SPatrick Venture TEST_F(DbusPassiveTestObj, ReadReturnsExpectedValues)
99da4a5dd1SPatrick Venture {
1000ef1faf7SPatrick Venture     // Verify read is returning the values.
1010ef1faf7SPatrick Venture     ReadReturn v;
1020ef1faf7SPatrick Venture     v.value = 0.01;
1030ef1faf7SPatrick Venture     // TODO: updated is set when the value is created, so we can range check
1040ef1faf7SPatrick Venture     // it.
1050ef1faf7SPatrick Venture     ReadReturn r = passive->read();
1060ef1faf7SPatrick Venture     EXPECT_EQ(v.value, r.value);
1070ef1faf7SPatrick Venture }
1080ef1faf7SPatrick Venture 
109da4a5dd1SPatrick Venture TEST_F(DbusPassiveTestObj, SetValueUpdatesValue)
110da4a5dd1SPatrick Venture {
1110ef1faf7SPatrick Venture     // Verify setvalue does as advertised.
1120ef1faf7SPatrick Venture 
1130ef1faf7SPatrick Venture     double value = 0.01;
1140ef1faf7SPatrick Venture     passive->setValue(value);
1150ef1faf7SPatrick Venture 
1160ef1faf7SPatrick Venture     // TODO: updated is set when the value is set, so we can range check it.
1170ef1faf7SPatrick Venture     ReadReturn r = passive->read();
1180ef1faf7SPatrick Venture     EXPECT_EQ(value, r.value);
1190ef1faf7SPatrick Venture }
1200ef1faf7SPatrick Venture 
121da4a5dd1SPatrick Venture TEST_F(DbusPassiveTestObj, GetScaleReturnsExpectedValue)
122da4a5dd1SPatrick Venture {
1230ef1faf7SPatrick Venture     // Verify the scale is returned as expected.
1240ef1faf7SPatrick Venture     EXPECT_EQ(_scale, passive->getScale());
1250ef1faf7SPatrick Venture }
1260ef1faf7SPatrick Venture 
127563a356fSPatrick Venture TEST_F(DbusPassiveTestObj, getIDReturnsExpectedValue)
128da4a5dd1SPatrick Venture {
129563a356fSPatrick Venture     // Verify getID returns the expected value.
130563a356fSPatrick Venture     EXPECT_EQ(id, passive->getID());
1310ef1faf7SPatrick Venture }
1320ef1faf7SPatrick Venture 
133da4a5dd1SPatrick Venture TEST_F(DbusPassiveTestObj, VerifyHandlesDbusSignal)
134da4a5dd1SPatrick Venture {
1350ef1faf7SPatrick Venture     // The dbus passive sensor listens for updates and if it's the Value
1360ef1faf7SPatrick Venture     // property, it needs to handle it.
1370ef1faf7SPatrick Venture 
1380ef1faf7SPatrick Venture     EXPECT_CALL(sdbus_mock, sd_bus_message_ref(IsNull()))
1390ef1faf7SPatrick Venture         .WillOnce(Return(nullptr));
1400ef1faf7SPatrick Venture     sdbusplus::message::message msg(nullptr, &sdbus_mock);
1410ef1faf7SPatrick Venture 
1420ef1faf7SPatrick Venture     const char* Value = "Value";
1430ef1faf7SPatrick Venture     int64_t xValue = 10000;
1440ef1faf7SPatrick Venture     const char* intf = "xyz.openbmc_project.Sensor.Value";
1451f802f5eSJames Feist     // string, std::map<std::string, std::variant<int64_t>>
1460ef1faf7SPatrick Venture     // msg.read(msgSensor, msgData);
1470ef1faf7SPatrick Venture 
148da4a5dd1SPatrick Venture     EXPECT_CALL(sdbus_mock, sd_bus_message_read_basic(IsNull(), 's', NotNull()))
1490ef1faf7SPatrick Venture         .WillOnce(Invoke([&](sd_bus_message* m, char type, void* p) {
1500ef1faf7SPatrick Venture             const char** s = static_cast<const char**>(p);
1510ef1faf7SPatrick Venture             // Read the first parameter, the string.
1520ef1faf7SPatrick Venture             *s = intf;
1530ef1faf7SPatrick Venture             return 0;
1540ef1faf7SPatrick Venture         }))
1550ef1faf7SPatrick Venture         .WillOnce(Invoke([&](sd_bus_message* m, char type, void* p) {
1560ef1faf7SPatrick Venture             const char** s = static_cast<const char**>(p);
1570ef1faf7SPatrick Venture             *s = Value;
1580ef1faf7SPatrick Venture             // Read the string in the pair (dictionary).
1590ef1faf7SPatrick Venture             return 0;
1600ef1faf7SPatrick Venture         }));
1610ef1faf7SPatrick Venture 
1620ef1faf7SPatrick Venture     // std::map
1630ef1faf7SPatrick Venture     EXPECT_CALL(sdbus_mock,
1640ef1faf7SPatrick Venture                 sd_bus_message_enter_container(IsNull(), 'a', StrEq("{sv}")))
1650ef1faf7SPatrick Venture         .WillOnce(Return(0));
1660ef1faf7SPatrick Venture 
1670ef1faf7SPatrick Venture     // while !at_end()
1680ef1faf7SPatrick Venture     EXPECT_CALL(sdbus_mock, sd_bus_message_at_end(IsNull(), 0))
1690ef1faf7SPatrick Venture         .WillOnce(Return(0))
1700ef1faf7SPatrick Venture         .WillOnce(Return(1)); // So it exits the loop after reading one pair.
1710ef1faf7SPatrick Venture 
1720ef1faf7SPatrick Venture     // std::pair
1730ef1faf7SPatrick Venture     EXPECT_CALL(sdbus_mock,
1740ef1faf7SPatrick Venture                 sd_bus_message_enter_container(IsNull(), 'e', StrEq("sv")))
1750ef1faf7SPatrick Venture         .WillOnce(Return(0));
1760ef1faf7SPatrick Venture 
1770ef1faf7SPatrick Venture     EXPECT_CALL(sdbus_mock,
1780ef1faf7SPatrick Venture                 sd_bus_message_verify_type(IsNull(), 'v', StrEq("x")))
1790ef1faf7SPatrick Venture         .WillOnce(Return(1));
1800ef1faf7SPatrick Venture     EXPECT_CALL(sdbus_mock,
1810ef1faf7SPatrick Venture                 sd_bus_message_enter_container(IsNull(), 'v', StrEq("x")))
1820ef1faf7SPatrick Venture         .WillOnce(Return(0));
1830ef1faf7SPatrick Venture 
184da4a5dd1SPatrick Venture     EXPECT_CALL(sdbus_mock, sd_bus_message_read_basic(IsNull(), 'x', NotNull()))
1850ef1faf7SPatrick Venture         .WillOnce(Invoke([&](sd_bus_message* m, char type, void* p) {
1860ef1faf7SPatrick Venture             int64_t* s = static_cast<int64_t*>(p);
1870ef1faf7SPatrick Venture             *s = xValue;
1880ef1faf7SPatrick Venture             return 0;
1890ef1faf7SPatrick Venture         }));
1900ef1faf7SPatrick Venture 
1910ef1faf7SPatrick Venture     EXPECT_CALL(sdbus_mock, sd_bus_message_exit_container(IsNull()))
1920ef1faf7SPatrick Venture         .WillOnce(Return(0))  /* variant. */
1930ef1faf7SPatrick Venture         .WillOnce(Return(0))  /* std::pair */
1940ef1faf7SPatrick Venture         .WillOnce(Return(0)); /* std::map */
1950ef1faf7SPatrick Venture 
1967af157b1SPatrick Venture     int rv = handleSensorValue(msg, passive);
1970ef1faf7SPatrick Venture     EXPECT_EQ(rv, 0); // It's always 0.
1980ef1faf7SPatrick Venture 
1990ef1faf7SPatrick Venture     ReadReturn r = passive->read();
2000ef1faf7SPatrick Venture     EXPECT_EQ(10, r.value);
2010ef1faf7SPatrick Venture }
2020ef1faf7SPatrick Venture 
203da4a5dd1SPatrick Venture TEST_F(DbusPassiveTestObj, VerifyIgnoresOtherPropertySignal)
204da4a5dd1SPatrick Venture {
2050ef1faf7SPatrick Venture     // The dbus passive sensor listens for updates and if it's the Value
2060ef1faf7SPatrick Venture     // property, it needs to handle it.  In this case, it won't be.
2070ef1faf7SPatrick Venture 
2080ef1faf7SPatrick Venture     EXPECT_CALL(sdbus_mock, sd_bus_message_ref(IsNull()))
2090ef1faf7SPatrick Venture         .WillOnce(Return(nullptr));
2100ef1faf7SPatrick Venture     sdbusplus::message::message msg(nullptr, &sdbus_mock);
2110ef1faf7SPatrick Venture 
2120ef1faf7SPatrick Venture     const char* Scale = "Scale";
2130ef1faf7SPatrick Venture     int64_t xScale = -6;
2140ef1faf7SPatrick Venture     const char* intf = "xyz.openbmc_project.Sensor.Value";
2151f802f5eSJames Feist     // string, std::map<std::string, std::variant<int64_t>>
2160ef1faf7SPatrick Venture     // msg.read(msgSensor, msgData);
2170ef1faf7SPatrick Venture 
218da4a5dd1SPatrick Venture     EXPECT_CALL(sdbus_mock, sd_bus_message_read_basic(IsNull(), 's', NotNull()))
2190ef1faf7SPatrick Venture         .WillOnce(Invoke([&](sd_bus_message* m, char type, void* p) {
2200ef1faf7SPatrick Venture             const char** s = static_cast<const char**>(p);
2210ef1faf7SPatrick Venture             // Read the first parameter, the string.
2220ef1faf7SPatrick Venture             *s = intf;
2230ef1faf7SPatrick Venture             return 0;
2240ef1faf7SPatrick Venture         }))
2250ef1faf7SPatrick Venture         .WillOnce(Invoke([&](sd_bus_message* m, char type, void* p) {
2260ef1faf7SPatrick Venture             const char** s = static_cast<const char**>(p);
2270ef1faf7SPatrick Venture             *s = Scale;
2280ef1faf7SPatrick Venture             // Read the string in the pair (dictionary).
2290ef1faf7SPatrick Venture             return 0;
2300ef1faf7SPatrick Venture         }));
2310ef1faf7SPatrick Venture 
2320ef1faf7SPatrick Venture     // std::map
2330ef1faf7SPatrick Venture     EXPECT_CALL(sdbus_mock,
2340ef1faf7SPatrick Venture                 sd_bus_message_enter_container(IsNull(), 'a', StrEq("{sv}")))
2350ef1faf7SPatrick Venture         .WillOnce(Return(0));
2360ef1faf7SPatrick Venture 
2370ef1faf7SPatrick Venture     // while !at_end()
2380ef1faf7SPatrick Venture     EXPECT_CALL(sdbus_mock, sd_bus_message_at_end(IsNull(), 0))
2390ef1faf7SPatrick Venture         .WillOnce(Return(0))
2400ef1faf7SPatrick Venture         .WillOnce(Return(1)); // So it exits the loop after reading one pair.
2410ef1faf7SPatrick Venture 
2420ef1faf7SPatrick Venture     // std::pair
2430ef1faf7SPatrick Venture     EXPECT_CALL(sdbus_mock,
2440ef1faf7SPatrick Venture                 sd_bus_message_enter_container(IsNull(), 'e', StrEq("sv")))
2450ef1faf7SPatrick Venture         .WillOnce(Return(0));
2460ef1faf7SPatrick Venture 
2470ef1faf7SPatrick Venture     EXPECT_CALL(sdbus_mock,
2480ef1faf7SPatrick Venture                 sd_bus_message_verify_type(IsNull(), 'v', StrEq("x")))
2490ef1faf7SPatrick Venture         .WillOnce(Return(1));
2500ef1faf7SPatrick Venture     EXPECT_CALL(sdbus_mock,
2510ef1faf7SPatrick Venture                 sd_bus_message_enter_container(IsNull(), 'v', StrEq("x")))
2520ef1faf7SPatrick Venture         .WillOnce(Return(0));
2530ef1faf7SPatrick Venture 
254da4a5dd1SPatrick Venture     EXPECT_CALL(sdbus_mock, sd_bus_message_read_basic(IsNull(), 'x', NotNull()))
2550ef1faf7SPatrick Venture         .WillOnce(Invoke([&](sd_bus_message* m, char type, void* p) {
2560ef1faf7SPatrick Venture             int64_t* s = static_cast<int64_t*>(p);
2570ef1faf7SPatrick Venture             *s = xScale;
2580ef1faf7SPatrick Venture             return 0;
2590ef1faf7SPatrick Venture         }));
2600ef1faf7SPatrick Venture 
2610ef1faf7SPatrick Venture     EXPECT_CALL(sdbus_mock, sd_bus_message_exit_container(IsNull()))
2620ef1faf7SPatrick Venture         .WillOnce(Return(0))  /* variant. */
2630ef1faf7SPatrick Venture         .WillOnce(Return(0))  /* std::pair */
2640ef1faf7SPatrick Venture         .WillOnce(Return(0)); /* std::map */
2650ef1faf7SPatrick Venture 
2667af157b1SPatrick Venture     int rv = handleSensorValue(msg, passive);
2670ef1faf7SPatrick Venture     EXPECT_EQ(rv, 0); // It's always 0.
2680ef1faf7SPatrick Venture 
2690ef1faf7SPatrick Venture     ReadReturn r = passive->read();
2700ef1faf7SPatrick Venture     EXPECT_EQ(0.01, r.value);
2710ef1faf7SPatrick Venture }
27236b7d8ebSJames Feist TEST_F(DbusPassiveTestObj, VerifyCriticalThresholdAssert)
27336b7d8ebSJames Feist {
27436b7d8ebSJames Feist 
27536b7d8ebSJames Feist     // Verifies when a threshold is crossed the sensor goes into error state
27636b7d8ebSJames Feist     EXPECT_CALL(sdbus_mock, sd_bus_message_ref(IsNull()))
27736b7d8ebSJames Feist         .WillOnce(Return(nullptr));
27836b7d8ebSJames Feist     sdbusplus::message::message msg(nullptr, &sdbus_mock);
27936b7d8ebSJames Feist 
28036b7d8ebSJames Feist     const char* criticalAlarm = "CriticalAlarmHigh";
28136b7d8ebSJames Feist     bool alarm = true;
28236b7d8ebSJames Feist     const char* intf = "xyz.openbmc_project.Sensor.Threshold.Critical";
28336b7d8ebSJames Feist 
28436b7d8ebSJames Feist     passive->setFailed(false);
28536b7d8ebSJames Feist 
28636b7d8ebSJames Feist     EXPECT_CALL(sdbus_mock, sd_bus_message_read_basic(IsNull(), 's', NotNull()))
28736b7d8ebSJames Feist         .WillOnce(Invoke([&](sd_bus_message* m, char type, void* p) {
28836b7d8ebSJames Feist             const char** s = static_cast<const char**>(p);
28936b7d8ebSJames Feist             // Read the first parameter, the string.
29036b7d8ebSJames Feist             *s = intf;
29136b7d8ebSJames Feist             return 0;
29236b7d8ebSJames Feist         }))
29336b7d8ebSJames Feist         .WillOnce(Invoke([&](sd_bus_message* m, char type, void* p) {
29436b7d8ebSJames Feist             const char** s = static_cast<const char**>(p);
29536b7d8ebSJames Feist             *s = criticalAlarm;
29636b7d8ebSJames Feist             // Read the string in the pair (dictionary).
29736b7d8ebSJames Feist             return 0;
29836b7d8ebSJames Feist         }));
29936b7d8ebSJames Feist 
30036b7d8ebSJames Feist     // std::map
30136b7d8ebSJames Feist     EXPECT_CALL(sdbus_mock,
30236b7d8ebSJames Feist                 sd_bus_message_enter_container(IsNull(), 'a', StrEq("{sv}")))
30336b7d8ebSJames Feist         .WillOnce(Return(0));
30436b7d8ebSJames Feist 
30536b7d8ebSJames Feist     // while !at_end()
30636b7d8ebSJames Feist     EXPECT_CALL(sdbus_mock, sd_bus_message_at_end(IsNull(), 0))
30736b7d8ebSJames Feist         .WillOnce(Return(0))
30836b7d8ebSJames Feist         .WillOnce(Return(1)); // So it exits the loop after reading one pair.
30936b7d8ebSJames Feist 
31036b7d8ebSJames Feist     // std::pair
31136b7d8ebSJames Feist     EXPECT_CALL(sdbus_mock,
31236b7d8ebSJames Feist                 sd_bus_message_enter_container(IsNull(), 'e', StrEq("sv")))
31336b7d8ebSJames Feist         .WillOnce(Return(0));
31436b7d8ebSJames Feist 
31536b7d8ebSJames Feist     EXPECT_CALL(sdbus_mock,
31636b7d8ebSJames Feist                 sd_bus_message_verify_type(IsNull(), 'v', StrEq("x")))
31736b7d8ebSJames Feist         .WillOnce(Return(0));
31836b7d8ebSJames Feist     EXPECT_CALL(sdbus_mock,
31936b7d8ebSJames Feist                 sd_bus_message_verify_type(IsNull(), 'v', StrEq("d")))
32036b7d8ebSJames Feist         .WillOnce(Return(0));
32136b7d8ebSJames Feist     EXPECT_CALL(sdbus_mock,
32236b7d8ebSJames Feist                 sd_bus_message_verify_type(IsNull(), 'v', StrEq("b")))
32336b7d8ebSJames Feist         .WillOnce(Return(1));
32436b7d8ebSJames Feist     EXPECT_CALL(sdbus_mock,
32536b7d8ebSJames Feist                 sd_bus_message_enter_container(IsNull(), 'v', StrEq("b")))
32636b7d8ebSJames Feist         .WillOnce(Return(0));
32736b7d8ebSJames Feist 
32836b7d8ebSJames Feist     EXPECT_CALL(sdbus_mock, sd_bus_message_read_basic(IsNull(), 'b', NotNull()))
32936b7d8ebSJames Feist         .WillOnce(Invoke([&](sd_bus_message* m, char type, void* p) {
33036b7d8ebSJames Feist             bool* s = static_cast<bool*>(p);
33136b7d8ebSJames Feist             *s = alarm;
33236b7d8ebSJames Feist             return 0;
33336b7d8ebSJames Feist         }));
33436b7d8ebSJames Feist 
33536b7d8ebSJames Feist     EXPECT_CALL(sdbus_mock, sd_bus_message_exit_container(IsNull()))
33636b7d8ebSJames Feist         .WillOnce(Return(0))  /* variant. */
33736b7d8ebSJames Feist         .WillOnce(Return(0))  /* std::pair */
33836b7d8ebSJames Feist         .WillOnce(Return(0)); /* std::map */
33936b7d8ebSJames Feist 
3407af157b1SPatrick Venture     int rv = handleSensorValue(msg, passive);
34136b7d8ebSJames Feist     EXPECT_EQ(rv, 0); // It's always 0.
34236b7d8ebSJames Feist     bool failed = passive->getFailed();
34336b7d8ebSJames Feist     EXPECT_EQ(failed, true);
34436b7d8ebSJames Feist }
34536b7d8ebSJames Feist 
34636b7d8ebSJames Feist TEST_F(DbusPassiveTestObj, VerifyCriticalThresholdDeassert)
34736b7d8ebSJames Feist {
34836b7d8ebSJames Feist 
34936b7d8ebSJames Feist     // Verifies when a threshold is deasserted a failed sensor goes back into
35036b7d8ebSJames Feist     // the normal state
35136b7d8ebSJames Feist     EXPECT_CALL(sdbus_mock, sd_bus_message_ref(IsNull()))
35236b7d8ebSJames Feist         .WillOnce(Return(nullptr));
35336b7d8ebSJames Feist     sdbusplus::message::message msg(nullptr, &sdbus_mock);
35436b7d8ebSJames Feist 
35536b7d8ebSJames Feist     const char* criticalAlarm = "CriticalAlarmHigh";
35636b7d8ebSJames Feist     bool alarm = false;
35736b7d8ebSJames Feist     const char* intf = "xyz.openbmc_project.Sensor.Threshold.Critical";
35836b7d8ebSJames Feist 
35936b7d8ebSJames Feist     passive->setFailed(true);
36036b7d8ebSJames Feist 
36136b7d8ebSJames Feist     EXPECT_CALL(sdbus_mock, sd_bus_message_read_basic(IsNull(), 's', NotNull()))
36236b7d8ebSJames Feist         .WillOnce(Invoke([&](sd_bus_message* m, char type, void* p) {
36336b7d8ebSJames Feist             const char** s = static_cast<const char**>(p);
36436b7d8ebSJames Feist             // Read the first parameter, the string.
36536b7d8ebSJames Feist             *s = intf;
36636b7d8ebSJames Feist             return 0;
36736b7d8ebSJames Feist         }))
36836b7d8ebSJames Feist         .WillOnce(Invoke([&](sd_bus_message* m, char type, void* p) {
36936b7d8ebSJames Feist             const char** s = static_cast<const char**>(p);
37036b7d8ebSJames Feist             *s = criticalAlarm;
37136b7d8ebSJames Feist             // Read the string in the pair (dictionary).
37236b7d8ebSJames Feist             return 0;
37336b7d8ebSJames Feist         }));
37436b7d8ebSJames Feist 
37536b7d8ebSJames Feist     // std::map
37636b7d8ebSJames Feist     EXPECT_CALL(sdbus_mock,
37736b7d8ebSJames Feist                 sd_bus_message_enter_container(IsNull(), 'a', StrEq("{sv}")))
37836b7d8ebSJames Feist         .WillOnce(Return(0));
37936b7d8ebSJames Feist 
38036b7d8ebSJames Feist     // while !at_end()
38136b7d8ebSJames Feist     EXPECT_CALL(sdbus_mock, sd_bus_message_at_end(IsNull(), 0))
38236b7d8ebSJames Feist         .WillOnce(Return(0))
38336b7d8ebSJames Feist         .WillOnce(Return(1)); // So it exits the loop after reading one pair.
38436b7d8ebSJames Feist 
38536b7d8ebSJames Feist     // std::pair
38636b7d8ebSJames Feist     EXPECT_CALL(sdbus_mock,
38736b7d8ebSJames Feist                 sd_bus_message_enter_container(IsNull(), 'e', StrEq("sv")))
38836b7d8ebSJames Feist         .WillOnce(Return(0));
38936b7d8ebSJames Feist 
39036b7d8ebSJames Feist     EXPECT_CALL(sdbus_mock,
39136b7d8ebSJames Feist                 sd_bus_message_verify_type(IsNull(), 'v', StrEq("x")))
39236b7d8ebSJames Feist         .WillOnce(Return(0));
39336b7d8ebSJames Feist     EXPECT_CALL(sdbus_mock,
39436b7d8ebSJames Feist                 sd_bus_message_verify_type(IsNull(), 'v', StrEq("d")))
39536b7d8ebSJames Feist         .WillOnce(Return(0));
39636b7d8ebSJames Feist     EXPECT_CALL(sdbus_mock,
39736b7d8ebSJames Feist                 sd_bus_message_verify_type(IsNull(), 'v', StrEq("b")))
39836b7d8ebSJames Feist         .WillOnce(Return(1));
39936b7d8ebSJames Feist     EXPECT_CALL(sdbus_mock,
40036b7d8ebSJames Feist                 sd_bus_message_enter_container(IsNull(), 'v', StrEq("b")))
40136b7d8ebSJames Feist         .WillOnce(Return(0));
40236b7d8ebSJames Feist 
40336b7d8ebSJames Feist     EXPECT_CALL(sdbus_mock, sd_bus_message_read_basic(IsNull(), 'b', NotNull()))
40436b7d8ebSJames Feist         .WillOnce(Invoke([&](sd_bus_message* m, char type, void* p) {
40536b7d8ebSJames Feist             bool* s = static_cast<bool*>(p);
40636b7d8ebSJames Feist             *s = alarm;
40736b7d8ebSJames Feist             return 0;
40836b7d8ebSJames Feist         }));
40936b7d8ebSJames Feist 
41036b7d8ebSJames Feist     EXPECT_CALL(sdbus_mock, sd_bus_message_exit_container(IsNull()))
41136b7d8ebSJames Feist         .WillOnce(Return(0))  /* variant. */
41236b7d8ebSJames Feist         .WillOnce(Return(0))  /* std::pair */
41336b7d8ebSJames Feist         .WillOnce(Return(0)); /* std::map */
41436b7d8ebSJames Feist 
4157af157b1SPatrick Venture     int rv = handleSensorValue(msg, passive);
41636b7d8ebSJames Feist     EXPECT_EQ(rv, 0); // It's always 0.
41736b7d8ebSJames Feist     bool failed = passive->getFailed();
41836b7d8ebSJames Feist     EXPECT_EQ(failed, false);
41936b7d8ebSJames Feist }
420