blob: 6494c52f4080ea9b9804f5b1e6f620baaa33c443 [file] [log] [blame]
Matt Spinlerb8323632019-09-20 15:11:04 -05001#include "elog_entry.hpp"
Matt Spinler131870c2019-09-25 13:29:04 -05002#include "extensions/openpower-pels/generic.hpp"
Matt Spinlercb6b0592019-07-16 15:58:51 -05003#include "extensions/openpower-pels/pel.hpp"
Matt Spinleraa659472019-10-23 09:26:48 -05004#include "mocks.hpp"
Matt Spinlercb6b0592019-07-16 15:58:51 -05005#include "pel_utils.hpp"
6
7#include <filesystem>
8#include <fstream>
9
10#include <gtest/gtest.h>
11
12namespace fs = std::filesystem;
13using namespace openpower::pels;
14
15class PELTest : public CleanLogID
16{
17};
18
19TEST_F(PELTest, FlattenTest)
20{
Matt Spinler42828bd2019-10-11 10:39:30 -050021 auto data = pelDataFactory(TestPELType::pelSimple);
22 auto origData = data;
23 auto pel = std::make_unique<PEL>(data);
Matt Spinlercb6b0592019-07-16 15:58:51 -050024
25 // Check a few fields
26 EXPECT_TRUE(pel->valid());
27 EXPECT_EQ(pel->id(), 0x80818283);
28 EXPECT_EQ(pel->plid(), 0x50515253);
29 EXPECT_EQ(pel->userHeader()->subsystem(), 0x10);
30 EXPECT_EQ(pel->userHeader()->actionFlags(), 0x80C0);
31
32 // Test that data in == data out
33 auto flattenedData = pel->data();
Matt Spinler07eefc52019-09-26 11:18:26 -050034 ASSERT_EQ(origData, flattenedData);
Matt Spinlercb6b0592019-07-16 15:58:51 -050035}
36
37TEST_F(PELTest, CommitTimeTest)
38{
Matt Spinler42828bd2019-10-11 10:39:30 -050039 auto data = pelDataFactory(TestPELType::pelSimple);
40 auto pel = std::make_unique<PEL>(data);
Matt Spinlercb6b0592019-07-16 15:58:51 -050041
42 auto origTime = pel->commitTime();
43 pel->setCommitTime();
44 auto newTime = pel->commitTime();
45
46 ASSERT_NE(origTime, newTime);
47
48 // Make a new PEL and check new value is still there
49 auto newData = pel->data();
50 auto newPel = std::make_unique<PEL>(newData);
51 ASSERT_EQ(newTime, newPel->commitTime());
52}
53
54TEST_F(PELTest, AssignIDTest)
55{
Matt Spinler42828bd2019-10-11 10:39:30 -050056 auto data = pelDataFactory(TestPELType::pelSimple);
57 auto pel = std::make_unique<PEL>(data);
Matt Spinlercb6b0592019-07-16 15:58:51 -050058
59 auto origID = pel->id();
60 pel->assignID();
61 auto newID = pel->id();
62
63 ASSERT_NE(origID, newID);
64
65 // Make a new PEL and check new value is still there
66 auto newData = pel->data();
67 auto newPel = std::make_unique<PEL>(newData);
68 ASSERT_EQ(newID, newPel->id());
69}
70
71TEST_F(PELTest, WithLogIDTest)
72{
Matt Spinler42828bd2019-10-11 10:39:30 -050073 auto data = pelDataFactory(TestPELType::pelSimple);
74 auto pel = std::make_unique<PEL>(data, 0x42);
Matt Spinlercb6b0592019-07-16 15:58:51 -050075
76 EXPECT_TRUE(pel->valid());
77 EXPECT_EQ(pel->obmcLogID(), 0x42);
78}
79
80TEST_F(PELTest, InvalidPELTest)
81{
Matt Spinler42828bd2019-10-11 10:39:30 -050082 auto data = pelDataFactory(TestPELType::pelSimple);
Matt Spinlercb6b0592019-07-16 15:58:51 -050083
84 // Too small
Matt Spinler42828bd2019-10-11 10:39:30 -050085 data.resize(PrivateHeader::flattenedSize());
Matt Spinlercb6b0592019-07-16 15:58:51 -050086
Matt Spinler42828bd2019-10-11 10:39:30 -050087 auto pel = std::make_unique<PEL>(data);
Matt Spinlercb6b0592019-07-16 15:58:51 -050088
89 EXPECT_TRUE(pel->privateHeader()->valid());
90 EXPECT_FALSE(pel->userHeader()->valid());
91 EXPECT_FALSE(pel->valid());
92
Matt Spinlercb6b0592019-07-16 15:58:51 -050093 // Now corrupt the private header
Matt Spinler42828bd2019-10-11 10:39:30 -050094 data = pelDataFactory(TestPELType::pelSimple);
95 data.at(0) = 0;
96 pel = std::make_unique<PEL>(data);
Matt Spinlercb6b0592019-07-16 15:58:51 -050097
98 EXPECT_FALSE(pel->privateHeader()->valid());
99 EXPECT_TRUE(pel->userHeader()->valid());
100 EXPECT_FALSE(pel->valid());
101}
102
103TEST_F(PELTest, EmptyDataTest)
104{
105 std::vector<uint8_t> data;
106 auto pel = std::make_unique<PEL>(data);
107
108 EXPECT_FALSE(pel->privateHeader()->valid());
109 EXPECT_FALSE(pel->userHeader()->valid());
110 EXPECT_FALSE(pel->valid());
111}
Matt Spinlerb8323632019-09-20 15:11:04 -0500112
113TEST_F(PELTest, CreateFromRegistryTest)
114{
115 message::Entry regEntry;
116 uint64_t timestamp = 5;
117
118 regEntry.name = "test";
119 regEntry.subsystem = 5;
120 regEntry.actionFlags = 0xC000;
Matt Spinlerbd716f02019-10-15 10:54:11 -0500121 regEntry.src.type = 0xBD;
122 regEntry.src.reasonCode = 0x1234;
Matt Spinlerb8323632019-09-20 15:11:04 -0500123
Matt Spinlerbd716f02019-10-15 10:54:11 -0500124 AdditionalData ad;
Matt Spinleraa659472019-10-23 09:26:48 -0500125 MockDataInterface dataIface;
Matt Spinlerbd716f02019-10-15 10:54:11 -0500126
Matt Spinleraa659472019-10-23 09:26:48 -0500127 PEL pel{regEntry, 42, timestamp, phosphor::logging::Entry::Level::Error, ad,
128 dataIface};
Matt Spinlerb8323632019-09-20 15:11:04 -0500129
130 EXPECT_TRUE(pel.valid());
131 EXPECT_EQ(pel.privateHeader()->obmcLogID(), 42);
132 EXPECT_EQ(pel.userHeader()->severity(), 0x40);
133
Matt Spinlerbd716f02019-10-15 10:54:11 -0500134 EXPECT_EQ(pel.primarySRC().value()->asciiString(),
135 "BD051234 ");
Matt Spinlerb8323632019-09-20 15:11:04 -0500136}
Matt Spinler131870c2019-09-25 13:29:04 -0500137
138// Test that we'll create Generic optional sections for sections that
139// there aren't explicit classes for.
140TEST_F(PELTest, GenericSectionTest)
141{
Matt Spinler42828bd2019-10-11 10:39:30 -0500142 auto data = pelDataFactory(TestPELType::pelSimple);
Matt Spinler131870c2019-09-25 13:29:04 -0500143
144 std::vector<uint8_t> section1{0x58, 0x58, // ID 'XX'
145 0x00, 0x18, // Size
146 0x01, 0x02, // version, subtype
147 0x03, 0x04, // comp ID
148
149 // some data
150 0x20, 0x30, 0x05, 0x09, 0x11, 0x1E, 0x1, 0x63,
151 0x20, 0x31, 0x06, 0x0F, 0x09, 0x22, 0x3A,
152 0x00};
153
154 std::vector<uint8_t> section2{
155 0x59, 0x59, // ID 'YY'
156 0x00, 0x20, // Size
157 0x01, 0x02, // version, subtype
158 0x03, 0x04, // comp ID
159
160 // some data
161 0x20, 0x30, 0x05, 0x09, 0x11, 0x1E, 0x1, 0x63, 0x20, 0x31, 0x06, 0x0F,
162 0x09, 0x22, 0x3A, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
163
164 // Add the new sections at the end
Matt Spinler42828bd2019-10-11 10:39:30 -0500165 data.insert(data.end(), section1.begin(), section1.end());
166 data.insert(data.end(), section2.begin(), section2.end());
Matt Spinler131870c2019-09-25 13:29:04 -0500167
168 // Increment the section count
Matt Spinler42828bd2019-10-11 10:39:30 -0500169 data.at(27) += 2;
170 auto origData = data;
Matt Spinler131870c2019-09-25 13:29:04 -0500171
Matt Spinler42828bd2019-10-11 10:39:30 -0500172 PEL pel{data};
Matt Spinler131870c2019-09-25 13:29:04 -0500173
174 const auto& sections = pel.optionalSections();
175
176 bool foundXX = false;
177 bool foundYY = false;
178
179 // Check that we can find these 2 Generic sections
180 for (const auto& section : sections)
181 {
182 if (section->header().id == 0x5858)
183 {
184 foundXX = true;
185 EXPECT_NE(dynamic_cast<Generic*>(section.get()), nullptr);
186 }
187 else if (section->header().id == 0x5959)
188 {
189 foundYY = true;
190 EXPECT_NE(dynamic_cast<Generic*>(section.get()), nullptr);
191 }
192 }
193
194 EXPECT_TRUE(foundXX);
195 EXPECT_TRUE(foundYY);
Matt Spinler07eefc52019-09-26 11:18:26 -0500196
197 // Now flatten and check
198 auto newData = pel.data();
199
200 EXPECT_EQ(origData, newData);
Matt Spinler131870c2019-09-25 13:29:04 -0500201}
202
203// Test that an invalid section will still get a Generic object
204TEST_F(PELTest, InvalidGenericTest)
205{
Matt Spinler42828bd2019-10-11 10:39:30 -0500206 auto data = pelDataFactory(TestPELType::pelSimple);
Matt Spinler131870c2019-09-25 13:29:04 -0500207
208 // Not a valid section
209 std::vector<uint8_t> section1{0x01, 0x02, 0x03};
210
Matt Spinler42828bd2019-10-11 10:39:30 -0500211 data.insert(data.end(), section1.begin(), section1.end());
Matt Spinler131870c2019-09-25 13:29:04 -0500212
213 // Increment the section count
Matt Spinler42828bd2019-10-11 10:39:30 -0500214 data.at(27) += 1;
Matt Spinler131870c2019-09-25 13:29:04 -0500215
Matt Spinler42828bd2019-10-11 10:39:30 -0500216 PEL pel{data};
Matt Spinler131870c2019-09-25 13:29:04 -0500217 EXPECT_FALSE(pel.valid());
218
219 const auto& sections = pel.optionalSections();
220
221 bool foundGeneric = false;
222 for (const auto& section : sections)
223 {
224 if (dynamic_cast<Generic*>(section.get()) != nullptr)
225 {
226 foundGeneric = true;
227 EXPECT_EQ(section->valid(), false);
228 break;
229 }
230 }
231
232 EXPECT_TRUE(foundGeneric);
233}
Matt Spinlerafa857c2019-10-24 13:03:46 -0500234
235// Create a UserData section out of AdditionalData
236TEST_F(PELTest, MakeUDSectionTest)
237{
238 std::vector<std::string> ad{"KEY1=VALUE1", "KEY2=VALUE2", "KEY3=VALUE3",
239 "ESEL=TEST"};
240 AdditionalData additionalData{ad};
241
242 auto ud = util::makeADUserDataSection(additionalData);
243
244 EXPECT_TRUE(ud->valid());
245 EXPECT_EQ(ud->header().id, 0x5544);
246 EXPECT_EQ(ud->header().version, 0x01);
247 EXPECT_EQ(ud->header().subType, 0x01);
248 EXPECT_EQ(ud->header().componentID, 0x2000);
249
250 const auto& d = ud->data();
251
252 std::string jsonString{d.begin(), d.end()};
253 std::string expected =
254 R"({"KEY1":"VALUE1","KEY2":"VALUE2","KEY3":"VALUE3"})";
255 EXPECT_EQ(jsonString, expected);
256
257 // Ensure we can read this as JSON
258 auto newJSON = nlohmann::json::parse(jsonString);
259 EXPECT_EQ(newJSON["KEY1"], "VALUE1");
260 EXPECT_EQ(newJSON["KEY2"], "VALUE2");
261 EXPECT_EQ(newJSON["KEY3"], "VALUE3");
262}