1 #include "Utils.hpp"
2 
3 #include <array>
4 #include <cstddef>
5 #include <cstdint>
6 #include <cstdlib>
7 #include <filesystem>
8 #include <fstream>
9 #include <iostream>
10 #include <new>
11 #include <string>
12 #include <vector>
13 
14 #include <gtest/gtest.h>
15 
16 namespace fs = std::filesystem;
17 class TestUtils : public testing::Test
18 {
19   public:
20     std::string testDir;
21     fs::path hwmonDir;
22     fs::path peciDir;
TestUtils()23     TestUtils()
24     {
25         // Create test environment
26         auto dir = std::to_array("./testDirXXXXXX");
27         testDir = mkdtemp(dir.data());
28 
29         if (testDir.empty())
30         {
31             throw std::bad_alloc();
32         }
33         hwmonDir = fs::path(testDir) / "hwmon";
34         fs::create_directory(hwmonDir);
35         auto hwmon10 = hwmonDir / "hwmon10";
36         fs::create_directory(hwmonDir / "hwmon10");
37         {
38             std::ofstream temp1Input{hwmon10 / "temp1_input"};
39             std::ofstream temp1Min{hwmon10 / "temp1_min"};
40             std::ofstream temp1Max{hwmon10 / "temp1_max"};
41             std::ofstream temp2Input{hwmon10 / "temp2_input"};
42         }
43         createPECIDir();
44     }
45 
~TestUtils()46     ~TestUtils() override
47     {
48         fs::remove_all(testDir);
49     }
50 
51     TestUtils(const TestUtils&) = delete;
52     TestUtils(TestUtils&&) = delete;
53     TestUtils& operator=(const TestUtils&) = delete;
54     TestUtils& operator=(TestUtils&&) = delete;
55 
createPECIDir()56     void createPECIDir()
57     {
58         peciDir = fs::path(testDir) / "peci";
59         auto peci0 = peciDir /
60                      "peci-0/device/0-30/peci-cputemp.0/hwmon/hwmon25";
61         fs::create_directories(peci0);
62         {
63             std::ofstream temp0Input{peci0 / "temp0_input"};
64             std::ofstream temp1Input{peci0 / "temp1_input"};
65             std::ofstream temp2Input{peci0 / "temp2_input"};
66             std::ofstream name{peci0 / "name"};
67         }
68         auto devDir = peciDir / "peci-0/peci_dev/peci-0";
69         fs::create_directories(devDir);
70         fs::create_directory_symlink("../../../peci-0", devDir / "device");
71         fs::create_directory_symlink("device/0-30", peciDir / "peci-0/0-30");
72 
73         // Let's keep this for debugging purpose
74         for (auto p = fs::recursive_directory_iterator(
75                  peciDir, fs::directory_options::follow_directory_symlink);
76              p != fs::recursive_directory_iterator(); ++p)
77         {
78             std::string path = p->path().string();
79             std::cerr << path << "\n";
80             if (p.depth() >= 6)
81             {
82                 p.disable_recursion_pending();
83             }
84         }
85     }
86 };
87 
TEST_F(TestUtils,findFiles_non_exist)88 TEST_F(TestUtils, findFiles_non_exist)
89 {
90     std::vector<fs::path> foundPaths;
91     auto ret = findFiles("non-exist", "", foundPaths);
92 
93     EXPECT_FALSE(ret);
94     EXPECT_TRUE(foundPaths.empty());
95 }
96 
TEST_F(TestUtils,findFiles_in_hwmon_no_match)97 TEST_F(TestUtils, findFiles_in_hwmon_no_match)
98 {
99     std::vector<fs::path> foundPaths;
100     auto ret = findFiles(hwmonDir, R"(in\d+_input)", foundPaths);
101 
102     EXPECT_TRUE(ret);
103     EXPECT_EQ(foundPaths.size(), 0U);
104 }
105 
TEST_F(TestUtils,findFiles_in_hwmon_match)106 TEST_F(TestUtils, findFiles_in_hwmon_match)
107 {
108     std::vector<fs::path> foundPaths;
109     auto ret = findFiles(hwmonDir, R"(temp\d+_input)", foundPaths);
110 
111     EXPECT_TRUE(ret);
112     EXPECT_EQ(foundPaths.size(), 2U);
113 }
114 
TEST_F(TestUtils,findFiles_in_peci_no_match)115 TEST_F(TestUtils, findFiles_in_peci_no_match)
116 {
117     std::vector<fs::path> foundPaths;
118     auto ret =
119         findFiles(peciDir, R"(peci-\d+/\d+-.+/peci-.+/hwmon/hwmon\d+/aaa$)",
120                   foundPaths, 6);
121 
122     EXPECT_TRUE(ret);
123     EXPECT_TRUE(foundPaths.empty());
124 }
125 
TEST_F(TestUtils,findFiles_in_peci_match)126 TEST_F(TestUtils, findFiles_in_peci_match)
127 {
128     std::vector<fs::path> foundPaths;
129     auto ret =
130         findFiles(peciDir, R"(peci-\d+/\d+-.+/peci-.+/hwmon/hwmon\d+/name$)",
131                   foundPaths, 6);
132     EXPECT_TRUE(ret);
133     EXPECT_EQ(foundPaths.size(), 1U);
134 
135     foundPaths.clear();
136 
137     ret = findFiles(peciDir,
138                     R"(peci-\d+/\d+-.+/peci-.+/hwmon/hwmon\d+/temp\d+_input)",
139                     foundPaths, 6);
140     EXPECT_TRUE(ret);
141     EXPECT_EQ(foundPaths.size(), 3U);
142 }
143 
TEST_F(TestUtils,findFiles_hwmonPath_end_with_slash)144 TEST_F(TestUtils, findFiles_hwmonPath_end_with_slash)
145 {
146     std::string p = hwmonDir.string() + "/";
147     std::vector<fs::path> foundPaths;
148     auto ret = findFiles(p, R"(temp\d+_input)", foundPaths);
149 
150     EXPECT_TRUE(ret);
151     EXPECT_EQ(foundPaths.size(), 2U);
152 }
153 
TEST_F(TestUtils,findFiles_peciPath_end_with_slash)154 TEST_F(TestUtils, findFiles_peciPath_end_with_slash)
155 {
156     std::string p = peciDir.string() + "/";
157     std::vector<fs::path> foundPaths;
158     auto ret =
159         findFiles(p, R"(peci-\d+/\d+-.+/peci-.+/hwmon/hwmon\d+/temp\d+_input)",
160                   foundPaths, 6);
161 
162     EXPECT_TRUE(ret);
163     EXPECT_EQ(foundPaths.size(), 3U);
164 }
165 
TEST_F(TestUtils,findFiles_in_sub_peci_match)166 TEST_F(TestUtils, findFiles_in_sub_peci_match)
167 {
168     std::vector<fs::path> foundPaths;
169     auto ret =
170         findFiles(peciDir / "peci-0", R"(\d+-.+/peci-.+/hwmon/hwmon\d+/name$)",
171                   foundPaths, 5);
172     EXPECT_TRUE(ret);
173     EXPECT_EQ(foundPaths.size(), 1U);
174 
175     foundPaths.clear();
176 
177     ret = findFiles(peciDir / "peci-0",
178                     R"(\d+-.+/peci-.+/hwmon/hwmon\d+/temp\d+_input)",
179                     foundPaths, 5);
180     EXPECT_TRUE(ret);
181     EXPECT_EQ(foundPaths.size(), 3U);
182 }
183 
TEST(GetDeviceBusAddrTest,DevNameInvalid)184 TEST(GetDeviceBusAddrTest, DevNameInvalid)
185 {
186     size_t bus = 0;
187     size_t addr = 0;
188     std::string devName;
189 
190     auto ret = getDeviceBusAddr(devName, bus, addr);
191     EXPECT_FALSE(ret);
192 
193     devName = "NoHyphen";
194     ret = getDeviceBusAddr(devName, bus, addr);
195     EXPECT_FALSE(ret);
196 
197     devName = "pwm-fan";
198     ret = getDeviceBusAddr(devName, bus, addr);
199     EXPECT_FALSE(ret);
200 }
201 
TEST(GetDeviceBusAddrTest,BusInvalid)202 TEST(GetDeviceBusAddrTest, BusInvalid)
203 {
204     size_t bus = 0;
205     size_t addr = 0;
206     std::string devName = "FF-00FF";
207 
208     auto ret = getDeviceBusAddr(devName, bus, addr);
209     EXPECT_FALSE(ret);
210 }
211 
TEST(GetDeviceBusAddrTest,AddrInvalid)212 TEST(GetDeviceBusAddrTest, AddrInvalid)
213 {
214     size_t bus = 0;
215     size_t addr = 0;
216     std::string devName = "12-fan";
217 
218     auto ret = getDeviceBusAddr(devName, bus, addr);
219     EXPECT_FALSE(ret);
220 }
221 
TEST(GetDeviceBusAddrTest,I3CBusAddrValid)222 TEST(GetDeviceBusAddrTest, I3CBusAddrValid)
223 {
224     uint64_t bus = 0;
225     uint64_t provisionedId = 0;
226     std::string devName = "0-22400000001";
227 
228     auto ret = getDeviceBusAddr(devName, bus, provisionedId);
229     EXPECT_TRUE(ret);
230     EXPECT_EQ(bus, 0);
231     EXPECT_EQ(provisionedId, 0x22400000001);
232 }
233 
TEST(GetDeviceBusAddrTest,AllValid)234 TEST(GetDeviceBusAddrTest, AllValid)
235 {
236     size_t bus = 0;
237     size_t addr = 0;
238     std::string devName = "12-00af";
239 
240     auto ret = getDeviceBusAddr(devName, bus, addr);
241     EXPECT_TRUE(ret);
242     EXPECT_EQ(bus, 12);
243     EXPECT_EQ(addr, 0xaf);
244 }
245