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