blob: 19aff02cd925ba0e88e9074736745b6a2a6512ec [file] [log] [blame]
Brad Bishope45d8c72022-05-25 15:12:53 -04001#include "fru_utils.hpp"
Patrick Venturea62466c2021-02-08 14:55:18 -08002
Andrew Jefferyf8ae2ba2022-03-25 15:13:55 +10303#include <algorithm>
Patrick Venturea62466c2021-02-08 14:55:18 -08004#include <array>
Andrew Jefferyf8ae2ba2022-03-25 15:13:55 +10305#include <iterator>
Patrick Venturea62466c2021-02-08 14:55:18 -08006
Ed Tanous23e3f452025-04-08 10:37:56 -07007#include "gmock/gmock.h"
Patrick Venturea62466c2021-02-08 14:55:18 -08008#include "gtest/gtest.h"
9
Ed Tanous23e3f452025-04-08 10:37:56 -070010using ::testing::Pair;
11using ::testing::UnorderedElementsAre;
12
Patrick Venturea62466c2021-02-08 14:55:18 -080013extern "C"
14{
15// Include for I2C_SMBUS_BLOCK_MAX
16#include <linux/i2c.h>
17}
18
Zev Weiss309c0b12022-02-25 01:44:12 +000019static constexpr size_t blockSize = I2C_SMBUS_BLOCK_MAX;
20
Patrick Venturea62466c2021-02-08 14:55:18 -080021TEST(ValidateHeaderTest, InvalidFruVersionReturnsFalse)
22{
23 // Validates the FruVersion is checked for the only legal value.
Ed Tanous07d467b2021-02-23 14:48:37 -080024 constexpr std::array<uint8_t, I2C_SMBUS_BLOCK_MAX> fruHeader = {
Patrick Venturea62466c2021-02-08 14:55:18 -080025 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
26
Ed Tanous07d467b2021-02-23 14:48:37 -080027 EXPECT_FALSE(validateHeader(fruHeader));
Patrick Venturea62466c2021-02-08 14:55:18 -080028}
Vijay Khemka1694ef62021-02-12 23:14:49 +000029
Vijay Khemka7a682a32021-04-12 22:15:00 +000030TEST(ValidateHeaderTest, InvalidReservedReturnsFalse)
31{
32 // Validates the reserved bit(7:4) of first bytes.
Ed Tanous07d467b2021-02-23 14:48:37 -080033 constexpr std::array<uint8_t, I2C_SMBUS_BLOCK_MAX> fruHeader = {
Vijay Khemka7a682a32021-04-12 22:15:00 +000034 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
35
Ed Tanous07d467b2021-02-23 14:48:37 -080036 EXPECT_FALSE(validateHeader(fruHeader));
Vijay Khemka7a682a32021-04-12 22:15:00 +000037}
38
39TEST(ValidateHeaderTest, InvalidPaddingReturnsFalse)
40{
41 // Validates the padding byte (7th byte).
Ed Tanous07d467b2021-02-23 14:48:37 -080042 constexpr std::array<uint8_t, I2C_SMBUS_BLOCK_MAX> fruHeader = {
Vijay Khemka7a682a32021-04-12 22:15:00 +000043 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00};
44
Ed Tanous07d467b2021-02-23 14:48:37 -080045 EXPECT_FALSE(validateHeader(fruHeader));
Vijay Khemka7a682a32021-04-12 22:15:00 +000046}
47
48TEST(ValidateHeaderTest, InvalidChecksumReturnsFalse)
49{
50 // Validates the checksum, check for incorrect value.
Ed Tanous07d467b2021-02-23 14:48:37 -080051 constexpr std::array<uint8_t, I2C_SMBUS_BLOCK_MAX> fruHeader = {
Vijay Khemka7a682a32021-04-12 22:15:00 +000052 0x01, 0x00, 0x01, 0x02, 0x03, 0x04, 0x00, 0x00};
53
Ed Tanous07d467b2021-02-23 14:48:37 -080054 EXPECT_FALSE(validateHeader(fruHeader));
Vijay Khemka7a682a32021-04-12 22:15:00 +000055}
56
57TEST(ValidateHeaderTest, ValidChecksumReturnsTrue)
58{
59 // Validates the checksum, check for correct value.
Ed Tanous07d467b2021-02-23 14:48:37 -080060 constexpr std::array<uint8_t, I2C_SMBUS_BLOCK_MAX> fruHeader = {
Vijay Khemka7a682a32021-04-12 22:15:00 +000061 0x01, 0x00, 0x01, 0x02, 0x03, 0x04, 0x00, 0xf5};
62
Ed Tanous07d467b2021-02-23 14:48:37 -080063 EXPECT_TRUE(validateHeader(fruHeader));
Vijay Khemka7a682a32021-04-12 22:15:00 +000064}
65
Vijay Khemka1694ef62021-02-12 23:14:49 +000066TEST(VerifyOffsetTest, EmptyFruDataReturnsFalse)
67{
68 // Validates the FruData size is checked for non empty.
Ed Tanous07d467b2021-02-23 14:48:37 -080069 std::vector<uint8_t> fruData = {};
Vijay Khemka1694ef62021-02-12 23:14:49 +000070
Ed Tanous07d467b2021-02-23 14:48:37 -080071 EXPECT_FALSE(verifyOffset(fruData, fruAreas::fruAreaChassis, 0));
Vijay Khemka1694ef62021-02-12 23:14:49 +000072}
73
74TEST(VerifyOffsetTest, AreaOutOfRangeReturnsFalse)
75{
76 // Validates the FruArea value, check if it is within range.
Ed Tanous07d467b2021-02-23 14:48:37 -080077 const std::vector<uint8_t> fruData = {0x01, 0x00, 0x00, 0x00, 0x00,
78 0x00, 0x00, 0x00, 0x00};
Vijay Khemka1694ef62021-02-12 23:14:49 +000079
80 unsigned int areaOutOfRange = 8;
81 EXPECT_FALSE(
Ed Tanous07d467b2021-02-23 14:48:37 -080082 verifyOffset(fruData, static_cast<fruAreas>(areaOutOfRange), 0));
Vijay Khemka1694ef62021-02-12 23:14:49 +000083}
84
85TEST(VerifyOffsetTest, OverlapNextAreaReturnsFalse)
86{
87 // Validates the Overlap of offsets with overlapped values.
Ed Tanous07d467b2021-02-23 14:48:37 -080088 const std::vector<uint8_t> fruData = {0x01, 0x00, 0x01, 0x02, 0x03,
89 0x04, 0x00, 0x00, 0x00};
Vijay Khemka1694ef62021-02-12 23:14:49 +000090
Ed Tanous07d467b2021-02-23 14:48:37 -080091 EXPECT_FALSE(verifyOffset(fruData, fruAreas::fruAreaChassis, 2));
Vijay Khemka1694ef62021-02-12 23:14:49 +000092}
93
94TEST(VerifyOffsetTest, OverlapPrevAreaReturnsFalse)
95{
96 // Validates the Overlap of offsets with overlapped values.
Ed Tanous07d467b2021-02-23 14:48:37 -080097 const std::vector<uint8_t> fruData = {0x01, 0x00, 0x01, 0x03, 0x02,
98 0x07, 0x00, 0x00, 0x00};
Vijay Khemka1694ef62021-02-12 23:14:49 +000099
Ed Tanous07d467b2021-02-23 14:48:37 -0800100 EXPECT_FALSE(verifyOffset(fruData, fruAreas::fruAreaProduct, 2));
Vijay Khemka1694ef62021-02-12 23:14:49 +0000101}
102
103TEST(VerifyOffsetTest, ValidInputDataNoOverlapReturnsTrue)
104{
105 // Validates all inputs with expected value and no overlap.
Ed Tanous07d467b2021-02-23 14:48:37 -0800106 const std::vector<uint8_t> fruData = {0x01, 0x00, 0x01, 0x02, 0x03,
107 0x04, 0x00, 0x00, 0x00};
Vijay Khemka1694ef62021-02-12 23:14:49 +0000108
Ed Tanous07d467b2021-02-23 14:48:37 -0800109 EXPECT_TRUE(verifyOffset(fruData, fruAreas::fruAreaChassis, 1));
Vijay Khemka1694ef62021-02-12 23:14:49 +0000110}
Andrew Jeffery8dacf6a2021-08-02 22:17:18 +0930111
112TEST(VerifyChecksumTest, EmptyInput)
113{
114 std::vector<uint8_t> data = {};
115
116 EXPECT_EQ(calculateChecksum(data), 0);
117}
118
119TEST(VerifyChecksumTest, SingleOneInput)
120{
121 std::vector<uint8_t> data(1, 1);
122
123 EXPECT_EQ(calculateChecksum(data), 255);
124}
125
126TEST(VerifyChecksumTest, AllOneInput)
127{
128 std::vector<uint8_t> data(256, 1);
129
130 EXPECT_EQ(calculateChecksum(data), 0);
131}
132
133TEST(VerifyChecksumTest, WrapBoundaryLow)
134{
Ed Tanousfbce8e22021-09-02 15:29:12 -0700135 std::vector<uint8_t> data = {255, 0};
Andrew Jeffery8dacf6a2021-08-02 22:17:18 +0930136
137 EXPECT_EQ(calculateChecksum(data), 1);
138}
139
140TEST(VerifyChecksumTest, WrapBoundaryExact)
141{
Ed Tanousfbce8e22021-09-02 15:29:12 -0700142 std::vector<uint8_t> data = {255, 1};
Andrew Jeffery8dacf6a2021-08-02 22:17:18 +0930143
144 EXPECT_EQ(calculateChecksum(data), 0);
145}
146
147TEST(VerifyChecksumTest, WrapBoundaryHigh)
148{
Ed Tanousfbce8e22021-09-02 15:29:12 -0700149 std::vector<uint8_t> data = {255, 2};
Andrew Jeffery8dacf6a2021-08-02 22:17:18 +0930150
151 EXPECT_EQ(calculateChecksum(data), 255);
152}
Oskar Senftbd4075f2021-10-05 23:42:43 -0400153
Zev Weiss309c0b12022-02-25 01:44:12 +0000154int64_t getDataTempl(const std::vector<uint8_t>& data, off_t offset,
Zev Weiss1525e852022-03-22 22:27:43 +0000155 size_t length, uint8_t* outBuf)
Oskar Senftbd4075f2021-10-05 23:42:43 -0400156{
Zev Weiss1525e852022-03-22 22:27:43 +0000157 if (offset >= static_cast<off_t>(data.size()))
Oskar Senftbd4075f2021-10-05 23:42:43 -0400158 {
159 return 0;
160 }
161
Ed Tanous3013fb42022-07-09 08:27:06 -0700162 uint16_t idx = offset;
163 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
164 for (; idx < std::min(data.size(), offset + length); ++idx, ++outBuf)
Oskar Senftbd4075f2021-10-05 23:42:43 -0400165 {
166 *outBuf = data[idx];
167 }
168
169 return idx - offset;
170}
171
Zev Weiss309c0b12022-02-25 01:44:12 +0000172TEST(FRUReaderTest, ReadData)
173{
174 std::vector<uint8_t> data = {};
Patrick Williams849f13a2024-12-18 15:43:19 -0500175 data.reserve(blockSize * 2);
Zev Weiss309c0b12022-02-25 01:44:12 +0000176 for (size_t i = 0; i < blockSize * 2; i++)
177 {
178 data.push_back(i);
179 }
Ed Tanous3013fb42022-07-09 08:27:06 -0700180 std::array<uint8_t, blockSize * 2> rdbuf{};
Zev Weiss309c0b12022-02-25 01:44:12 +0000181 auto getData = [&data](auto o, auto l, auto* b) {
182 return getDataTempl(data, o, l, b);
183 };
184 FRUReader reader(getData);
185
186 EXPECT_EQ(reader.read(0, data.size(), rdbuf.data()),
187 static_cast<ssize_t>(data.size()));
188 EXPECT_TRUE(std::equal(rdbuf.begin(), rdbuf.end(), data.begin()));
189 for (size_t i = 0; i < blockSize * 2; i++)
190 {
191 EXPECT_EQ(reader.read(i, 1, rdbuf.data()), 1);
192 EXPECT_EQ(rdbuf[i], i);
193 }
194 EXPECT_EQ(reader.read(blockSize - 1, 2, rdbuf.data()), 2);
195 EXPECT_EQ(rdbuf[0], blockSize - 1);
196 EXPECT_EQ(rdbuf[1], blockSize);
197}
198
199TEST(FRUReaderTest, StartPastUnknownEOF)
200{
201 const std::vector<uint8_t> data = {};
202 auto getData = [&data](auto o, auto l, auto* b) {
203 return getDataTempl(data, o, l, b);
204 };
205 FRUReader reader(getData);
206
207 EXPECT_EQ(reader.read(1, 1, nullptr), 0);
208}
209
210TEST(FRUReaderTest, StartPastKnownEOF)
211{
212 std::vector<uint8_t> data = {};
213 data.resize(blockSize / 2);
Ed Tanous3013fb42022-07-09 08:27:06 -0700214 std::array<uint8_t, blockSize> blockData{};
Zev Weiss309c0b12022-02-25 01:44:12 +0000215 auto getData = [&data](auto o, auto l, auto* b) {
216 return getDataTempl(data, o, l, b);
217 };
218 FRUReader reader(getData);
219
220 EXPECT_EQ(reader.read(0, blockSize, blockData.data()),
221 static_cast<ssize_t>(data.size()));
222 EXPECT_EQ(reader.read(data.size(), 1, nullptr), 0);
223 EXPECT_EQ(reader.read(data.size() + 1, 1, nullptr), 0);
224 EXPECT_EQ(reader.read(blockSize, 1, nullptr), 0);
225 EXPECT_EQ(reader.read(blockSize + 1, 1, nullptr), 0);
226}
227
228TEST(FRUReaderTest, DecreasingEOF)
229{
230 const std::vector<uint8_t> data = {};
231 auto getData = [&data](auto o, auto l, auto* b) {
232 return getDataTempl(data, o, l, b);
233 };
234 FRUReader reader(getData);
235
236 EXPECT_EQ(reader.read(blockSize * 2, 1, nullptr), 0);
237 EXPECT_EQ(reader.read(blockSize + (blockSize / 2), 1, nullptr), 0);
238 EXPECT_EQ(reader.read(blockSize, 1, nullptr), 0);
239 EXPECT_EQ(reader.read(blockSize / 2, 1, nullptr), 0);
240 EXPECT_EQ(reader.read(0, 1, nullptr), 0);
241}
242
243TEST(FRUReaderTest, CacheHit)
244{
245 std::vector<uint8_t> data = {'X'};
Ed Tanous3013fb42022-07-09 08:27:06 -0700246 std::array<uint8_t, blockSize> read1{};
247 std::array<uint8_t, blockSize> read2{};
Zev Weiss309c0b12022-02-25 01:44:12 +0000248 auto getData = [&data](auto o, auto l, auto* b) {
249 return getDataTempl(data, o, l, b);
250 };
251 FRUReader reader(getData);
252
253 // cache hit should return the same data for the second read even if we
254 // change it behind the FRUReader's back after the first
255 EXPECT_EQ(reader.read(0, blockSize, read1.data()), 1);
256 data[0] = 'Y';
257 EXPECT_EQ(reader.read(0, blockSize, read2.data()), 1);
258 EXPECT_EQ(read1[0], read2[0]);
259}
260
261TEST(FRUReaderTest, ReadPastKnownEnd)
262{
263 const std::vector<uint8_t> data = {'X', 'Y'};
Ed Tanous3013fb42022-07-09 08:27:06 -0700264 std::array<uint8_t, blockSize> rdbuf{};
Zev Weiss309c0b12022-02-25 01:44:12 +0000265 auto getData = [&data](auto o, auto l, auto* b) {
266 return getDataTempl(data, o, l, b);
267 };
268 FRUReader reader(getData);
269
270 EXPECT_EQ(reader.read(0, data.size(), rdbuf.data()),
271 static_cast<ssize_t>(data.size()));
272 EXPECT_EQ(rdbuf[0], 'X');
273 EXPECT_EQ(rdbuf[1], 'Y');
274 EXPECT_EQ(reader.read(1, data.size(), rdbuf.data()),
275 static_cast<ssize_t>(data.size() - 1));
276 EXPECT_EQ(rdbuf[0], 'Y');
277}
278
279TEST(FRUReaderTest, MultiBlockRead)
280{
281 std::vector<uint8_t> data = {};
282 data.resize(blockSize, 'X');
283 data.resize(2 * blockSize, 'Y');
Ed Tanous3013fb42022-07-09 08:27:06 -0700284 std::array<uint8_t, 2 * blockSize> rdbuf{};
Zev Weiss309c0b12022-02-25 01:44:12 +0000285 auto getData = [&data](auto o, auto l, auto* b) {
286 return getDataTempl(data, o, l, b);
287 };
288 FRUReader reader(getData);
289
290 EXPECT_EQ(reader.read(0, 2 * blockSize, rdbuf.data()),
291 static_cast<ssize_t>(2 * blockSize));
292 EXPECT_TRUE(std::equal(rdbuf.begin(), rdbuf.end(), data.begin()));
293}
294
295TEST(FRUReaderTest, ShrinkingEEPROM)
296{
297 std::vector<uint8_t> data = {};
298 data.resize(3 * blockSize, 'X');
Ed Tanous3013fb42022-07-09 08:27:06 -0700299 std::array<uint8_t, blockSize> rdbuf{};
Zev Weiss309c0b12022-02-25 01:44:12 +0000300 auto getData = [&data](auto o, auto l, auto* b) {
301 return getDataTempl(data, o, l, b);
302 };
303 FRUReader reader(getData);
304
305 EXPECT_EQ(reader.read(data.size() - 1, 2, rdbuf.data()), 1);
306 data.resize(blockSize);
307 EXPECT_EQ(reader.read(data.size() - 1, 2, rdbuf.data()), 1);
308}
309
Oskar Senftbd4075f2021-10-05 23:42:43 -0400310TEST(FindFRUHeaderTest, InvalidHeader)
311{
312 const std::vector<uint8_t> data = {255, 16};
Zev Weiss1525e852022-03-22 22:27:43 +0000313 off_t offset = 0;
Ed Tanous3013fb42022-07-09 08:27:06 -0700314 std::array<uint8_t, I2C_SMBUS_BLOCK_MAX> blockData{};
Zev Weiss309c0b12022-02-25 01:44:12 +0000315 auto getData = [&data](auto o, auto l, auto* b) {
316 return getDataTempl(data, o, l, b);
Andrew Jefferyf8ae2ba2022-03-25 15:13:55 +1030317 };
Zev Weiss309c0b12022-02-25 01:44:12 +0000318 FRUReader reader(getData);
Oskar Senftbd4075f2021-10-05 23:42:43 -0400319
Zev Weiss309c0b12022-02-25 01:44:12 +0000320 EXPECT_FALSE(findFRUHeader(reader, "error", blockData, offset));
Oskar Senftbd4075f2021-10-05 23:42:43 -0400321}
322
323TEST(FindFRUHeaderTest, NoData)
324{
325 const std::vector<uint8_t> data = {};
Zev Weiss1525e852022-03-22 22:27:43 +0000326 off_t offset = 0;
Ed Tanous3013fb42022-07-09 08:27:06 -0700327 std::array<uint8_t, I2C_SMBUS_BLOCK_MAX> blockData{};
Zev Weiss309c0b12022-02-25 01:44:12 +0000328 auto getData = [&data](auto o, auto l, auto* b) {
329 return getDataTempl(data, o, l, b);
Andrew Jefferyf8ae2ba2022-03-25 15:13:55 +1030330 };
Zev Weiss309c0b12022-02-25 01:44:12 +0000331 FRUReader reader(getData);
Oskar Senftbd4075f2021-10-05 23:42:43 -0400332
Zev Weiss309c0b12022-02-25 01:44:12 +0000333 EXPECT_FALSE(findFRUHeader(reader, "error", blockData, offset));
Oskar Senftbd4075f2021-10-05 23:42:43 -0400334}
335
336TEST(FindFRUHeaderTest, ValidHeader)
337{
Andrew Jefferyf8ae2ba2022-03-25 15:13:55 +1030338 const std::vector<uint8_t> data = {0x01, 0x00, 0x01, 0x02,
339 0x03, 0x04, 0x00, 0xf5};
Zev Weiss1525e852022-03-22 22:27:43 +0000340 off_t offset = 0;
Ed Tanous3013fb42022-07-09 08:27:06 -0700341 std::array<uint8_t, I2C_SMBUS_BLOCK_MAX> blockData{};
Zev Weiss309c0b12022-02-25 01:44:12 +0000342 auto getData = [&data](auto o, auto l, auto* b) {
343 return getDataTempl(data, o, l, b);
Andrew Jefferyf8ae2ba2022-03-25 15:13:55 +1030344 };
Zev Weiss309c0b12022-02-25 01:44:12 +0000345 FRUReader reader(getData);
Oskar Senftbd4075f2021-10-05 23:42:43 -0400346
Zev Weiss309c0b12022-02-25 01:44:12 +0000347 EXPECT_TRUE(findFRUHeader(reader, "error", blockData, offset));
Oskar Senftbd4075f2021-10-05 23:42:43 -0400348 EXPECT_EQ(0, offset);
349}
350
351TEST(FindFRUHeaderTest, TyanInvalidHeader)
352{
353 std::vector<uint8_t> data = {'$', 'T', 'Y', 'A', 'N', '$', 0, 0};
354 data.resize(0x6000 + I2C_SMBUS_BLOCK_MAX);
Zev Weiss1525e852022-03-22 22:27:43 +0000355 off_t offset = 0;
Ed Tanous3013fb42022-07-09 08:27:06 -0700356 std::array<uint8_t, I2C_SMBUS_BLOCK_MAX> blockData{};
Zev Weiss309c0b12022-02-25 01:44:12 +0000357 auto getData = [&data](auto o, auto l, auto* b) {
358 return getDataTempl(data, o, l, b);
Andrew Jefferyf8ae2ba2022-03-25 15:13:55 +1030359 };
Zev Weiss309c0b12022-02-25 01:44:12 +0000360 FRUReader reader(getData);
Oskar Senftbd4075f2021-10-05 23:42:43 -0400361
Zev Weiss309c0b12022-02-25 01:44:12 +0000362 EXPECT_FALSE(findFRUHeader(reader, "error", blockData, offset));
Oskar Senftbd4075f2021-10-05 23:42:43 -0400363}
364
365TEST(FindFRUHeaderTest, TyanNoData)
366{
367 const std::vector<uint8_t> data = {'$', 'T', 'Y', 'A', 'N', '$', 0, 0};
Zev Weiss1525e852022-03-22 22:27:43 +0000368 off_t offset = 0;
Ed Tanous3013fb42022-07-09 08:27:06 -0700369 std::array<uint8_t, I2C_SMBUS_BLOCK_MAX> blockData{};
Zev Weiss309c0b12022-02-25 01:44:12 +0000370 auto getData = [&data](auto o, auto l, auto* b) {
371 return getDataTempl(data, o, l, b);
Andrew Jefferyf8ae2ba2022-03-25 15:13:55 +1030372 };
Zev Weiss309c0b12022-02-25 01:44:12 +0000373 FRUReader reader(getData);
Oskar Senftbd4075f2021-10-05 23:42:43 -0400374
Zev Weiss309c0b12022-02-25 01:44:12 +0000375 EXPECT_FALSE(findFRUHeader(reader, "error", blockData, offset));
Oskar Senftbd4075f2021-10-05 23:42:43 -0400376}
377
378TEST(FindFRUHeaderTest, TyanValidHeader)
379{
380 std::vector<uint8_t> data = {'$', 'T', 'Y', 'A', 'N', '$', 0, 0};
381 data.resize(0x6000);
382 constexpr std::array<uint8_t, I2C_SMBUS_BLOCK_MAX> fruHeader = {
383 0x01, 0x00, 0x01, 0x02, 0x03, 0x04, 0x00, 0xf5};
384 copy(fruHeader.begin(), fruHeader.end(), back_inserter(data));
385
Zev Weiss1525e852022-03-22 22:27:43 +0000386 off_t offset = 0;
Ed Tanous3013fb42022-07-09 08:27:06 -0700387 std::array<uint8_t, I2C_SMBUS_BLOCK_MAX> blockData{};
Zev Weiss309c0b12022-02-25 01:44:12 +0000388 auto getData = [&data](auto o, auto l, auto* b) {
389 return getDataTempl(data, o, l, b);
Andrew Jefferyf8ae2ba2022-03-25 15:13:55 +1030390 };
Zev Weiss309c0b12022-02-25 01:44:12 +0000391 FRUReader reader(getData);
Oskar Senftbd4075f2021-10-05 23:42:43 -0400392
Zev Weiss309c0b12022-02-25 01:44:12 +0000393 EXPECT_TRUE(findFRUHeader(reader, "error", blockData, offset));
Oskar Senftbd4075f2021-10-05 23:42:43 -0400394 EXPECT_EQ(0x6000, offset);
395}
Ed Tanous23e3f452025-04-08 10:37:56 -0700396
397TEST(formatIPMIFRU, FullDecode)
398{
399 const std::array<uint8_t, 176> bmcFru = {
400 0x01, 0x00, 0x00, 0x01, 0x0b, 0x00, 0x00, 0xf3, 0x01, 0x0a, 0x19, 0x1f,
401 0x0f, 0xe6, 0xc6, 0x4e, 0x56, 0x49, 0x44, 0x49, 0x41, 0xc5, 0x50, 0x33,
402 0x38, 0x30, 0x39, 0xcd, 0x31, 0x35, 0x38, 0x33, 0x33, 0x32, 0x34, 0x38,
403 0x30, 0x30, 0x31, 0x35, 0x30, 0xd2, 0x36, 0x39, 0x39, 0x2d, 0x31, 0x33,
404 0x38, 0x30, 0x39, 0x2d, 0x30, 0x34, 0x30, 0x34, 0x2d, 0x36, 0x30, 0x30,
405 0xc0, 0x01, 0x01, 0xd6, 0x4d, 0x41, 0x43, 0x3a, 0x20, 0x33, 0x43, 0x3a,
406 0x36, 0x44, 0x3a, 0x36, 0x36, 0x3a, 0x31, 0x34, 0x3a, 0x43, 0x38, 0x3a,
407 0x37, 0x41, 0xc1, 0x3b, 0x01, 0x09, 0x19, 0xc6, 0x4e, 0x56, 0x49, 0x44,
408 0x49, 0x41, 0xc9, 0x50, 0x33, 0x38, 0x30, 0x39, 0x2d, 0x42, 0x4d, 0x43,
409 0xd2, 0x36, 0x39, 0x39, 0x2d, 0x31, 0x33, 0x38, 0x30, 0x39, 0x2d, 0x30,
410 0x34, 0x30, 0x34, 0x2d, 0x36, 0x30, 0x30, 0xc4, 0x41, 0x45, 0x2e, 0x31,
411 0xcd, 0x31, 0x35, 0x38, 0x33, 0x33, 0x32, 0x34, 0x38, 0x30, 0x30, 0x31,
412 0x35, 0x30, 0xc0, 0xc4, 0x76, 0x30, 0x2e, 0x31, 0xc1, 0x00, 0x00, 0x00,
413 0x00, 0x00, 0x00, 0xb4, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
414 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
415 boost::container::flat_map<std::string, std::string> result;
416 ASSERT_EQ(formatIPMIFRU(bmcFru, result), resCodes::resOK);
417
418 EXPECT_THAT(
419 result,
420 UnorderedElementsAre(
421 Pair("BOARD_FRU_VERSION_ID", ""), Pair("BOARD_INFO_AM1", "01"),
422 Pair("BOARD_INFO_AM2", "MAC: 3C:6D:66:14:C8:7A"),
423 Pair("BOARD_LANGUAGE_CODE", "25"),
424 Pair("BOARD_MANUFACTURER", "NVIDIA"),
425 Pair("BOARD_MANUFACTURE_DATE", "20240831T055100Z"),
426 Pair("BOARD_PART_NUMBER", "699-13809-0404-600"),
427 Pair("BOARD_PRODUCT_NAME", "P3809"),
428 Pair("BOARD_SERIAL_NUMBER", "1583324800150"),
429 Pair("Common_Format_Version", "1"), Pair("PRODUCT_ASSET_TAG", ""),
430 Pair("PRODUCT_FRU_VERSION_ID", "v0.1"),
431 Pair("PRODUCT_LANGUAGE_CODE", "25"),
432 Pair("PRODUCT_MANUFACTURER", "NVIDIA"),
433 Pair("PRODUCT_PART_NUMBER", "699-13809-0404-600"),
434 Pair("PRODUCT_PRODUCT_NAME", "P3809-BMC"),
435 Pair("PRODUCT_SERIAL_NUMBER", "1583324800150"),
436 Pair("PRODUCT_VERSION", "AE.1")));
437}