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
TEST(HostSensorTest,BoringConstructorTest)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
TEST(HostSensorTest,CreateHostTempSensorTest)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
TEST(HostSensorTest,VerifyWriteThenReadMatches)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