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