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