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> 6a83a3eccSPatrick Venture 7a83a3eccSPatrick Venture #include <functional> 88729eb98SPatrick Venture #include <memory> 90ef1faf7SPatrick Venture #include <string> 101f802f5eSJames Feist #include <variant> 110ef1faf7SPatrick Venture 12da4a5dd1SPatrick Venture #include <gmock/gmock.h> 13da4a5dd1SPatrick Venture #include <gtest/gtest.h> 140ef1faf7SPatrick Venture 15a076487aSPatrick Venture namespace pid_control 16a076487aSPatrick Venture { 17a076487aSPatrick Venture namespace 18a076487aSPatrick Venture { 19a076487aSPatrick Venture 20da4a5dd1SPatrick Venture using ::testing::_; 210ef1faf7SPatrick Venture using ::testing::InSequence; 220ef1faf7SPatrick Venture using ::testing::Invoke; 230ef1faf7SPatrick Venture using ::testing::IsNull; 240ef1faf7SPatrick Venture using ::testing::NotNull; 250ef1faf7SPatrick Venture using ::testing::Return; 260ef1faf7SPatrick Venture using ::testing::StrEq; 270ef1faf7SPatrick Venture 280ef1faf7SPatrick Venture std::string SensorIntf = "xyz.openbmc_project.Sensor.Value"; 290ef1faf7SPatrick Venture 30da4a5dd1SPatrick Venture TEST(DbusPassiveTest, FactoryFailsWithInvalidType) 31da4a5dd1SPatrick Venture { 320ef1faf7SPatrick Venture // Verify the type is checked by the factory. 330ef1faf7SPatrick Venture 340ef1faf7SPatrick Venture sdbusplus::SdBusMock sdbus_mock; 350ef1faf7SPatrick Venture auto bus_mock = sdbusplus::get_mocked_new(&sdbus_mock); 360ef1faf7SPatrick Venture std::string type = "invalid"; 370ef1faf7SPatrick Venture std::string id = "id"; 380ef1faf7SPatrick Venture 398729eb98SPatrick Venture auto helper = std::make_unique<DbusHelperMock>(); 40f81f2886SJames Feist auto info = conf::SensorConfig(); 410ef1faf7SPatrick Venture 4298b704e1SJames Feist std::unique_ptr<ReadInterface> ri = DbusPassive::createDbusPassive( 438729eb98SPatrick Venture bus_mock, type, id, std::move(helper), &info, nullptr); 440ef1faf7SPatrick Venture 450ef1faf7SPatrick Venture EXPECT_EQ(ri, nullptr); 460ef1faf7SPatrick Venture } 470ef1faf7SPatrick Venture 48da4a5dd1SPatrick Venture TEST(DbusPassiveTest, BoringConstructorTest) 49da4a5dd1SPatrick Venture { 50f8cb4644SPatrick Venture // Simply build the object, does no error checking. 510ef1faf7SPatrick Venture 520ef1faf7SPatrick Venture sdbusplus::SdBusMock sdbus_mock; 530ef1faf7SPatrick Venture auto bus_mock = sdbusplus::get_mocked_new(&sdbus_mock); 540ef1faf7SPatrick Venture std::string type = "invalid"; 550ef1faf7SPatrick Venture std::string id = "id"; 560ef1faf7SPatrick Venture std::string path = "/xyz/openbmc_project/sensors/unknown/id"; 570ef1faf7SPatrick Venture 588729eb98SPatrick Venture auto helper = std::make_unique<DbusHelperMock>(); 59f8cb4644SPatrick Venture struct SensorProperties properties; 600ef1faf7SPatrick Venture 618729eb98SPatrick Venture DbusPassive(bus_mock, type, id, std::move(helper), properties, false, path, 628729eb98SPatrick Venture nullptr); 630ef1faf7SPatrick Venture // Success 640ef1faf7SPatrick Venture } 650ef1faf7SPatrick Venture 66da4a5dd1SPatrick Venture class DbusPassiveTestObj : public ::testing::Test 67da4a5dd1SPatrick Venture { 680ef1faf7SPatrick Venture protected: 69da4a5dd1SPatrick Venture DbusPassiveTestObj() : 70da4a5dd1SPatrick Venture sdbus_mock(), 718729eb98SPatrick Venture bus_mock(std::move(sdbusplus::get_mocked_new(&sdbus_mock))), 728729eb98SPatrick Venture helper(std::make_unique<DbusHelperMock>()) 730ef1faf7SPatrick Venture { 74*9b93692dSPatrick Venture EXPECT_CALL(*helper, getService(StrEq(SensorIntf), StrEq(path))) 750ef1faf7SPatrick Venture .WillOnce(Return("asdf")); 760ef1faf7SPatrick Venture 778729eb98SPatrick Venture EXPECT_CALL(*helper, 78*9b93692dSPatrick Venture getProperties(StrEq("asdf"), StrEq(path), NotNull())) 79*9b93692dSPatrick Venture .WillOnce( 80*9b93692dSPatrick Venture Invoke([&](const std::string& service, const std::string& path, 81*9b93692dSPatrick Venture struct SensorProperties* prop) { 820ef1faf7SPatrick Venture prop->scale = _scale; 830ef1faf7SPatrick Venture prop->value = _value; 840ef1faf7SPatrick Venture prop->unit = "x"; 856b9f5999SPatrick Venture prop->min = 0; 866b9f5999SPatrick Venture prop->max = 0; 870ef1faf7SPatrick Venture })); 88*9b93692dSPatrick Venture EXPECT_CALL(*helper, thresholdsAsserted(StrEq("asdf"), StrEq(path))) 8936b7d8ebSJames Feist .WillOnce(Return(false)); 900ef1faf7SPatrick Venture 91f81f2886SJames Feist auto info = conf::SensorConfig(); 928729eb98SPatrick Venture ri = DbusPassive::createDbusPassive(bus_mock, type, id, 938729eb98SPatrick Venture std::move(helper), &info, nullptr); 940ef1faf7SPatrick Venture passive = reinterpret_cast<DbusPassive*>(ri.get()); 950ef1faf7SPatrick Venture EXPECT_FALSE(passive == nullptr); 960ef1faf7SPatrick Venture } 970ef1faf7SPatrick Venture 980ef1faf7SPatrick Venture sdbusplus::SdBusMock sdbus_mock; 990ef1faf7SPatrick Venture sdbusplus::bus::bus bus_mock; 1008729eb98SPatrick Venture std::unique_ptr<DbusHelperMock> helper; 1010ef1faf7SPatrick Venture std::string type = "temp"; 1020ef1faf7SPatrick Venture std::string id = "id"; 1030ef1faf7SPatrick Venture std::string path = "/xyz/openbmc_project/sensors/temperature/id"; 1040ef1faf7SPatrick Venture int64_t _scale = -3; 1050ef1faf7SPatrick Venture int64_t _value = 10; 1060ef1faf7SPatrick Venture 1070ef1faf7SPatrick Venture std::unique_ptr<ReadInterface> ri; 1080ef1faf7SPatrick Venture DbusPassive* passive; 1090ef1faf7SPatrick Venture }; 1100ef1faf7SPatrick Venture 111da4a5dd1SPatrick Venture TEST_F(DbusPassiveTestObj, ReadReturnsExpectedValues) 112da4a5dd1SPatrick Venture { 1130ef1faf7SPatrick Venture // Verify read is returning the values. 1140ef1faf7SPatrick Venture ReadReturn v; 1150ef1faf7SPatrick Venture v.value = 0.01; 1160ef1faf7SPatrick Venture // TODO: updated is set when the value is created, so we can range check 1170ef1faf7SPatrick Venture // it. 1180ef1faf7SPatrick Venture ReadReturn r = passive->read(); 1190ef1faf7SPatrick Venture EXPECT_EQ(v.value, r.value); 1200ef1faf7SPatrick Venture } 1210ef1faf7SPatrick Venture 122da4a5dd1SPatrick Venture TEST_F(DbusPassiveTestObj, SetValueUpdatesValue) 123da4a5dd1SPatrick Venture { 1240ef1faf7SPatrick Venture // Verify setvalue does as advertised. 1250ef1faf7SPatrick Venture 1260ef1faf7SPatrick Venture double value = 0.01; 1270ef1faf7SPatrick Venture passive->setValue(value); 1280ef1faf7SPatrick Venture 1290ef1faf7SPatrick Venture // TODO: updated is set when the value is set, so we can range check it. 1300ef1faf7SPatrick Venture ReadReturn r = passive->read(); 1310ef1faf7SPatrick Venture EXPECT_EQ(value, r.value); 1320ef1faf7SPatrick Venture } 1330ef1faf7SPatrick Venture 134da4a5dd1SPatrick Venture TEST_F(DbusPassiveTestObj, GetScaleReturnsExpectedValue) 135da4a5dd1SPatrick Venture { 1360ef1faf7SPatrick Venture // Verify the scale is returned as expected. 1370ef1faf7SPatrick Venture EXPECT_EQ(_scale, passive->getScale()); 1380ef1faf7SPatrick Venture } 1390ef1faf7SPatrick Venture 140563a356fSPatrick Venture TEST_F(DbusPassiveTestObj, getIDReturnsExpectedValue) 141da4a5dd1SPatrick Venture { 142563a356fSPatrick Venture // Verify getID returns the expected value. 143563a356fSPatrick Venture EXPECT_EQ(id, passive->getID()); 1440ef1faf7SPatrick Venture } 1450ef1faf7SPatrick Venture 1466b9f5999SPatrick Venture TEST_F(DbusPassiveTestObj, GetMinValueReturnsExpectedValue) 1476b9f5999SPatrick Venture { 1486b9f5999SPatrick Venture EXPECT_DOUBLE_EQ(0, passive->getMin()); 1496b9f5999SPatrick Venture } 1506b9f5999SPatrick Venture 151da4a5dd1SPatrick Venture TEST_F(DbusPassiveTestObj, VerifyHandlesDbusSignal) 152da4a5dd1SPatrick Venture { 1530ef1faf7SPatrick Venture // The dbus passive sensor listens for updates and if it's the Value 1540ef1faf7SPatrick Venture // property, it needs to handle it. 1550ef1faf7SPatrick Venture 1560ef1faf7SPatrick Venture EXPECT_CALL(sdbus_mock, sd_bus_message_ref(IsNull())) 1570ef1faf7SPatrick Venture .WillOnce(Return(nullptr)); 1580ef1faf7SPatrick Venture sdbusplus::message::message msg(nullptr, &sdbus_mock); 1590ef1faf7SPatrick Venture 1600ef1faf7SPatrick Venture const char* Value = "Value"; 1610ef1faf7SPatrick Venture int64_t xValue = 10000; 1620ef1faf7SPatrick Venture const char* intf = "xyz.openbmc_project.Sensor.Value"; 1631f802f5eSJames Feist // string, std::map<std::string, std::variant<int64_t>> 1640ef1faf7SPatrick Venture // msg.read(msgSensor, msgData); 1650ef1faf7SPatrick Venture 166da4a5dd1SPatrick Venture EXPECT_CALL(sdbus_mock, sd_bus_message_read_basic(IsNull(), 's', NotNull())) 1670ef1faf7SPatrick Venture .WillOnce(Invoke([&](sd_bus_message* m, char type, void* p) { 1680ef1faf7SPatrick Venture const char** s = static_cast<const char**>(p); 1690ef1faf7SPatrick Venture // Read the first parameter, the string. 1700ef1faf7SPatrick Venture *s = intf; 1710ef1faf7SPatrick Venture return 0; 1720ef1faf7SPatrick Venture })) 1730ef1faf7SPatrick Venture .WillOnce(Invoke([&](sd_bus_message* m, char type, void* p) { 1740ef1faf7SPatrick Venture const char** s = static_cast<const char**>(p); 1750ef1faf7SPatrick Venture *s = Value; 1760ef1faf7SPatrick Venture // Read the string in the pair (dictionary). 1770ef1faf7SPatrick Venture return 0; 1780ef1faf7SPatrick Venture })); 1790ef1faf7SPatrick Venture 1800ef1faf7SPatrick Venture // std::map 1810ef1faf7SPatrick Venture EXPECT_CALL(sdbus_mock, 1820ef1faf7SPatrick Venture sd_bus_message_enter_container(IsNull(), 'a', StrEq("{sv}"))) 1830ef1faf7SPatrick Venture .WillOnce(Return(0)); 1840ef1faf7SPatrick Venture 1850ef1faf7SPatrick Venture // while !at_end() 1860ef1faf7SPatrick Venture EXPECT_CALL(sdbus_mock, sd_bus_message_at_end(IsNull(), 0)) 1870ef1faf7SPatrick Venture .WillOnce(Return(0)) 1880ef1faf7SPatrick Venture .WillOnce(Return(1)); // So it exits the loop after reading one pair. 1890ef1faf7SPatrick Venture 1900ef1faf7SPatrick Venture // std::pair 1910ef1faf7SPatrick Venture EXPECT_CALL(sdbus_mock, 1920ef1faf7SPatrick Venture sd_bus_message_enter_container(IsNull(), 'e', StrEq("sv"))) 1930ef1faf7SPatrick Venture .WillOnce(Return(0)); 1940ef1faf7SPatrick Venture 1950ef1faf7SPatrick Venture EXPECT_CALL(sdbus_mock, 1960ef1faf7SPatrick Venture sd_bus_message_verify_type(IsNull(), 'v', StrEq("x"))) 1970ef1faf7SPatrick Venture .WillOnce(Return(1)); 1980ef1faf7SPatrick Venture EXPECT_CALL(sdbus_mock, 1990ef1faf7SPatrick Venture sd_bus_message_enter_container(IsNull(), 'v', StrEq("x"))) 2000ef1faf7SPatrick Venture .WillOnce(Return(0)); 2010ef1faf7SPatrick Venture 202da4a5dd1SPatrick Venture EXPECT_CALL(sdbus_mock, sd_bus_message_read_basic(IsNull(), 'x', NotNull())) 2030ef1faf7SPatrick Venture .WillOnce(Invoke([&](sd_bus_message* m, char type, void* p) { 2040ef1faf7SPatrick Venture int64_t* s = static_cast<int64_t*>(p); 2050ef1faf7SPatrick Venture *s = xValue; 2060ef1faf7SPatrick Venture return 0; 2070ef1faf7SPatrick Venture })); 2080ef1faf7SPatrick Venture 2090ef1faf7SPatrick Venture EXPECT_CALL(sdbus_mock, sd_bus_message_exit_container(IsNull())) 2100ef1faf7SPatrick Venture .WillOnce(Return(0)) /* variant. */ 2110ef1faf7SPatrick Venture .WillOnce(Return(0)) /* std::pair */ 2120ef1faf7SPatrick Venture .WillOnce(Return(0)); /* std::map */ 2130ef1faf7SPatrick Venture 2147af157b1SPatrick Venture int rv = handleSensorValue(msg, passive); 2150ef1faf7SPatrick Venture EXPECT_EQ(rv, 0); // It's always 0. 2160ef1faf7SPatrick Venture 2170ef1faf7SPatrick Venture ReadReturn r = passive->read(); 2180ef1faf7SPatrick Venture EXPECT_EQ(10, r.value); 2190ef1faf7SPatrick Venture } 2200ef1faf7SPatrick Venture 221da4a5dd1SPatrick Venture TEST_F(DbusPassiveTestObj, VerifyIgnoresOtherPropertySignal) 222da4a5dd1SPatrick Venture { 2230ef1faf7SPatrick Venture // The dbus passive sensor listens for updates and if it's the Value 2240ef1faf7SPatrick Venture // property, it needs to handle it. In this case, it won't be. 2250ef1faf7SPatrick Venture 2260ef1faf7SPatrick Venture EXPECT_CALL(sdbus_mock, sd_bus_message_ref(IsNull())) 2270ef1faf7SPatrick Venture .WillOnce(Return(nullptr)); 2280ef1faf7SPatrick Venture sdbusplus::message::message msg(nullptr, &sdbus_mock); 2290ef1faf7SPatrick Venture 2300ef1faf7SPatrick Venture const char* Scale = "Scale"; 2310ef1faf7SPatrick Venture int64_t xScale = -6; 2320ef1faf7SPatrick Venture const char* intf = "xyz.openbmc_project.Sensor.Value"; 2331f802f5eSJames Feist // string, std::map<std::string, std::variant<int64_t>> 2340ef1faf7SPatrick Venture // msg.read(msgSensor, msgData); 2350ef1faf7SPatrick Venture 236da4a5dd1SPatrick Venture EXPECT_CALL(sdbus_mock, sd_bus_message_read_basic(IsNull(), 's', NotNull())) 2370ef1faf7SPatrick Venture .WillOnce(Invoke([&](sd_bus_message* m, char type, void* p) { 2380ef1faf7SPatrick Venture const char** s = static_cast<const char**>(p); 2390ef1faf7SPatrick Venture // Read the first parameter, the string. 2400ef1faf7SPatrick Venture *s = intf; 2410ef1faf7SPatrick Venture return 0; 2420ef1faf7SPatrick Venture })) 2430ef1faf7SPatrick Venture .WillOnce(Invoke([&](sd_bus_message* m, char type, void* p) { 2440ef1faf7SPatrick Venture const char** s = static_cast<const char**>(p); 2450ef1faf7SPatrick Venture *s = Scale; 2460ef1faf7SPatrick Venture // Read the string in the pair (dictionary). 2470ef1faf7SPatrick Venture return 0; 2480ef1faf7SPatrick Venture })); 2490ef1faf7SPatrick Venture 2500ef1faf7SPatrick Venture // std::map 2510ef1faf7SPatrick Venture EXPECT_CALL(sdbus_mock, 2520ef1faf7SPatrick Venture sd_bus_message_enter_container(IsNull(), 'a', StrEq("{sv}"))) 2530ef1faf7SPatrick Venture .WillOnce(Return(0)); 2540ef1faf7SPatrick Venture 2550ef1faf7SPatrick Venture // while !at_end() 2560ef1faf7SPatrick Venture EXPECT_CALL(sdbus_mock, sd_bus_message_at_end(IsNull(), 0)) 2570ef1faf7SPatrick Venture .WillOnce(Return(0)) 2580ef1faf7SPatrick Venture .WillOnce(Return(1)); // So it exits the loop after reading one pair. 2590ef1faf7SPatrick Venture 2600ef1faf7SPatrick Venture // std::pair 2610ef1faf7SPatrick Venture EXPECT_CALL(sdbus_mock, 2620ef1faf7SPatrick Venture sd_bus_message_enter_container(IsNull(), 'e', StrEq("sv"))) 2630ef1faf7SPatrick Venture .WillOnce(Return(0)); 2640ef1faf7SPatrick Venture 2650ef1faf7SPatrick Venture EXPECT_CALL(sdbus_mock, 2660ef1faf7SPatrick Venture sd_bus_message_verify_type(IsNull(), 'v', StrEq("x"))) 2670ef1faf7SPatrick Venture .WillOnce(Return(1)); 2680ef1faf7SPatrick Venture EXPECT_CALL(sdbus_mock, 2690ef1faf7SPatrick Venture sd_bus_message_enter_container(IsNull(), 'v', StrEq("x"))) 2700ef1faf7SPatrick Venture .WillOnce(Return(0)); 2710ef1faf7SPatrick Venture 272da4a5dd1SPatrick Venture EXPECT_CALL(sdbus_mock, sd_bus_message_read_basic(IsNull(), 'x', NotNull())) 2730ef1faf7SPatrick Venture .WillOnce(Invoke([&](sd_bus_message* m, char type, void* p) { 2740ef1faf7SPatrick Venture int64_t* s = static_cast<int64_t*>(p); 2750ef1faf7SPatrick Venture *s = xScale; 2760ef1faf7SPatrick Venture return 0; 2770ef1faf7SPatrick Venture })); 2780ef1faf7SPatrick Venture 2790ef1faf7SPatrick Venture EXPECT_CALL(sdbus_mock, sd_bus_message_exit_container(IsNull())) 2800ef1faf7SPatrick Venture .WillOnce(Return(0)) /* variant. */ 2810ef1faf7SPatrick Venture .WillOnce(Return(0)) /* std::pair */ 2820ef1faf7SPatrick Venture .WillOnce(Return(0)); /* std::map */ 2830ef1faf7SPatrick Venture 2847af157b1SPatrick Venture int rv = handleSensorValue(msg, passive); 2850ef1faf7SPatrick Venture EXPECT_EQ(rv, 0); // It's always 0. 2860ef1faf7SPatrick Venture 2870ef1faf7SPatrick Venture ReadReturn r = passive->read(); 2880ef1faf7SPatrick Venture EXPECT_EQ(0.01, r.value); 2890ef1faf7SPatrick Venture } 29036b7d8ebSJames Feist TEST_F(DbusPassiveTestObj, VerifyCriticalThresholdAssert) 29136b7d8ebSJames Feist { 29236b7d8ebSJames Feist 29336b7d8ebSJames Feist // Verifies when a threshold is crossed the sensor goes into error state 29436b7d8ebSJames Feist EXPECT_CALL(sdbus_mock, sd_bus_message_ref(IsNull())) 29536b7d8ebSJames Feist .WillOnce(Return(nullptr)); 29636b7d8ebSJames Feist sdbusplus::message::message msg(nullptr, &sdbus_mock); 29736b7d8ebSJames Feist 29836b7d8ebSJames Feist const char* criticalAlarm = "CriticalAlarmHigh"; 29936b7d8ebSJames Feist bool alarm = true; 30036b7d8ebSJames Feist const char* intf = "xyz.openbmc_project.Sensor.Threshold.Critical"; 30136b7d8ebSJames Feist 30236b7d8ebSJames Feist passive->setFailed(false); 30336b7d8ebSJames Feist 30436b7d8ebSJames Feist EXPECT_CALL(sdbus_mock, sd_bus_message_read_basic(IsNull(), 's', NotNull())) 30536b7d8ebSJames Feist .WillOnce(Invoke([&](sd_bus_message* m, char type, void* p) { 30636b7d8ebSJames Feist const char** s = static_cast<const char**>(p); 30736b7d8ebSJames Feist // Read the first parameter, the string. 30836b7d8ebSJames Feist *s = intf; 30936b7d8ebSJames Feist return 0; 31036b7d8ebSJames Feist })) 31136b7d8ebSJames Feist .WillOnce(Invoke([&](sd_bus_message* m, char type, void* p) { 31236b7d8ebSJames Feist const char** s = static_cast<const char**>(p); 31336b7d8ebSJames Feist *s = criticalAlarm; 31436b7d8ebSJames Feist // Read the string in the pair (dictionary). 31536b7d8ebSJames Feist return 0; 31636b7d8ebSJames Feist })); 31736b7d8ebSJames Feist 31836b7d8ebSJames Feist // std::map 31936b7d8ebSJames Feist EXPECT_CALL(sdbus_mock, 32036b7d8ebSJames Feist sd_bus_message_enter_container(IsNull(), 'a', StrEq("{sv}"))) 32136b7d8ebSJames Feist .WillOnce(Return(0)); 32236b7d8ebSJames Feist 32336b7d8ebSJames Feist // while !at_end() 32436b7d8ebSJames Feist EXPECT_CALL(sdbus_mock, sd_bus_message_at_end(IsNull(), 0)) 32536b7d8ebSJames Feist .WillOnce(Return(0)) 32636b7d8ebSJames Feist .WillOnce(Return(1)); // So it exits the loop after reading one pair. 32736b7d8ebSJames Feist 32836b7d8ebSJames Feist // std::pair 32936b7d8ebSJames Feist EXPECT_CALL(sdbus_mock, 33036b7d8ebSJames Feist sd_bus_message_enter_container(IsNull(), 'e', StrEq("sv"))) 33136b7d8ebSJames Feist .WillOnce(Return(0)); 33236b7d8ebSJames Feist 33336b7d8ebSJames Feist EXPECT_CALL(sdbus_mock, 33436b7d8ebSJames Feist sd_bus_message_verify_type(IsNull(), 'v', StrEq("x"))) 33536b7d8ebSJames Feist .WillOnce(Return(0)); 33636b7d8ebSJames Feist EXPECT_CALL(sdbus_mock, 33736b7d8ebSJames Feist sd_bus_message_verify_type(IsNull(), 'v', StrEq("d"))) 33836b7d8ebSJames Feist .WillOnce(Return(0)); 33936b7d8ebSJames Feist EXPECT_CALL(sdbus_mock, 34036b7d8ebSJames Feist sd_bus_message_verify_type(IsNull(), 'v', StrEq("b"))) 34136b7d8ebSJames Feist .WillOnce(Return(1)); 34236b7d8ebSJames Feist EXPECT_CALL(sdbus_mock, 34336b7d8ebSJames Feist sd_bus_message_enter_container(IsNull(), 'v', StrEq("b"))) 34436b7d8ebSJames Feist .WillOnce(Return(0)); 34536b7d8ebSJames Feist 34636b7d8ebSJames Feist EXPECT_CALL(sdbus_mock, sd_bus_message_read_basic(IsNull(), 'b', NotNull())) 34736b7d8ebSJames Feist .WillOnce(Invoke([&](sd_bus_message* m, char type, void* p) { 34836b7d8ebSJames Feist bool* s = static_cast<bool*>(p); 34936b7d8ebSJames Feist *s = alarm; 35036b7d8ebSJames Feist return 0; 35136b7d8ebSJames Feist })); 35236b7d8ebSJames Feist 35336b7d8ebSJames Feist EXPECT_CALL(sdbus_mock, sd_bus_message_exit_container(IsNull())) 35436b7d8ebSJames Feist .WillOnce(Return(0)) /* variant. */ 35536b7d8ebSJames Feist .WillOnce(Return(0)) /* std::pair */ 35636b7d8ebSJames Feist .WillOnce(Return(0)); /* std::map */ 35736b7d8ebSJames Feist 3587af157b1SPatrick Venture int rv = handleSensorValue(msg, passive); 35936b7d8ebSJames Feist EXPECT_EQ(rv, 0); // It's always 0. 36036b7d8ebSJames Feist bool failed = passive->getFailed(); 36136b7d8ebSJames Feist EXPECT_EQ(failed, true); 36236b7d8ebSJames Feist } 36336b7d8ebSJames Feist 36436b7d8ebSJames Feist TEST_F(DbusPassiveTestObj, VerifyCriticalThresholdDeassert) 36536b7d8ebSJames Feist { 36636b7d8ebSJames Feist 36736b7d8ebSJames Feist // Verifies when a threshold is deasserted a failed sensor goes back into 36836b7d8ebSJames Feist // the normal state 36936b7d8ebSJames Feist EXPECT_CALL(sdbus_mock, sd_bus_message_ref(IsNull())) 37036b7d8ebSJames Feist .WillOnce(Return(nullptr)); 37136b7d8ebSJames Feist sdbusplus::message::message msg(nullptr, &sdbus_mock); 37236b7d8ebSJames Feist 37336b7d8ebSJames Feist const char* criticalAlarm = "CriticalAlarmHigh"; 37436b7d8ebSJames Feist bool alarm = false; 37536b7d8ebSJames Feist const char* intf = "xyz.openbmc_project.Sensor.Threshold.Critical"; 37636b7d8ebSJames Feist 37736b7d8ebSJames Feist passive->setFailed(true); 37836b7d8ebSJames Feist 37936b7d8ebSJames Feist EXPECT_CALL(sdbus_mock, sd_bus_message_read_basic(IsNull(), 's', NotNull())) 38036b7d8ebSJames Feist .WillOnce(Invoke([&](sd_bus_message* m, char type, void* p) { 38136b7d8ebSJames Feist const char** s = static_cast<const char**>(p); 38236b7d8ebSJames Feist // Read the first parameter, the string. 38336b7d8ebSJames Feist *s = intf; 38436b7d8ebSJames Feist return 0; 38536b7d8ebSJames Feist })) 38636b7d8ebSJames Feist .WillOnce(Invoke([&](sd_bus_message* m, char type, void* p) { 38736b7d8ebSJames Feist const char** s = static_cast<const char**>(p); 38836b7d8ebSJames Feist *s = criticalAlarm; 38936b7d8ebSJames Feist // Read the string in the pair (dictionary). 39036b7d8ebSJames Feist return 0; 39136b7d8ebSJames Feist })); 39236b7d8ebSJames Feist 39336b7d8ebSJames Feist // std::map 39436b7d8ebSJames Feist EXPECT_CALL(sdbus_mock, 39536b7d8ebSJames Feist sd_bus_message_enter_container(IsNull(), 'a', StrEq("{sv}"))) 39636b7d8ebSJames Feist .WillOnce(Return(0)); 39736b7d8ebSJames Feist 39836b7d8ebSJames Feist // while !at_end() 39936b7d8ebSJames Feist EXPECT_CALL(sdbus_mock, sd_bus_message_at_end(IsNull(), 0)) 40036b7d8ebSJames Feist .WillOnce(Return(0)) 40136b7d8ebSJames Feist .WillOnce(Return(1)); // So it exits the loop after reading one pair. 40236b7d8ebSJames Feist 40336b7d8ebSJames Feist // std::pair 40436b7d8ebSJames Feist EXPECT_CALL(sdbus_mock, 40536b7d8ebSJames Feist sd_bus_message_enter_container(IsNull(), 'e', StrEq("sv"))) 40636b7d8ebSJames Feist .WillOnce(Return(0)); 40736b7d8ebSJames Feist 40836b7d8ebSJames Feist EXPECT_CALL(sdbus_mock, 40936b7d8ebSJames Feist sd_bus_message_verify_type(IsNull(), 'v', StrEq("x"))) 41036b7d8ebSJames Feist .WillOnce(Return(0)); 41136b7d8ebSJames Feist EXPECT_CALL(sdbus_mock, 41236b7d8ebSJames Feist sd_bus_message_verify_type(IsNull(), 'v', StrEq("d"))) 41336b7d8ebSJames Feist .WillOnce(Return(0)); 41436b7d8ebSJames Feist EXPECT_CALL(sdbus_mock, 41536b7d8ebSJames Feist sd_bus_message_verify_type(IsNull(), 'v', StrEq("b"))) 41636b7d8ebSJames Feist .WillOnce(Return(1)); 41736b7d8ebSJames Feist EXPECT_CALL(sdbus_mock, 41836b7d8ebSJames Feist sd_bus_message_enter_container(IsNull(), 'v', StrEq("b"))) 41936b7d8ebSJames Feist .WillOnce(Return(0)); 42036b7d8ebSJames Feist 42136b7d8ebSJames Feist EXPECT_CALL(sdbus_mock, sd_bus_message_read_basic(IsNull(), 'b', NotNull())) 42236b7d8ebSJames Feist .WillOnce(Invoke([&](sd_bus_message* m, char type, void* p) { 42336b7d8ebSJames Feist bool* s = static_cast<bool*>(p); 42436b7d8ebSJames Feist *s = alarm; 42536b7d8ebSJames Feist return 0; 42636b7d8ebSJames Feist })); 42736b7d8ebSJames Feist 42836b7d8ebSJames Feist EXPECT_CALL(sdbus_mock, sd_bus_message_exit_container(IsNull())) 42936b7d8ebSJames Feist .WillOnce(Return(0)) /* variant. */ 43036b7d8ebSJames Feist .WillOnce(Return(0)) /* std::pair */ 43136b7d8ebSJames Feist .WillOnce(Return(0)); /* std::map */ 43236b7d8ebSJames Feist 4337af157b1SPatrick Venture int rv = handleSensorValue(msg, passive); 43436b7d8ebSJames Feist EXPECT_EQ(rv, 0); // It's always 0. 43536b7d8ebSJames Feist bool failed = passive->getFailed(); 43636b7d8ebSJames Feist EXPECT_EQ(failed, false); 43736b7d8ebSJames Feist } 4386b9f5999SPatrick Venture 439*9b93692dSPatrick Venture void GetPropertiesMax3k(const std::string& service, const std::string& path, 440*9b93692dSPatrick Venture SensorProperties* prop) 4416b9f5999SPatrick Venture { 4426b9f5999SPatrick Venture prop->scale = -3; 4436b9f5999SPatrick Venture prop->value = 10; 4446b9f5999SPatrick Venture prop->unit = "x"; 4456b9f5999SPatrick Venture prop->min = 0; 4466b9f5999SPatrick Venture prop->max = 3000; 4476b9f5999SPatrick Venture } 4486b9f5999SPatrick Venture 449*9b93692dSPatrick Venture using GetPropertiesFunction = std::function<void( 450*9b93692dSPatrick Venture const std::string&, const std::string&, SensorProperties*)>; 4516b9f5999SPatrick Venture 4526b9f5999SPatrick Venture // TODO: There is definitely a cleaner way to do this. 4536b9f5999SPatrick Venture class DbusPassiveTest3kMaxObj : public ::testing::Test 4546b9f5999SPatrick Venture { 4556b9f5999SPatrick Venture protected: 4566b9f5999SPatrick Venture DbusPassiveTest3kMaxObj() : 4576b9f5999SPatrick Venture sdbus_mock(), 4588729eb98SPatrick Venture bus_mock(std::move(sdbusplus::get_mocked_new(&sdbus_mock))), 4598729eb98SPatrick Venture helper(std::make_unique<DbusHelperMock>()) 4606b9f5999SPatrick Venture { 461*9b93692dSPatrick Venture EXPECT_CALL(*helper, getService(StrEq(SensorIntf), StrEq(path))) 4626b9f5999SPatrick Venture .WillOnce(Return("asdf")); 4636b9f5999SPatrick Venture 4648729eb98SPatrick Venture EXPECT_CALL(*helper, 465*9b93692dSPatrick Venture getProperties(StrEq("asdf"), StrEq(path), NotNull())) 4666b9f5999SPatrick Venture .WillOnce(_getProps); 467*9b93692dSPatrick Venture EXPECT_CALL(*helper, thresholdsAsserted(StrEq("asdf"), StrEq(path))) 4686b9f5999SPatrick Venture .WillOnce(Return(false)); 4696b9f5999SPatrick Venture 4706b9f5999SPatrick Venture auto info = conf::SensorConfig(); 4718729eb98SPatrick Venture ri = DbusPassive::createDbusPassive(bus_mock, type, id, 4728729eb98SPatrick Venture std::move(helper), &info, nullptr); 4736b9f5999SPatrick Venture passive = reinterpret_cast<DbusPassive*>(ri.get()); 4746b9f5999SPatrick Venture EXPECT_FALSE(passive == nullptr); 4756b9f5999SPatrick Venture } 4766b9f5999SPatrick Venture 4776b9f5999SPatrick Venture sdbusplus::SdBusMock sdbus_mock; 4786b9f5999SPatrick Venture sdbusplus::bus::bus bus_mock; 4798729eb98SPatrick Venture std::unique_ptr<DbusHelperMock> helper; 4806b9f5999SPatrick Venture std::string type = "temp"; 4816b9f5999SPatrick Venture std::string id = "id"; 4826b9f5999SPatrick Venture std::string path = "/xyz/openbmc_project/sensors/temperature/id"; 4836b9f5999SPatrick Venture int64_t _scale = -3; 4846b9f5999SPatrick Venture int64_t _value = 10; 4856b9f5999SPatrick Venture 4866b9f5999SPatrick Venture std::unique_ptr<ReadInterface> ri; 4876b9f5999SPatrick Venture DbusPassive* passive; 4886b9f5999SPatrick Venture GetPropertiesFunction _getProps = &GetPropertiesMax3k; 4896b9f5999SPatrick Venture }; 4906b9f5999SPatrick Venture 4916b9f5999SPatrick Venture TEST_F(DbusPassiveTest3kMaxObj, ReadMinAndMaxReturnsExpected) 4926b9f5999SPatrick Venture { 4936b9f5999SPatrick Venture EXPECT_DOUBLE_EQ(0, passive->getMin()); 4946b9f5999SPatrick Venture EXPECT_DOUBLE_EQ(3, passive->getMax()); 4956b9f5999SPatrick Venture } 4966b9f5999SPatrick Venture 4976b9f5999SPatrick Venture class DbusPassiveTest3kMaxIgnoredObj : public ::testing::Test 4986b9f5999SPatrick Venture { 4996b9f5999SPatrick Venture protected: 5006b9f5999SPatrick Venture DbusPassiveTest3kMaxIgnoredObj() : 5016b9f5999SPatrick Venture sdbus_mock(), 5028729eb98SPatrick Venture bus_mock(std::move(sdbusplus::get_mocked_new(&sdbus_mock))), 5038729eb98SPatrick Venture helper(std::make_unique<DbusHelperMock>()) 5046b9f5999SPatrick Venture { 505*9b93692dSPatrick Venture EXPECT_CALL(*helper, getService(StrEq(SensorIntf), StrEq(path))) 5066b9f5999SPatrick Venture .WillOnce(Return("asdf")); 5076b9f5999SPatrick Venture 5088729eb98SPatrick Venture EXPECT_CALL(*helper, 509*9b93692dSPatrick Venture getProperties(StrEq("asdf"), StrEq(path), NotNull())) 5106b9f5999SPatrick Venture .WillOnce(_getProps); 511*9b93692dSPatrick Venture EXPECT_CALL(*helper, thresholdsAsserted(StrEq("asdf"), StrEq(path))) 5126b9f5999SPatrick Venture .WillOnce(Return(false)); 5136b9f5999SPatrick Venture 5146b9f5999SPatrick Venture auto info = conf::SensorConfig(); 5156b9f5999SPatrick Venture info.ignoreDbusMinMax = true; 5168729eb98SPatrick Venture ri = DbusPassive::createDbusPassive(bus_mock, type, id, 5178729eb98SPatrick Venture std::move(helper), &info, nullptr); 5186b9f5999SPatrick Venture passive = reinterpret_cast<DbusPassive*>(ri.get()); 5196b9f5999SPatrick Venture EXPECT_FALSE(passive == nullptr); 5206b9f5999SPatrick Venture } 5216b9f5999SPatrick Venture 5226b9f5999SPatrick Venture sdbusplus::SdBusMock sdbus_mock; 5236b9f5999SPatrick Venture sdbusplus::bus::bus bus_mock; 5248729eb98SPatrick Venture std::unique_ptr<DbusHelperMock> helper; 5256b9f5999SPatrick Venture std::string type = "temp"; 5266b9f5999SPatrick Venture std::string id = "id"; 5276b9f5999SPatrick Venture std::string path = "/xyz/openbmc_project/sensors/temperature/id"; 5286b9f5999SPatrick Venture int64_t _scale = -3; 5296b9f5999SPatrick Venture int64_t _value = 10; 5306b9f5999SPatrick Venture 5316b9f5999SPatrick Venture std::unique_ptr<ReadInterface> ri; 5326b9f5999SPatrick Venture DbusPassive* passive; 5336b9f5999SPatrick Venture GetPropertiesFunction _getProps = &GetPropertiesMax3k; 5346b9f5999SPatrick Venture }; 5356b9f5999SPatrick Venture 5366b9f5999SPatrick Venture TEST_F(DbusPassiveTest3kMaxIgnoredObj, ReadMinAndMaxReturnsExpected) 5376b9f5999SPatrick Venture { 5386b9f5999SPatrick Venture EXPECT_DOUBLE_EQ(0, passive->getMin()); 5396b9f5999SPatrick Venture EXPECT_DOUBLE_EQ(0, passive->getMax()); 5406b9f5999SPatrick Venture } 541a076487aSPatrick Venture 542a076487aSPatrick Venture } // namespace 543a076487aSPatrick Venture } // namespace pid_control 544