1 /**
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  */
16 #include "extensions/openpower-pels/extended_user_header.hpp"
17 #include "mocks.hpp"
18 #include "pel_utils.hpp"
19 
20 #include <gtest/gtest.h>
21 
22 using namespace openpower::pels;
23 using ::testing::Return;
24 
25 const std::vector<uint8_t> sectionData{
26     // section header
27     'E', 'H', 0x00, 0x60, // ID and Size
28     0x01, 0x00,           // version, subtype
29     0x03, 0x04,           // comp ID
30 
31     // MTMS
32     'T', 'T', 'T', 'T', '-', 'M', 'M', 'M', '1', '2', '3', '4', '5', '6', '7',
33     '8', '9', 'A', 'B', 'C',
34 
35     // Server FW version
36     'S', 'E', 'R', 'V', 'E', 'R', '_', 'V', 'E', 'R', 'S', 'I', 'O', 'N', '\0',
37     '\0',
38 
39     // Subsystem FW Version
40     'B', 'M', 'C', '_', 'V', 'E', 'R', 'S', 'I', 'O', 'N', '\0', '\0', '\0',
41     '\0', '\0',
42 
43     // Reserved
44     0x00, 0x00, 0x00, 0x00,
45 
46     // Reference time
47     0x20, 0x25, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60,
48 
49     // Reserved
50     0x00, 0x00, 0x00,
51 
52     // SymptomID length
53     20,
54 
55     // SymptomID
56     'B', 'D', '8', 'D', '4', '2', '0', '0', '_', '1', '2', '3', '4', '5', '6',
57     '7', '8', '\0', '\0', '\0'};
58 
59 // The section size without the symptom ID
60 const size_t baseSectionSize = 76;
61 
62 TEST(ExtUserHeaderTest, StreamConstructorTest)
63 {
64     auto data = sectionData;
65     Stream stream{data};
66     ExtendedUserHeader euh{stream};
67 
68     EXPECT_EQ(euh.valid(), true);
69     EXPECT_EQ(euh.header().id, 0x4548); // EH
70     EXPECT_EQ(euh.header().size, sectionData.size());
71     EXPECT_EQ(euh.header().version, 0x01);
72     EXPECT_EQ(euh.header().subType, 0x00);
73     EXPECT_EQ(euh.header().componentID, 0x0304);
74 
75     EXPECT_EQ(euh.flattenedSize(), sectionData.size());
76     EXPECT_EQ(euh.machineTypeModel(), "TTTT-MMM");
77     EXPECT_EQ(euh.machineSerialNumber(), "123456789ABC");
78     EXPECT_EQ(euh.serverFWVersion(), "SERVER_VERSION");
79     EXPECT_EQ(euh.subsystemFWVersion(), "BMC_VERSION");
80     EXPECT_EQ(euh.symptomID(), "BD8D4200_12345678");
81 
82     BCDTime time{0x20, 0x25, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60};
83     EXPECT_EQ(time, euh.refTime());
84 
85     // Flatten it and make sure nothing changes
86     std::vector<uint8_t> newData;
87     Stream newStream{newData};
88 
89     euh.flatten(newStream);
90     EXPECT_EQ(sectionData, newData);
91 }
92 
93 // Same as above, with with symptom ID empty
94 TEST(ExtUserHeaderTest, StreamConstructorNoIDTest)
95 {
96     auto data = sectionData;
97     data.resize(baseSectionSize);
98     data[3] = baseSectionSize; // The size in the header
99     data.back() = 0;           // Symptom ID length
100 
101     Stream stream{data};
102     ExtendedUserHeader euh{stream};
103 
104     EXPECT_EQ(euh.valid(), true);
105     EXPECT_EQ(euh.header().id, 0x4548); // EH
106     EXPECT_EQ(euh.header().size, baseSectionSize);
107     EXPECT_EQ(euh.header().version, 0x01);
108     EXPECT_EQ(euh.header().subType, 0x00);
109     EXPECT_EQ(euh.header().componentID, 0x0304);
110 
111     EXPECT_EQ(euh.flattenedSize(), baseSectionSize);
112     EXPECT_EQ(euh.machineTypeModel(), "TTTT-MMM");
113     EXPECT_EQ(euh.machineSerialNumber(), "123456789ABC");
114     EXPECT_EQ(euh.serverFWVersion(), "SERVER_VERSION");
115     EXPECT_EQ(euh.subsystemFWVersion(), "BMC_VERSION");
116     EXPECT_EQ(euh.symptomID(), "");
117 
118     BCDTime time{0x20, 0x25, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60};
119     EXPECT_EQ(time, euh.refTime());
120 
121     // Flatten it and make sure nothing changes
122     std::vector<uint8_t> newData;
123     Stream newStream{newData};
124 
125     euh.flatten(newStream);
126     EXPECT_EQ(data, newData);
127 }
128 
129 TEST(ExtUserHeaderTest, ConstructorTest)
130 {
131     auto srcData = pelDataFactory(TestPELType::primarySRCSection);
132     Stream srcStream{srcData};
133     SRC src{srcStream};
134 
135     message::Entry entry; // Empty Symptom ID vector
136 
137     {
138         MockDataInterface dataIface;
139 
140         EXPECT_CALL(dataIface, getMachineTypeModel())
141             .WillOnce(Return("AAAA-BBB"));
142 
143         EXPECT_CALL(dataIface, getMachineSerialNumber())
144             .WillOnce(Return("123456789ABC"));
145 
146         EXPECT_CALL(dataIface, getServerFWVersion())
147             .WillOnce(Return("SERVER_VERSION"));
148 
149         EXPECT_CALL(dataIface, getBMCFWVersion())
150             .WillOnce(Return("BMC_VERSION"));
151 
152         ExtendedUserHeader euh{dataIface, entry, src};
153 
154         EXPECT_EQ(euh.valid(), true);
155         EXPECT_EQ(euh.header().id, 0x4548); // EH
156 
157         // The symptom ID accounts for the extra 20 bytes
158         EXPECT_EQ(euh.header().size, baseSectionSize + 20);
159         EXPECT_EQ(euh.header().version, 0x01);
160         EXPECT_EQ(euh.header().subType, 0x00);
161         EXPECT_EQ(euh.header().componentID, 0x2000);
162 
163         EXPECT_EQ(euh.flattenedSize(), baseSectionSize + 20);
164         EXPECT_EQ(euh.machineTypeModel(), "AAAA-BBB");
165         EXPECT_EQ(euh.machineSerialNumber(), "123456789ABC");
166         EXPECT_EQ(euh.serverFWVersion(), "SERVER_VERSION");
167         EXPECT_EQ(euh.subsystemFWVersion(), "BMC_VERSION");
168 
169         // The default symptom ID is the ascii string + word 3
170         EXPECT_EQ(euh.symptomID(), "BD8D5678_03030310");
171 
172         BCDTime time;
173         EXPECT_EQ(time, euh.refTime());
174     }
175 
176     {
177         MockDataInterface dataIface;
178 
179         // These 4 items are too long and will get truncated
180         // in the section.
181         EXPECT_CALL(dataIface, getMachineTypeModel())
182             .WillOnce(Return("AAAA-BBBBBBBBBBB"));
183 
184         EXPECT_CALL(dataIface, getMachineSerialNumber())
185             .WillOnce(Return("123456789ABC123456789"));
186 
187         EXPECT_CALL(dataIface, getServerFWVersion())
188             .WillOnce(Return("SERVER_VERSION_WAY_TOO_LONG"));
189 
190         EXPECT_CALL(dataIface, getBMCFWVersion())
191             .WillOnce(Return("BMC_VERSION_WAY_TOO_LONG"));
192 
193         // Use SRC words 3 through 9
194         entry.src.symptomID = {3, 4, 5, 6, 7, 8, 9};
195         ExtendedUserHeader euh{dataIface, entry, src};
196 
197         EXPECT_EQ(euh.valid(), true);
198         EXPECT_EQ(euh.header().id, 0x4548); // EH
199         EXPECT_EQ(euh.header().size, baseSectionSize + 72);
200         EXPECT_EQ(euh.header().version, 0x01);
201         EXPECT_EQ(euh.header().subType, 0x00);
202         EXPECT_EQ(euh.header().componentID, 0x2000);
203 
204         EXPECT_EQ(euh.flattenedSize(), baseSectionSize + 72);
205         EXPECT_EQ(euh.machineTypeModel(), "AAAA-BBB");
206         EXPECT_EQ(euh.machineSerialNumber(), "123456789ABC");
207         EXPECT_EQ(euh.serverFWVersion(), "SERVER_VERSION_");
208         EXPECT_EQ(euh.subsystemFWVersion(), "BMC_VERSION_WAY");
209 
210         EXPECT_EQ(euh.symptomID(), "BD8D5678_03030310_04040404_05050505_"
211                                    "06060606_07070707_08080808_09090909");
212         BCDTime time;
213         EXPECT_EQ(time, euh.refTime());
214     }
215 
216     {
217         MockDataInterface dataIface;
218 
219         // Empty fields
220         EXPECT_CALL(dataIface, getMachineTypeModel()).WillOnce(Return(""));
221 
222         EXPECT_CALL(dataIface, getMachineSerialNumber()).WillOnce(Return(""));
223 
224         EXPECT_CALL(dataIface, getServerFWVersion()).WillOnce(Return(""));
225 
226         EXPECT_CALL(dataIface, getBMCFWVersion()).WillOnce(Return(""));
227 
228         entry.src.symptomID = {8, 9};
229         ExtendedUserHeader euh{dataIface, entry, src};
230 
231         EXPECT_EQ(euh.valid(), true);
232         EXPECT_EQ(euh.header().id, 0x4548); // EH
233         EXPECT_EQ(euh.header().size, baseSectionSize + 28);
234         EXPECT_EQ(euh.header().version, 0x01);
235         EXPECT_EQ(euh.header().subType, 0x00);
236         EXPECT_EQ(euh.header().componentID, 0x2000);
237 
238         EXPECT_EQ(euh.flattenedSize(), baseSectionSize + 28);
239         EXPECT_EQ(euh.machineTypeModel(), "");
240         EXPECT_EQ(euh.machineSerialNumber(), "");
241         EXPECT_EQ(euh.serverFWVersion(), "");
242         EXPECT_EQ(euh.subsystemFWVersion(), "");
243 
244         EXPECT_EQ(euh.symptomID(), "BD8D5678_08080808_09090909");
245 
246         BCDTime time;
247         EXPECT_EQ(time, euh.refTime());
248     }
249 
250     {
251         MockDataInterface dataIface;
252 
253         EXPECT_CALL(dataIface, getMachineTypeModel())
254             .WillOnce(Return("AAAA-BBB"));
255 
256         EXPECT_CALL(dataIface, getMachineSerialNumber())
257             .WillOnce(Return("123456789ABC"));
258 
259         EXPECT_CALL(dataIface, getServerFWVersion())
260             .WillOnce(Return("SERVER_VERSION"));
261 
262         EXPECT_CALL(dataIface, getBMCFWVersion())
263             .WillOnce(Return("BMC_VERSION"));
264 
265         // Way too long, will be truncated
266         entry.src.symptomID = {9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9};
267 
268         ExtendedUserHeader euh{dataIface, entry, src};
269 
270         EXPECT_EQ(euh.valid(), true);
271         EXPECT_EQ(euh.header().id, 0x4548); // EH
272         EXPECT_EQ(euh.header().size, baseSectionSize + 80);
273         EXPECT_EQ(euh.header().version, 0x01);
274         EXPECT_EQ(euh.header().subType, 0x00);
275         EXPECT_EQ(euh.header().componentID, 0x2000);
276 
277         EXPECT_EQ(euh.flattenedSize(), baseSectionSize + 80);
278         EXPECT_EQ(euh.machineTypeModel(), "AAAA-BBB");
279         EXPECT_EQ(euh.machineSerialNumber(), "123456789ABC");
280         EXPECT_EQ(euh.serverFWVersion(), "SERVER_VERSION");
281         EXPECT_EQ(euh.subsystemFWVersion(), "BMC_VERSION");
282 
283         EXPECT_EQ(euh.symptomID(),
284                   "BD8D5678_09090909_09090909_09090909_09090909_09090909_"
285                   "09090909_09090909_0909090");
286 
287         BCDTime time;
288         EXPECT_EQ(time, euh.refTime());
289     }
290 }
291 
292 TEST(ExtUserHeaderTest, BadDataTest)
293 {
294     auto data = sectionData;
295     data.resize(20);
296 
297     Stream stream{data};
298     ExtendedUserHeader euh{stream};
299 
300     EXPECT_EQ(euh.valid(), false);
301 }
302