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_CASE_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 
45 class FindSensorsTest : public ::testing::Test
46 {
47   protected:
48     const std::unordered_map<std::string, std::string> sensors = {
49         {"/abcd/_a", "b"}, {"_a", "c"},          {"/abcd_a", "d"},
50         {"/_a_a", "e"},    {"one/slash", "one"}, {"other_/slash", "other"},
51     };
52 
53     std::vector<std::pair<std::string, std::string>> results;
54 };
55 
56 TEST_F(FindSensorsTest, NoMatches)
57 {
58     const std::string target = "abcd";
59 
60     EXPECT_FALSE(findSensors(sensors, target, results));
61 }
62 
63 TEST_F(FindSensorsTest, OneMatches)
64 {
65     const std::string target = "_a";
66 
67     EXPECT_TRUE(findSensors(sensors, target, results));
68 
69     std::vector<std::pair<std::string, std::string>> expected_results = {
70         {"/abcd/_a", "b"},
71     };
72 
73     EXPECT_THAT(results, UnorderedElementsAreArray(expected_results));
74 }
75 
76 TEST_F(FindSensorsTest, MultipleMatches)
77 {
78     const std::string target = "slash";
79     EXPECT_TRUE(findSensors(sensors, target, results));
80 
81     std::vector<std::pair<std::string, std::string>> expected_results = {
82         {"one/slash", "one"},
83         {"other_/slash", "other"},
84     };
85 
86     EXPECT_THAT(results, UnorderedElementsAreArray(expected_results));
87 }
88 
89 TEST(GetZoneIndexTest, ZoneAlreadyAssigned)
90 {
91     std::map<std::string, int64_t> zones = {
92         {"a", 0},
93     };
94     const std::map<std::string, int64_t> expected_zones = {
95         {"a", 0},
96     };
97 
98     EXPECT_THAT(getZoneIndex("a", zones), Eq(0));
99     EXPECT_THAT(zones, ContainerEq(expected_zones));
100 }
101 
102 TEST(GetZoneIndexTest, ZoneNotYetAssignedZeroBased)
103 {
104     /* This calls into setZoneIndex, but is a case hit by getZoneIndex. */
105     std::map<std::string, int64_t> zones;
106     const std::map<std::string, int64_t> expected_zones = {
107         {"a", 0},
108     };
109 
110     EXPECT_THAT(getZoneIndex("a", zones), Eq(0));
111     EXPECT_THAT(zones, ContainerEq(expected_zones));
112 }
113 
114 TEST(SetZoneIndexTest, ZoneAlreadyAssigned)
115 {
116     std::map<std::string, int64_t> zones = {
117         {"a", 0},
118     };
119     const std::map<std::string, int64_t> expected_zones = {
120         {"a", 0},
121     };
122 
123     EXPECT_THAT(setZoneIndex("a", zones, 0), Eq(0));
124     EXPECT_THAT(zones, ContainerEq(expected_zones));
125 }
126 
127 TEST(SetZoneIndexTest, ZoneNotYetAssignedEmptyListZeroBased)
128 {
129     constexpr int64_t index = 0;
130     std::map<std::string, int64_t> zones;
131     const std::map<std::string, int64_t> expected_zones = {
132         {"a", index},
133     };
134 
135     EXPECT_THAT(setZoneIndex("a", zones, index), Eq(index));
136     EXPECT_THAT(zones, ContainerEq(expected_zones));
137 }
138 
139 TEST(SetZoneIndexTest, ZoneNotYetAssignedEmptyListNonZeroBased)
140 {
141     constexpr int64_t index = 5;
142     std::map<std::string, int64_t> zones;
143     const std::map<std::string, int64_t> expected_zones = {
144         {"a", index},
145     };
146 
147     EXPECT_THAT(setZoneIndex("a", zones, index), Eq(index));
148     EXPECT_THAT(zones, ContainerEq(expected_zones));
149 }
150 
151 TEST(SetZoneIndexTest, ZoneListNotEmptyAssignsNextIndexZeroBased)
152 {
153     std::map<std::string, int64_t> zones = {
154         {"a", 0},
155     };
156     const std::map<std::string, int64_t> expected_zones = {
157         {"a", 0},
158         {"b", 1},
159     };
160 
161     EXPECT_THAT(setZoneIndex("b", zones, 0), Eq(1));
162     EXPECT_THAT(zones, ContainerEq(expected_zones));
163 }
164 
165 TEST(SetZoneIndexTest, ZoneListNotEmptyAssignsNextIndexNonZeroBased)
166 {
167     std::map<std::string, int64_t> zones = {
168         {"a", 0},
169     };
170     const std::map<std::string, int64_t> expected_zones = {
171         {"a", 0},
172         {"b", 5},
173     };
174 
175     EXPECT_THAT(setZoneIndex("b", zones, 5), Eq(5));
176     EXPECT_THAT(zones, ContainerEq(expected_zones));
177 }
178 
179 TEST(SetZoneIndexTest, ZoneListNotEmptyAssignsIntoGap)
180 {
181     std::map<std::string, int64_t> zones = {
182         {"a", 0},
183         {"b", 5},
184     };
185     const std::map<std::string, int64_t> expected_zones = {
186         {"a", 0},
187         {"c", 1},
188         {"b", 5},
189     };
190 
191     EXPECT_THAT(setZoneIndex("c", zones, 0), Eq(1));
192     EXPECT_THAT(zones, ContainerEq(expected_zones));
193 }
194 
195 } // namespace
196 } // namespace pid_control
197