blob: 696284243a3d15b8b6d1ead7b9d6e2aaa10fc0b0 [file] [log] [blame]
Alexander Hansen40fb5492025-10-28 17:56:12 +01001// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright 2019 IBM Corporation
3
Matt Spinler32f13c92019-10-09 12:48:25 -05004#include "extensions/openpower-pels/callouts.hpp"
5#include "pel_utils.hpp"
6
Matt Spinler4efed0e2024-02-26 11:16:07 -06007#include <format>
8
Matt Spinler32f13c92019-10-09 12:48:25 -05009#include <gtest/gtest.h>
10
11using namespace openpower::pels;
12using namespace openpower::pels::src;
13
14TEST(CalloutsTest, UnflattenFlattenTest)
15{
16 std::vector<uint8_t> data{0xC0, 0x00, 0x00,
17 0x00}; // ID, flags, length in words
18
19 // Add 2 callouts
20 auto callout = srcDataFactory(TestSRCType::calloutStructureA);
21 data.insert(data.end(), callout.begin(), callout.end());
22
23 callout = srcDataFactory(TestSRCType::calloutStructureB);
24 data.insert(data.end(), callout.begin(), callout.end());
25
26 Stream stream{data};
27
28 // Set the actual word length value at offset 2
29 uint16_t wordLength = data.size() / 4;
30 stream.offset(2);
31 stream << wordLength;
32 stream.offset(0);
33
34 Callouts callouts{stream};
35
36 EXPECT_EQ(callouts.flattenedSize(), data.size());
37 EXPECT_EQ(callouts.callouts().size(), 2);
38
39 // spot check that each callout has the right substructures
40 EXPECT_TRUE(callouts.callouts().front()->fruIdentity());
41 EXPECT_FALSE(callouts.callouts().front()->pceIdentity());
42 EXPECT_FALSE(callouts.callouts().front()->mru());
43
44 EXPECT_TRUE(callouts.callouts().back()->fruIdentity());
45 EXPECT_TRUE(callouts.callouts().back()->pceIdentity());
46 EXPECT_TRUE(callouts.callouts().back()->mru());
47
48 // Flatten
49 std::vector<uint8_t> newData;
50 Stream newStream{newData};
51
52 callouts.flatten(newStream);
53 EXPECT_EQ(data, newData);
54}
55
56TEST(CalloutsTest, BadDataTest)
57{
58 // Start out with a valid 2 callout object, then truncate it.
59 std::vector<uint8_t> data{0xC0, 0x00, 0x00,
60 0x00}; // ID, flags, length in words
61
62 // Add 2 callouts
63 auto callout = srcDataFactory(TestSRCType::calloutStructureA);
64 data.insert(data.end(), callout.begin(), callout.end());
65
66 callout = srcDataFactory(TestSRCType::calloutStructureB);
67 data.insert(data.end(), callout.begin(), callout.end());
68
69 Stream stream{data};
70
71 // Set the actual word length value at offset 2
72 uint16_t wordLength = data.size() / 4;
73 stream.offset(2);
74 stream << wordLength;
75 stream.offset(0);
76
77 // Shorten the data by an arbitrary amount so unflattening goes awry.
78 data.resize(data.size() - 37);
79
80 EXPECT_THROW(Callouts callouts{stream}, std::out_of_range);
81}
Matt Spinlere0366f32020-03-13 13:02:19 -050082
83TEST(CalloutsTest, TestAddCallouts)
84{
85 Callouts callouts;
86
87 // Empty Callouts size
88 size_t lastSize = 4;
89
90 for (size_t i = 0; i < maxNumberOfCallouts; i++)
91 {
Matt Spinler4efed0e2024-02-26 11:16:07 -060092 auto loc = std::format("U1-P{}", i);
Matt Spinlere0366f32020-03-13 13:02:19 -050093 auto callout = std::make_unique<Callout>(
Matt Spinler4efed0e2024-02-26 11:16:07 -060094 CalloutPriority::high, loc, "1234567", "ABCD", "123456789ABC");
Matt Spinlere0366f32020-03-13 13:02:19 -050095 auto calloutSize = callout->flattenedSize();
96
97 callouts.addCallout(std::move(callout));
98
99 EXPECT_EQ(callouts.flattenedSize(), lastSize + calloutSize);
100
101 lastSize = callouts.flattenedSize();
102
103 EXPECT_EQ(callouts.callouts().size(), i + 1);
104 }
105
106 // Try to add an 11th callout. Shouldn't work
107
108 auto callout = std::make_unique<Callout>(CalloutPriority::high, "U1-P1",
109 "1234567", "ABCD", "123456789ABC");
110 callouts.addCallout(std::move(callout));
111
112 EXPECT_EQ(callouts.callouts().size(), maxNumberOfCallouts);
113}
Miguel Gomez53ef1552020-10-14 21:16:32 +0000114
115TEST(CalloutsTest, TestSortCallouts)
116{
117 Callouts callouts;
118
119 // Add callouts with different priorities to test sorting in descending
120 // order
121
122 auto c0 = std::make_unique<Callout>(CalloutPriority::high, "U1-P1",
123 "1234567", "ABC", "123456789ABC");
124
125 callouts.addCallout(std::move(c0));
126
127 auto c1 = std::make_unique<Callout>(CalloutPriority::medium, "U1-P2",
128 "1234567", "ABCD", "123456789ABC");
129
130 callouts.addCallout(std::move(c1));
131
132 auto c2 = std::make_unique<Callout>(CalloutPriority::low, "U1-P3",
133 "1234567", "ABCDE", "123456789ABC");
134
135 callouts.addCallout(std::move(c2));
136
137 auto c3 = std::make_unique<Callout>(CalloutPriority::high, "U1-P4",
138 "1234567", "ABCDE1", "123456789ABC");
139
140 callouts.addCallout(std::move(c3));
141
142 auto c4 = std::make_unique<Callout>(CalloutPriority::high, "U1-P5",
143 "1234567", "ABCDE2", "123456789ABC");
144
145 callouts.addCallout(std::move(c4));
146
147 auto c5 = std::make_unique<Callout>(CalloutPriority::low, "U1-P6",
148 "1234567", "ABCDE2", "123456789ABC");
149
150 callouts.addCallout(std::move(c5));
151
152 auto c6 = std::make_unique<Callout>(CalloutPriority::medium, "U1-P7",
153 "1234567", "ABCD2", "123456789ABC");
154
155 callouts.addCallout(std::move(c6));
156
157 auto c7 = std::make_unique<Callout>(CalloutPriority::mediumGroupA, "U1-P8",
158 "1234567", "ABCDE3", "123456789ABC");
159
160 callouts.addCallout(std::move(c7));
161
162 auto c8 = std::make_unique<Callout>(CalloutPriority::mediumGroupC, "U1-P9",
163 "1234567", "ABCDE4", "123456789ABC");
164
165 callouts.addCallout(std::move(c8));
166
167 auto c9 = std::make_unique<Callout>(CalloutPriority::low, "U1-P10",
168 "1234567", "ABCDE3", "123456789ABC");
169
170 callouts.addCallout(std::move(c9));
171
172 const auto& calloutObjects = callouts.callouts();
173 EXPECT_EQ(calloutObjects[0]->locationCode(), "U1-P1");
174 EXPECT_EQ(calloutObjects[0]->priority(), 'H');
175 EXPECT_EQ(calloutObjects[1]->locationCode(), "U1-P4");
176 EXPECT_EQ(calloutObjects[1]->priority(), 'H');
177 EXPECT_EQ(calloutObjects[2]->locationCode(), "U1-P5");
178 EXPECT_EQ(calloutObjects[2]->priority(), 'H');
179 EXPECT_EQ(calloutObjects[3]->locationCode(), "U1-P2");
180 EXPECT_EQ(calloutObjects[3]->priority(), 'M');
181 EXPECT_EQ(calloutObjects[4]->locationCode(), "U1-P7");
182 EXPECT_EQ(calloutObjects[4]->priority(), 'M');
183 EXPECT_EQ(calloutObjects[5]->locationCode(), "U1-P8");
184 EXPECT_EQ(calloutObjects[5]->priority(), 'A');
185 EXPECT_EQ(calloutObjects[6]->locationCode(), "U1-P9");
186 EXPECT_EQ(calloutObjects[6]->priority(), 'C');
187 EXPECT_EQ(calloutObjects[7]->locationCode(), "U1-P3");
188 EXPECT_EQ(calloutObjects[7]->priority(), 'L');
189 EXPECT_EQ(calloutObjects[8]->locationCode(), "U1-P6");
190 EXPECT_EQ(calloutObjects[8]->priority(), 'L');
191 EXPECT_EQ(calloutObjects[9]->locationCode(), "U1-P10");
192 EXPECT_EQ(calloutObjects[9]->priority(), 'L');
193}
Matt Spinler4efed0e2024-02-26 11:16:07 -0600194
195TEST(CalloutsTest, TestDupCallouts)
196{
197 {
198 // Duplicate callouts, keep the high priority one
199 Callouts callouts;
200 auto c0 = std::make_unique<Callout>(CalloutPriority::medium, "U1-P1",
201 "1234567", "ABC", "123456789ABC");
202 callouts.addCallout(std::move(c0));
203
204 auto c1 = std::make_unique<Callout>(CalloutPriority::high, "U1-P1",
205 "1234567", "ABCD", "123456789ABC");
206 callouts.addCallout(std::move(c1));
207
208 EXPECT_EQ(callouts.callouts().size(), 1);
209 const auto& calloutObjects = callouts.callouts();
210 EXPECT_EQ(calloutObjects[0]->priority(), 'H');
211 }
212
213 {
214 // Different callouts, keep them both
215 Callouts callouts;
216 auto c0 = std::make_unique<Callout>(CalloutPriority::high, "U1-P1",
217 "1234567", "ABC", "123456789ABC");
218 callouts.addCallout(std::move(c0));
219
220 auto c1 = std::make_unique<Callout>(CalloutPriority::medium, "U1-P2",
221 "1234567", "ABCD", "123456789ABC");
222 callouts.addCallout(std::move(c1));
223
224 EXPECT_EQ(callouts.callouts().size(), 2);
225 }
226
227 {
228 // Two duplicates and two unique. Needs sorting.
229 Callouts callouts;
230 auto c0 = std::make_unique<Callout>(CalloutPriority::low, "U1-P9",
231 "1234567", "ABCD", "123456789ABC");
232 callouts.addCallout(std::move(c0));
233
234 auto c1 = std::make_unique<Callout>(CalloutPriority::low, "U1-P1",
235 "1234567", "ABC", "123456789ABC");
236 callouts.addCallout(std::move(c1));
237
238 auto c2 = std::make_unique<Callout>(CalloutPriority::high, "U1-P1",
239 "1234567", "ABC", "123456789ABC");
240 callouts.addCallout(std::move(c2));
241
242 auto c3 = std::make_unique<Callout>(CalloutPriority::medium, "U1-P5",
243 "1234567", "ABCD", "123456789ABC");
244 callouts.addCallout(std::move(c3));
245
246 const auto& calloutObjects = callouts.callouts();
247 EXPECT_EQ(callouts.callouts().size(), 3);
248 EXPECT_EQ(calloutObjects[0]->priority(), 'H');
249 EXPECT_EQ(calloutObjects[0]->locationCode(), "U1-P1");
250 EXPECT_EQ(calloutObjects[1]->priority(), 'M');
251 EXPECT_EQ(calloutObjects[1]->locationCode(), "U1-P5");
252 EXPECT_EQ(calloutObjects[2]->priority(), 'L');
253 EXPECT_EQ(calloutObjects[2]->locationCode(), "U1-P9");
254 }
255}