xref: /openbmc/phosphor-logging/test/openpower-pels/src_callouts_test.cpp (revision 4efed0efdec2da163d1811236ed33243d2db20e9)
197f7abcfSMatt Spinler /**
297f7abcfSMatt Spinler  * Copyright © 2019 IBM Corporation
397f7abcfSMatt Spinler  *
497f7abcfSMatt Spinler  * Licensed under the Apache License, Version 2.0 (the "License");
597f7abcfSMatt Spinler  * you may not use this file except in compliance with the License.
697f7abcfSMatt Spinler  * You may obtain a copy of the License at
797f7abcfSMatt Spinler  *
897f7abcfSMatt Spinler  *     http://www.apache.org/licenses/LICENSE-2.0
997f7abcfSMatt Spinler  *
1097f7abcfSMatt Spinler  * Unless required by applicable law or agreed to in writing, software
1197f7abcfSMatt Spinler  * distributed under the License is distributed on an "AS IS" BASIS,
1297f7abcfSMatt Spinler  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1397f7abcfSMatt Spinler  * See the License for the specific language governing permissions and
1497f7abcfSMatt Spinler  * limitations under the License.
1597f7abcfSMatt Spinler  */
1632f13c91SMatt Spinler #include "extensions/openpower-pels/callouts.hpp"
1732f13c91SMatt Spinler #include "pel_utils.hpp"
1832f13c91SMatt Spinler 
19*4efed0efSMatt Spinler #include <format>
20*4efed0efSMatt Spinler 
2132f13c91SMatt Spinler #include <gtest/gtest.h>
2232f13c91SMatt Spinler 
2332f13c91SMatt Spinler using namespace openpower::pels;
2432f13c91SMatt Spinler using namespace openpower::pels::src;
2532f13c91SMatt Spinler 
TEST(CalloutsTest,UnflattenFlattenTest)2632f13c91SMatt Spinler TEST(CalloutsTest, UnflattenFlattenTest)
2732f13c91SMatt Spinler {
2832f13c91SMatt Spinler     std::vector<uint8_t> data{0xC0, 0x00, 0x00,
2932f13c91SMatt Spinler                               0x00}; // ID, flags, length in words
3032f13c91SMatt Spinler 
3132f13c91SMatt Spinler     // Add 2 callouts
3232f13c91SMatt Spinler     auto callout = srcDataFactory(TestSRCType::calloutStructureA);
3332f13c91SMatt Spinler     data.insert(data.end(), callout.begin(), callout.end());
3432f13c91SMatt Spinler 
3532f13c91SMatt Spinler     callout = srcDataFactory(TestSRCType::calloutStructureB);
3632f13c91SMatt Spinler     data.insert(data.end(), callout.begin(), callout.end());
3732f13c91SMatt Spinler 
3832f13c91SMatt Spinler     Stream stream{data};
3932f13c91SMatt Spinler 
4032f13c91SMatt Spinler     // Set the actual word length value at offset 2
4132f13c91SMatt Spinler     uint16_t wordLength = data.size() / 4;
4232f13c91SMatt Spinler     stream.offset(2);
4332f13c91SMatt Spinler     stream << wordLength;
4432f13c91SMatt Spinler     stream.offset(0);
4532f13c91SMatt Spinler 
4632f13c91SMatt Spinler     Callouts callouts{stream};
4732f13c91SMatt Spinler 
4832f13c91SMatt Spinler     EXPECT_EQ(callouts.flattenedSize(), data.size());
4932f13c91SMatt Spinler     EXPECT_EQ(callouts.callouts().size(), 2);
5032f13c91SMatt Spinler 
5132f13c91SMatt Spinler     // spot check that each callout has the right substructures
5232f13c91SMatt Spinler     EXPECT_TRUE(callouts.callouts().front()->fruIdentity());
5332f13c91SMatt Spinler     EXPECT_FALSE(callouts.callouts().front()->pceIdentity());
5432f13c91SMatt Spinler     EXPECT_FALSE(callouts.callouts().front()->mru());
5532f13c91SMatt Spinler 
5632f13c91SMatt Spinler     EXPECT_TRUE(callouts.callouts().back()->fruIdentity());
5732f13c91SMatt Spinler     EXPECT_TRUE(callouts.callouts().back()->pceIdentity());
5832f13c91SMatt Spinler     EXPECT_TRUE(callouts.callouts().back()->mru());
5932f13c91SMatt Spinler 
6032f13c91SMatt Spinler     // Flatten
6132f13c91SMatt Spinler     std::vector<uint8_t> newData;
6232f13c91SMatt Spinler     Stream newStream{newData};
6332f13c91SMatt Spinler 
6432f13c91SMatt Spinler     callouts.flatten(newStream);
6532f13c91SMatt Spinler     EXPECT_EQ(data, newData);
6632f13c91SMatt Spinler }
6732f13c91SMatt Spinler 
TEST(CalloutsTest,BadDataTest)6832f13c91SMatt Spinler TEST(CalloutsTest, BadDataTest)
6932f13c91SMatt Spinler {
7032f13c91SMatt Spinler     // Start out with a valid 2 callout object, then truncate it.
7132f13c91SMatt Spinler     std::vector<uint8_t> data{0xC0, 0x00, 0x00,
7232f13c91SMatt Spinler                               0x00}; // ID, flags, length in words
7332f13c91SMatt Spinler 
7432f13c91SMatt Spinler     // Add 2 callouts
7532f13c91SMatt Spinler     auto callout = srcDataFactory(TestSRCType::calloutStructureA);
7632f13c91SMatt Spinler     data.insert(data.end(), callout.begin(), callout.end());
7732f13c91SMatt Spinler 
7832f13c91SMatt Spinler     callout = srcDataFactory(TestSRCType::calloutStructureB);
7932f13c91SMatt Spinler     data.insert(data.end(), callout.begin(), callout.end());
8032f13c91SMatt Spinler 
8132f13c91SMatt Spinler     Stream stream{data};
8232f13c91SMatt Spinler 
8332f13c91SMatt Spinler     // Set the actual word length value at offset 2
8432f13c91SMatt Spinler     uint16_t wordLength = data.size() / 4;
8532f13c91SMatt Spinler     stream.offset(2);
8632f13c91SMatt Spinler     stream << wordLength;
8732f13c91SMatt Spinler     stream.offset(0);
8832f13c91SMatt Spinler 
8932f13c91SMatt Spinler     // Shorten the data by an arbitrary amount so unflattening goes awry.
9032f13c91SMatt Spinler     data.resize(data.size() - 37);
9132f13c91SMatt Spinler 
9232f13c91SMatt Spinler     EXPECT_THROW(Callouts callouts{stream}, std::out_of_range);
9332f13c91SMatt Spinler }
94e0366f31SMatt Spinler 
TEST(CalloutsTest,TestAddCallouts)95e0366f31SMatt Spinler TEST(CalloutsTest, TestAddCallouts)
96e0366f31SMatt Spinler {
97e0366f31SMatt Spinler     Callouts callouts;
98e0366f31SMatt Spinler 
99e0366f31SMatt Spinler     // Empty Callouts size
100e0366f31SMatt Spinler     size_t lastSize = 4;
101e0366f31SMatt Spinler 
102e0366f31SMatt Spinler     for (size_t i = 0; i < maxNumberOfCallouts; i++)
103e0366f31SMatt Spinler     {
104*4efed0efSMatt Spinler         auto loc = std::format("U1-P{}", i);
105e0366f31SMatt Spinler         auto callout = std::make_unique<Callout>(
106*4efed0efSMatt Spinler             CalloutPriority::high, loc, "1234567", "ABCD", "123456789ABC");
107e0366f31SMatt Spinler         auto calloutSize = callout->flattenedSize();
108e0366f31SMatt Spinler 
109e0366f31SMatt Spinler         callouts.addCallout(std::move(callout));
110e0366f31SMatt Spinler 
111e0366f31SMatt Spinler         EXPECT_EQ(callouts.flattenedSize(), lastSize + calloutSize);
112e0366f31SMatt Spinler 
113e0366f31SMatt Spinler         lastSize = callouts.flattenedSize();
114e0366f31SMatt Spinler 
115e0366f31SMatt Spinler         EXPECT_EQ(callouts.callouts().size(), i + 1);
116e0366f31SMatt Spinler     }
117e0366f31SMatt Spinler 
118e0366f31SMatt Spinler     // Try to add an 11th callout.  Shouldn't work
119e0366f31SMatt Spinler 
120e0366f31SMatt Spinler     auto callout = std::make_unique<Callout>(CalloutPriority::high, "U1-P1",
121e0366f31SMatt Spinler                                              "1234567", "ABCD", "123456789ABC");
122e0366f31SMatt Spinler     callouts.addCallout(std::move(callout));
123e0366f31SMatt Spinler 
124e0366f31SMatt Spinler     EXPECT_EQ(callouts.callouts().size(), maxNumberOfCallouts);
125e0366f31SMatt Spinler }
12653ef1552SMiguel Gomez 
TEST(CalloutsTest,TestSortCallouts)12753ef1552SMiguel Gomez TEST(CalloutsTest, TestSortCallouts)
12853ef1552SMiguel Gomez {
12953ef1552SMiguel Gomez     Callouts callouts;
13053ef1552SMiguel Gomez 
13153ef1552SMiguel Gomez     // Add  callouts with different priorities to test sorting in descending
13253ef1552SMiguel Gomez     // order
13353ef1552SMiguel Gomez 
13453ef1552SMiguel Gomez     auto c0 = std::make_unique<Callout>(CalloutPriority::high, "U1-P1",
13553ef1552SMiguel Gomez                                         "1234567", "ABC", "123456789ABC");
13653ef1552SMiguel Gomez 
13753ef1552SMiguel Gomez     callouts.addCallout(std::move(c0));
13853ef1552SMiguel Gomez 
13953ef1552SMiguel Gomez     auto c1 = std::make_unique<Callout>(CalloutPriority::medium, "U1-P2",
14053ef1552SMiguel Gomez                                         "1234567", "ABCD", "123456789ABC");
14153ef1552SMiguel Gomez 
14253ef1552SMiguel Gomez     callouts.addCallout(std::move(c1));
14353ef1552SMiguel Gomez 
14453ef1552SMiguel Gomez     auto c2 = std::make_unique<Callout>(CalloutPriority::low, "U1-P3",
14553ef1552SMiguel Gomez                                         "1234567", "ABCDE", "123456789ABC");
14653ef1552SMiguel Gomez 
14753ef1552SMiguel Gomez     callouts.addCallout(std::move(c2));
14853ef1552SMiguel Gomez 
14953ef1552SMiguel Gomez     auto c3 = std::make_unique<Callout>(CalloutPriority::high, "U1-P4",
15053ef1552SMiguel Gomez                                         "1234567", "ABCDE1", "123456789ABC");
15153ef1552SMiguel Gomez 
15253ef1552SMiguel Gomez     callouts.addCallout(std::move(c3));
15353ef1552SMiguel Gomez 
15453ef1552SMiguel Gomez     auto c4 = std::make_unique<Callout>(CalloutPriority::high, "U1-P5",
15553ef1552SMiguel Gomez                                         "1234567", "ABCDE2", "123456789ABC");
15653ef1552SMiguel Gomez 
15753ef1552SMiguel Gomez     callouts.addCallout(std::move(c4));
15853ef1552SMiguel Gomez 
15953ef1552SMiguel Gomez     auto c5 = std::make_unique<Callout>(CalloutPriority::low, "U1-P6",
16053ef1552SMiguel Gomez                                         "1234567", "ABCDE2", "123456789ABC");
16153ef1552SMiguel Gomez 
16253ef1552SMiguel Gomez     callouts.addCallout(std::move(c5));
16353ef1552SMiguel Gomez 
16453ef1552SMiguel Gomez     auto c6 = std::make_unique<Callout>(CalloutPriority::medium, "U1-P7",
16553ef1552SMiguel Gomez                                         "1234567", "ABCD2", "123456789ABC");
16653ef1552SMiguel Gomez 
16753ef1552SMiguel Gomez     callouts.addCallout(std::move(c6));
16853ef1552SMiguel Gomez 
16953ef1552SMiguel Gomez     auto c7 = std::make_unique<Callout>(CalloutPriority::mediumGroupA, "U1-P8",
17053ef1552SMiguel Gomez                                         "1234567", "ABCDE3", "123456789ABC");
17153ef1552SMiguel Gomez 
17253ef1552SMiguel Gomez     callouts.addCallout(std::move(c7));
17353ef1552SMiguel Gomez 
17453ef1552SMiguel Gomez     auto c8 = std::make_unique<Callout>(CalloutPriority::mediumGroupC, "U1-P9",
17553ef1552SMiguel Gomez                                         "1234567", "ABCDE4", "123456789ABC");
17653ef1552SMiguel Gomez 
17753ef1552SMiguel Gomez     callouts.addCallout(std::move(c8));
17853ef1552SMiguel Gomez 
17953ef1552SMiguel Gomez     auto c9 = std::make_unique<Callout>(CalloutPriority::low, "U1-P10",
18053ef1552SMiguel Gomez                                         "1234567", "ABCDE3", "123456789ABC");
18153ef1552SMiguel Gomez 
18253ef1552SMiguel Gomez     callouts.addCallout(std::move(c9));
18353ef1552SMiguel Gomez 
18453ef1552SMiguel Gomez     const auto& calloutObjects = callouts.callouts();
18553ef1552SMiguel Gomez     EXPECT_EQ(calloutObjects[0]->locationCode(), "U1-P1");
18653ef1552SMiguel Gomez     EXPECT_EQ(calloutObjects[0]->priority(), 'H');
18753ef1552SMiguel Gomez     EXPECT_EQ(calloutObjects[1]->locationCode(), "U1-P4");
18853ef1552SMiguel Gomez     EXPECT_EQ(calloutObjects[1]->priority(), 'H');
18953ef1552SMiguel Gomez     EXPECT_EQ(calloutObjects[2]->locationCode(), "U1-P5");
19053ef1552SMiguel Gomez     EXPECT_EQ(calloutObjects[2]->priority(), 'H');
19153ef1552SMiguel Gomez     EXPECT_EQ(calloutObjects[3]->locationCode(), "U1-P2");
19253ef1552SMiguel Gomez     EXPECT_EQ(calloutObjects[3]->priority(), 'M');
19353ef1552SMiguel Gomez     EXPECT_EQ(calloutObjects[4]->locationCode(), "U1-P7");
19453ef1552SMiguel Gomez     EXPECT_EQ(calloutObjects[4]->priority(), 'M');
19553ef1552SMiguel Gomez     EXPECT_EQ(calloutObjects[5]->locationCode(), "U1-P8");
19653ef1552SMiguel Gomez     EXPECT_EQ(calloutObjects[5]->priority(), 'A');
19753ef1552SMiguel Gomez     EXPECT_EQ(calloutObjects[6]->locationCode(), "U1-P9");
19853ef1552SMiguel Gomez     EXPECT_EQ(calloutObjects[6]->priority(), 'C');
19953ef1552SMiguel Gomez     EXPECT_EQ(calloutObjects[7]->locationCode(), "U1-P3");
20053ef1552SMiguel Gomez     EXPECT_EQ(calloutObjects[7]->priority(), 'L');
20153ef1552SMiguel Gomez     EXPECT_EQ(calloutObjects[8]->locationCode(), "U1-P6");
20253ef1552SMiguel Gomez     EXPECT_EQ(calloutObjects[8]->priority(), 'L');
20353ef1552SMiguel Gomez     EXPECT_EQ(calloutObjects[9]->locationCode(), "U1-P10");
20453ef1552SMiguel Gomez     EXPECT_EQ(calloutObjects[9]->priority(), 'L');
20553ef1552SMiguel Gomez }
206*4efed0efSMatt Spinler 
TEST(CalloutsTest,TestDupCallouts)207*4efed0efSMatt Spinler TEST(CalloutsTest, TestDupCallouts)
208*4efed0efSMatt Spinler {
209*4efed0efSMatt Spinler     {
210*4efed0efSMatt Spinler         // Duplicate callouts, keep the high priority one
211*4efed0efSMatt Spinler         Callouts callouts;
212*4efed0efSMatt Spinler         auto c0 = std::make_unique<Callout>(CalloutPriority::medium, "U1-P1",
213*4efed0efSMatt Spinler                                             "1234567", "ABC", "123456789ABC");
214*4efed0efSMatt Spinler         callouts.addCallout(std::move(c0));
215*4efed0efSMatt Spinler 
216*4efed0efSMatt Spinler         auto c1 = std::make_unique<Callout>(CalloutPriority::high, "U1-P1",
217*4efed0efSMatt Spinler                                             "1234567", "ABCD", "123456789ABC");
218*4efed0efSMatt Spinler         callouts.addCallout(std::move(c1));
219*4efed0efSMatt Spinler 
220*4efed0efSMatt Spinler         EXPECT_EQ(callouts.callouts().size(), 1);
221*4efed0efSMatt Spinler         const auto& calloutObjects = callouts.callouts();
222*4efed0efSMatt Spinler         EXPECT_EQ(calloutObjects[0]->priority(), 'H');
223*4efed0efSMatt Spinler     }
224*4efed0efSMatt Spinler 
225*4efed0efSMatt Spinler     {
226*4efed0efSMatt Spinler         // Different callouts, keep them both
227*4efed0efSMatt Spinler         Callouts callouts;
228*4efed0efSMatt Spinler         auto c0 = std::make_unique<Callout>(CalloutPriority::high, "U1-P1",
229*4efed0efSMatt Spinler                                             "1234567", "ABC", "123456789ABC");
230*4efed0efSMatt Spinler         callouts.addCallout(std::move(c0));
231*4efed0efSMatt Spinler 
232*4efed0efSMatt Spinler         auto c1 = std::make_unique<Callout>(CalloutPriority::medium, "U1-P2",
233*4efed0efSMatt Spinler                                             "1234567", "ABCD", "123456789ABC");
234*4efed0efSMatt Spinler         callouts.addCallout(std::move(c1));
235*4efed0efSMatt Spinler 
236*4efed0efSMatt Spinler         EXPECT_EQ(callouts.callouts().size(), 2);
237*4efed0efSMatt Spinler     }
238*4efed0efSMatt Spinler 
239*4efed0efSMatt Spinler     {
240*4efed0efSMatt Spinler         // Two duplicates and two unique.  Needs sorting.
241*4efed0efSMatt Spinler         Callouts callouts;
242*4efed0efSMatt Spinler         auto c0 = std::make_unique<Callout>(CalloutPriority::low, "U1-P9",
243*4efed0efSMatt Spinler                                             "1234567", "ABCD", "123456789ABC");
244*4efed0efSMatt Spinler         callouts.addCallout(std::move(c0));
245*4efed0efSMatt Spinler 
246*4efed0efSMatt Spinler         auto c1 = std::make_unique<Callout>(CalloutPriority::low, "U1-P1",
247*4efed0efSMatt Spinler                                             "1234567", "ABC", "123456789ABC");
248*4efed0efSMatt Spinler         callouts.addCallout(std::move(c1));
249*4efed0efSMatt Spinler 
250*4efed0efSMatt Spinler         auto c2 = std::make_unique<Callout>(CalloutPriority::high, "U1-P1",
251*4efed0efSMatt Spinler                                             "1234567", "ABC", "123456789ABC");
252*4efed0efSMatt Spinler         callouts.addCallout(std::move(c2));
253*4efed0efSMatt Spinler 
254*4efed0efSMatt Spinler         auto c3 = std::make_unique<Callout>(CalloutPriority::medium, "U1-P5",
255*4efed0efSMatt Spinler                                             "1234567", "ABCD", "123456789ABC");
256*4efed0efSMatt Spinler         callouts.addCallout(std::move(c3));
257*4efed0efSMatt Spinler 
258*4efed0efSMatt Spinler         const auto& calloutObjects = callouts.callouts();
259*4efed0efSMatt Spinler         EXPECT_EQ(callouts.callouts().size(), 3);
260*4efed0efSMatt Spinler         EXPECT_EQ(calloutObjects[0]->priority(), 'H');
261*4efed0efSMatt Spinler         EXPECT_EQ(calloutObjects[0]->locationCode(), "U1-P1");
262*4efed0efSMatt Spinler         EXPECT_EQ(calloutObjects[1]->priority(), 'M');
263*4efed0efSMatt Spinler         EXPECT_EQ(calloutObjects[1]->locationCode(), "U1-P5");
264*4efed0efSMatt Spinler         EXPECT_EQ(calloutObjects[2]->priority(), 'L');
265*4efed0efSMatt Spinler         EXPECT_EQ(calloutObjects[2]->locationCode(), "U1-P9");
266*4efed0efSMatt Spinler     }
267*4efed0efSMatt Spinler }
268