1 #include "estoraged_conf.hpp"
2 #include "getConfig.hpp"
3
4 #include <boost/container/flat_map.hpp>
5 #include <util.hpp>
6
7 #include <filesystem>
8 #include <fstream>
9
10 #include <gmock/gmock-matchers.h>
11 #include <gmock/gmock.h>
12 #include <gtest/gtest.h>
13
14 namespace estoraged_test
15 {
16 using estoraged::util::findPredictedMediaLifeLeftPercent;
17 using estoraged::util::getPartNumber;
18 using estoraged::util::getSerialNumber;
19
TEST(utilTest,passFindPredictedMediaLife)20 TEST(utilTest, passFindPredictedMediaLife)
21 {
22 std::string prefixName = ".";
23 std::string testFileName = prefixName + "/life_time";
24 std::ofstream testFile;
25 testFile.open(testFileName,
26 std::ios::out | std::ios::binary | std::ios::trunc);
27 testFile << "0x07 0x04";
28 testFile.close();
29 EXPECT_EQ(findPredictedMediaLifeLeftPercent(prefixName), 40);
30 EXPECT_TRUE(std::filesystem::remove(testFileName));
31 }
32
TEST(utilTest,estimatesSame)33 TEST(utilTest, estimatesSame)
34 {
35 std::string prefixName = ".";
36 std::string testFileName = prefixName + "/life_time";
37 std::ofstream testFile;
38 testFile.open(testFileName,
39 std::ios::out | std::ios::binary | std::ios::trunc);
40 testFile << "0x04 0x04";
41 testFile.close();
42
43 EXPECT_EQ(findPredictedMediaLifeLeftPercent(prefixName), 70);
44 EXPECT_TRUE(std::filesystem::remove(testFileName));
45 }
46
TEST(utilTest,estimatesNotAvailable)47 TEST(utilTest, estimatesNotAvailable)
48 {
49 std::string prefixName = ".";
50 std::string testFileName = prefixName + "/life_time";
51 std::ofstream testFile;
52 testFile.open(testFileName,
53 std::ios::out | std::ios::binary | std::ios::trunc);
54 testFile.close();
55
56 EXPECT_EQ(findPredictedMediaLifeLeftPercent(prefixName), 255);
57 EXPECT_TRUE(std::filesystem::remove(testFileName));
58 }
59
TEST(utilTest,getPartNumberFail)60 TEST(utilTest, getPartNumberFail)
61 {
62 std::string prefixName = ".";
63 std::string testFileName = prefixName + "/name";
64 /* The part name file won't exist for this test. */
65 EXPECT_EQ(getPartNumber(prefixName), "unknown");
66 }
67
TEST(utilTest,getPartNumberPass)68 TEST(utilTest, getPartNumberPass)
69 {
70 std::string prefixName = ".";
71 std::string testFileName = prefixName + "/name";
72 std::ofstream testFile;
73 testFile.open(testFileName,
74 std::ios::out | std::ios::binary | std::ios::trunc);
75 testFile << "ABCD1234";
76 testFile.close();
77 EXPECT_EQ(getPartNumber(prefixName), "ABCD1234");
78 EXPECT_TRUE(std::filesystem::remove(testFileName));
79 }
80
TEST(utilTest,getSerialNumberFail)81 TEST(utilTest, getSerialNumberFail)
82 {
83 std::string prefixName = ".";
84 std::string testFileName = prefixName + "/serial";
85 /* The serial number file won't exist for this test. */
86 EXPECT_EQ(getSerialNumber(prefixName), "unknown");
87 }
88
TEST(utilTest,getSerialNumberPass)89 TEST(utilTest, getSerialNumberPass)
90 {
91 std::string prefixName = ".";
92 std::string testFileName = prefixName + "/serial";
93 std::ofstream testFile;
94 testFile.open(testFileName,
95 std::ios::out | std::ios::binary | std::ios::trunc);
96 testFile << "0x12345678";
97 testFile.close();
98 EXPECT_EQ(getSerialNumber(prefixName), "0x12345678");
99 EXPECT_TRUE(std::filesystem::remove(testFileName));
100 }
101
102 /* Test case where we successfully find the device file. */
TEST(utilTest,findDevicePass)103 TEST(utilTest, findDevicePass)
104 {
105 estoraged::StorageData data;
106
107 /* Set up the map of properties. */
108 data.emplace(std::string("Type"),
109 estoraged::BasicVariantType("EmmcDevice"));
110 data.emplace(std::string("Name"), estoraged::BasicVariantType("emmc"));
111 data.emplace(std::string("LocationCode"),
112 estoraged::BasicVariantType("U102020"));
113
114 /* Create a dummy device. */
115 std::filesystem::create_directories("abc/device");
116 const std::string dummyTypeFileName("abc/device/type");
117 std::ofstream dummyTypeFile(dummyTypeFileName,
118 std::ios::out | std::ios::trunc);
119 dummyTypeFile << "SSD";
120 dummyTypeFile.close();
121
122 /* Another device. */
123 std::filesystem::create_directories("def/device");
124
125 /* Create a dummy eMMC device. */
126 std::filesystem::create_directories("mmcblk0/device");
127 const std::string typeFileName("mmcblk0/device/type");
128 std::ofstream typeFile(typeFileName, std::ios::out | std::ios::trunc);
129 typeFile << "MMC";
130 typeFile.close();
131
132 /* Look for the device file. */
133 std::filesystem::path deviceFile, sysfsDir;
134 std::string luksName, locationCode;
135 auto result =
136 estoraged::util::findDevice(data, std::filesystem::path("./"));
137 EXPECT_TRUE(result.has_value());
138
139 /* Validate the results. */
140 EXPECT_EQ("/dev/mmcblk0", result->deviceFile.string());
141 EXPECT_EQ("./mmcblk0/device", result->sysfsDir.string());
142 EXPECT_EQ("luks-mmcblk0", result->luksName);
143 EXPECT_EQ("U102020", result->locationCode);
144 EXPECT_EQ(ERASE_MAX_GEOMETRY, result->eraseMaxGeometry);
145 EXPECT_EQ(ERASE_MIN_GEOMETRY, result->eraseMinGeometry);
146 EXPECT_EQ("SSD", result->driveType);
147 EXPECT_EQ("eMMC", result->driveProtocol);
148
149 /* Delete the dummy files. */
150 EXPECT_EQ(3U, std::filesystem::remove_all("mmcblk0"));
151 EXPECT_EQ(3U, std::filesystem::remove_all("abc"));
152 EXPECT_EQ(2U, std::filesystem::remove_all("def"));
153 }
154
155 /* Test case where we successfully find the device file with updating the
156 * min/max geometry. */
TEST(utilTest,findDeviceWithMaxAndMinGeometryPass)157 TEST(utilTest, findDeviceWithMaxAndMinGeometryPass)
158 {
159 estoraged::StorageData data;
160
161 /* Set up the map of properties. */
162 data.emplace(std::string("Type"),
163 estoraged::BasicVariantType("EmmcDevice"));
164 data.emplace(std::string("Name"), estoraged::BasicVariantType("emmc"));
165 data.emplace(std::string("LocationCode"),
166 estoraged::BasicVariantType("U102020"));
167 data.emplace(std::string("EraseMaxGeometry"),
168 estoraged::BasicVariantType((uint64_t)5566));
169 data.emplace(std::string("EraseMinGeometry"),
170 estoraged::BasicVariantType((uint64_t)1234));
171
172 /* Create a dummy device. */
173 std::filesystem::create_directories("abc/device");
174 const std::string dummyTypeFileName("abc/device/type");
175 std::ofstream dummyTypeFile(dummyTypeFileName,
176 std::ios::out | std::ios::trunc);
177 dummyTypeFile << "SSD";
178 dummyTypeFile.close();
179
180 /* Another device. */
181 std::filesystem::create_directories("def/device");
182
183 /* Create a dummy eMMC device. */
184 std::filesystem::create_directories("mmcblk0/device");
185 const std::string typeFileName("mmcblk0/device/type");
186 std::ofstream typeFile(typeFileName, std::ios::out | std::ios::trunc);
187 typeFile << "MMC";
188 typeFile.close();
189
190 /* Look for the device file. */
191 std::filesystem::path deviceFile, sysfsDir;
192 std::string luksName, locationCode;
193 auto result =
194 estoraged::util::findDevice(data, std::filesystem::path("./"));
195 EXPECT_TRUE(result.has_value());
196
197 /* Validate the results. */
198 EXPECT_EQ("/dev/mmcblk0", result->deviceFile.string());
199 EXPECT_EQ("./mmcblk0/device", result->sysfsDir.string());
200 EXPECT_EQ("luks-mmcblk0", result->luksName);
201 EXPECT_EQ("U102020", result->locationCode);
202 EXPECT_EQ(5566, result->eraseMaxGeometry);
203 EXPECT_EQ(1234, result->eraseMinGeometry);
204 EXPECT_EQ("SSD", result->driveType);
205 EXPECT_EQ("eMMC", result->driveProtocol);
206
207 /* Delete the dummy files. */
208 EXPECT_EQ(3U, std::filesystem::remove_all("mmcblk0"));
209 EXPECT_EQ(3U, std::filesystem::remove_all("abc"));
210 EXPECT_EQ(2U, std::filesystem::remove_all("def"));
211 }
212
213 /* Test case where the "Type" property doesn't exist. */
TEST(utilTest,findDeviceNoTypeFail)214 TEST(utilTest, findDeviceNoTypeFail)
215 {
216 estoraged::StorageData data;
217
218 /* Set up the map of properties (with the "Type" property missing). */
219 data.emplace(std::string("Name"), estoraged::BasicVariantType("emmc"));
220
221 /* Create a dummy device. */
222 std::filesystem::create_directories("abc/device");
223 const std::string dummyTypeFileName("abc/device/type");
224 std::ofstream dummyTypeFile(dummyTypeFileName,
225 std::ios::out | std::ios::trunc);
226 dummyTypeFile << "SSD";
227 dummyTypeFile.close();
228
229 /* Another device. */
230 std::filesystem::create_directories("def/device");
231
232 /* Create a dummy eMMC device. */
233 std::filesystem::create_directories("mmcblk0/device");
234 const std::string typeFileName("mmcblk0/device/type");
235 std::ofstream typeFile(typeFileName, std::ios::out | std::ios::trunc);
236 typeFile << "MMC";
237 typeFile.close();
238
239 /* Look for the device file. */
240 auto result =
241 estoraged::util::findDevice(data, std::filesystem::path("./"));
242 EXPECT_FALSE(result.has_value());
243
244 /* Delete the dummy files. */
245 EXPECT_EQ(3U, std::filesystem::remove_all("mmcblk0"));
246 EXPECT_EQ(3U, std::filesystem::remove_all("abc"));
247 EXPECT_EQ(2U, std::filesystem::remove_all("def"));
248 }
249
250 /* Test case where the device type is not supported. */
TEST(utilTest,findDeviceUnsupportedTypeFail)251 TEST(utilTest, findDeviceUnsupportedTypeFail)
252 {
253 estoraged::StorageData data;
254
255 /* Set up the map of properties (with an unsupported "Type"). */
256 data.emplace(std::string("Type"), estoraged::BasicVariantType("NvmeDrive"));
257 data.emplace(std::string("Name"),
258 estoraged::BasicVariantType("some_drive"));
259
260 /* Create a dummy device. */
261 std::filesystem::create_directories("abc/device");
262 const std::string dummyTypeFileName("abc/device/type");
263 std::ofstream dummyTypeFile(dummyTypeFileName,
264 std::ios::out | std::ios::trunc);
265 dummyTypeFile << "SSD";
266 dummyTypeFile.close();
267
268 /* Another device. */
269 std::filesystem::create_directories("def/device");
270
271 /* Create a dummy eMMC device. */
272 std::filesystem::create_directories("mmcblk0/device");
273 const std::string typeFileName("mmcblk0/device/type");
274 std::ofstream typeFile(typeFileName, std::ios::out | std::ios::trunc);
275 typeFile << "MMC";
276 typeFile.close();
277
278 /* Look for the device file. */
279 auto result =
280 estoraged::util::findDevice(data, std::filesystem::path("./"));
281 EXPECT_FALSE(result.has_value());
282
283 /* Delete the dummy files. */
284 EXPECT_EQ(3U, std::filesystem::remove_all("mmcblk0"));
285 EXPECT_EQ(3U, std::filesystem::remove_all("abc"));
286 EXPECT_EQ(2U, std::filesystem::remove_all("def"));
287 }
288
289 /* Test case where we can't find the device file. */
TEST(utilTest,findDeviceNotFoundFail)290 TEST(utilTest, findDeviceNotFoundFail)
291 {
292 estoraged::StorageData data;
293
294 /* Set up the map of properties. */
295 data.emplace(std::string("Type"),
296 estoraged::BasicVariantType("EmmcDevice"));
297 data.emplace(std::string("Name"), estoraged::BasicVariantType("emmc"));
298
299 /* Create a dummy device. */
300 std::filesystem::create_directories("abc/device");
301 const std::string dummyTypeFileName("abc/device/type");
302 std::ofstream dummyTypeFile(dummyTypeFileName,
303 std::ios::out | std::ios::trunc);
304 dummyTypeFile << "SSD";
305 dummyTypeFile.close();
306
307 /* Another device. */
308 std::filesystem::create_directories("def/device");
309
310 /* Look for the device file. */
311 auto result =
312 estoraged::util::findDevice(data, std::filesystem::path("./"));
313 EXPECT_FALSE(result.has_value());
314
315 /* Delete the dummy files. */
316 EXPECT_EQ(3U, std::filesystem::remove_all("abc"));
317 EXPECT_EQ(2U, std::filesystem::remove_all("def"));
318 }
319
320 } // namespace estoraged_test
321