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