blob: 5a6ce52bed4e5a8a665a83a8cd6bffb1be328d95 [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
7#include "gtest/gtest.h"
8
9extern "C"
10{
11// Include for I2C_SMBUS_BLOCK_MAX
12#include <linux/i2c.h>
13}
14
15TEST(ValidateHeaderTest, InvalidFruVersionReturnsFalse)
16{
17 // Validates the FruVersion is checked for the only legal value.
Ed Tanous07d467b2021-02-23 14:48:37 -080018 constexpr std::array<uint8_t, I2C_SMBUS_BLOCK_MAX> fruHeader = {
Patrick Venturea62466c2021-02-08 14:55:18 -080019 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
20
Ed Tanous07d467b2021-02-23 14:48:37 -080021 EXPECT_FALSE(validateHeader(fruHeader));
Patrick Venturea62466c2021-02-08 14:55:18 -080022}
Vijay Khemka1694ef62021-02-12 23:14:49 +000023
Vijay Khemka7a682a32021-04-12 22:15:00 +000024TEST(ValidateHeaderTest, InvalidReservedReturnsFalse)
25{
26 // Validates the reserved bit(7:4) of first bytes.
Ed Tanous07d467b2021-02-23 14:48:37 -080027 constexpr std::array<uint8_t, I2C_SMBUS_BLOCK_MAX> fruHeader = {
Vijay Khemka7a682a32021-04-12 22:15:00 +000028 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
29
Ed Tanous07d467b2021-02-23 14:48:37 -080030 EXPECT_FALSE(validateHeader(fruHeader));
Vijay Khemka7a682a32021-04-12 22:15:00 +000031}
32
33TEST(ValidateHeaderTest, InvalidPaddingReturnsFalse)
34{
35 // Validates the padding byte (7th byte).
Ed Tanous07d467b2021-02-23 14:48:37 -080036 constexpr std::array<uint8_t, I2C_SMBUS_BLOCK_MAX> fruHeader = {
Vijay Khemka7a682a32021-04-12 22:15:00 +000037 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00};
38
Ed Tanous07d467b2021-02-23 14:48:37 -080039 EXPECT_FALSE(validateHeader(fruHeader));
Vijay Khemka7a682a32021-04-12 22:15:00 +000040}
41
42TEST(ValidateHeaderTest, InvalidChecksumReturnsFalse)
43{
44 // Validates the checksum, check for incorrect value.
Ed Tanous07d467b2021-02-23 14:48:37 -080045 constexpr std::array<uint8_t, I2C_SMBUS_BLOCK_MAX> fruHeader = {
Vijay Khemka7a682a32021-04-12 22:15:00 +000046 0x01, 0x00, 0x01, 0x02, 0x03, 0x04, 0x00, 0x00};
47
Ed Tanous07d467b2021-02-23 14:48:37 -080048 EXPECT_FALSE(validateHeader(fruHeader));
Vijay Khemka7a682a32021-04-12 22:15:00 +000049}
50
51TEST(ValidateHeaderTest, ValidChecksumReturnsTrue)
52{
53 // Validates the checksum, check for correct value.
Ed Tanous07d467b2021-02-23 14:48:37 -080054 constexpr std::array<uint8_t, I2C_SMBUS_BLOCK_MAX> fruHeader = {
Vijay Khemka7a682a32021-04-12 22:15:00 +000055 0x01, 0x00, 0x01, 0x02, 0x03, 0x04, 0x00, 0xf5};
56
Ed Tanous07d467b2021-02-23 14:48:37 -080057 EXPECT_TRUE(validateHeader(fruHeader));
Vijay Khemka7a682a32021-04-12 22:15:00 +000058}
59
Vijay Khemka1694ef62021-02-12 23:14:49 +000060TEST(VerifyOffsetTest, EmptyFruDataReturnsFalse)
61{
62 // Validates the FruData size is checked for non empty.
Ed Tanous07d467b2021-02-23 14:48:37 -080063 std::vector<uint8_t> fruData = {};
Vijay Khemka1694ef62021-02-12 23:14:49 +000064
Ed Tanous07d467b2021-02-23 14:48:37 -080065 EXPECT_FALSE(verifyOffset(fruData, fruAreas::fruAreaChassis, 0));
Vijay Khemka1694ef62021-02-12 23:14:49 +000066}
67
68TEST(VerifyOffsetTest, AreaOutOfRangeReturnsFalse)
69{
70 // Validates the FruArea value, check if it is within range.
Ed Tanous07d467b2021-02-23 14:48:37 -080071 const std::vector<uint8_t> fruData = {0x01, 0x00, 0x00, 0x00, 0x00,
72 0x00, 0x00, 0x00, 0x00};
Vijay Khemka1694ef62021-02-12 23:14:49 +000073
74 unsigned int areaOutOfRange = 8;
75 EXPECT_FALSE(
Ed Tanous07d467b2021-02-23 14:48:37 -080076 verifyOffset(fruData, static_cast<fruAreas>(areaOutOfRange), 0));
Vijay Khemka1694ef62021-02-12 23:14:49 +000077}
78
79TEST(VerifyOffsetTest, OverlapNextAreaReturnsFalse)
80{
81 // Validates the Overlap of offsets with overlapped values.
Ed Tanous07d467b2021-02-23 14:48:37 -080082 const std::vector<uint8_t> fruData = {0x01, 0x00, 0x01, 0x02, 0x03,
83 0x04, 0x00, 0x00, 0x00};
Vijay Khemka1694ef62021-02-12 23:14:49 +000084
Ed Tanous07d467b2021-02-23 14:48:37 -080085 EXPECT_FALSE(verifyOffset(fruData, fruAreas::fruAreaChassis, 2));
Vijay Khemka1694ef62021-02-12 23:14:49 +000086}
87
88TEST(VerifyOffsetTest, OverlapPrevAreaReturnsFalse)
89{
90 // Validates the Overlap of offsets with overlapped values.
Ed Tanous07d467b2021-02-23 14:48:37 -080091 const std::vector<uint8_t> fruData = {0x01, 0x00, 0x01, 0x03, 0x02,
92 0x07, 0x00, 0x00, 0x00};
Vijay Khemka1694ef62021-02-12 23:14:49 +000093
Ed Tanous07d467b2021-02-23 14:48:37 -080094 EXPECT_FALSE(verifyOffset(fruData, fruAreas::fruAreaProduct, 2));
Vijay Khemka1694ef62021-02-12 23:14:49 +000095}
96
97TEST(VerifyOffsetTest, ValidInputDataNoOverlapReturnsTrue)
98{
99 // Validates all inputs with expected value and no overlap.
Ed Tanous07d467b2021-02-23 14:48:37 -0800100 const std::vector<uint8_t> fruData = {0x01, 0x00, 0x01, 0x02, 0x03,
101 0x04, 0x00, 0x00, 0x00};
Vijay Khemka1694ef62021-02-12 23:14:49 +0000102
Ed Tanous07d467b2021-02-23 14:48:37 -0800103 EXPECT_TRUE(verifyOffset(fruData, fruAreas::fruAreaChassis, 1));
Vijay Khemka1694ef62021-02-12 23:14:49 +0000104}
Andrew Jeffery8dacf6a2021-08-02 22:17:18 +0930105
106TEST(VerifyChecksumTest, EmptyInput)
107{
108 std::vector<uint8_t> data = {};
109
110 EXPECT_EQ(calculateChecksum(data), 0);
111}
112
113TEST(VerifyChecksumTest, SingleOneInput)
114{
115 std::vector<uint8_t> data(1, 1);
116
117 EXPECT_EQ(calculateChecksum(data), 255);
118}
119
120TEST(VerifyChecksumTest, AllOneInput)
121{
122 std::vector<uint8_t> data(256, 1);
123
124 EXPECT_EQ(calculateChecksum(data), 0);
125}
126
127TEST(VerifyChecksumTest, WrapBoundaryLow)
128{
Ed Tanousfbce8e22021-09-02 15:29:12 -0700129 std::vector<uint8_t> data = {255, 0};
Andrew Jeffery8dacf6a2021-08-02 22:17:18 +0930130
131 EXPECT_EQ(calculateChecksum(data), 1);
132}
133
134TEST(VerifyChecksumTest, WrapBoundaryExact)
135{
Ed Tanousfbce8e22021-09-02 15:29:12 -0700136 std::vector<uint8_t> data = {255, 1};
Andrew Jeffery8dacf6a2021-08-02 22:17:18 +0930137
138 EXPECT_EQ(calculateChecksum(data), 0);
139}
140
141TEST(VerifyChecksumTest, WrapBoundaryHigh)
142{
Ed Tanousfbce8e22021-09-02 15:29:12 -0700143 std::vector<uint8_t> data = {255, 2};
Andrew Jeffery8dacf6a2021-08-02 22:17:18 +0930144
145 EXPECT_EQ(calculateChecksum(data), 255);
146}
Oskar Senftbd4075f2021-10-05 23:42:43 -0400147
Andrew Jefferyf8ae2ba2022-03-25 15:13:55 +1030148int64_t getDataTempl(const std::vector<uint8_t>& data,
149 [[maybe_unused]] int flag, [[maybe_unused]] int file,
Zev Weiss1525e852022-03-22 22:27:43 +0000150 [[maybe_unused]] uint16_t address, off_t offset,
151 size_t length, uint8_t* outBuf)
Oskar Senftbd4075f2021-10-05 23:42:43 -0400152{
Zev Weiss1525e852022-03-22 22:27:43 +0000153 if (offset >= static_cast<off_t>(data.size()))
Oskar Senftbd4075f2021-10-05 23:42:43 -0400154 {
155 return 0;
156 }
157
158 uint16_t idx;
Andrew Jefferyf8ae2ba2022-03-25 15:13:55 +1030159 for (idx = offset; idx < data.size() && idx < offset + length;
Oskar Senftbd4075f2021-10-05 23:42:43 -0400160 ++idx, ++outBuf)
161 {
162 *outBuf = data[idx];
163 }
164
165 return idx - offset;
166}
167
168TEST(FindFRUHeaderTest, InvalidHeader)
169{
170 const std::vector<uint8_t> data = {255, 16};
Zev Weiss1525e852022-03-22 22:27:43 +0000171 off_t offset = 0;
Oskar Senftbd4075f2021-10-05 23:42:43 -0400172 std::array<uint8_t, I2C_SMBUS_BLOCK_MAX> blockData;
Andrew Jefferyf8ae2ba2022-03-25 15:13:55 +1030173 auto getData = [&data](auto fl, auto fi, auto a, auto o, auto l, auto* b) {
174 return getDataTempl(data, fl, fi, a, o, l, b);
175 };
Oskar Senftbd4075f2021-10-05 23:42:43 -0400176
177 EXPECT_FALSE(findFRUHeader(0, 0, 0, getData, "error", blockData, offset));
178}
179
180TEST(FindFRUHeaderTest, NoData)
181{
182 const std::vector<uint8_t> data = {};
Zev Weiss1525e852022-03-22 22:27:43 +0000183 off_t offset = 0;
Oskar Senftbd4075f2021-10-05 23:42:43 -0400184 std::array<uint8_t, I2C_SMBUS_BLOCK_MAX> blockData;
Andrew Jefferyf8ae2ba2022-03-25 15:13:55 +1030185 auto getData = [&data](auto fl, auto fi, auto a, auto o, auto l, auto* b) {
186 return getDataTempl(data, fl, fi, a, o, l, b);
187 };
Oskar Senftbd4075f2021-10-05 23:42:43 -0400188
189 EXPECT_FALSE(findFRUHeader(0, 0, 0, getData, "error", blockData, offset));
190}
191
192TEST(FindFRUHeaderTest, ValidHeader)
193{
Andrew Jefferyf8ae2ba2022-03-25 15:13:55 +1030194 const std::vector<uint8_t> data = {0x01, 0x00, 0x01, 0x02,
195 0x03, 0x04, 0x00, 0xf5};
Zev Weiss1525e852022-03-22 22:27:43 +0000196 off_t offset = 0;
Oskar Senftbd4075f2021-10-05 23:42:43 -0400197 std::array<uint8_t, I2C_SMBUS_BLOCK_MAX> blockData;
Andrew Jefferyf8ae2ba2022-03-25 15:13:55 +1030198 auto getData = [&data](auto fl, auto fi, auto a, auto o, auto l, auto* b) {
199 return getDataTempl(data, fl, fi, a, o, l, b);
200 };
Oskar Senftbd4075f2021-10-05 23:42:43 -0400201
202 EXPECT_TRUE(findFRUHeader(0, 0, 0, getData, "error", blockData, offset));
203 EXPECT_EQ(0, offset);
204}
205
206TEST(FindFRUHeaderTest, TyanInvalidHeader)
207{
208 std::vector<uint8_t> data = {'$', 'T', 'Y', 'A', 'N', '$', 0, 0};
209 data.resize(0x6000 + I2C_SMBUS_BLOCK_MAX);
Zev Weiss1525e852022-03-22 22:27:43 +0000210 off_t offset = 0;
Oskar Senftbd4075f2021-10-05 23:42:43 -0400211 std::array<uint8_t, I2C_SMBUS_BLOCK_MAX> blockData;
Andrew Jefferyf8ae2ba2022-03-25 15:13:55 +1030212 auto getData = [&data](auto fl, auto fi, auto a, auto o, auto l, auto* b) {
213 return getDataTempl(data, fl, fi, a, o, l, b);
214 };
Oskar Senftbd4075f2021-10-05 23:42:43 -0400215
216 EXPECT_FALSE(findFRUHeader(0, 0, 0, getData, "error", blockData, offset));
217}
218
219TEST(FindFRUHeaderTest, TyanNoData)
220{
221 const std::vector<uint8_t> data = {'$', 'T', 'Y', 'A', 'N', '$', 0, 0};
Zev Weiss1525e852022-03-22 22:27:43 +0000222 off_t offset = 0;
Oskar Senftbd4075f2021-10-05 23:42:43 -0400223 std::array<uint8_t, I2C_SMBUS_BLOCK_MAX> blockData;
Andrew Jefferyf8ae2ba2022-03-25 15:13:55 +1030224 auto getData = [&data](auto fl, auto fi, auto a, auto o, auto l, auto* b) {
225 return getDataTempl(data, fl, fi, a, o, l, b);
226 };
Oskar Senftbd4075f2021-10-05 23:42:43 -0400227
228 EXPECT_FALSE(findFRUHeader(0, 0, 0, getData, "error", blockData, offset));
229}
230
231TEST(FindFRUHeaderTest, TyanValidHeader)
232{
233 std::vector<uint8_t> data = {'$', 'T', 'Y', 'A', 'N', '$', 0, 0};
234 data.resize(0x6000);
235 constexpr std::array<uint8_t, I2C_SMBUS_BLOCK_MAX> fruHeader = {
236 0x01, 0x00, 0x01, 0x02, 0x03, 0x04, 0x00, 0xf5};
237 copy(fruHeader.begin(), fruHeader.end(), back_inserter(data));
238
Zev Weiss1525e852022-03-22 22:27:43 +0000239 off_t offset = 0;
Oskar Senftbd4075f2021-10-05 23:42:43 -0400240 std::array<uint8_t, I2C_SMBUS_BLOCK_MAX> blockData;
Andrew Jefferyf8ae2ba2022-03-25 15:13:55 +1030241 auto getData = [&data](auto fl, auto fi, auto a, auto o, auto l, auto* b) {
242 return getDataTempl(data, fl, fi, a, o, l, b);
243 };
Oskar Senftbd4075f2021-10-05 23:42:43 -0400244
245 EXPECT_TRUE(findFRUHeader(0, 0, 0, getData, "error", blockData, offset));
246 EXPECT_EQ(0x6000, offset);
247}