1 #include "fan_pwm.hpp"
2 #include "hwmonio_mock.hpp"
3 
4 #include <sdbusplus/test/sdbus_mock.hpp>
5 
6 #include <string>
7 
8 #include <gmock/gmock.h>
9 #include <gtest/gtest.h>
10 
11 using ::testing::_;
12 using ::testing::Invoke;
13 using ::testing::IsNull;
14 using ::testing::NotNull;
15 using ::testing::Return;
16 using ::testing::StrEq;
17 
18 static auto FanPwmIntf = "xyz.openbmc_project.Control.FanPwm";
19 static auto FanPwmProp = "Target";
20 
21 // Handle basic expectations we'll need for all these tests, if it's found that
22 // this is helpful for more tests, it can be promoted in scope.
SetupDbusObject(sdbusplus::SdBusMock * sdbus_mock,const std::string & path,const std::string & intf,const std::string property="")23 void SetupDbusObject(sdbusplus::SdBusMock* sdbus_mock, const std::string& path,
24                      const std::string& intf, const std::string property = "")
25 {
26     if (property.empty())
27     {
28         EXPECT_CALL(*sdbus_mock,
29                     sd_bus_emit_properties_changed_strv(IsNull(), StrEq(path),
30                                                         StrEq(intf), NotNull()))
31             .WillOnce(Return(0));
32     }
33     else
34     {
35         EXPECT_CALL(*sdbus_mock,
36                     sd_bus_emit_properties_changed_strv(IsNull(), StrEq(path),
37                                                         StrEq(intf), NotNull()))
38             .WillOnce(Invoke(
39                 [=](sd_bus*, const char*, const char*, const char** names) {
40                     EXPECT_STREQ(property.c_str(), names[0]);
41                     return 0;
42                 }));
43     }
44 
45     return;
46 }
47 
TEST(FanPwmTest,BasicConstructorDeferredTest)48 TEST(FanPwmTest, BasicConstructorDeferredTest)
49 {
50     // Attempt to just instantiate one.
51 
52     // NOTE: This test's goal is to figure out what's minimally required to
53     // mock to instantiate this object.
54     sdbusplus::SdBusMock sdbus_mock;
55     auto bus_mock = sdbusplus::get_mocked_new(&sdbus_mock);
56 
57     std::string instancePath = "";
58     std::string devPath = "";
59     std::string id = "";
60     std::string objPath = "asdf";
61     bool defer = true;
62     uint64_t target = 0x01;
63 
64     std::unique_ptr<hwmonio::HwmonIOInterface> hwmonio_mock =
65         std::make_unique<hwmonio::HwmonIOMock>();
66 
67     SetupDbusObject(&sdbus_mock, objPath, FanPwmIntf, FanPwmProp);
68 
69     hwmon::FanPwm f(std::move(hwmonio_mock), devPath, id, bus_mock,
70                     objPath.c_str(), defer, target);
71 }
72 
TEST(FanPwmTest,BasicConstructorNotDeferredTest)73 TEST(FanPwmTest, BasicConstructorNotDeferredTest)
74 {
75     // Attempt to just instantiate one.
76 
77     // NOTE: This test's goal is to figure out what's minimally required to
78     // mock to instantiate this object.
79     sdbusplus::SdBusMock sdbus_mock;
80     auto bus_mock = sdbusplus::get_mocked_new(&sdbus_mock);
81 
82     std::string instancePath = "";
83     std::string devPath = "";
84     std::string id = "";
85     std::string objPath = "asdf";
86     bool defer = false;
87     uint64_t target = 0x01;
88 
89     std::unique_ptr<hwmonio::HwmonIOInterface> hwmonio_mock =
90         std::make_unique<hwmonio::HwmonIOMock>();
91 
92     SetupDbusObject(&sdbus_mock, objPath, FanPwmIntf, FanPwmProp);
93 
94     EXPECT_CALL(sdbus_mock, sd_bus_emit_object_added(IsNull(), StrEq("asdf")))
95         .WillOnce(Return(0));
96 
97     EXPECT_CALL(sdbus_mock, sd_bus_emit_object_removed(IsNull(), StrEq("asdf")))
98         .WillOnce(Return(0));
99 
100     hwmon::FanPwm f(std::move(hwmonio_mock), devPath, id, bus_mock,
101                     objPath.c_str(), defer, target);
102 }
103 
TEST(FanPwmTest,WriteTargetValue)104 TEST(FanPwmTest, WriteTargetValue)
105 {
106     // Create a FanPwm and write a value to the object.
107 
108     sdbusplus::SdBusMock sdbus_mock;
109     auto bus_mock = sdbusplus::get_mocked_new(&sdbus_mock);
110 
111     std::string instancePath = "";
112     std::string devPath = "devp";
113     std::string id = "the_id";
114     std::string objPath = "asdf";
115     bool defer = true;
116     uint64_t target = 0x01;
117 
118     std::unique_ptr<hwmonio::HwmonIOInterface> hwmonio_mock =
119         std::make_unique<hwmonio::HwmonIOMock>();
120 
121     SetupDbusObject(&sdbus_mock, objPath, FanPwmIntf, FanPwmProp);
122 
123     hwmonio::HwmonIOMock* hwmonio =
124         reinterpret_cast<hwmonio::HwmonIOMock*>(hwmonio_mock.get());
125 
126     hwmon::FanPwm f(std::move(hwmonio_mock), devPath, id, bus_mock,
127                     objPath.c_str(), defer, target);
128 
129     target = 0x64;
130 
131     EXPECT_CALL(*hwmonio,
132                 write(static_cast<uint32_t>(target), StrEq("pwm"),
133                       StrEq("the_id"), _, hwmonio::retries, hwmonio::delay));
134 
135     EXPECT_CALL(sdbus_mock,
136                 sd_bus_emit_properties_changed_strv(
137                     IsNull(), StrEq("asdf"), StrEq(FanPwmIntf), NotNull()))
138         .WillOnce(
139             Invoke([&](sd_bus*, const char*, const char*, const char** names) {
140                 EXPECT_EQ(0, strncmp("Target", names[0], 6));
141                 return 0;
142             }));
143 
144     EXPECT_EQ(target, f.target(target));
145 }
146 
TEST(FanPwmTest,WriteTargetValueNoUpdate)147 TEST(FanPwmTest, WriteTargetValueNoUpdate)
148 {
149     // Create a FanPwm and write a value to the object that was the previous
150     // value.
151 
152     sdbusplus::SdBusMock sdbus_mock;
153     auto bus_mock = sdbusplus::get_mocked_new(&sdbus_mock);
154 
155     std::string instancePath = "";
156     std::string devPath = "devp";
157     std::string id = "the_id";
158     std::string objPath = "asdf";
159     bool defer = true;
160     uint64_t target = 0x01;
161 
162     std::unique_ptr<hwmonio::HwmonIOInterface> hwmonio_mock =
163         std::make_unique<hwmonio::HwmonIOMock>();
164 
165     SetupDbusObject(&sdbus_mock, objPath, FanPwmIntf, FanPwmProp);
166 
167     hwmon::FanPwm f(std::move(hwmonio_mock), devPath, id, bus_mock,
168                     objPath.c_str(), defer, target);
169 
170     EXPECT_EQ(target, f.target(target));
171 }
172