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