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 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 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 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 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 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 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 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. */ 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. */ 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. */ 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. */ 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. */ 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