blob: 29840944e86fdfd684d1e20c87bff9f4c06141aa [file] [log] [blame]
Patrick Venturea62466c2021-02-08 14:55:18 -08001#include "FruUtils.hpp"
2
3#include <array>
Oskar Senftbd4075f2021-10-05 23:42:43 -04004#include<algorithm>
5#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
148int64_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
171TEST(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
182TEST(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
193TEST(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
206TEST(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
218TEST(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
229TEST(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}