1 #include "failsafeloggers/builder.hpp" 2 #include "failsafeloggers/failsafe_logger.hpp" 3 #include "failsafeloggers/failsafe_logger_utility.hpp" 4 #include "sensors/host.hpp" 5 #include "test/helpers.hpp" 6 7 #include <sdbusplus/test/sdbus_mock.hpp> 8 9 #include <chrono> 10 #include <memory> 11 #include <string> 12 #include <vector> 13 14 #include <gmock/gmock.h> 15 #include <gtest/gtest.h> 16 17 namespace pid_control 18 { 19 namespace 20 { 21 22 using ::testing::IsNull; 23 using ::testing::Return; 24 using ::testing::StrEq; 25 26 TEST(HostSensorTest, BoringConstructorTest) 27 { 28 // WARN: The host sensor is not presently meant to be created this way, 29 // TODO: Can I move the constructor into private? 30 } 31 32 TEST(HostSensorTest, CreateHostTempSensorTest) 33 { 34 // The normal case for this sensor is to be a temperature sensor, where 35 // the value is treated as a margin sensor. 36 37 sdbusplus::SdBusMock sdbus_mock; 38 auto bus_mock = sdbusplus::get_mocked_new(&sdbus_mock); 39 std::string name = "fleeting0"; 40 int64_t timeout = 1; 41 const char* objPath = "/asdf/asdf0"; 42 bool defer = false; 43 std::string interface = "xyz.openbmc_project.Sensor.Value"; 44 45 std::vector<std::string> properties = {}; 46 double d; 47 48 // The createTemp updates all the properties, however, only Scale is set 49 // to non-default. 50 SetupDbusObject(&sdbus_mock, defer, objPath, interface, properties, &d); 51 52 // This is called during object destruction. 53 EXPECT_CALL(sdbus_mock, 54 sd_bus_emit_object_removed(IsNull(), StrEq(objPath))) 55 .WillOnce(Return(0)); 56 57 std::unique_ptr<Sensor> s = 58 HostSensor::createTemp(name, timeout, bus_mock, objPath, defer); 59 } 60 61 TEST(HostSensorTest, VerifyWriteThenReadMatches) 62 { 63 // Verify that when value is updated, the information matches 64 // what we expect when read back. 65 66 sdbusplus::SdBusMock sdbus_mock; 67 auto bus_mock = sdbusplus::get_mocked_new(&sdbus_mock); 68 std::string name = "fleeting0"; 69 int64_t timeout = 1; 70 const char* objPath = "/asdf/asdf0"; 71 bool defer = false; 72 std::string interface = "xyz.openbmc_project.Sensor.Value"; 73 74 std::vector<std::string> properties = {}; 75 double d; 76 77 SetupDbusObject(&sdbus_mock, defer, objPath, interface, properties, &d); 78 79 EXPECT_CALL(sdbus_mock, 80 sd_bus_emit_object_removed(IsNull(), StrEq(objPath))) 81 .WillOnce(Return(0)); 82 83 std::unique_ptr<Sensor> s = 84 HostSensor::createTemp(name, timeout, bus_mock, objPath, defer); 85 86 // Value is updated from dbus calls only (normally). 87 HostSensor* hs = static_cast<HostSensor*>(s.get()); 88 double new_value = 2; 89 90 ReadReturn r = hs->read(); 91 EXPECT_EQ(r.value, 0); 92 93 EXPECT_CALL(sdbus_mock, 94 sd_bus_emit_properties_changed_strv( 95 IsNull(), StrEq(objPath), StrEq(interface), NotNull())) 96 .WillOnce(Invoke( 97 [=]([[maybe_unused]] sd_bus* bus, [[maybe_unused]] const char* path, 98 [[maybe_unused]] const char* interface, const char** names) { 99 EXPECT_STREQ("Value", names[0]); 100 return 0; 101 })); 102 103 std::chrono::high_resolution_clock::time_point t1 = 104 std::chrono::high_resolution_clock::now(); 105 106 hs->value(new_value); 107 r = hs->read(); 108 EXPECT_EQ(r.value, new_value); 109 110 auto duration = 111 std::chrono::duration_cast<std::chrono::seconds>(t1 - r.updated) 112 .count(); 113 114 // Verify it was updated within the last second. 115 EXPECT_TRUE(duration < 1); 116 } 117 118 } // namespace 119 } // namespace pid_control 120