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