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>(); 591df9e879SPatrick Venture 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 { 749b93692dSPatrick Venture EXPECT_CALL(*helper, getService(StrEq(SensorIntf), StrEq(path))) 750ef1faf7SPatrick Venture .WillOnce(Return("asdf")); 760ef1faf7SPatrick Venture 778729eb98SPatrick Venture EXPECT_CALL(*helper, 789b93692dSPatrick Venture getProperties(StrEq("asdf"), StrEq(path), NotNull())) 79*a1ae4fa1SHarvey.Wu .WillOnce(Invoke([&]([[maybe_unused]] const std::string& service, 80*a1ae4fa1SHarvey.Wu [[maybe_unused]] const std::string& path, 811df9e879SPatrick Venture 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; 878f73ad76SAlex.Song prop->available = true; 880ef1faf7SPatrick Venture })); 899b93692dSPatrick Venture EXPECT_CALL(*helper, thresholdsAsserted(StrEq("asdf"), StrEq(path))) 9036b7d8ebSJames Feist .WillOnce(Return(false)); 910ef1faf7SPatrick Venture 92f81f2886SJames Feist auto info = conf::SensorConfig(); 938f73ad76SAlex.Song info.unavailableAsFailed = true; 948729eb98SPatrick Venture ri = DbusPassive::createDbusPassive(bus_mock, type, id, 958729eb98SPatrick Venture std::move(helper), &info, nullptr); 960ef1faf7SPatrick Venture passive = reinterpret_cast<DbusPassive*>(ri.get()); 970ef1faf7SPatrick Venture EXPECT_FALSE(passive == nullptr); 980ef1faf7SPatrick Venture } 990ef1faf7SPatrick Venture 1000ef1faf7SPatrick Venture sdbusplus::SdBusMock sdbus_mock; 101b228bc30SPatrick Williams sdbusplus::bus_t bus_mock; 1028729eb98SPatrick Venture std::unique_ptr<DbusHelperMock> helper; 1030ef1faf7SPatrick Venture std::string type = "temp"; 1040ef1faf7SPatrick Venture std::string id = "id"; 1050ef1faf7SPatrick Venture std::string path = "/xyz/openbmc_project/sensors/temperature/id"; 1060ef1faf7SPatrick Venture int64_t _scale = -3; 1070ef1faf7SPatrick Venture int64_t _value = 10; 1080ef1faf7SPatrick Venture 1090ef1faf7SPatrick Venture std::unique_ptr<ReadInterface> ri; 1100ef1faf7SPatrick Venture DbusPassive* passive; 1110ef1faf7SPatrick Venture }; 1120ef1faf7SPatrick Venture 113da4a5dd1SPatrick Venture TEST_F(DbusPassiveTestObj, ReadReturnsExpectedValues) 114da4a5dd1SPatrick Venture { 1150ef1faf7SPatrick Venture // Verify read is returning the values. 1160ef1faf7SPatrick Venture ReadReturn v; 1170ef1faf7SPatrick Venture v.value = 0.01; 1180ef1faf7SPatrick Venture // TODO: updated is set when the value is created, so we can range check 1190ef1faf7SPatrick Venture // it. 1200ef1faf7SPatrick Venture ReadReturn r = passive->read(); 1210ef1faf7SPatrick Venture EXPECT_EQ(v.value, r.value); 1220ef1faf7SPatrick Venture } 1230ef1faf7SPatrick Venture 124da4a5dd1SPatrick Venture TEST_F(DbusPassiveTestObj, SetValueUpdatesValue) 125da4a5dd1SPatrick Venture { 1260ef1faf7SPatrick Venture // Verify setvalue does as advertised. 1270ef1faf7SPatrick Venture 1280ef1faf7SPatrick Venture double value = 0.01; 1290ef1faf7SPatrick Venture passive->setValue(value); 1300ef1faf7SPatrick Venture 1310ef1faf7SPatrick Venture // TODO: updated is set when the value is set, so we can range check it. 1320ef1faf7SPatrick Venture ReadReturn r = passive->read(); 1330ef1faf7SPatrick Venture EXPECT_EQ(value, r.value); 1340ef1faf7SPatrick Venture } 1350ef1faf7SPatrick Venture 136da4a5dd1SPatrick Venture TEST_F(DbusPassiveTestObj, GetScaleReturnsExpectedValue) 137da4a5dd1SPatrick Venture { 1380ef1faf7SPatrick Venture // Verify the scale is returned as expected. 1390ef1faf7SPatrick Venture EXPECT_EQ(_scale, passive->getScale()); 1400ef1faf7SPatrick Venture } 1410ef1faf7SPatrick Venture 142563a356fSPatrick Venture TEST_F(DbusPassiveTestObj, getIDReturnsExpectedValue) 143da4a5dd1SPatrick Venture { 144563a356fSPatrick Venture // Verify getID returns the expected value. 145563a356fSPatrick Venture EXPECT_EQ(id, passive->getID()); 1460ef1faf7SPatrick Venture } 1470ef1faf7SPatrick Venture 1486b9f5999SPatrick Venture TEST_F(DbusPassiveTestObj, GetMinValueReturnsExpectedValue) 1496b9f5999SPatrick Venture { 1506b9f5999SPatrick Venture EXPECT_DOUBLE_EQ(0, passive->getMin()); 1516b9f5999SPatrick Venture } 1526b9f5999SPatrick Venture 153da4a5dd1SPatrick Venture TEST_F(DbusPassiveTestObj, VerifyHandlesDbusSignal) 154da4a5dd1SPatrick Venture { 1550ef1faf7SPatrick Venture // The dbus passive sensor listens for updates and if it's the Value 1560ef1faf7SPatrick Venture // property, it needs to handle it. 1570ef1faf7SPatrick Venture 1580ef1faf7SPatrick Venture EXPECT_CALL(sdbus_mock, sd_bus_message_ref(IsNull())) 1590ef1faf7SPatrick Venture .WillOnce(Return(nullptr)); 160b228bc30SPatrick Williams sdbusplus::message_t msg(nullptr, &sdbus_mock); 1610ef1faf7SPatrick Venture 1620ef1faf7SPatrick Venture const char* Value = "Value"; 1630ef1faf7SPatrick Venture int64_t xValue = 10000; 1640ef1faf7SPatrick Venture const char* intf = "xyz.openbmc_project.Sensor.Value"; 1651f802f5eSJames Feist // string, std::map<std::string, std::variant<int64_t>> 1660ef1faf7SPatrick Venture // msg.read(msgSensor, msgData); 1670ef1faf7SPatrick Venture 168da4a5dd1SPatrick Venture EXPECT_CALL(sdbus_mock, sd_bus_message_read_basic(IsNull(), 's', NotNull())) 169*a1ae4fa1SHarvey.Wu .WillOnce(Invoke([&]([[maybe_unused]] sd_bus_message* m, 170*a1ae4fa1SHarvey.Wu [[maybe_unused]] char type, void* p) { 1710ef1faf7SPatrick Venture const char** s = static_cast<const char**>(p); 1720ef1faf7SPatrick Venture // Read the first parameter, the string. 1730ef1faf7SPatrick Venture *s = intf; 1740ef1faf7SPatrick Venture return 0; 1750ef1faf7SPatrick Venture })) 176*a1ae4fa1SHarvey.Wu .WillOnce(Invoke([&]([[maybe_unused]] sd_bus_message* m, 177*a1ae4fa1SHarvey.Wu [[maybe_unused]] char type, void* p) { 1780ef1faf7SPatrick Venture const char** s = static_cast<const char**>(p); 1790ef1faf7SPatrick Venture *s = Value; 1800ef1faf7SPatrick Venture // Read the string in the pair (dictionary). 1810ef1faf7SPatrick Venture return 0; 1820ef1faf7SPatrick Venture })); 1830ef1faf7SPatrick Venture 1840ef1faf7SPatrick Venture // std::map 1850ef1faf7SPatrick Venture EXPECT_CALL(sdbus_mock, 1860ef1faf7SPatrick Venture sd_bus_message_enter_container(IsNull(), 'a', StrEq("{sv}"))) 1870ef1faf7SPatrick Venture .WillOnce(Return(0)); 1880ef1faf7SPatrick Venture 1890ef1faf7SPatrick Venture // while !at_end() 1900ef1faf7SPatrick Venture EXPECT_CALL(sdbus_mock, sd_bus_message_at_end(IsNull(), 0)) 1910ef1faf7SPatrick Venture .WillOnce(Return(0)) 1920ef1faf7SPatrick Venture .WillOnce(Return(1)); // So it exits the loop after reading one pair. 1930ef1faf7SPatrick Venture 1940ef1faf7SPatrick Venture // std::pair 1950ef1faf7SPatrick Venture EXPECT_CALL(sdbus_mock, 1960ef1faf7SPatrick Venture sd_bus_message_enter_container(IsNull(), 'e', StrEq("sv"))) 1970ef1faf7SPatrick Venture .WillOnce(Return(0)); 1980ef1faf7SPatrick Venture 1990ef1faf7SPatrick Venture EXPECT_CALL(sdbus_mock, 2000ef1faf7SPatrick Venture sd_bus_message_verify_type(IsNull(), 'v', StrEq("x"))) 2010ef1faf7SPatrick Venture .WillOnce(Return(1)); 2020ef1faf7SPatrick Venture EXPECT_CALL(sdbus_mock, 2030ef1faf7SPatrick Venture sd_bus_message_enter_container(IsNull(), 'v', StrEq("x"))) 2040ef1faf7SPatrick Venture .WillOnce(Return(0)); 2050ef1faf7SPatrick Venture 206da4a5dd1SPatrick Venture EXPECT_CALL(sdbus_mock, sd_bus_message_read_basic(IsNull(), 'x', NotNull())) 207*a1ae4fa1SHarvey.Wu .WillOnce(Invoke([&]([[maybe_unused]] sd_bus_message* m, 208*a1ae4fa1SHarvey.Wu [[maybe_unused]] char type, void* p) { 2090ef1faf7SPatrick Venture int64_t* s = static_cast<int64_t*>(p); 2100ef1faf7SPatrick Venture *s = xValue; 2110ef1faf7SPatrick Venture return 0; 2120ef1faf7SPatrick Venture })); 2130ef1faf7SPatrick Venture 2140ef1faf7SPatrick Venture EXPECT_CALL(sdbus_mock, sd_bus_message_exit_container(IsNull())) 2150ef1faf7SPatrick Venture .WillOnce(Return(0)) /* variant. */ 2160ef1faf7SPatrick Venture .WillOnce(Return(0)) /* std::pair */ 2170ef1faf7SPatrick Venture .WillOnce(Return(0)); /* std::map */ 2180ef1faf7SPatrick Venture 2197af157b1SPatrick Venture int rv = handleSensorValue(msg, passive); 2200ef1faf7SPatrick Venture EXPECT_EQ(rv, 0); // It's always 0. 2210ef1faf7SPatrick Venture 2220ef1faf7SPatrick Venture ReadReturn r = passive->read(); 2230ef1faf7SPatrick Venture EXPECT_EQ(10, r.value); 2240ef1faf7SPatrick Venture } 2250ef1faf7SPatrick Venture 226da4a5dd1SPatrick Venture TEST_F(DbusPassiveTestObj, VerifyIgnoresOtherPropertySignal) 227da4a5dd1SPatrick Venture { 2280ef1faf7SPatrick Venture // The dbus passive sensor listens for updates and if it's the Value 2290ef1faf7SPatrick Venture // property, it needs to handle it. In this case, it won't be. 2300ef1faf7SPatrick Venture 2310ef1faf7SPatrick Venture EXPECT_CALL(sdbus_mock, sd_bus_message_ref(IsNull())) 2320ef1faf7SPatrick Venture .WillOnce(Return(nullptr)); 233b228bc30SPatrick Williams sdbusplus::message_t msg(nullptr, &sdbus_mock); 2340ef1faf7SPatrick Venture 2350ef1faf7SPatrick Venture const char* Scale = "Scale"; 2360ef1faf7SPatrick Venture int64_t xScale = -6; 2370ef1faf7SPatrick Venture const char* intf = "xyz.openbmc_project.Sensor.Value"; 2381f802f5eSJames Feist // string, std::map<std::string, std::variant<int64_t>> 2390ef1faf7SPatrick Venture // msg.read(msgSensor, msgData); 2400ef1faf7SPatrick Venture 241da4a5dd1SPatrick Venture EXPECT_CALL(sdbus_mock, sd_bus_message_read_basic(IsNull(), 's', NotNull())) 242*a1ae4fa1SHarvey.Wu .WillOnce(Invoke([&]([[maybe_unused]] sd_bus_message* m, 243*a1ae4fa1SHarvey.Wu [[maybe_unused]] char type, void* p) { 2440ef1faf7SPatrick Venture const char** s = static_cast<const char**>(p); 2450ef1faf7SPatrick Venture // Read the first parameter, the string. 2460ef1faf7SPatrick Venture *s = intf; 2470ef1faf7SPatrick Venture return 0; 2480ef1faf7SPatrick Venture })) 249*a1ae4fa1SHarvey.Wu .WillOnce(Invoke([&]([[maybe_unused]] sd_bus_message* m, 250*a1ae4fa1SHarvey.Wu [[maybe_unused]] char type, void* p) { 2510ef1faf7SPatrick Venture const char** s = static_cast<const char**>(p); 2520ef1faf7SPatrick Venture *s = Scale; 2530ef1faf7SPatrick Venture // Read the string in the pair (dictionary). 2540ef1faf7SPatrick Venture return 0; 2550ef1faf7SPatrick Venture })); 2560ef1faf7SPatrick Venture 2570ef1faf7SPatrick Venture // std::map 2580ef1faf7SPatrick Venture EXPECT_CALL(sdbus_mock, 2590ef1faf7SPatrick Venture sd_bus_message_enter_container(IsNull(), 'a', StrEq("{sv}"))) 2600ef1faf7SPatrick Venture .WillOnce(Return(0)); 2610ef1faf7SPatrick Venture 2620ef1faf7SPatrick Venture // while !at_end() 2630ef1faf7SPatrick Venture EXPECT_CALL(sdbus_mock, sd_bus_message_at_end(IsNull(), 0)) 2640ef1faf7SPatrick Venture .WillOnce(Return(0)) 2650ef1faf7SPatrick Venture .WillOnce(Return(1)); // So it exits the loop after reading one pair. 2660ef1faf7SPatrick Venture 2670ef1faf7SPatrick Venture // std::pair 2680ef1faf7SPatrick Venture EXPECT_CALL(sdbus_mock, 2690ef1faf7SPatrick Venture sd_bus_message_enter_container(IsNull(), 'e', StrEq("sv"))) 2700ef1faf7SPatrick Venture .WillOnce(Return(0)); 2710ef1faf7SPatrick Venture 2720ef1faf7SPatrick Venture EXPECT_CALL(sdbus_mock, 2730ef1faf7SPatrick Venture sd_bus_message_verify_type(IsNull(), 'v', StrEq("x"))) 2740ef1faf7SPatrick Venture .WillOnce(Return(1)); 2750ef1faf7SPatrick Venture EXPECT_CALL(sdbus_mock, 2760ef1faf7SPatrick Venture sd_bus_message_enter_container(IsNull(), 'v', StrEq("x"))) 2770ef1faf7SPatrick Venture .WillOnce(Return(0)); 2780ef1faf7SPatrick Venture 279da4a5dd1SPatrick Venture EXPECT_CALL(sdbus_mock, sd_bus_message_read_basic(IsNull(), 'x', NotNull())) 280*a1ae4fa1SHarvey.Wu .WillOnce(Invoke([&]([[maybe_unused]] sd_bus_message* m, 281*a1ae4fa1SHarvey.Wu [[maybe_unused]] char type, void* p) { 2820ef1faf7SPatrick Venture int64_t* s = static_cast<int64_t*>(p); 2830ef1faf7SPatrick Venture *s = xScale; 2840ef1faf7SPatrick Venture return 0; 2850ef1faf7SPatrick Venture })); 2860ef1faf7SPatrick Venture 2870ef1faf7SPatrick Venture EXPECT_CALL(sdbus_mock, sd_bus_message_exit_container(IsNull())) 2880ef1faf7SPatrick Venture .WillOnce(Return(0)) /* variant. */ 2890ef1faf7SPatrick Venture .WillOnce(Return(0)) /* std::pair */ 2900ef1faf7SPatrick Venture .WillOnce(Return(0)); /* std::map */ 2910ef1faf7SPatrick Venture 2927af157b1SPatrick Venture int rv = handleSensorValue(msg, passive); 2930ef1faf7SPatrick Venture EXPECT_EQ(rv, 0); // It's always 0. 2940ef1faf7SPatrick Venture 2950ef1faf7SPatrick Venture ReadReturn r = passive->read(); 2960ef1faf7SPatrick Venture EXPECT_EQ(0.01, r.value); 2970ef1faf7SPatrick Venture } 2988f73ad76SAlex.Song 29936b7d8ebSJames Feist TEST_F(DbusPassiveTestObj, VerifyCriticalThresholdAssert) 30036b7d8ebSJames Feist { 30136b7d8ebSJames Feist 30236b7d8ebSJames Feist // Verifies when a threshold is crossed the sensor goes into error state 30336b7d8ebSJames Feist EXPECT_CALL(sdbus_mock, sd_bus_message_ref(IsNull())) 30436b7d8ebSJames Feist .WillOnce(Return(nullptr)); 305b228bc30SPatrick Williams sdbusplus::message_t msg(nullptr, &sdbus_mock); 30636b7d8ebSJames Feist 30736b7d8ebSJames Feist const char* criticalAlarm = "CriticalAlarmHigh"; 30836b7d8ebSJames Feist bool alarm = true; 30936b7d8ebSJames Feist const char* intf = "xyz.openbmc_project.Sensor.Threshold.Critical"; 31036b7d8ebSJames Feist 31136b7d8ebSJames Feist passive->setFailed(false); 31236b7d8ebSJames Feist 31336b7d8ebSJames Feist EXPECT_CALL(sdbus_mock, sd_bus_message_read_basic(IsNull(), 's', NotNull())) 314*a1ae4fa1SHarvey.Wu .WillOnce(Invoke([&]([[maybe_unused]] sd_bus_message* m, 315*a1ae4fa1SHarvey.Wu [[maybe_unused]] char type, void* p) { 31636b7d8ebSJames Feist const char** s = static_cast<const char**>(p); 31736b7d8ebSJames Feist // Read the first parameter, the string. 31836b7d8ebSJames Feist *s = intf; 31936b7d8ebSJames Feist return 0; 32036b7d8ebSJames Feist })) 321*a1ae4fa1SHarvey.Wu .WillOnce(Invoke([&]([[maybe_unused]] sd_bus_message* m, 322*a1ae4fa1SHarvey.Wu [[maybe_unused]] char type, void* p) { 32336b7d8ebSJames Feist const char** s = static_cast<const char**>(p); 32436b7d8ebSJames Feist *s = criticalAlarm; 32536b7d8ebSJames Feist // Read the string in the pair (dictionary). 32636b7d8ebSJames Feist return 0; 32736b7d8ebSJames Feist })); 32836b7d8ebSJames Feist 32936b7d8ebSJames Feist // std::map 33036b7d8ebSJames Feist EXPECT_CALL(sdbus_mock, 33136b7d8ebSJames Feist sd_bus_message_enter_container(IsNull(), 'a', StrEq("{sv}"))) 33236b7d8ebSJames Feist .WillOnce(Return(0)); 33336b7d8ebSJames Feist 33436b7d8ebSJames Feist // while !at_end() 33536b7d8ebSJames Feist EXPECT_CALL(sdbus_mock, sd_bus_message_at_end(IsNull(), 0)) 33636b7d8ebSJames Feist .WillOnce(Return(0)) 33736b7d8ebSJames Feist .WillOnce(Return(1)); // So it exits the loop after reading one pair. 33836b7d8ebSJames Feist 33936b7d8ebSJames Feist // std::pair 34036b7d8ebSJames Feist EXPECT_CALL(sdbus_mock, 34136b7d8ebSJames Feist sd_bus_message_enter_container(IsNull(), 'e', StrEq("sv"))) 34236b7d8ebSJames Feist .WillOnce(Return(0)); 34336b7d8ebSJames Feist 34436b7d8ebSJames Feist EXPECT_CALL(sdbus_mock, 34536b7d8ebSJames Feist sd_bus_message_verify_type(IsNull(), 'v', StrEq("x"))) 34636b7d8ebSJames Feist .WillOnce(Return(0)); 34736b7d8ebSJames Feist EXPECT_CALL(sdbus_mock, 34836b7d8ebSJames Feist sd_bus_message_verify_type(IsNull(), 'v', StrEq("d"))) 34936b7d8ebSJames Feist .WillOnce(Return(0)); 35036b7d8ebSJames Feist EXPECT_CALL(sdbus_mock, 35136b7d8ebSJames Feist sd_bus_message_verify_type(IsNull(), 'v', StrEq("b"))) 35236b7d8ebSJames Feist .WillOnce(Return(1)); 35336b7d8ebSJames Feist EXPECT_CALL(sdbus_mock, 35436b7d8ebSJames Feist sd_bus_message_enter_container(IsNull(), 'v', StrEq("b"))) 35536b7d8ebSJames Feist .WillOnce(Return(0)); 35636b7d8ebSJames Feist 35736b7d8ebSJames Feist EXPECT_CALL(sdbus_mock, sd_bus_message_read_basic(IsNull(), 'b', NotNull())) 358*a1ae4fa1SHarvey.Wu .WillOnce(Invoke([&]([[maybe_unused]] sd_bus_message* m, 359*a1ae4fa1SHarvey.Wu [[maybe_unused]] char type, void* p) { 36036b7d8ebSJames Feist bool* s = static_cast<bool*>(p); 36136b7d8ebSJames Feist *s = alarm; 36236b7d8ebSJames Feist return 0; 36336b7d8ebSJames Feist })); 36436b7d8ebSJames Feist 36536b7d8ebSJames Feist EXPECT_CALL(sdbus_mock, sd_bus_message_exit_container(IsNull())) 36636b7d8ebSJames Feist .WillOnce(Return(0)) /* variant. */ 36736b7d8ebSJames Feist .WillOnce(Return(0)) /* std::pair */ 36836b7d8ebSJames Feist .WillOnce(Return(0)); /* std::map */ 36936b7d8ebSJames Feist 3707af157b1SPatrick Venture int rv = handleSensorValue(msg, passive); 37136b7d8ebSJames Feist EXPECT_EQ(rv, 0); // It's always 0. 37236b7d8ebSJames Feist bool failed = passive->getFailed(); 37336b7d8ebSJames Feist EXPECT_EQ(failed, true); 37436b7d8ebSJames Feist } 37536b7d8ebSJames Feist 37636b7d8ebSJames Feist TEST_F(DbusPassiveTestObj, VerifyCriticalThresholdDeassert) 37736b7d8ebSJames Feist { 37836b7d8ebSJames Feist 37936b7d8ebSJames Feist // Verifies when a threshold is deasserted a failed sensor goes back into 38036b7d8ebSJames Feist // the normal state 38136b7d8ebSJames Feist EXPECT_CALL(sdbus_mock, sd_bus_message_ref(IsNull())) 38236b7d8ebSJames Feist .WillOnce(Return(nullptr)); 383b228bc30SPatrick Williams sdbusplus::message_t msg(nullptr, &sdbus_mock); 38436b7d8ebSJames Feist 38536b7d8ebSJames Feist const char* criticalAlarm = "CriticalAlarmHigh"; 38636b7d8ebSJames Feist bool alarm = false; 38736b7d8ebSJames Feist const char* intf = "xyz.openbmc_project.Sensor.Threshold.Critical"; 38836b7d8ebSJames Feist 38936b7d8ebSJames Feist passive->setFailed(true); 39036b7d8ebSJames Feist 39136b7d8ebSJames Feist EXPECT_CALL(sdbus_mock, sd_bus_message_read_basic(IsNull(), 's', NotNull())) 392*a1ae4fa1SHarvey.Wu .WillOnce(Invoke([&]([[maybe_unused]] sd_bus_message* m, 393*a1ae4fa1SHarvey.Wu [[maybe_unused]] char type, void* p) { 39436b7d8ebSJames Feist const char** s = static_cast<const char**>(p); 39536b7d8ebSJames Feist // Read the first parameter, the string. 39636b7d8ebSJames Feist *s = intf; 39736b7d8ebSJames Feist return 0; 39836b7d8ebSJames Feist })) 399*a1ae4fa1SHarvey.Wu .WillOnce(Invoke([&]([[maybe_unused]] sd_bus_message* m, 400*a1ae4fa1SHarvey.Wu [[maybe_unused]] char type, void* p) { 40136b7d8ebSJames Feist const char** s = static_cast<const char**>(p); 40236b7d8ebSJames Feist *s = criticalAlarm; 40336b7d8ebSJames Feist // Read the string in the pair (dictionary). 40436b7d8ebSJames Feist return 0; 40536b7d8ebSJames Feist })); 40636b7d8ebSJames Feist 40736b7d8ebSJames Feist // std::map 40836b7d8ebSJames Feist EXPECT_CALL(sdbus_mock, 40936b7d8ebSJames Feist sd_bus_message_enter_container(IsNull(), 'a', StrEq("{sv}"))) 41036b7d8ebSJames Feist .WillOnce(Return(0)); 41136b7d8ebSJames Feist 41236b7d8ebSJames Feist // while !at_end() 41336b7d8ebSJames Feist EXPECT_CALL(sdbus_mock, sd_bus_message_at_end(IsNull(), 0)) 41436b7d8ebSJames Feist .WillOnce(Return(0)) 41536b7d8ebSJames Feist .WillOnce(Return(1)); // So it exits the loop after reading one pair. 41636b7d8ebSJames Feist 41736b7d8ebSJames Feist // std::pair 41836b7d8ebSJames Feist EXPECT_CALL(sdbus_mock, 41936b7d8ebSJames Feist sd_bus_message_enter_container(IsNull(), 'e', StrEq("sv"))) 42036b7d8ebSJames Feist .WillOnce(Return(0)); 42136b7d8ebSJames Feist 42236b7d8ebSJames Feist EXPECT_CALL(sdbus_mock, 42336b7d8ebSJames Feist sd_bus_message_verify_type(IsNull(), 'v', StrEq("x"))) 42436b7d8ebSJames Feist .WillOnce(Return(0)); 42536b7d8ebSJames Feist EXPECT_CALL(sdbus_mock, 42636b7d8ebSJames Feist sd_bus_message_verify_type(IsNull(), 'v', StrEq("d"))) 42736b7d8ebSJames Feist .WillOnce(Return(0)); 42836b7d8ebSJames Feist EXPECT_CALL(sdbus_mock, 42936b7d8ebSJames Feist sd_bus_message_verify_type(IsNull(), 'v', StrEq("b"))) 43036b7d8ebSJames Feist .WillOnce(Return(1)); 43136b7d8ebSJames Feist EXPECT_CALL(sdbus_mock, 43236b7d8ebSJames Feist sd_bus_message_enter_container(IsNull(), 'v', StrEq("b"))) 43336b7d8ebSJames Feist .WillOnce(Return(0)); 43436b7d8ebSJames Feist 43536b7d8ebSJames Feist EXPECT_CALL(sdbus_mock, sd_bus_message_read_basic(IsNull(), 'b', NotNull())) 436*a1ae4fa1SHarvey.Wu .WillOnce(Invoke([&]([[maybe_unused]] sd_bus_message* m, 437*a1ae4fa1SHarvey.Wu [[maybe_unused]] char type, void* p) { 43836b7d8ebSJames Feist bool* s = static_cast<bool*>(p); 43936b7d8ebSJames Feist *s = alarm; 44036b7d8ebSJames Feist return 0; 44136b7d8ebSJames Feist })); 44236b7d8ebSJames Feist 44336b7d8ebSJames Feist EXPECT_CALL(sdbus_mock, sd_bus_message_exit_container(IsNull())) 44436b7d8ebSJames Feist .WillOnce(Return(0)) /* variant. */ 44536b7d8ebSJames Feist .WillOnce(Return(0)) /* std::pair */ 44636b7d8ebSJames Feist .WillOnce(Return(0)); /* std::map */ 44736b7d8ebSJames Feist 4487af157b1SPatrick Venture int rv = handleSensorValue(msg, passive); 44936b7d8ebSJames Feist EXPECT_EQ(rv, 0); // It's always 0. 45036b7d8ebSJames Feist bool failed = passive->getFailed(); 45136b7d8ebSJames Feist EXPECT_EQ(failed, false); 45236b7d8ebSJames Feist } 4536b9f5999SPatrick Venture 4548f73ad76SAlex.Song TEST_F(DbusPassiveTestObj, VerifyAvailableDeassert) 4558f73ad76SAlex.Song { 4568f73ad76SAlex.Song 4578f73ad76SAlex.Song // Verifies when Availble is deasserted && unavailableAsFailed == true, 4588f73ad76SAlex.Song // the sensor goes into error state 4598f73ad76SAlex.Song EXPECT_CALL(sdbus_mock, sd_bus_message_ref(IsNull())) 4608f73ad76SAlex.Song .WillOnce(Return(nullptr)); 461b228bc30SPatrick Williams sdbusplus::message_t msg(nullptr, &sdbus_mock); 4628f73ad76SAlex.Song 4638f73ad76SAlex.Song const char* property = "Available"; 4648f73ad76SAlex.Song bool asserted = false; 4658f73ad76SAlex.Song const char* intf = "xyz.openbmc_project.State.Decorator.Availability"; 4668f73ad76SAlex.Song 4678f73ad76SAlex.Song passive->setAvailable(true); 4688f73ad76SAlex.Song 4698f73ad76SAlex.Song EXPECT_CALL(sdbus_mock, sd_bus_message_read_basic(IsNull(), 's', NotNull())) 470*a1ae4fa1SHarvey.Wu .WillOnce(Invoke([&]([[maybe_unused]] sd_bus_message* m, 471*a1ae4fa1SHarvey.Wu [[maybe_unused]] char type, void* p) { 4728f73ad76SAlex.Song const char** s = static_cast<const char**>(p); 4738f73ad76SAlex.Song // Read the first parameter, the string. 4748f73ad76SAlex.Song *s = intf; 4758f73ad76SAlex.Song return 0; 4768f73ad76SAlex.Song })) 477*a1ae4fa1SHarvey.Wu .WillOnce(Invoke([&]([[maybe_unused]] sd_bus_message* m, 478*a1ae4fa1SHarvey.Wu [[maybe_unused]] char type, void* p) { 4798f73ad76SAlex.Song const char** s = static_cast<const char**>(p); 4808f73ad76SAlex.Song *s = property; 4818f73ad76SAlex.Song // Read the string in the pair (dictionary). 4828f73ad76SAlex.Song return 0; 4838f73ad76SAlex.Song })); 4848f73ad76SAlex.Song 4858f73ad76SAlex.Song // std::map 4868f73ad76SAlex.Song EXPECT_CALL(sdbus_mock, 4878f73ad76SAlex.Song sd_bus_message_enter_container(IsNull(), 'a', StrEq("{sv}"))) 4888f73ad76SAlex.Song .WillOnce(Return(0)); 4898f73ad76SAlex.Song 4908f73ad76SAlex.Song // while !at_end() 4918f73ad76SAlex.Song EXPECT_CALL(sdbus_mock, sd_bus_message_at_end(IsNull(), 0)) 4928f73ad76SAlex.Song .WillOnce(Return(0)) 4938f73ad76SAlex.Song .WillOnce(Return(1)); // So it exits the loop after reading one pair. 4948f73ad76SAlex.Song 4958f73ad76SAlex.Song // std::pair 4968f73ad76SAlex.Song EXPECT_CALL(sdbus_mock, 4978f73ad76SAlex.Song sd_bus_message_enter_container(IsNull(), 'e', StrEq("sv"))) 4988f73ad76SAlex.Song .WillOnce(Return(0)); 4998f73ad76SAlex.Song 5008f73ad76SAlex.Song EXPECT_CALL(sdbus_mock, 5018f73ad76SAlex.Song sd_bus_message_verify_type(IsNull(), 'v', StrEq("x"))) 5028f73ad76SAlex.Song .WillOnce(Return(0)); 5038f73ad76SAlex.Song EXPECT_CALL(sdbus_mock, 5048f73ad76SAlex.Song sd_bus_message_verify_type(IsNull(), 'v', StrEq("d"))) 5058f73ad76SAlex.Song .WillOnce(Return(0)); 5068f73ad76SAlex.Song EXPECT_CALL(sdbus_mock, 5078f73ad76SAlex.Song sd_bus_message_verify_type(IsNull(), 'v', StrEq("b"))) 5088f73ad76SAlex.Song .WillOnce(Return(1)); 5098f73ad76SAlex.Song EXPECT_CALL(sdbus_mock, 5108f73ad76SAlex.Song sd_bus_message_enter_container(IsNull(), 'v', StrEq("b"))) 5118f73ad76SAlex.Song .WillOnce(Return(0)); 5128f73ad76SAlex.Song 5138f73ad76SAlex.Song EXPECT_CALL(sdbus_mock, sd_bus_message_read_basic(IsNull(), 'b', NotNull())) 514*a1ae4fa1SHarvey.Wu .WillOnce(Invoke([&]([[maybe_unused]] sd_bus_message* m, 515*a1ae4fa1SHarvey.Wu [[maybe_unused]] char type, void* p) { 5168f73ad76SAlex.Song bool* s = static_cast<bool*>(p); 5178f73ad76SAlex.Song *s = asserted; 5188f73ad76SAlex.Song return 0; 5198f73ad76SAlex.Song })); 5208f73ad76SAlex.Song 5218f73ad76SAlex.Song EXPECT_CALL(sdbus_mock, sd_bus_message_exit_container(IsNull())) 5228f73ad76SAlex.Song .WillOnce(Return(0)) /* variant. */ 5238f73ad76SAlex.Song .WillOnce(Return(0)) /* std::pair */ 5248f73ad76SAlex.Song .WillOnce(Return(0)); /* std::map */ 5258f73ad76SAlex.Song 5268f73ad76SAlex.Song int rv = handleSensorValue(msg, passive); 5278f73ad76SAlex.Song EXPECT_EQ(rv, 0); // It's always 0. 5288f73ad76SAlex.Song bool failed = passive->getFailed(); 5298f73ad76SAlex.Song EXPECT_EQ(failed, true); 5308f73ad76SAlex.Song } 5318f73ad76SAlex.Song 5328f73ad76SAlex.Song TEST_F(DbusPassiveTestObj, VerifyAvailableAssert) 5338f73ad76SAlex.Song { 5348f73ad76SAlex.Song 5358f73ad76SAlex.Song // Verifies when Availble is asserted && unavailableAsFailed == true, 5368f73ad76SAlex.Song // an error sensor goes back to normal state 5378f73ad76SAlex.Song EXPECT_CALL(sdbus_mock, sd_bus_message_ref(IsNull())) 5388f73ad76SAlex.Song .WillOnce(Return(nullptr)); 539b228bc30SPatrick Williams sdbusplus::message_t msg(nullptr, &sdbus_mock); 5408f73ad76SAlex.Song 5418f73ad76SAlex.Song const char* property = "Available"; 5428f73ad76SAlex.Song bool asserted = true; 5438f73ad76SAlex.Song const char* intf = "xyz.openbmc_project.State.Decorator.Availability"; 5448f73ad76SAlex.Song 5458f73ad76SAlex.Song passive->setAvailable(false); 5468f73ad76SAlex.Song bool failed = passive->getFailed(); 5478f73ad76SAlex.Song EXPECT_EQ(failed, true); 5488f73ad76SAlex.Song 5498f73ad76SAlex.Song EXPECT_CALL(sdbus_mock, sd_bus_message_read_basic(IsNull(), 's', NotNull())) 550*a1ae4fa1SHarvey.Wu .WillOnce(Invoke([&]([[maybe_unused]] sd_bus_message* m, 551*a1ae4fa1SHarvey.Wu [[maybe_unused]] char type, void* p) { 5528f73ad76SAlex.Song const char** s = static_cast<const char**>(p); 5538f73ad76SAlex.Song // Read the first parameter, the string. 5548f73ad76SAlex.Song *s = intf; 5558f73ad76SAlex.Song return 0; 5568f73ad76SAlex.Song })) 557*a1ae4fa1SHarvey.Wu .WillOnce(Invoke([&]([[maybe_unused]] sd_bus_message* m, 558*a1ae4fa1SHarvey.Wu [[maybe_unused]] char type, void* p) { 5598f73ad76SAlex.Song const char** s = static_cast<const char**>(p); 5608f73ad76SAlex.Song *s = property; 5618f73ad76SAlex.Song // Read the string in the pair (dictionary). 5628f73ad76SAlex.Song return 0; 5638f73ad76SAlex.Song })); 5648f73ad76SAlex.Song 5658f73ad76SAlex.Song // std::map 5668f73ad76SAlex.Song EXPECT_CALL(sdbus_mock, 5678f73ad76SAlex.Song sd_bus_message_enter_container(IsNull(), 'a', StrEq("{sv}"))) 5688f73ad76SAlex.Song .WillOnce(Return(0)); 5698f73ad76SAlex.Song 5708f73ad76SAlex.Song // while !at_end() 5718f73ad76SAlex.Song EXPECT_CALL(sdbus_mock, sd_bus_message_at_end(IsNull(), 0)) 5728f73ad76SAlex.Song .WillOnce(Return(0)) 5738f73ad76SAlex.Song .WillOnce(Return(1)); // So it exits the loop after reading one pair. 5748f73ad76SAlex.Song 5758f73ad76SAlex.Song // std::pair 5768f73ad76SAlex.Song EXPECT_CALL(sdbus_mock, 5778f73ad76SAlex.Song sd_bus_message_enter_container(IsNull(), 'e', StrEq("sv"))) 5788f73ad76SAlex.Song .WillOnce(Return(0)); 5798f73ad76SAlex.Song 5808f73ad76SAlex.Song EXPECT_CALL(sdbus_mock, 5818f73ad76SAlex.Song sd_bus_message_verify_type(IsNull(), 'v', StrEq("x"))) 5828f73ad76SAlex.Song .WillOnce(Return(0)); 5838f73ad76SAlex.Song EXPECT_CALL(sdbus_mock, 5848f73ad76SAlex.Song sd_bus_message_verify_type(IsNull(), 'v', StrEq("d"))) 5858f73ad76SAlex.Song .WillOnce(Return(0)); 5868f73ad76SAlex.Song EXPECT_CALL(sdbus_mock, 5878f73ad76SAlex.Song sd_bus_message_verify_type(IsNull(), 'v', StrEq("b"))) 5888f73ad76SAlex.Song .WillOnce(Return(1)); 5898f73ad76SAlex.Song EXPECT_CALL(sdbus_mock, 5908f73ad76SAlex.Song sd_bus_message_enter_container(IsNull(), 'v', StrEq("b"))) 5918f73ad76SAlex.Song .WillOnce(Return(0)); 5928f73ad76SAlex.Song 5938f73ad76SAlex.Song EXPECT_CALL(sdbus_mock, sd_bus_message_read_basic(IsNull(), 'b', NotNull())) 594*a1ae4fa1SHarvey.Wu .WillOnce(Invoke([&]([[maybe_unused]] sd_bus_message* m, 595*a1ae4fa1SHarvey.Wu [[maybe_unused]] char type, void* p) { 5968f73ad76SAlex.Song bool* s = static_cast<bool*>(p); 5978f73ad76SAlex.Song *s = asserted; 5988f73ad76SAlex.Song return 0; 5998f73ad76SAlex.Song })); 6008f73ad76SAlex.Song 6018f73ad76SAlex.Song EXPECT_CALL(sdbus_mock, sd_bus_message_exit_container(IsNull())) 6028f73ad76SAlex.Song .WillOnce(Return(0)) /* variant. */ 6038f73ad76SAlex.Song .WillOnce(Return(0)) /* std::pair */ 6048f73ad76SAlex.Song .WillOnce(Return(0)); /* std::map */ 6058f73ad76SAlex.Song 6068f73ad76SAlex.Song int rv = handleSensorValue(msg, passive); 6078f73ad76SAlex.Song EXPECT_EQ(rv, 0); // It's always 0. 6088f73ad76SAlex.Song failed = passive->getFailed(); 6098f73ad76SAlex.Song EXPECT_EQ(failed, false); 6108f73ad76SAlex.Song } 6118f73ad76SAlex.Song 6128f73ad76SAlex.Song class DbusPassiveTestUnaSensorNotAsFailedObj : public ::testing::Test 6138f73ad76SAlex.Song { 6148f73ad76SAlex.Song protected: 6158f73ad76SAlex.Song DbusPassiveTestUnaSensorNotAsFailedObj() : 6168f73ad76SAlex.Song sdbus_mock(), 6178f73ad76SAlex.Song bus_mock(std::move(sdbusplus::get_mocked_new(&sdbus_mock))), 6188f73ad76SAlex.Song helper(std::make_unique<DbusHelperMock>()) 6198f73ad76SAlex.Song { 6208f73ad76SAlex.Song EXPECT_CALL(*helper, getService(StrEq(SensorIntf), StrEq(path))) 6218f73ad76SAlex.Song .WillOnce(Return("asdf")); 6228f73ad76SAlex.Song 6238f73ad76SAlex.Song EXPECT_CALL(*helper, 6248f73ad76SAlex.Song getProperties(StrEq("asdf"), StrEq(path), NotNull())) 625*a1ae4fa1SHarvey.Wu .WillOnce(Invoke([&]([[maybe_unused]] const std::string& service, 626*a1ae4fa1SHarvey.Wu [[maybe_unused]] const std::string& path, 6278f73ad76SAlex.Song SensorProperties* prop) { 6288f73ad76SAlex.Song prop->scale = _scale; 6298f73ad76SAlex.Song prop->value = _value; 6308f73ad76SAlex.Song prop->unit = "x"; 6318f73ad76SAlex.Song prop->min = 0; 6328f73ad76SAlex.Song prop->max = 0; 6338f73ad76SAlex.Song prop->available = true; 6348f73ad76SAlex.Song })); 6358f73ad76SAlex.Song EXPECT_CALL(*helper, thresholdsAsserted(StrEq("asdf"), StrEq(path))) 6368f73ad76SAlex.Song .WillOnce(Return(false)); 6378f73ad76SAlex.Song 6388f73ad76SAlex.Song auto info = conf::SensorConfig(); 6398f73ad76SAlex.Song info.unavailableAsFailed = false; 6408f73ad76SAlex.Song ri = DbusPassive::createDbusPassive(bus_mock, type, id, 6418f73ad76SAlex.Song std::move(helper), &info, nullptr); 6428f73ad76SAlex.Song passive = reinterpret_cast<DbusPassive*>(ri.get()); 6438f73ad76SAlex.Song EXPECT_FALSE(passive == nullptr); 6448f73ad76SAlex.Song } 6458f73ad76SAlex.Song 6468f73ad76SAlex.Song sdbusplus::SdBusMock sdbus_mock; 647b228bc30SPatrick Williams sdbusplus::bus_t bus_mock; 6488f73ad76SAlex.Song std::unique_ptr<DbusHelperMock> helper; 6498f73ad76SAlex.Song std::string type = "temp"; 6508f73ad76SAlex.Song std::string id = "id"; 6518f73ad76SAlex.Song std::string path = "/xyz/openbmc_project/sensors/temperature/id"; 6528f73ad76SAlex.Song int64_t _scale = -3; 6538f73ad76SAlex.Song int64_t _value = 10; 6548f73ad76SAlex.Song 6558f73ad76SAlex.Song std::unique_ptr<ReadInterface> ri; 6568f73ad76SAlex.Song DbusPassive* passive; 6578f73ad76SAlex.Song }; 6588f73ad76SAlex.Song 6598f73ad76SAlex.Song TEST_F(DbusPassiveTestUnaSensorNotAsFailedObj, VerifyAvailableDeassert) 6608f73ad76SAlex.Song { 6618f73ad76SAlex.Song 6628f73ad76SAlex.Song // Verifies when Availble is deasserted && unavailableAsFailed == false, 6638f73ad76SAlex.Song // the sensor remains at OK state but reading goes to NaN. 6648f73ad76SAlex.Song EXPECT_CALL(sdbus_mock, sd_bus_message_ref(IsNull())) 6658f73ad76SAlex.Song .WillOnce(Return(nullptr)); 666b228bc30SPatrick Williams sdbusplus::message_t msg(nullptr, &sdbus_mock); 6678f73ad76SAlex.Song 6688f73ad76SAlex.Song const char* property = "Available"; 6698f73ad76SAlex.Song bool asserted = false; 6708f73ad76SAlex.Song const char* intf = "xyz.openbmc_project.State.Decorator.Availability"; 6718f73ad76SAlex.Song 6728f73ad76SAlex.Song passive->setAvailable(true); 6738f73ad76SAlex.Song 6748f73ad76SAlex.Song EXPECT_CALL(sdbus_mock, sd_bus_message_read_basic(IsNull(), 's', NotNull())) 675*a1ae4fa1SHarvey.Wu .WillOnce(Invoke([&]([[maybe_unused]] sd_bus_message* m, 676*a1ae4fa1SHarvey.Wu [[maybe_unused]] char type, void* p) { 6778f73ad76SAlex.Song const char** s = static_cast<const char**>(p); 6788f73ad76SAlex.Song // Read the first parameter, the string. 6798f73ad76SAlex.Song *s = intf; 6808f73ad76SAlex.Song return 0; 6818f73ad76SAlex.Song })) 682*a1ae4fa1SHarvey.Wu .WillOnce(Invoke([&]([[maybe_unused]] sd_bus_message* m, 683*a1ae4fa1SHarvey.Wu [[maybe_unused]] char type, void* p) { 6848f73ad76SAlex.Song const char** s = static_cast<const char**>(p); 6858f73ad76SAlex.Song *s = property; 6868f73ad76SAlex.Song // Read the string in the pair (dictionary). 6878f73ad76SAlex.Song return 0; 6888f73ad76SAlex.Song })); 6898f73ad76SAlex.Song 6908f73ad76SAlex.Song // std::map 6918f73ad76SAlex.Song EXPECT_CALL(sdbus_mock, 6928f73ad76SAlex.Song sd_bus_message_enter_container(IsNull(), 'a', StrEq("{sv}"))) 6938f73ad76SAlex.Song .WillOnce(Return(0)); 6948f73ad76SAlex.Song 6958f73ad76SAlex.Song // while !at_end() 6968f73ad76SAlex.Song EXPECT_CALL(sdbus_mock, sd_bus_message_at_end(IsNull(), 0)) 6978f73ad76SAlex.Song .WillOnce(Return(0)) 6988f73ad76SAlex.Song .WillOnce(Return(1)); // So it exits the loop after reading one pair. 6998f73ad76SAlex.Song 7008f73ad76SAlex.Song // std::pair 7018f73ad76SAlex.Song EXPECT_CALL(sdbus_mock, 7028f73ad76SAlex.Song sd_bus_message_enter_container(IsNull(), 'e', StrEq("sv"))) 7038f73ad76SAlex.Song .WillOnce(Return(0)); 7048f73ad76SAlex.Song 7058f73ad76SAlex.Song EXPECT_CALL(sdbus_mock, 7068f73ad76SAlex.Song sd_bus_message_verify_type(IsNull(), 'v', StrEq("x"))) 7078f73ad76SAlex.Song .WillOnce(Return(0)); 7088f73ad76SAlex.Song EXPECT_CALL(sdbus_mock, 7098f73ad76SAlex.Song sd_bus_message_verify_type(IsNull(), 'v', StrEq("d"))) 7108f73ad76SAlex.Song .WillOnce(Return(0)); 7118f73ad76SAlex.Song EXPECT_CALL(sdbus_mock, 7128f73ad76SAlex.Song sd_bus_message_verify_type(IsNull(), 'v', StrEq("b"))) 7138f73ad76SAlex.Song .WillOnce(Return(1)); 7148f73ad76SAlex.Song EXPECT_CALL(sdbus_mock, 7158f73ad76SAlex.Song sd_bus_message_enter_container(IsNull(), 'v', StrEq("b"))) 7168f73ad76SAlex.Song .WillOnce(Return(0)); 7178f73ad76SAlex.Song 7188f73ad76SAlex.Song EXPECT_CALL(sdbus_mock, sd_bus_message_read_basic(IsNull(), 'b', NotNull())) 719*a1ae4fa1SHarvey.Wu .WillOnce(Invoke([&]([[maybe_unused]] sd_bus_message* m, 720*a1ae4fa1SHarvey.Wu [[maybe_unused]] char type, void* p) { 7218f73ad76SAlex.Song bool* s = static_cast<bool*>(p); 7228f73ad76SAlex.Song *s = asserted; 7238f73ad76SAlex.Song return 0; 7248f73ad76SAlex.Song })); 7258f73ad76SAlex.Song 7268f73ad76SAlex.Song EXPECT_CALL(sdbus_mock, sd_bus_message_exit_container(IsNull())) 7278f73ad76SAlex.Song .WillOnce(Return(0)) /* variant. */ 7288f73ad76SAlex.Song .WillOnce(Return(0)) /* std::pair */ 7298f73ad76SAlex.Song .WillOnce(Return(0)); /* std::map */ 7308f73ad76SAlex.Song 7318f73ad76SAlex.Song int rv = handleSensorValue(msg, passive); 7328f73ad76SAlex.Song EXPECT_EQ(rv, 0); // It's always 0. 7338f73ad76SAlex.Song bool failed = passive->getFailed(); 7348f73ad76SAlex.Song EXPECT_EQ(failed, false); 7358f73ad76SAlex.Song ReadReturn r = passive->read(); 7368f73ad76SAlex.Song EXPECT_FALSE(std::isfinite(r.value)); 7378f73ad76SAlex.Song } 7388f73ad76SAlex.Song 7398f73ad76SAlex.Song TEST_F(DbusPassiveTestUnaSensorNotAsFailedObj, VerifyAvailableAssert) 7408f73ad76SAlex.Song { 7418f73ad76SAlex.Song 7428f73ad76SAlex.Song // Verifies when a sensor's state goes from unavailble to available 7438f73ad76SAlex.Song // && unavailableAsFailed == false, this sensor remains at OK state. 7448f73ad76SAlex.Song EXPECT_CALL(sdbus_mock, sd_bus_message_ref(IsNull())) 7458f73ad76SAlex.Song .WillOnce(Return(nullptr)); 746b228bc30SPatrick Williams sdbusplus::message_t msg(nullptr, &sdbus_mock); 7478f73ad76SAlex.Song 7488f73ad76SAlex.Song const char* property = "Available"; 7498f73ad76SAlex.Song bool asserted = true; 7508f73ad76SAlex.Song const char* intf = "xyz.openbmc_project.State.Decorator.Availability"; 7518f73ad76SAlex.Song 7528f73ad76SAlex.Song passive->setAvailable(false); 7538f73ad76SAlex.Song bool failed = passive->getFailed(); 7548f73ad76SAlex.Song EXPECT_EQ(failed, false); 7558f73ad76SAlex.Song 7568f73ad76SAlex.Song EXPECT_CALL(sdbus_mock, sd_bus_message_read_basic(IsNull(), 's', NotNull())) 757*a1ae4fa1SHarvey.Wu .WillOnce(Invoke([&]([[maybe_unused]] sd_bus_message* m, 758*a1ae4fa1SHarvey.Wu [[maybe_unused]] char type, void* p) { 7598f73ad76SAlex.Song const char** s = static_cast<const char**>(p); 7608f73ad76SAlex.Song // Read the first parameter, the string. 7618f73ad76SAlex.Song *s = intf; 7628f73ad76SAlex.Song return 0; 7638f73ad76SAlex.Song })) 764*a1ae4fa1SHarvey.Wu .WillOnce(Invoke([&]([[maybe_unused]] sd_bus_message* m, 765*a1ae4fa1SHarvey.Wu [[maybe_unused]] char type, void* p) { 7668f73ad76SAlex.Song const char** s = static_cast<const char**>(p); 7678f73ad76SAlex.Song *s = property; 7688f73ad76SAlex.Song // Read the string in the pair (dictionary). 7698f73ad76SAlex.Song return 0; 7708f73ad76SAlex.Song })); 7718f73ad76SAlex.Song 7728f73ad76SAlex.Song // std::map 7738f73ad76SAlex.Song EXPECT_CALL(sdbus_mock, 7748f73ad76SAlex.Song sd_bus_message_enter_container(IsNull(), 'a', StrEq("{sv}"))) 7758f73ad76SAlex.Song .WillOnce(Return(0)); 7768f73ad76SAlex.Song 7778f73ad76SAlex.Song // while !at_end() 7788f73ad76SAlex.Song EXPECT_CALL(sdbus_mock, sd_bus_message_at_end(IsNull(), 0)) 7798f73ad76SAlex.Song .WillOnce(Return(0)) 7808f73ad76SAlex.Song .WillOnce(Return(1)); // So it exits the loop after reading one pair. 7818f73ad76SAlex.Song 7828f73ad76SAlex.Song // std::pair 7838f73ad76SAlex.Song EXPECT_CALL(sdbus_mock, 7848f73ad76SAlex.Song sd_bus_message_enter_container(IsNull(), 'e', StrEq("sv"))) 7858f73ad76SAlex.Song .WillOnce(Return(0)); 7868f73ad76SAlex.Song 7878f73ad76SAlex.Song EXPECT_CALL(sdbus_mock, 7888f73ad76SAlex.Song sd_bus_message_verify_type(IsNull(), 'v', StrEq("x"))) 7898f73ad76SAlex.Song .WillOnce(Return(0)); 7908f73ad76SAlex.Song EXPECT_CALL(sdbus_mock, 7918f73ad76SAlex.Song sd_bus_message_verify_type(IsNull(), 'v', StrEq("d"))) 7928f73ad76SAlex.Song .WillOnce(Return(0)); 7938f73ad76SAlex.Song EXPECT_CALL(sdbus_mock, 7948f73ad76SAlex.Song sd_bus_message_verify_type(IsNull(), 'v', StrEq("b"))) 7958f73ad76SAlex.Song .WillOnce(Return(1)); 7968f73ad76SAlex.Song EXPECT_CALL(sdbus_mock, 7978f73ad76SAlex.Song sd_bus_message_enter_container(IsNull(), 'v', StrEq("b"))) 7988f73ad76SAlex.Song .WillOnce(Return(0)); 7998f73ad76SAlex.Song 8008f73ad76SAlex.Song EXPECT_CALL(sdbus_mock, sd_bus_message_read_basic(IsNull(), 'b', NotNull())) 801*a1ae4fa1SHarvey.Wu .WillOnce(Invoke([&]([[maybe_unused]] sd_bus_message* m, 802*a1ae4fa1SHarvey.Wu [[maybe_unused]] char type, void* p) { 8038f73ad76SAlex.Song bool* s = static_cast<bool*>(p); 8048f73ad76SAlex.Song *s = asserted; 8058f73ad76SAlex.Song return 0; 8068f73ad76SAlex.Song })); 8078f73ad76SAlex.Song 8088f73ad76SAlex.Song EXPECT_CALL(sdbus_mock, sd_bus_message_exit_container(IsNull())) 8098f73ad76SAlex.Song .WillOnce(Return(0)) /* variant. */ 8108f73ad76SAlex.Song .WillOnce(Return(0)) /* std::pair */ 8118f73ad76SAlex.Song .WillOnce(Return(0)); /* std::map */ 8128f73ad76SAlex.Song 8138f73ad76SAlex.Song int rv = handleSensorValue(msg, passive); 8148f73ad76SAlex.Song EXPECT_EQ(rv, 0); // It's always 0. 8158f73ad76SAlex.Song failed = passive->getFailed(); 8168f73ad76SAlex.Song EXPECT_EQ(failed, false); 8178f73ad76SAlex.Song } 8188f73ad76SAlex.Song 819*a1ae4fa1SHarvey.Wu void GetPropertiesMax3k([[maybe_unused]] const std::string& service, 820*a1ae4fa1SHarvey.Wu [[maybe_unused]] const std::string& path, 8219b93692dSPatrick Venture SensorProperties* prop) 8226b9f5999SPatrick Venture { 8236b9f5999SPatrick Venture prop->scale = -3; 8246b9f5999SPatrick Venture prop->value = 10; 8256b9f5999SPatrick Venture prop->unit = "x"; 8266b9f5999SPatrick Venture prop->min = 0; 8276b9f5999SPatrick Venture prop->max = 3000; 8286b9f5999SPatrick Venture } 8296b9f5999SPatrick Venture 8309b93692dSPatrick Venture using GetPropertiesFunction = std::function<void( 8319b93692dSPatrick Venture const std::string&, const std::string&, SensorProperties*)>; 8326b9f5999SPatrick Venture 8336b9f5999SPatrick Venture // TODO: There is definitely a cleaner way to do this. 8346b9f5999SPatrick Venture class DbusPassiveTest3kMaxObj : public ::testing::Test 8356b9f5999SPatrick Venture { 8366b9f5999SPatrick Venture protected: 8376b9f5999SPatrick Venture DbusPassiveTest3kMaxObj() : 8386b9f5999SPatrick Venture sdbus_mock(), 8398729eb98SPatrick Venture bus_mock(std::move(sdbusplus::get_mocked_new(&sdbus_mock))), 8408729eb98SPatrick Venture helper(std::make_unique<DbusHelperMock>()) 8416b9f5999SPatrick Venture { 8429b93692dSPatrick Venture EXPECT_CALL(*helper, getService(StrEq(SensorIntf), StrEq(path))) 8436b9f5999SPatrick Venture .WillOnce(Return("asdf")); 8446b9f5999SPatrick Venture 8458729eb98SPatrick Venture EXPECT_CALL(*helper, 8469b93692dSPatrick Venture getProperties(StrEq("asdf"), StrEq(path), NotNull())) 8476b9f5999SPatrick Venture .WillOnce(_getProps); 8489b93692dSPatrick Venture EXPECT_CALL(*helper, thresholdsAsserted(StrEq("asdf"), StrEq(path))) 8496b9f5999SPatrick Venture .WillOnce(Return(false)); 8506b9f5999SPatrick Venture 8516b9f5999SPatrick Venture auto info = conf::SensorConfig(); 8528729eb98SPatrick Venture ri = DbusPassive::createDbusPassive(bus_mock, type, id, 8538729eb98SPatrick Venture std::move(helper), &info, nullptr); 8546b9f5999SPatrick Venture passive = reinterpret_cast<DbusPassive*>(ri.get()); 8556b9f5999SPatrick Venture EXPECT_FALSE(passive == nullptr); 8566b9f5999SPatrick Venture } 8576b9f5999SPatrick Venture 8586b9f5999SPatrick Venture sdbusplus::SdBusMock sdbus_mock; 859b228bc30SPatrick Williams sdbusplus::bus_t bus_mock; 8608729eb98SPatrick Venture std::unique_ptr<DbusHelperMock> helper; 8616b9f5999SPatrick Venture std::string type = "temp"; 8626b9f5999SPatrick Venture std::string id = "id"; 8636b9f5999SPatrick Venture std::string path = "/xyz/openbmc_project/sensors/temperature/id"; 8646b9f5999SPatrick Venture int64_t _scale = -3; 8656b9f5999SPatrick Venture int64_t _value = 10; 8666b9f5999SPatrick Venture 8676b9f5999SPatrick Venture std::unique_ptr<ReadInterface> ri; 8686b9f5999SPatrick Venture DbusPassive* passive; 8696b9f5999SPatrick Venture GetPropertiesFunction _getProps = &GetPropertiesMax3k; 8706b9f5999SPatrick Venture }; 8716b9f5999SPatrick Venture 8726b9f5999SPatrick Venture TEST_F(DbusPassiveTest3kMaxObj, ReadMinAndMaxReturnsExpected) 8736b9f5999SPatrick Venture { 8746b9f5999SPatrick Venture EXPECT_DOUBLE_EQ(0, passive->getMin()); 8756b9f5999SPatrick Venture EXPECT_DOUBLE_EQ(3, passive->getMax()); 8766b9f5999SPatrick Venture } 8776b9f5999SPatrick Venture 8786b9f5999SPatrick Venture class DbusPassiveTest3kMaxIgnoredObj : public ::testing::Test 8796b9f5999SPatrick Venture { 8806b9f5999SPatrick Venture protected: 8816b9f5999SPatrick Venture DbusPassiveTest3kMaxIgnoredObj() : 8826b9f5999SPatrick Venture sdbus_mock(), 8838729eb98SPatrick Venture bus_mock(std::move(sdbusplus::get_mocked_new(&sdbus_mock))), 8848729eb98SPatrick Venture helper(std::make_unique<DbusHelperMock>()) 8856b9f5999SPatrick Venture { 8869b93692dSPatrick Venture EXPECT_CALL(*helper, getService(StrEq(SensorIntf), StrEq(path))) 8876b9f5999SPatrick Venture .WillOnce(Return("asdf")); 8886b9f5999SPatrick Venture 8898729eb98SPatrick Venture EXPECT_CALL(*helper, 8909b93692dSPatrick Venture getProperties(StrEq("asdf"), StrEq(path), NotNull())) 8916b9f5999SPatrick Venture .WillOnce(_getProps); 8929b93692dSPatrick Venture EXPECT_CALL(*helper, thresholdsAsserted(StrEq("asdf"), StrEq(path))) 8936b9f5999SPatrick Venture .WillOnce(Return(false)); 8946b9f5999SPatrick Venture 8956b9f5999SPatrick Venture auto info = conf::SensorConfig(); 8966b9f5999SPatrick Venture info.ignoreDbusMinMax = true; 8978729eb98SPatrick Venture ri = DbusPassive::createDbusPassive(bus_mock, type, id, 8988729eb98SPatrick Venture std::move(helper), &info, nullptr); 8996b9f5999SPatrick Venture passive = reinterpret_cast<DbusPassive*>(ri.get()); 9006b9f5999SPatrick Venture EXPECT_FALSE(passive == nullptr); 9016b9f5999SPatrick Venture } 9026b9f5999SPatrick Venture 9036b9f5999SPatrick Venture sdbusplus::SdBusMock sdbus_mock; 904b228bc30SPatrick Williams sdbusplus::bus_t bus_mock; 9058729eb98SPatrick Venture std::unique_ptr<DbusHelperMock> helper; 9066b9f5999SPatrick Venture std::string type = "temp"; 9076b9f5999SPatrick Venture std::string id = "id"; 9086b9f5999SPatrick Venture std::string path = "/xyz/openbmc_project/sensors/temperature/id"; 9096b9f5999SPatrick Venture int64_t _scale = -3; 9106b9f5999SPatrick Venture int64_t _value = 10; 9116b9f5999SPatrick Venture 9126b9f5999SPatrick Venture std::unique_ptr<ReadInterface> ri; 9136b9f5999SPatrick Venture DbusPassive* passive; 9146b9f5999SPatrick Venture GetPropertiesFunction _getProps = &GetPropertiesMax3k; 9156b9f5999SPatrick Venture }; 9166b9f5999SPatrick Venture 9176b9f5999SPatrick Venture TEST_F(DbusPassiveTest3kMaxIgnoredObj, ReadMinAndMaxReturnsExpected) 9186b9f5999SPatrick Venture { 9196b9f5999SPatrick Venture EXPECT_DOUBLE_EQ(0, passive->getMin()); 9206b9f5999SPatrick Venture EXPECT_DOUBLE_EQ(0, passive->getMax()); 9216b9f5999SPatrick Venture } 922a076487aSPatrick Venture 923a076487aSPatrick Venture } // namespace 924a076487aSPatrick Venture } // namespace pid_control 925