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