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