blob: 28a8e989e4aa12f7f9ef7415e8cd6934fe3398ae [file] [log] [blame]
Matt Spinler97f7abc2019-11-06 09:40:23 -06001/**
2 * Copyright © 2019 IBM Corporation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Matt Spinlera906c942019-10-08 13:42:05 -050016#include "extensions/openpower-pels/fru_identity.hpp"
17
18#include <gtest/gtest.h>
19
20using namespace openpower::pels;
21using namespace openpower::pels::src;
22
23// Unflatten a FRUIdentity that is a HW FRU callout
24TEST(FRUIdentityTest, TestHardwareFRU)
25{
26 // Has PN, SN, CCIN
27 std::vector<uint8_t> data{'I', 'D', 0x1C, 0x1D, // type, size, flags
28 '1', '2', '3', '4', // PN
29 '5', '6', '7', 0x00, 'A', 'A', 'A', 'A', // CCIN
30 '1', '2', '3', '4', '5', '6', '7', '8', // SN
31 '9', 'A', 'B', 'C'};
32
33 Stream stream{data};
34
35 FRUIdentity fru{stream};
36
37 EXPECT_EQ(fru.failingComponentType(), FRUIdentity::hardwareFRU);
38 EXPECT_EQ(fru.flattenedSize(), data.size());
Matt Spinlerba0ee002020-03-13 11:24:14 -050039 EXPECT_EQ(fru.type(), 0x4944);
Matt Spinlera906c942019-10-08 13:42:05 -050040
41 EXPECT_EQ(fru.getPN().value(), "1234567");
42 EXPECT_EQ(fru.getCCIN().value(), "AAAA");
43 EXPECT_EQ(fru.getSN().value(), "123456789ABC");
44 EXPECT_FALSE(fru.getMaintProc());
45
46 // Flatten
47 std::vector<uint8_t> newData;
48 Stream newStream{newData};
49 fru.flatten(newStream);
50 EXPECT_EQ(data, newData);
51}
52
53// Unflatten a FRUIdentity that is a Maintenance Procedure callout
54TEST(FRUIdentityTest, TestMaintProcedure)
55{
56 // Only contains the maintenance procedure
57 std::vector<uint8_t> data{
58 0x49, 0x44, 0x0C, 0x42, // type, size, flags
59 '1', '2', '3', '4', '5', '6', '7', 0x00 // Procedure
60 };
61
62 Stream stream{data};
63
64 FRUIdentity fru{stream};
65
66 EXPECT_EQ(fru.failingComponentType(), FRUIdentity::maintenanceProc);
67 EXPECT_EQ(fru.flattenedSize(), data.size());
68
69 EXPECT_EQ(fru.getMaintProc().value(), "1234567");
70 EXPECT_FALSE(fru.getPN());
71 EXPECT_FALSE(fru.getCCIN());
72 EXPECT_FALSE(fru.getSN());
73
74 // Flatten
75 std::vector<uint8_t> newData;
76 Stream newStream{newData};
77 fru.flatten(newStream);
78 EXPECT_EQ(data, newData);
79}
80
81// Try to unflatten garbage data
82TEST(FRUIdentityTest, BadDataTest)
83{
84 std::vector<uint8_t> data{0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
85 0xFF, 0xFF, 0xFF, 0xFF};
86
87 Stream stream{data};
88
89 EXPECT_THROW(FRUIdentity fru{stream}, std::out_of_range);
90}
Matt Spinlerba0ee002020-03-13 11:24:14 -050091
92void testHWCallout(const std::string& pn, const std::string ccin,
93 const std::string& sn, const std::string& expectedPN,
94 const std::string& expectedCCIN,
95 const std::string& expectedSN)
96{
97 FRUIdentity fru{pn, ccin, sn};
98
99 EXPECT_EQ(fru.flattenedSize(), 28);
100 EXPECT_EQ(fru.type(), 0x4944);
101 EXPECT_EQ(fru.failingComponentType(), FRUIdentity::hardwareFRU);
102 EXPECT_EQ(fru.getPN().value(), expectedPN);
103 EXPECT_EQ(fru.getCCIN().value(), expectedCCIN);
104 EXPECT_EQ(fru.getSN().value(), expectedSN);
105 EXPECT_FALSE(fru.getMaintProc());
106
107 // Flatten and unflatten, then compare again
108 std::vector<uint8_t> data;
109 Stream stream{data};
110 fru.flatten(stream);
111
112 EXPECT_EQ(data.size(), fru.flattenedSize());
113
114 stream.offset(0);
115 FRUIdentity newFRU{stream};
116
117 EXPECT_EQ(newFRU.flattenedSize(), fru.flattenedSize());
118 EXPECT_EQ(newFRU.type(), fru.type());
119 EXPECT_EQ(newFRU.failingComponentType(), fru.failingComponentType());
120 EXPECT_EQ(newFRU.getPN().value(), fru.getPN().value());
121 EXPECT_EQ(newFRU.getCCIN().value(), fru.getCCIN().value());
122 EXPECT_EQ(newFRU.getSN().value(), fru.getSN().value());
123 EXPECT_FALSE(newFRU.getMaintProc());
124}
125
126// Test the constructor that takes in a PN/SN/CCIN
127TEST(FRUIdentityTest, CreateHardwareCalloutTest)
128{
129 // The right sizes
130 testHWCallout("1234567", "1234", "123456789ABC",
131 // expected
132 "1234567", "1234", "123456789ABC");
133
134 // Too long
135 testHWCallout("1234567long", "1234long", "123456789ABClong",
136 // expected
137 "1234567", "1234", "123456789ABC");
138 // Too short
139 testHWCallout("11", "22", "333",
140 // expected
141 "11", "22", "333");
142
143 // empty
144 testHWCallout("", "", "",
145 // expected
146 "", "", "");
147
148 // Leading spaces in the part number will be stripped
149 testHWCallout(" 567", "1234", "123456789ABC",
150 // expected
151 "567", "1234", "123456789ABC");
152
153 // All spaces in the part number
154 testHWCallout(" ", "1234", "123456789ABC",
155 // expected
156 "", "1234", "123456789ABC");
157}
158
159// Test the constructor that takes in a maint procedure
160TEST(FRUIdentityTest, CreateProcedureCalloutTest)
161{
Matt Spinlera27e2e52020-04-09 11:06:11 -0500162 {
Matt Spinler479b6922021-08-17 16:34:59 -0500163 FRUIdentity fru{"bmc_code"};
Matt Spinlerba0ee002020-03-13 11:24:14 -0500164
Matt Spinlera27e2e52020-04-09 11:06:11 -0500165 EXPECT_EQ(fru.flattenedSize(), 12);
166 EXPECT_EQ(fru.type(), 0x4944);
167 EXPECT_EQ(fru.failingComponentType(), FRUIdentity::maintenanceProc);
Matt Spinlerea2873d2021-08-18 10:35:40 -0500168 EXPECT_EQ(fru.getMaintProc().value(), "BMC0001");
Matt Spinlera27e2e52020-04-09 11:06:11 -0500169 EXPECT_FALSE(fru.getPN());
170 EXPECT_FALSE(fru.getCCIN());
171 EXPECT_FALSE(fru.getSN());
Matt Spinlerba0ee002020-03-13 11:24:14 -0500172
Matt Spinlera27e2e52020-04-09 11:06:11 -0500173 // Flatten and unflatten, then compare again
174 std::vector<uint8_t> data;
175 Stream stream{data};
176 fru.flatten(stream);
Matt Spinlerba0ee002020-03-13 11:24:14 -0500177
Matt Spinlera27e2e52020-04-09 11:06:11 -0500178 EXPECT_EQ(data.size(), fru.flattenedSize());
Matt Spinlerba0ee002020-03-13 11:24:14 -0500179
Matt Spinlera27e2e52020-04-09 11:06:11 -0500180 stream.offset(0);
181 FRUIdentity newFRU{stream};
Matt Spinlerba0ee002020-03-13 11:24:14 -0500182
Matt Spinlera27e2e52020-04-09 11:06:11 -0500183 EXPECT_EQ(newFRU.flattenedSize(), 12);
184 EXPECT_EQ(newFRU.type(), 0x4944);
185 EXPECT_EQ(newFRU.failingComponentType(), FRUIdentity::maintenanceProc);
Matt Spinlerea2873d2021-08-18 10:35:40 -0500186 EXPECT_EQ(newFRU.getMaintProc().value(), "BMC0001");
Matt Spinlera27e2e52020-04-09 11:06:11 -0500187 EXPECT_FALSE(newFRU.getPN());
188 EXPECT_FALSE(newFRU.getCCIN());
189 EXPECT_FALSE(newFRU.getSN());
190 }
191
192 {
193 // Invalid maintenance procedure
194 FRUIdentity fru{"invalid"};
195
196 EXPECT_EQ(fru.flattenedSize(), 12);
197 EXPECT_EQ(fru.type(), 0x4944);
198 EXPECT_EQ(fru.failingComponentType(), FRUIdentity::maintenanceProc);
199 EXPECT_EQ(fru.getMaintProc().value(), "INVALID");
200 EXPECT_FALSE(fru.getPN());
201 EXPECT_FALSE(fru.getCCIN());
202 EXPECT_FALSE(fru.getSN());
203 }
Matt Spinler468aab52020-08-13 11:04:31 -0500204
205 {
206 // Raw maintenance procedure
Matt Spinlerea2873d2021-08-18 10:35:40 -0500207 FRUIdentity fru{"BMCXXXXLONG", CalloutValueType::raw};
208 EXPECT_EQ(fru.getMaintProc().value(), "BMCXXXX");
Matt Spinler468aab52020-08-13 11:04:31 -0500209 }
Matt Spinlerba0ee002020-03-13 11:24:14 -0500210}
Matt Spinler2b6dfa02020-04-09 11:39:05 -0500211
212// Test the constructor that takes in a symbolic FRU.
213TEST(FRUIdentityTest, CreateSymbolicFRUCalloutTest)
214{
215 // Symbolic FRU (not trusted)
216 {
217 FRUIdentity fru{"service_docs", false};
218
219 EXPECT_EQ(fru.flattenedSize(), 12);
220 EXPECT_EQ(fru.type(), 0x4944);
221 EXPECT_EQ(fru.failingComponentType(), FRUIdentity::symbolicFRU);
222 EXPECT_EQ(fru.getPN().value(), "SVCDOCS");
223 EXPECT_FALSE(fru.getMaintProc());
224 EXPECT_FALSE(fru.getCCIN());
225 EXPECT_FALSE(fru.getSN());
226
227 // Flatten and unflatten, then compare again
228 std::vector<uint8_t> data;
229 Stream stream{data};
230 fru.flatten(stream);
231
232 EXPECT_EQ(data.size(), fru.flattenedSize());
233
234 stream.offset(0);
235 FRUIdentity newFRU{stream};
236
237 EXPECT_EQ(newFRU.flattenedSize(), 12);
238 EXPECT_EQ(newFRU.type(), 0x4944);
239 EXPECT_EQ(newFRU.failingComponentType(), FRUIdentity::symbolicFRU);
240 EXPECT_EQ(newFRU.getPN().value(), "SVCDOCS");
241 EXPECT_FALSE(newFRU.getMaintProc());
242 EXPECT_FALSE(newFRU.getCCIN());
243 EXPECT_FALSE(newFRU.getSN());
244 }
245
246 // Trusted symbolic FRU
247 {
248 FRUIdentity fru{"service_docs", true};
249
250 EXPECT_EQ(fru.flattenedSize(), 12);
251 EXPECT_EQ(fru.type(), 0x4944);
252 EXPECT_EQ(fru.failingComponentType(),
253 FRUIdentity::symbolicFRUTrustedLocCode);
254 EXPECT_EQ(fru.getPN().value(), "SVCDOCS");
255 EXPECT_FALSE(fru.getMaintProc());
256 EXPECT_FALSE(fru.getCCIN());
257 EXPECT_FALSE(fru.getSN());
258 }
259
260 // Invalid symbolic FRU
261 {
262 FRUIdentity fru{"garbage", false};
263
264 EXPECT_EQ(fru.flattenedSize(), 12);
265 EXPECT_EQ(fru.type(), 0x4944);
266 EXPECT_EQ(fru.failingComponentType(), FRUIdentity::symbolicFRU);
267 EXPECT_EQ(fru.getPN().value(), "INVALID");
268 EXPECT_FALSE(fru.getMaintProc());
269 EXPECT_FALSE(fru.getCCIN());
270 EXPECT_FALSE(fru.getSN());
271 }
Matt Spinler468aab52020-08-13 11:04:31 -0500272
273 // Raw symbolic FRU
274 {
275 FRUIdentity fru{"SOMEFRULONG", CalloutValueType::raw, false};
276
277 EXPECT_EQ(fru.getPN().value(), "SOMEFRU");
278 }
Matt Spinler2b6dfa02020-04-09 11:39:05 -0500279}