1 #include "FruUtils.hpp" 2 3 #include <array> 4 #include<algorithm> 5 #include<iterator> 6 7 #include "gtest/gtest.h" 8 9 extern "C" 10 { 11 // Include for I2C_SMBUS_BLOCK_MAX 12 #include <linux/i2c.h> 13 } 14 15 TEST(ValidateHeaderTest, InvalidFruVersionReturnsFalse) 16 { 17 // Validates the FruVersion is checked for the only legal value. 18 constexpr std::array<uint8_t, I2C_SMBUS_BLOCK_MAX> fruHeader = { 19 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 20 21 EXPECT_FALSE(validateHeader(fruHeader)); 22 } 23 24 TEST(ValidateHeaderTest, InvalidReservedReturnsFalse) 25 { 26 // Validates the reserved bit(7:4) of first bytes. 27 constexpr std::array<uint8_t, I2C_SMBUS_BLOCK_MAX> fruHeader = { 28 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 29 30 EXPECT_FALSE(validateHeader(fruHeader)); 31 } 32 33 TEST(ValidateHeaderTest, InvalidPaddingReturnsFalse) 34 { 35 // Validates the padding byte (7th byte). 36 constexpr std::array<uint8_t, I2C_SMBUS_BLOCK_MAX> fruHeader = { 37 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00}; 38 39 EXPECT_FALSE(validateHeader(fruHeader)); 40 } 41 42 TEST(ValidateHeaderTest, InvalidChecksumReturnsFalse) 43 { 44 // Validates the checksum, check for incorrect value. 45 constexpr std::array<uint8_t, I2C_SMBUS_BLOCK_MAX> fruHeader = { 46 0x01, 0x00, 0x01, 0x02, 0x03, 0x04, 0x00, 0x00}; 47 48 EXPECT_FALSE(validateHeader(fruHeader)); 49 } 50 51 TEST(ValidateHeaderTest, ValidChecksumReturnsTrue) 52 { 53 // Validates the checksum, check for correct value. 54 constexpr std::array<uint8_t, I2C_SMBUS_BLOCK_MAX> fruHeader = { 55 0x01, 0x00, 0x01, 0x02, 0x03, 0x04, 0x00, 0xf5}; 56 57 EXPECT_TRUE(validateHeader(fruHeader)); 58 } 59 60 TEST(VerifyOffsetTest, EmptyFruDataReturnsFalse) 61 { 62 // Validates the FruData size is checked for non empty. 63 std::vector<uint8_t> fruData = {}; 64 65 EXPECT_FALSE(verifyOffset(fruData, fruAreas::fruAreaChassis, 0)); 66 } 67 68 TEST(VerifyOffsetTest, AreaOutOfRangeReturnsFalse) 69 { 70 // Validates the FruArea value, check if it is within range. 71 const std::vector<uint8_t> fruData = {0x01, 0x00, 0x00, 0x00, 0x00, 72 0x00, 0x00, 0x00, 0x00}; 73 74 unsigned int areaOutOfRange = 8; 75 EXPECT_FALSE( 76 verifyOffset(fruData, static_cast<fruAreas>(areaOutOfRange), 0)); 77 } 78 79 TEST(VerifyOffsetTest, OverlapNextAreaReturnsFalse) 80 { 81 // Validates the Overlap of offsets with overlapped values. 82 const std::vector<uint8_t> fruData = {0x01, 0x00, 0x01, 0x02, 0x03, 83 0x04, 0x00, 0x00, 0x00}; 84 85 EXPECT_FALSE(verifyOffset(fruData, fruAreas::fruAreaChassis, 2)); 86 } 87 88 TEST(VerifyOffsetTest, OverlapPrevAreaReturnsFalse) 89 { 90 // Validates the Overlap of offsets with overlapped values. 91 const std::vector<uint8_t> fruData = {0x01, 0x00, 0x01, 0x03, 0x02, 92 0x07, 0x00, 0x00, 0x00}; 93 94 EXPECT_FALSE(verifyOffset(fruData, fruAreas::fruAreaProduct, 2)); 95 } 96 97 TEST(VerifyOffsetTest, ValidInputDataNoOverlapReturnsTrue) 98 { 99 // Validates all inputs with expected value and no overlap. 100 const std::vector<uint8_t> fruData = {0x01, 0x00, 0x01, 0x02, 0x03, 101 0x04, 0x00, 0x00, 0x00}; 102 103 EXPECT_TRUE(verifyOffset(fruData, fruAreas::fruAreaChassis, 1)); 104 } 105 106 TEST(VerifyChecksumTest, EmptyInput) 107 { 108 std::vector<uint8_t> data = {}; 109 110 EXPECT_EQ(calculateChecksum(data), 0); 111 } 112 113 TEST(VerifyChecksumTest, SingleOneInput) 114 { 115 std::vector<uint8_t> data(1, 1); 116 117 EXPECT_EQ(calculateChecksum(data), 255); 118 } 119 120 TEST(VerifyChecksumTest, AllOneInput) 121 { 122 std::vector<uint8_t> data(256, 1); 123 124 EXPECT_EQ(calculateChecksum(data), 0); 125 } 126 127 TEST(VerifyChecksumTest, WrapBoundaryLow) 128 { 129 std::vector<uint8_t> data = {255, 0}; 130 131 EXPECT_EQ(calculateChecksum(data), 1); 132 } 133 134 TEST(VerifyChecksumTest, WrapBoundaryExact) 135 { 136 std::vector<uint8_t> data = {255, 1}; 137 138 EXPECT_EQ(calculateChecksum(data), 0); 139 } 140 141 TEST(VerifyChecksumTest, WrapBoundaryHigh) 142 { 143 std::vector<uint8_t> data = {255, 2}; 144 145 EXPECT_EQ(calculateChecksum(data), 255); 146 } 147 148 int64_t getDataTempl( 149 const std::vector<uint8_t>& data, 150 [[maybe_unused]] int flag, 151 [[maybe_unused]] int file, 152 [[maybe_unused]] uint16_t address, 153 uint16_t offset, uint8_t length, uint8_t* outBuf) 154 { 155 if (offset >= data.size()) 156 { 157 return 0; 158 } 159 160 uint16_t idx; 161 for (idx = offset; 162 idx < data.size() && idx < offset + length; 163 ++idx, ++outBuf) 164 { 165 *outBuf = data[idx]; 166 } 167 168 return idx - offset; 169 } 170 171 TEST(FindFRUHeaderTest, InvalidHeader) 172 { 173 const std::vector<uint8_t> data = {255, 16}; 174 uint16_t offset = 0; 175 std::array<uint8_t, I2C_SMBUS_BLOCK_MAX> blockData; 176 auto getData = [&data](auto fl, auto fi, auto a, auto o, auto l, 177 auto* b) { return getDataTempl(data, fl, fi, a, o, l, b); }; 178 179 EXPECT_FALSE(findFRUHeader(0, 0, 0, getData, "error", blockData, offset)); 180 } 181 182 TEST(FindFRUHeaderTest, NoData) 183 { 184 const std::vector<uint8_t> data = {}; 185 uint16_t offset = 0; 186 std::array<uint8_t, I2C_SMBUS_BLOCK_MAX> blockData; 187 auto getData = [&data](auto fl, auto fi, auto a, auto o, auto l, 188 auto* b) { return getDataTempl(data, fl, fi, a, o, l, b); }; 189 190 EXPECT_FALSE(findFRUHeader(0, 0, 0, getData, "error", blockData, offset)); 191 } 192 193 TEST(FindFRUHeaderTest, ValidHeader) 194 { 195 const std::vector<uint8_t> data = { 196 0x01, 0x00, 0x01, 0x02, 0x03, 0x04, 0x00, 0xf5}; 197 uint16_t offset = 0; 198 std::array<uint8_t, I2C_SMBUS_BLOCK_MAX> blockData; 199 auto getData = [&data](auto fl, auto fi, auto a, auto o, auto l, 200 auto* b) { return getDataTempl(data, fl, fi, a, o, l, b); }; 201 202 EXPECT_TRUE(findFRUHeader(0, 0, 0, getData, "error", blockData, offset)); 203 EXPECT_EQ(0, offset); 204 } 205 206 TEST(FindFRUHeaderTest, TyanInvalidHeader) 207 { 208 std::vector<uint8_t> data = {'$', 'T', 'Y', 'A', 'N', '$', 0, 0}; 209 data.resize(0x6000 + I2C_SMBUS_BLOCK_MAX); 210 uint16_t offset = 0; 211 std::array<uint8_t, I2C_SMBUS_BLOCK_MAX> blockData; 212 auto getData = [&data](auto fl, auto fi, auto a, auto o, auto l, 213 auto* b) { return getDataTempl(data, fl, fi, a, o, l, b); }; 214 215 EXPECT_FALSE(findFRUHeader(0, 0, 0, getData, "error", blockData, offset)); 216 } 217 218 TEST(FindFRUHeaderTest, TyanNoData) 219 { 220 const std::vector<uint8_t> data = {'$', 'T', 'Y', 'A', 'N', '$', 0, 0}; 221 uint16_t offset = 0; 222 std::array<uint8_t, I2C_SMBUS_BLOCK_MAX> blockData; 223 auto getData = [&data](auto fl, auto fi, auto a, auto o, auto l, 224 auto* b) { return getDataTempl(data, fl, fi, a, o, l, b); }; 225 226 EXPECT_FALSE(findFRUHeader(0, 0, 0, getData, "error", blockData, offset)); 227 } 228 229 TEST(FindFRUHeaderTest, TyanValidHeader) 230 { 231 std::vector<uint8_t> data = {'$', 'T', 'Y', 'A', 'N', '$', 0, 0}; 232 data.resize(0x6000); 233 constexpr std::array<uint8_t, I2C_SMBUS_BLOCK_MAX> fruHeader = { 234 0x01, 0x00, 0x01, 0x02, 0x03, 0x04, 0x00, 0xf5}; 235 copy(fruHeader.begin(), fruHeader.end(), back_inserter(data)); 236 237 uint16_t offset = 0; 238 std::array<uint8_t, I2C_SMBUS_BLOCK_MAX> blockData; 239 auto getData = [&data](auto fl, auto fi, auto a, auto o, auto l, 240 auto* b) { return getDataTempl(data, fl, fi, a, o, l, b); }; 241 242 EXPECT_TRUE(findFRUHeader(0, 0, 0, getData, "error", blockData, offset)); 243 EXPECT_EQ(0x6000, offset); 244 } 245