1 #include "dbus/dbusutil.hpp"
2
3 #include <xyz/openbmc_project/Sensor/Value/common.hpp>
4
5 #include <cstdint>
6 #include <map>
7 #include <string>
8 #include <tuple>
9 #include <unordered_map>
10 #include <utility>
11 #include <vector>
12
13 #include <gmock/gmock.h>
14 #include <gtest/gtest.h>
15
16 namespace pid_control
17 {
18 namespace
19 {
20
21 using SensorValue = sdbusplus::common::xyz::openbmc_project::sensor::Value;
22
23 using ::testing::ContainerEq;
24 using ::testing::Eq;
25 using ::testing::StrEq;
26 using ::testing::UnorderedElementsAreArray;
27
28 class GetSensorPathTest :
29 public ::testing::TestWithParam<
30 std::tuple<std::string, std::string, std::string>>
31 {};
32
TEST_P(GetSensorPathTest,ReturnsExpectedValue)33 TEST_P(GetSensorPathTest, ReturnsExpectedValue)
34 {
35 // type, id, output
36 const auto& params = GetParam();
37 EXPECT_THAT(getSensorPath(std::get<0>(params), std::get<1>(params)),
38 StrEq(std::get<2>(params)));
39 }
40
41 INSTANTIATE_TEST_SUITE_P(
42 GetSensorPathTests, GetSensorPathTest,
43 ::testing::Values(
44 std::make_tuple("fan", "0",
45 std::format("{}/{}/0",
46 SensorValue::namespace_path::value,
47 SensorValue::namespace_path::fan_tach)),
48 std::make_tuple("as", "we",
49 std::format("{}/unknown/we",
50 SensorValue::namespace_path::value)),
51 std::make_tuple("margin", "9",
52 std::format("{}/{}/9",
53 SensorValue::namespace_path::value,
54 SensorValue::namespace_path::temperature)),
55 std::make_tuple("temp", "123",
56 std::format("{}/{}/123",
57 SensorValue::namespace_path::value,
58 SensorValue::namespace_path::temperature)),
59 std::make_tuple("power", "9000",
60 std::format("{}/{}/9000",
61 SensorValue::namespace_path::value,
62 SensorValue::namespace_path::power)),
63 std::make_tuple("powersum", "total",
64 std::format("{}/{}/total",
65 SensorValue::namespace_path::value,
66 SensorValue::namespace_path::power))));
67
68 class FindSensorsTest : public ::testing::Test
69 {
70 protected:
71 const std::unordered_map<std::string, std::string> sensors = {
72 {"/abcd/_a", "b"}, {"_a", "c"}, {"/abcd_a", "d"},
73 {"/_a_a", "e"}, {"one/slash", "one"}, {"other_/slash", "other"},
74 };
75
76 std::vector<std::pair<std::string, std::string>> results;
77 };
78
TEST_F(FindSensorsTest,NoMatches)79 TEST_F(FindSensorsTest, NoMatches)
80 {
81 const std::string target = "abcd";
82
83 EXPECT_FALSE(findSensors(sensors, target, results));
84 }
85
TEST_F(FindSensorsTest,OneMatches)86 TEST_F(FindSensorsTest, OneMatches)
87 {
88 const std::string target = "_a";
89
90 EXPECT_TRUE(findSensors(sensors, target, results));
91
92 std::vector<std::pair<std::string, std::string>> expected_results = {
93 {"/abcd/_a", "b"},
94 };
95
96 EXPECT_THAT(results, UnorderedElementsAreArray(expected_results));
97 }
98
TEST_F(FindSensorsTest,MultipleMatches)99 TEST_F(FindSensorsTest, MultipleMatches)
100 {
101 const std::string target = "slash";
102 EXPECT_TRUE(findSensors(sensors, target, results));
103
104 std::vector<std::pair<std::string, std::string>> expected_results = {
105 {"one/slash", "one"},
106 {"other_/slash", "other"},
107 };
108
109 EXPECT_THAT(results, UnorderedElementsAreArray(expected_results));
110 }
111
TEST(GetZoneIndexTest,ZoneAlreadyAssigned)112 TEST(GetZoneIndexTest, ZoneAlreadyAssigned)
113 {
114 std::map<std::string, int64_t> zones = {
115 {"a", 0},
116 };
117 const std::map<std::string, int64_t> expected_zones = {
118 {"a", 0},
119 };
120
121 EXPECT_THAT(getZoneIndex("a", zones), Eq(0));
122 EXPECT_THAT(zones, ContainerEq(expected_zones));
123 }
124
TEST(GetZoneIndexTest,ZoneNotYetAssignedZeroBased)125 TEST(GetZoneIndexTest, ZoneNotYetAssignedZeroBased)
126 {
127 /* This calls into setZoneIndex, but is a case hit by getZoneIndex. */
128 std::map<std::string, int64_t> zones;
129 const std::map<std::string, int64_t> expected_zones = {
130 {"a", 0},
131 };
132
133 EXPECT_THAT(getZoneIndex("a", zones), Eq(0));
134 EXPECT_THAT(zones, ContainerEq(expected_zones));
135 }
136
TEST(SetZoneIndexTest,ZoneAlreadyAssigned)137 TEST(SetZoneIndexTest, ZoneAlreadyAssigned)
138 {
139 std::map<std::string, int64_t> zones = {
140 {"a", 0},
141 };
142 const std::map<std::string, int64_t> expected_zones = {
143 {"a", 0},
144 };
145
146 EXPECT_THAT(setZoneIndex("a", zones, 0), Eq(0));
147 EXPECT_THAT(zones, ContainerEq(expected_zones));
148 }
149
TEST(SetZoneIndexTest,ZoneNotYetAssignedEmptyListZeroBased)150 TEST(SetZoneIndexTest, ZoneNotYetAssignedEmptyListZeroBased)
151 {
152 constexpr int64_t index = 0;
153 std::map<std::string, int64_t> zones;
154 const std::map<std::string, int64_t> expected_zones = {
155 {"a", index},
156 };
157
158 EXPECT_THAT(setZoneIndex("a", zones, index), Eq(index));
159 EXPECT_THAT(zones, ContainerEq(expected_zones));
160 }
161
TEST(SetZoneIndexTest,ZoneNotYetAssignedEmptyListNonZeroBased)162 TEST(SetZoneIndexTest, ZoneNotYetAssignedEmptyListNonZeroBased)
163 {
164 constexpr int64_t index = 5;
165 std::map<std::string, int64_t> zones;
166 const std::map<std::string, int64_t> expected_zones = {
167 {"a", index},
168 };
169
170 EXPECT_THAT(setZoneIndex("a", zones, index), Eq(index));
171 EXPECT_THAT(zones, ContainerEq(expected_zones));
172 }
173
TEST(SetZoneIndexTest,ZoneListNotEmptyAssignsNextIndexZeroBased)174 TEST(SetZoneIndexTest, ZoneListNotEmptyAssignsNextIndexZeroBased)
175 {
176 std::map<std::string, int64_t> zones = {
177 {"a", 0},
178 };
179 const std::map<std::string, int64_t> expected_zones = {
180 {"a", 0},
181 {"b", 1},
182 };
183
184 EXPECT_THAT(setZoneIndex("b", zones, 0), Eq(1));
185 EXPECT_THAT(zones, ContainerEq(expected_zones));
186 }
187
TEST(SetZoneIndexTest,ZoneListNotEmptyAssignsNextIndexNonZeroBased)188 TEST(SetZoneIndexTest, ZoneListNotEmptyAssignsNextIndexNonZeroBased)
189 {
190 std::map<std::string, int64_t> zones = {
191 {"a", 0},
192 };
193 const std::map<std::string, int64_t> expected_zones = {
194 {"a", 0},
195 {"b", 5},
196 };
197
198 EXPECT_THAT(setZoneIndex("b", zones, 5), Eq(5));
199 EXPECT_THAT(zones, ContainerEq(expected_zones));
200 }
201
TEST(SetZoneIndexTest,ZoneListNotEmptyAssignsIntoGap)202 TEST(SetZoneIndexTest, ZoneListNotEmptyAssignsIntoGap)
203 {
204 std::map<std::string, int64_t> zones = {
205 {"a", 0},
206 {"b", 5},
207 };
208 const std::map<std::string, int64_t> expected_zones = {
209 {"a", 0},
210 {"c", 1},
211 {"b", 5},
212 };
213
214 EXPECT_THAT(setZoneIndex("c", zones, 0), Eq(1));
215 EXPECT_THAT(zones, ContainerEq(expected_zones));
216 }
217
218 } // namespace
219 } // namespace pid_control
220