1*05f0c6dcSMatt Spinler /**
2*05f0c6dcSMatt Spinler  * Copyright © 2020 IBM Corporation
3*05f0c6dcSMatt Spinler  *
4*05f0c6dcSMatt Spinler  * Licensed under the Apache License, Version 2.0 (the "License");
5*05f0c6dcSMatt Spinler  * you may not use this file except in compliance with the License.
6*05f0c6dcSMatt Spinler  * You may obtain a copy of the License at
7*05f0c6dcSMatt Spinler  *
8*05f0c6dcSMatt Spinler  *     http://www.apache.org/licenses/LICENSE-2.0
9*05f0c6dcSMatt Spinler  *
10*05f0c6dcSMatt Spinler  * Unless required by applicable law or agreed to in writing, software
11*05f0c6dcSMatt Spinler  * distributed under the License is distributed on an "AS IS" BASIS,
12*05f0c6dcSMatt Spinler  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*05f0c6dcSMatt Spinler  * See the License for the specific language governing permissions and
14*05f0c6dcSMatt Spinler  * limitations under the License.
15*05f0c6dcSMatt Spinler  */
16*05f0c6dcSMatt Spinler #include "extensions/openpower-pels/service_indicators.hpp"
17*05f0c6dcSMatt Spinler #include "mocks.hpp"
18*05f0c6dcSMatt Spinler #include "pel_utils.hpp"
19*05f0c6dcSMatt Spinler 
20*05f0c6dcSMatt Spinler #include <gtest/gtest.h>
21*05f0c6dcSMatt Spinler 
22*05f0c6dcSMatt Spinler using namespace openpower::pels;
23*05f0c6dcSMatt Spinler using CalloutVector = std::vector<std::unique_ptr<src::Callout>>;
24*05f0c6dcSMatt Spinler using ::testing::_;
25*05f0c6dcSMatt Spinler using ::testing::Return;
26*05f0c6dcSMatt Spinler using ::testing::Throw;
27*05f0c6dcSMatt Spinler 
28*05f0c6dcSMatt Spinler // Test the ignore() function works
29*05f0c6dcSMatt Spinler TEST(ServiceIndicatorsTest, IgnoreTest)
30*05f0c6dcSMatt Spinler {
31*05f0c6dcSMatt Spinler     MockDataInterface dataIface;
32*05f0c6dcSMatt Spinler     service_indicators::LightPath lightPath{dataIface};
33*05f0c6dcSMatt Spinler 
34*05f0c6dcSMatt Spinler     // PEL must have serviceable action flag set and be created
35*05f0c6dcSMatt Spinler     // by the BMC or Hostboot.
36*05f0c6dcSMatt Spinler     std::vector<std::tuple<char, uint16_t, bool>> testParams{
37*05f0c6dcSMatt Spinler         {'O', 0xA400, false}, // BMC serviceable, don't ignore
38*05f0c6dcSMatt Spinler         {'B', 0xA400, false}, // Hostboot serviceable, don't ignore
39*05f0c6dcSMatt Spinler         {'H', 0xA400, true},  // PHYP serviceable, ignore
40*05f0c6dcSMatt Spinler         {'O', 0x2400, true},  // BMC not serviceable, ignore
41*05f0c6dcSMatt Spinler         {'B', 0x2400, true},  // Hostboot not serviceable, ignore
42*05f0c6dcSMatt Spinler         {'H', 0x2400, true},  // PHYP not serviceable, ignore
43*05f0c6dcSMatt Spinler     };
44*05f0c6dcSMatt Spinler 
45*05f0c6dcSMatt Spinler     for (const auto& test : testParams)
46*05f0c6dcSMatt Spinler     {
47*05f0c6dcSMatt Spinler         auto data = pelFactory(1, std::get<char>(test), 0x20,
48*05f0c6dcSMatt Spinler                                std::get<uint16_t>(test), 500);
49*05f0c6dcSMatt Spinler         PEL pel{data};
50*05f0c6dcSMatt Spinler 
51*05f0c6dcSMatt Spinler         EXPECT_EQ(lightPath.ignore(pel), std::get<bool>(test));
52*05f0c6dcSMatt Spinler     }
53*05f0c6dcSMatt Spinler }
54*05f0c6dcSMatt Spinler 
55*05f0c6dcSMatt Spinler // Test that only high, medium, and medium group A hardware
56*05f0c6dcSMatt Spinler // callouts have their location codes extracted.
57*05f0c6dcSMatt Spinler TEST(ServiceIndicatorsTest, OneCalloutPriorityTest)
58*05f0c6dcSMatt Spinler {
59*05f0c6dcSMatt Spinler     MockDataInterface dataIface;
60*05f0c6dcSMatt Spinler     service_indicators::LightPath lightPath{dataIface};
61*05f0c6dcSMatt Spinler 
62*05f0c6dcSMatt Spinler     // The priorities to test, with the expected getLocationCodes results.
63*05f0c6dcSMatt Spinler     std::vector<std::tuple<CalloutPriority, std::vector<std::string>>>
64*05f0c6dcSMatt Spinler         testCallouts{{CalloutPriority::high, {"U27-P1"}},
65*05f0c6dcSMatt Spinler                      {CalloutPriority::medium, {"U27-P1"}},
66*05f0c6dcSMatt Spinler                      {CalloutPriority::mediumGroupA, {"U27-P1"}},
67*05f0c6dcSMatt Spinler                      {CalloutPriority::mediumGroupB, {}},
68*05f0c6dcSMatt Spinler                      {CalloutPriority::mediumGroupC, {}},
69*05f0c6dcSMatt Spinler                      {CalloutPriority::low, {}}};
70*05f0c6dcSMatt Spinler 
71*05f0c6dcSMatt Spinler     for (const auto& test : testCallouts)
72*05f0c6dcSMatt Spinler     {
73*05f0c6dcSMatt Spinler         auto callout = std::make_unique<src::Callout>(
74*05f0c6dcSMatt Spinler             std::get<CalloutPriority>(test), "U27-P1", "1234567", "aaaa",
75*05f0c6dcSMatt Spinler             "123456789ABC");
76*05f0c6dcSMatt Spinler 
77*05f0c6dcSMatt Spinler         CalloutVector callouts;
78*05f0c6dcSMatt Spinler         callouts.push_back(std::move(callout));
79*05f0c6dcSMatt Spinler 
80*05f0c6dcSMatt Spinler         EXPECT_EQ(lightPath.getLocationCodes(callouts),
81*05f0c6dcSMatt Spinler                   std::get<std::vector<std::string>>(test));
82*05f0c6dcSMatt Spinler     }
83*05f0c6dcSMatt Spinler }
84*05f0c6dcSMatt Spinler 
85*05f0c6dcSMatt Spinler // Test that only normal hardware callouts and symbolic FRU
86*05f0c6dcSMatt Spinler // callouts with trusted location codes have their location
87*05f0c6dcSMatt Spinler // codes extracted.
88*05f0c6dcSMatt Spinler TEST(ServiceIndicatorsTest, OneCalloutTypeTest)
89*05f0c6dcSMatt Spinler {
90*05f0c6dcSMatt Spinler     MockDataInterface dataIface;
91*05f0c6dcSMatt Spinler     service_indicators::LightPath lightPath{dataIface};
92*05f0c6dcSMatt Spinler 
93*05f0c6dcSMatt Spinler     // Regular hardware callout
94*05f0c6dcSMatt Spinler     {
95*05f0c6dcSMatt Spinler         CalloutVector callouts;
96*05f0c6dcSMatt Spinler         callouts.push_back(
97*05f0c6dcSMatt Spinler             std::make_unique<src::Callout>(CalloutPriority::high, "U27-P1",
98*05f0c6dcSMatt Spinler                                            "1234567", "aaaa", "123456789ABC"));
99*05f0c6dcSMatt Spinler 
100*05f0c6dcSMatt Spinler         EXPECT_EQ(lightPath.getLocationCodes(callouts),
101*05f0c6dcSMatt Spinler                   std::vector<std::string>{"U27-P1"});
102*05f0c6dcSMatt Spinler     }
103*05f0c6dcSMatt Spinler 
104*05f0c6dcSMatt Spinler     // Symbolic FRU with trusted loc code callout
105*05f0c6dcSMatt Spinler     {
106*05f0c6dcSMatt Spinler         CalloutVector callouts;
107*05f0c6dcSMatt Spinler         callouts.push_back(std::make_unique<src::Callout>(
108*05f0c6dcSMatt Spinler             CalloutPriority::high, "service_docs", "U27-P1", true));
109*05f0c6dcSMatt Spinler 
110*05f0c6dcSMatt Spinler         EXPECT_EQ(lightPath.getLocationCodes(callouts),
111*05f0c6dcSMatt Spinler                   std::vector<std::string>{"U27-P1"});
112*05f0c6dcSMatt Spinler     }
113*05f0c6dcSMatt Spinler 
114*05f0c6dcSMatt Spinler     // Symbolic FRU without trusted loc code callout
115*05f0c6dcSMatt Spinler     {
116*05f0c6dcSMatt Spinler         CalloutVector callouts;
117*05f0c6dcSMatt Spinler         callouts.push_back(std::make_unique<src::Callout>(
118*05f0c6dcSMatt Spinler             CalloutPriority::high, "service_docs", "U27-P1", false));
119*05f0c6dcSMatt Spinler 
120*05f0c6dcSMatt Spinler         EXPECT_EQ(lightPath.getLocationCodes(callouts),
121*05f0c6dcSMatt Spinler                   std::vector<std::string>{});
122*05f0c6dcSMatt Spinler     }
123*05f0c6dcSMatt Spinler 
124*05f0c6dcSMatt Spinler     // Procedure callout
125*05f0c6dcSMatt Spinler     {
126*05f0c6dcSMatt Spinler         CalloutVector callouts;
127*05f0c6dcSMatt Spinler         callouts.push_back(
128*05f0c6dcSMatt Spinler             std::make_unique<src::Callout>(CalloutPriority::high, "bmc_code"));
129*05f0c6dcSMatt Spinler 
130*05f0c6dcSMatt Spinler         EXPECT_EQ(lightPath.getLocationCodes(callouts),
131*05f0c6dcSMatt Spinler                   std::vector<std::string>{});
132*05f0c6dcSMatt Spinler     }
133*05f0c6dcSMatt Spinler }
134*05f0c6dcSMatt Spinler 
135*05f0c6dcSMatt Spinler // Test that only the callouts in the first group have their location
136*05f0c6dcSMatt Spinler // codes extracted, where a group is one or more callouts listed
137*05f0c6dcSMatt Spinler // together with priorities of high, medium, or medium group A
138*05f0c6dcSMatt Spinler // (and medium is only ever contains 1 item).
139*05f0c6dcSMatt Spinler TEST(ServiceIndicatorsTest, CalloutGroupingTest)
140*05f0c6dcSMatt Spinler {
141*05f0c6dcSMatt Spinler     MockDataInterface dataIface;
142*05f0c6dcSMatt Spinler     service_indicators::LightPath lightPath{dataIface};
143*05f0c6dcSMatt Spinler 
144*05f0c6dcSMatt Spinler     // high/high/medium/high just grabs the first 2
145*05f0c6dcSMatt Spinler     {
146*05f0c6dcSMatt Spinler         CalloutVector callouts;
147*05f0c6dcSMatt Spinler         callouts.push_back(
148*05f0c6dcSMatt Spinler             std::make_unique<src::Callout>(CalloutPriority::high, "U27-P1",
149*05f0c6dcSMatt Spinler                                            "1234567", "aaaa", "123456789ABC"));
150*05f0c6dcSMatt Spinler         callouts.push_back(
151*05f0c6dcSMatt Spinler             std::make_unique<src::Callout>(CalloutPriority::high, "U27-P2",
152*05f0c6dcSMatt Spinler                                            "1234567", "aaaa", "123456789ABC"));
153*05f0c6dcSMatt Spinler         callouts.push_back(
154*05f0c6dcSMatt Spinler             std::make_unique<src::Callout>(CalloutPriority::medium, "U27-P3",
155*05f0c6dcSMatt Spinler                                            "1234567", "aaaa", "123456789ABC"));
156*05f0c6dcSMatt Spinler         // This high priority callout after a medium isn't actually valid, since
157*05f0c6dcSMatt Spinler         // callouts are sorted, but test it anyway.
158*05f0c6dcSMatt Spinler         callouts.push_back(
159*05f0c6dcSMatt Spinler             std::make_unique<src::Callout>(CalloutPriority::high, "U27-P4",
160*05f0c6dcSMatt Spinler                                            "1234567", "aaaa", "123456789ABC"));
161*05f0c6dcSMatt Spinler 
162*05f0c6dcSMatt Spinler         EXPECT_EQ(lightPath.getLocationCodes(callouts),
163*05f0c6dcSMatt Spinler                   (std::vector<std::string>{"U27-P1", "U27-P2"}));
164*05f0c6dcSMatt Spinler     }
165*05f0c6dcSMatt Spinler 
166*05f0c6dcSMatt Spinler     // medium/medium just grabs the first medium
167*05f0c6dcSMatt Spinler     {
168*05f0c6dcSMatt Spinler         CalloutVector callouts;
169*05f0c6dcSMatt Spinler         callouts.push_back(
170*05f0c6dcSMatt Spinler             std::make_unique<src::Callout>(CalloutPriority::medium, "U27-P1",
171*05f0c6dcSMatt Spinler                                            "1234567", "aaaa", "123456789ABC"));
172*05f0c6dcSMatt Spinler         callouts.push_back(
173*05f0c6dcSMatt Spinler             std::make_unique<src::Callout>(CalloutPriority::medium, "U27-P2",
174*05f0c6dcSMatt Spinler                                            "1234567", "aaaa", "123456789ABC"));
175*05f0c6dcSMatt Spinler 
176*05f0c6dcSMatt Spinler         EXPECT_EQ(lightPath.getLocationCodes(callouts),
177*05f0c6dcSMatt Spinler                   std::vector<std::string>{"U27-P1"});
178*05f0c6dcSMatt Spinler     }
179*05f0c6dcSMatt Spinler 
180*05f0c6dcSMatt Spinler     // mediumA/mediumA/medium just grabs the first 2
181*05f0c6dcSMatt Spinler     {
182*05f0c6dcSMatt Spinler         CalloutVector callouts;
183*05f0c6dcSMatt Spinler         callouts.push_back(std::make_unique<src::Callout>(
184*05f0c6dcSMatt Spinler             CalloutPriority::mediumGroupA, "U27-P1", "1234567", "aaaa",
185*05f0c6dcSMatt Spinler             "123456789ABC"));
186*05f0c6dcSMatt Spinler 
187*05f0c6dcSMatt Spinler         callouts.push_back(std::make_unique<src::Callout>(
188*05f0c6dcSMatt Spinler             CalloutPriority::mediumGroupA, "U27-P2", "1234567", "aaaa",
189*05f0c6dcSMatt Spinler             "123456789ABC"));
190*05f0c6dcSMatt Spinler 
191*05f0c6dcSMatt Spinler         callouts.push_back(
192*05f0c6dcSMatt Spinler             std::make_unique<src::Callout>(CalloutPriority::medium, "U27-P3",
193*05f0c6dcSMatt Spinler                                            "1234567", "aaaa", "123456789ABC"));
194*05f0c6dcSMatt Spinler 
195*05f0c6dcSMatt Spinler         EXPECT_EQ(lightPath.getLocationCodes(callouts),
196*05f0c6dcSMatt Spinler                   (std::vector<std::string>{"U27-P1", "U27-P2"}));
197*05f0c6dcSMatt Spinler     }
198*05f0c6dcSMatt Spinler }
199*05f0c6dcSMatt Spinler 
200*05f0c6dcSMatt Spinler // Test that if any callouts in group are not HW/trusted symbolic
201*05f0c6dcSMatt Spinler // FRU callouts then no location codes will be extracted
202*05f0c6dcSMatt Spinler TEST(ServiceIndicatorsTest, CalloutMixedTypesTest)
203*05f0c6dcSMatt Spinler {
204*05f0c6dcSMatt Spinler     MockDataInterface dataIface;
205*05f0c6dcSMatt Spinler     service_indicators::LightPath lightPath{dataIface};
206*05f0c6dcSMatt Spinler 
207*05f0c6dcSMatt Spinler     // Mixing FRU with trusted symbolic FRU is OK
208*05f0c6dcSMatt Spinler     {
209*05f0c6dcSMatt Spinler         CalloutVector callouts;
210*05f0c6dcSMatt Spinler         callouts.push_back(
211*05f0c6dcSMatt Spinler             std::make_unique<src::Callout>(CalloutPriority::high, "U27-P1",
212*05f0c6dcSMatt Spinler                                            "1234567", "aaaa", "123456789ABC"));
213*05f0c6dcSMatt Spinler         callouts.push_back(std::make_unique<src::Callout>(
214*05f0c6dcSMatt Spinler             CalloutPriority::high, "service_docs", "U27-P2", true));
215*05f0c6dcSMatt Spinler 
216*05f0c6dcSMatt Spinler         EXPECT_EQ(lightPath.getLocationCodes(callouts),
217*05f0c6dcSMatt Spinler                   (std::vector<std::string>{"U27-P1", "U27-P2"}));
218*05f0c6dcSMatt Spinler     }
219*05f0c6dcSMatt Spinler 
220*05f0c6dcSMatt Spinler     // Normal FRU callout with a non-trusted symbolic FRU callout not OK
221*05f0c6dcSMatt Spinler     {
222*05f0c6dcSMatt Spinler         CalloutVector callouts;
223*05f0c6dcSMatt Spinler         callouts.push_back(
224*05f0c6dcSMatt Spinler             std::make_unique<src::Callout>(CalloutPriority::high, "U27-P1",
225*05f0c6dcSMatt Spinler                                            "1234567", "aaaa", "123456789ABC"));
226*05f0c6dcSMatt Spinler         callouts.push_back(std::make_unique<src::Callout>(
227*05f0c6dcSMatt Spinler             CalloutPriority::high, "service_docs", "U27-P2", false));
228*05f0c6dcSMatt Spinler 
229*05f0c6dcSMatt Spinler         EXPECT_EQ(lightPath.getLocationCodes(callouts),
230*05f0c6dcSMatt Spinler                   (std::vector<std::string>{}));
231*05f0c6dcSMatt Spinler     }
232*05f0c6dcSMatt Spinler 
233*05f0c6dcSMatt Spinler     // Normal FRU callout with a procedure callout not OK
234*05f0c6dcSMatt Spinler     {
235*05f0c6dcSMatt Spinler         CalloutVector callouts;
236*05f0c6dcSMatt Spinler         callouts.push_back(
237*05f0c6dcSMatt Spinler             std::make_unique<src::Callout>(CalloutPriority::high, "U27-P1",
238*05f0c6dcSMatt Spinler                                            "1234567", "aaaa", "123456789ABC"));
239*05f0c6dcSMatt Spinler         callouts.push_back(
240*05f0c6dcSMatt Spinler             std::make_unique<src::Callout>(CalloutPriority::high, "bmc_code"));
241*05f0c6dcSMatt Spinler 
242*05f0c6dcSMatt Spinler         EXPECT_EQ(lightPath.getLocationCodes(callouts),
243*05f0c6dcSMatt Spinler                   (std::vector<std::string>{}));
244*05f0c6dcSMatt Spinler     }
245*05f0c6dcSMatt Spinler 
246*05f0c6dcSMatt Spinler     // Trusted symbolic FRU callout with a non-trusted symbolic
247*05f0c6dcSMatt Spinler     // FRU callout not OK
248*05f0c6dcSMatt Spinler     {
249*05f0c6dcSMatt Spinler         CalloutVector callouts;
250*05f0c6dcSMatt Spinler         callouts.push_back(std::make_unique<src::Callout>(
251*05f0c6dcSMatt Spinler             CalloutPriority::high, "service_docs", "U27-P2", true));
252*05f0c6dcSMatt Spinler 
253*05f0c6dcSMatt Spinler         callouts.push_back(std::make_unique<src::Callout>(
254*05f0c6dcSMatt Spinler             CalloutPriority::high, "service_docs", "U27-P2", false));
255*05f0c6dcSMatt Spinler 
256*05f0c6dcSMatt Spinler         EXPECT_EQ(lightPath.getLocationCodes(callouts),
257*05f0c6dcSMatt Spinler                   (std::vector<std::string>{}));
258*05f0c6dcSMatt Spinler     }
259*05f0c6dcSMatt Spinler }
260