105f0c6dcSMatt Spinler /**
205f0c6dcSMatt Spinler  * Copyright © 2020 IBM Corporation
305f0c6dcSMatt Spinler  *
405f0c6dcSMatt Spinler  * Licensed under the Apache License, Version 2.0 (the "License");
505f0c6dcSMatt Spinler  * you may not use this file except in compliance with the License.
605f0c6dcSMatt Spinler  * You may obtain a copy of the License at
705f0c6dcSMatt Spinler  *
805f0c6dcSMatt Spinler  *     http://www.apache.org/licenses/LICENSE-2.0
905f0c6dcSMatt Spinler  *
1005f0c6dcSMatt Spinler  * Unless required by applicable law or agreed to in writing, software
1105f0c6dcSMatt Spinler  * distributed under the License is distributed on an "AS IS" BASIS,
1205f0c6dcSMatt Spinler  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1305f0c6dcSMatt Spinler  * See the License for the specific language governing permissions and
1405f0c6dcSMatt Spinler  * limitations under the License.
1505f0c6dcSMatt Spinler  */
1605f0c6dcSMatt Spinler #include "extensions/openpower-pels/service_indicators.hpp"
1705f0c6dcSMatt Spinler #include "mocks.hpp"
1805f0c6dcSMatt Spinler #include "pel_utils.hpp"
1905f0c6dcSMatt Spinler 
2005f0c6dcSMatt Spinler #include <gtest/gtest.h>
2105f0c6dcSMatt Spinler 
2205f0c6dcSMatt Spinler using namespace openpower::pels;
2305f0c6dcSMatt Spinler using CalloutVector = std::vector<std::unique_ptr<src::Callout>>;
2405f0c6dcSMatt Spinler using ::testing::_;
2505f0c6dcSMatt Spinler using ::testing::Return;
2605f0c6dcSMatt Spinler using ::testing::Throw;
2705f0c6dcSMatt Spinler 
2805f0c6dcSMatt Spinler // Test the ignore() function works
TEST(ServiceIndicatorsTest,IgnoreTest)2905f0c6dcSMatt Spinler TEST(ServiceIndicatorsTest, IgnoreTest)
3005f0c6dcSMatt Spinler {
3105f0c6dcSMatt Spinler     MockDataInterface dataIface;
3205f0c6dcSMatt Spinler     service_indicators::LightPath lightPath{dataIface};
3305f0c6dcSMatt Spinler 
3405f0c6dcSMatt Spinler     // PEL must have serviceable action flag set and be created
3505f0c6dcSMatt Spinler     // by the BMC or Hostboot.
3605f0c6dcSMatt Spinler     std::vector<std::tuple<char, uint16_t, bool>> testParams{
3705f0c6dcSMatt Spinler         {'O', 0xA400, false}, // BMC serviceable, don't ignore
3805f0c6dcSMatt Spinler         {'B', 0xA400, false}, // Hostboot serviceable, don't ignore
3905f0c6dcSMatt Spinler         {'H', 0xA400, true},  // PHYP serviceable, ignore
4005f0c6dcSMatt Spinler         {'O', 0x2400, true},  // BMC not serviceable, ignore
4105f0c6dcSMatt Spinler         {'B', 0x2400, true},  // Hostboot not serviceable, ignore
4205f0c6dcSMatt Spinler         {'H', 0x2400, true},  // PHYP not serviceable, ignore
4305f0c6dcSMatt Spinler     };
4405f0c6dcSMatt Spinler 
4505f0c6dcSMatt Spinler     for (const auto& test : testParams)
4605f0c6dcSMatt Spinler     {
4705f0c6dcSMatt Spinler         auto data = pelFactory(1, std::get<char>(test), 0x20,
4805f0c6dcSMatt Spinler                                std::get<uint16_t>(test), 500);
4905f0c6dcSMatt Spinler         PEL pel{data};
5005f0c6dcSMatt Spinler 
5105f0c6dcSMatt Spinler         EXPECT_EQ(lightPath.ignore(pel), std::get<bool>(test));
5205f0c6dcSMatt Spinler     }
5305f0c6dcSMatt Spinler }
5405f0c6dcSMatt Spinler 
5505f0c6dcSMatt Spinler // Test that only high, medium, and medium group A hardware
5605f0c6dcSMatt Spinler // callouts have their location codes extracted.
TEST(ServiceIndicatorsTest,OneCalloutPriorityTest)5705f0c6dcSMatt Spinler TEST(ServiceIndicatorsTest, OneCalloutPriorityTest)
5805f0c6dcSMatt Spinler {
5905f0c6dcSMatt Spinler     MockDataInterface dataIface;
6005f0c6dcSMatt Spinler     service_indicators::LightPath lightPath{dataIface};
6105f0c6dcSMatt Spinler 
6205f0c6dcSMatt Spinler     // The priorities to test, with the expected getLocationCodes results.
6305f0c6dcSMatt Spinler     std::vector<std::tuple<CalloutPriority, std::vector<std::string>>>
6405f0c6dcSMatt Spinler         testCallouts{{CalloutPriority::high, {"U27-P1"}},
6505f0c6dcSMatt Spinler                      {CalloutPriority::medium, {"U27-P1"}},
6605f0c6dcSMatt Spinler                      {CalloutPriority::mediumGroupA, {"U27-P1"}},
6705f0c6dcSMatt Spinler                      {CalloutPriority::mediumGroupB, {}},
6805f0c6dcSMatt Spinler                      {CalloutPriority::mediumGroupC, {}},
6905f0c6dcSMatt Spinler                      {CalloutPriority::low, {}}};
7005f0c6dcSMatt Spinler 
7105f0c6dcSMatt Spinler     for (const auto& test : testCallouts)
7205f0c6dcSMatt Spinler     {
7305f0c6dcSMatt Spinler         auto callout = std::make_unique<src::Callout>(
7405f0c6dcSMatt Spinler             std::get<CalloutPriority>(test), "U27-P1", "1234567", "aaaa",
7505f0c6dcSMatt Spinler             "123456789ABC");
7605f0c6dcSMatt Spinler 
7705f0c6dcSMatt Spinler         CalloutVector callouts;
7805f0c6dcSMatt Spinler         callouts.push_back(std::move(callout));
7905f0c6dcSMatt Spinler 
8005f0c6dcSMatt Spinler         EXPECT_EQ(lightPath.getLocationCodes(callouts),
8105f0c6dcSMatt Spinler                   std::get<std::vector<std::string>>(test));
8205f0c6dcSMatt Spinler     }
8305f0c6dcSMatt Spinler }
8405f0c6dcSMatt Spinler 
8505f0c6dcSMatt Spinler // Test that only normal hardware callouts and symbolic FRU
8605f0c6dcSMatt Spinler // callouts with trusted location codes have their location
8705f0c6dcSMatt Spinler // codes extracted.
TEST(ServiceIndicatorsTest,OneCalloutTypeTest)8805f0c6dcSMatt Spinler TEST(ServiceIndicatorsTest, OneCalloutTypeTest)
8905f0c6dcSMatt Spinler {
9005f0c6dcSMatt Spinler     MockDataInterface dataIface;
9105f0c6dcSMatt Spinler     service_indicators::LightPath lightPath{dataIface};
9205f0c6dcSMatt Spinler 
9305f0c6dcSMatt Spinler     // Regular hardware callout
9405f0c6dcSMatt Spinler     {
9505f0c6dcSMatt Spinler         CalloutVector callouts;
9605f0c6dcSMatt Spinler         callouts.push_back(
9705f0c6dcSMatt Spinler             std::make_unique<src::Callout>(CalloutPriority::high, "U27-P1",
9805f0c6dcSMatt Spinler                                            "1234567", "aaaa", "123456789ABC"));
9905f0c6dcSMatt Spinler 
10005f0c6dcSMatt Spinler         EXPECT_EQ(lightPath.getLocationCodes(callouts),
10105f0c6dcSMatt Spinler                   std::vector<std::string>{"U27-P1"});
10205f0c6dcSMatt Spinler     }
10305f0c6dcSMatt Spinler 
10405f0c6dcSMatt Spinler     // Symbolic FRU with trusted loc code callout
10505f0c6dcSMatt Spinler     {
10605f0c6dcSMatt Spinler         CalloutVector callouts;
10705f0c6dcSMatt Spinler         callouts.push_back(std::make_unique<src::Callout>(
10805f0c6dcSMatt Spinler             CalloutPriority::high, "service_docs", "U27-P1", true));
10905f0c6dcSMatt Spinler 
11005f0c6dcSMatt Spinler         EXPECT_EQ(lightPath.getLocationCodes(callouts),
11105f0c6dcSMatt Spinler                   std::vector<std::string>{"U27-P1"});
11205f0c6dcSMatt Spinler     }
11305f0c6dcSMatt Spinler 
11405f0c6dcSMatt Spinler     // Symbolic FRU without trusted loc code callout
11505f0c6dcSMatt Spinler     {
11605f0c6dcSMatt Spinler         CalloutVector callouts;
11705f0c6dcSMatt Spinler         callouts.push_back(std::make_unique<src::Callout>(
11805f0c6dcSMatt Spinler             CalloutPriority::high, "service_docs", "U27-P1", false));
11905f0c6dcSMatt Spinler 
12005f0c6dcSMatt Spinler         EXPECT_EQ(lightPath.getLocationCodes(callouts),
12105f0c6dcSMatt Spinler                   std::vector<std::string>{});
12205f0c6dcSMatt Spinler     }
12305f0c6dcSMatt Spinler 
12405f0c6dcSMatt Spinler     // Procedure callout
12505f0c6dcSMatt Spinler     {
12605f0c6dcSMatt Spinler         CalloutVector callouts;
12705f0c6dcSMatt Spinler         callouts.push_back(
12805f0c6dcSMatt Spinler             std::make_unique<src::Callout>(CalloutPriority::high, "bmc_code"));
12905f0c6dcSMatt Spinler 
13005f0c6dcSMatt Spinler         EXPECT_EQ(lightPath.getLocationCodes(callouts),
13105f0c6dcSMatt Spinler                   std::vector<std::string>{});
13205f0c6dcSMatt Spinler     }
13305f0c6dcSMatt Spinler }
13405f0c6dcSMatt Spinler 
13505f0c6dcSMatt Spinler // Test that only the callouts in the first group have their location
13605f0c6dcSMatt Spinler // codes extracted, where a group is one or more callouts listed
13705f0c6dcSMatt Spinler // together with priorities of high, medium, or medium group A
13805f0c6dcSMatt Spinler // (and medium is only ever contains 1 item).
TEST(ServiceIndicatorsTest,CalloutGroupingTest)13905f0c6dcSMatt Spinler TEST(ServiceIndicatorsTest, CalloutGroupingTest)
14005f0c6dcSMatt Spinler {
14105f0c6dcSMatt Spinler     MockDataInterface dataIface;
14205f0c6dcSMatt Spinler     service_indicators::LightPath lightPath{dataIface};
14305f0c6dcSMatt Spinler 
14405f0c6dcSMatt Spinler     // high/high/medium/high just grabs the first 2
14505f0c6dcSMatt Spinler     {
14605f0c6dcSMatt Spinler         CalloutVector callouts;
14705f0c6dcSMatt Spinler         callouts.push_back(
14805f0c6dcSMatt Spinler             std::make_unique<src::Callout>(CalloutPriority::high, "U27-P1",
14905f0c6dcSMatt Spinler                                            "1234567", "aaaa", "123456789ABC"));
15005f0c6dcSMatt Spinler         callouts.push_back(
15105f0c6dcSMatt Spinler             std::make_unique<src::Callout>(CalloutPriority::high, "U27-P2",
15205f0c6dcSMatt Spinler                                            "1234567", "aaaa", "123456789ABC"));
15305f0c6dcSMatt Spinler         callouts.push_back(
15405f0c6dcSMatt Spinler             std::make_unique<src::Callout>(CalloutPriority::medium, "U27-P3",
15505f0c6dcSMatt Spinler                                            "1234567", "aaaa", "123456789ABC"));
15605f0c6dcSMatt Spinler         // This high priority callout after a medium isn't actually valid, since
15705f0c6dcSMatt Spinler         // callouts are sorted, but test it anyway.
15805f0c6dcSMatt Spinler         callouts.push_back(
15905f0c6dcSMatt Spinler             std::make_unique<src::Callout>(CalloutPriority::high, "U27-P4",
16005f0c6dcSMatt Spinler                                            "1234567", "aaaa", "123456789ABC"));
16105f0c6dcSMatt Spinler 
16205f0c6dcSMatt Spinler         EXPECT_EQ(lightPath.getLocationCodes(callouts),
16305f0c6dcSMatt Spinler                   (std::vector<std::string>{"U27-P1", "U27-P2"}));
16405f0c6dcSMatt Spinler     }
16505f0c6dcSMatt Spinler 
16605f0c6dcSMatt Spinler     // medium/medium just grabs the first medium
16705f0c6dcSMatt Spinler     {
16805f0c6dcSMatt Spinler         CalloutVector callouts;
16905f0c6dcSMatt Spinler         callouts.push_back(
17005f0c6dcSMatt Spinler             std::make_unique<src::Callout>(CalloutPriority::medium, "U27-P1",
17105f0c6dcSMatt Spinler                                            "1234567", "aaaa", "123456789ABC"));
17205f0c6dcSMatt Spinler         callouts.push_back(
17305f0c6dcSMatt Spinler             std::make_unique<src::Callout>(CalloutPriority::medium, "U27-P2",
17405f0c6dcSMatt Spinler                                            "1234567", "aaaa", "123456789ABC"));
17505f0c6dcSMatt Spinler 
17605f0c6dcSMatt Spinler         EXPECT_EQ(lightPath.getLocationCodes(callouts),
17705f0c6dcSMatt Spinler                   std::vector<std::string>{"U27-P1"});
17805f0c6dcSMatt Spinler     }
17905f0c6dcSMatt Spinler 
18005f0c6dcSMatt Spinler     // mediumA/mediumA/medium just grabs the first 2
18105f0c6dcSMatt Spinler     {
18205f0c6dcSMatt Spinler         CalloutVector callouts;
18305f0c6dcSMatt Spinler         callouts.push_back(std::make_unique<src::Callout>(
18405f0c6dcSMatt Spinler             CalloutPriority::mediumGroupA, "U27-P1", "1234567", "aaaa",
18505f0c6dcSMatt Spinler             "123456789ABC"));
18605f0c6dcSMatt Spinler 
18705f0c6dcSMatt Spinler         callouts.push_back(std::make_unique<src::Callout>(
18805f0c6dcSMatt Spinler             CalloutPriority::mediumGroupA, "U27-P2", "1234567", "aaaa",
18905f0c6dcSMatt Spinler             "123456789ABC"));
19005f0c6dcSMatt Spinler 
19105f0c6dcSMatt Spinler         callouts.push_back(
19205f0c6dcSMatt Spinler             std::make_unique<src::Callout>(CalloutPriority::medium, "U27-P3",
19305f0c6dcSMatt Spinler                                            "1234567", "aaaa", "123456789ABC"));
19405f0c6dcSMatt Spinler 
19505f0c6dcSMatt Spinler         EXPECT_EQ(lightPath.getLocationCodes(callouts),
19605f0c6dcSMatt Spinler                   (std::vector<std::string>{"U27-P1", "U27-P2"}));
19705f0c6dcSMatt Spinler     }
19805f0c6dcSMatt Spinler }
19905f0c6dcSMatt Spinler 
20005f0c6dcSMatt Spinler // Test that if any callouts in group are not HW/trusted symbolic
20105f0c6dcSMatt Spinler // FRU callouts then no location codes will be extracted
TEST(ServiceIndicatorsTest,CalloutMixedTypesTest)20205f0c6dcSMatt Spinler TEST(ServiceIndicatorsTest, CalloutMixedTypesTest)
20305f0c6dcSMatt Spinler {
20405f0c6dcSMatt Spinler     MockDataInterface dataIface;
20505f0c6dcSMatt Spinler     service_indicators::LightPath lightPath{dataIface};
20605f0c6dcSMatt Spinler 
20705f0c6dcSMatt Spinler     // Mixing FRU with trusted symbolic FRU is OK
20805f0c6dcSMatt Spinler     {
20905f0c6dcSMatt Spinler         CalloutVector callouts;
21005f0c6dcSMatt Spinler         callouts.push_back(
21105f0c6dcSMatt Spinler             std::make_unique<src::Callout>(CalloutPriority::high, "U27-P1",
21205f0c6dcSMatt Spinler                                            "1234567", "aaaa", "123456789ABC"));
21305f0c6dcSMatt Spinler         callouts.push_back(std::make_unique<src::Callout>(
21405f0c6dcSMatt Spinler             CalloutPriority::high, "service_docs", "U27-P2", true));
21505f0c6dcSMatt Spinler 
21605f0c6dcSMatt Spinler         EXPECT_EQ(lightPath.getLocationCodes(callouts),
21705f0c6dcSMatt Spinler                   (std::vector<std::string>{"U27-P1", "U27-P2"}));
21805f0c6dcSMatt Spinler     }
21905f0c6dcSMatt Spinler 
22005f0c6dcSMatt Spinler     // Normal FRU callout with a non-trusted symbolic FRU callout not OK
22105f0c6dcSMatt Spinler     {
22205f0c6dcSMatt Spinler         CalloutVector callouts;
22305f0c6dcSMatt Spinler         callouts.push_back(
22405f0c6dcSMatt Spinler             std::make_unique<src::Callout>(CalloutPriority::high, "U27-P1",
22505f0c6dcSMatt Spinler                                            "1234567", "aaaa", "123456789ABC"));
22605f0c6dcSMatt Spinler         callouts.push_back(std::make_unique<src::Callout>(
22705f0c6dcSMatt Spinler             CalloutPriority::high, "service_docs", "U27-P2", false));
22805f0c6dcSMatt Spinler 
22905f0c6dcSMatt Spinler         EXPECT_EQ(lightPath.getLocationCodes(callouts),
23005f0c6dcSMatt Spinler                   (std::vector<std::string>{}));
23105f0c6dcSMatt Spinler     }
23205f0c6dcSMatt Spinler 
23305f0c6dcSMatt Spinler     // Normal FRU callout with a procedure callout not OK
23405f0c6dcSMatt Spinler     {
23505f0c6dcSMatt Spinler         CalloutVector callouts;
23605f0c6dcSMatt Spinler         callouts.push_back(
23705f0c6dcSMatt Spinler             std::make_unique<src::Callout>(CalloutPriority::high, "U27-P1",
23805f0c6dcSMatt Spinler                                            "1234567", "aaaa", "123456789ABC"));
23905f0c6dcSMatt Spinler         callouts.push_back(
24005f0c6dcSMatt Spinler             std::make_unique<src::Callout>(CalloutPriority::high, "bmc_code"));
24105f0c6dcSMatt Spinler 
24205f0c6dcSMatt Spinler         EXPECT_EQ(lightPath.getLocationCodes(callouts),
24305f0c6dcSMatt Spinler                   (std::vector<std::string>{}));
24405f0c6dcSMatt Spinler     }
24505f0c6dcSMatt Spinler 
24605f0c6dcSMatt Spinler     // Trusted symbolic FRU callout with a non-trusted symbolic
24705f0c6dcSMatt Spinler     // FRU callout not OK
24805f0c6dcSMatt Spinler     {
24905f0c6dcSMatt Spinler         CalloutVector callouts;
25005f0c6dcSMatt Spinler         callouts.push_back(std::make_unique<src::Callout>(
25105f0c6dcSMatt Spinler             CalloutPriority::high, "service_docs", "U27-P2", true));
25205f0c6dcSMatt Spinler 
25305f0c6dcSMatt Spinler         callouts.push_back(std::make_unique<src::Callout>(
25405f0c6dcSMatt Spinler             CalloutPriority::high, "service_docs", "U27-P2", false));
25505f0c6dcSMatt Spinler 
25605f0c6dcSMatt Spinler         EXPECT_EQ(lightPath.getLocationCodes(callouts),
25705f0c6dcSMatt Spinler                   (std::vector<std::string>{}));
25805f0c6dcSMatt Spinler     }
25905f0c6dcSMatt Spinler }
26034a904cfSMatt Spinler 
26134a904cfSMatt Spinler // Test the activate() function
TEST(ServiceIndicatorsTest,ActivateTest)26234a904cfSMatt Spinler TEST(ServiceIndicatorsTest, ActivateTest)
26334a904cfSMatt Spinler {
26434a904cfSMatt Spinler     // pelFactory() will create a PEL with 1 callout with location code
26534a904cfSMatt Spinler     // U42.  Test the LED for that gets activated.
26634a904cfSMatt Spinler     {
26734a904cfSMatt Spinler         MockDataInterface dataIface;
26834a904cfSMatt Spinler         service_indicators::LightPath lightPath{dataIface};
26934a904cfSMatt Spinler 
27034a904cfSMatt Spinler         EXPECT_CALL(dataIface, getInventoryFromLocCode("U42", 0, true))
271*bad056beSMatt Spinler             .WillOnce(
272*bad056beSMatt Spinler                 Return(std::vector<std::string>{"/system/chassis/processor"}));
27334a904cfSMatt Spinler 
274993168deSMatt Spinler         EXPECT_CALL(dataIface,
275993168deSMatt Spinler                     setFunctional("/system/chassis/processor", false))
27634a904cfSMatt Spinler             .Times(1);
27734a904cfSMatt Spinler 
27876198a2eSSumit Kumar         EXPECT_CALL(dataIface,
27976198a2eSSumit Kumar                     setCriticalAssociation("/system/chassis/processor"))
28076198a2eSSumit Kumar             .Times(1);
28176198a2eSSumit Kumar 
28234a904cfSMatt Spinler         auto data = pelFactory(1, 'O', 0x20, 0xA400, 500);
28334a904cfSMatt Spinler         PEL pel{data};
28434a904cfSMatt Spinler 
28534a904cfSMatt Spinler         lightPath.activate(pel);
28634a904cfSMatt Spinler     }
28734a904cfSMatt Spinler 
288*bad056beSMatt Spinler     // With the same U42 callout, have it be associated with two
289*bad056beSMatt Spinler     // inventory paths
290*bad056beSMatt Spinler     {
291*bad056beSMatt Spinler         MockDataInterface dataIface;
292*bad056beSMatt Spinler         service_indicators::LightPath lightPath{dataIface};
293*bad056beSMatt Spinler 
294*bad056beSMatt Spinler         EXPECT_CALL(dataIface, getInventoryFromLocCode("U42", 0, true))
295*bad056beSMatt Spinler             .WillOnce(Return(std::vector<std::string>{"/system/chassis/cpu0",
296*bad056beSMatt Spinler                                                       "/system/chassis/cpu1"}));
297*bad056beSMatt Spinler 
298*bad056beSMatt Spinler         EXPECT_CALL(dataIface, setFunctional("/system/chassis/cpu0", false))
299*bad056beSMatt Spinler             .Times(1);
300*bad056beSMatt Spinler         EXPECT_CALL(dataIface, setFunctional("/system/chassis/cpu1", false))
301*bad056beSMatt Spinler             .Times(1);
302*bad056beSMatt Spinler 
303*bad056beSMatt Spinler         EXPECT_CALL(dataIface, setCriticalAssociation("/system/chassis/cpu0"))
304*bad056beSMatt Spinler             .Times(1);
305*bad056beSMatt Spinler         EXPECT_CALL(dataIface, setCriticalAssociation("/system/chassis/cpu1"))
306*bad056beSMatt Spinler             .Times(1);
307*bad056beSMatt Spinler 
308*bad056beSMatt Spinler         auto data = pelFactory(1, 'O', 0x20, 0xA400, 500);
309*bad056beSMatt Spinler         PEL pel{data};
310*bad056beSMatt Spinler 
311*bad056beSMatt Spinler         lightPath.activate(pel);
312*bad056beSMatt Spinler     }
313*bad056beSMatt Spinler 
31448c44dbbSMatt Spinler     // A non-info BMC PEL with no callouts will set the platform SAI LED.
31548c44dbbSMatt Spinler     {
31648c44dbbSMatt Spinler         MockDataInterface dataIface;
31748c44dbbSMatt Spinler         service_indicators::LightPath lightPath{dataIface};
31848c44dbbSMatt Spinler 
31948c44dbbSMatt Spinler         EXPECT_CALL(dataIface,
32048c44dbbSMatt Spinler                     assertLEDGroup("/xyz/openbmc_project/led/groups/"
32148c44dbbSMatt Spinler                                    "platform_system_attention_indicator",
32248c44dbbSMatt Spinler                                    true))
32348c44dbbSMatt Spinler             .Times(1);
32448c44dbbSMatt Spinler 
32548c44dbbSMatt Spinler         auto data = pelDataFactory(TestPELType::pelSimple);
32648c44dbbSMatt Spinler         PEL pel{data};
32748c44dbbSMatt Spinler 
32848c44dbbSMatt Spinler         lightPath.activate(pel);
32948c44dbbSMatt Spinler     }
33048c44dbbSMatt Spinler 
33148c44dbbSMatt Spinler     // Make getInventoryFromLocCode fail - will set the platform SAI LED
33234a904cfSMatt Spinler     {
33334a904cfSMatt Spinler         MockDataInterface dataIface;
33434a904cfSMatt Spinler         service_indicators::LightPath lightPath{dataIface};
33534a904cfSMatt Spinler 
33634a904cfSMatt Spinler         EXPECT_CALL(dataIface, getInventoryFromLocCode("U42", 0, true))
33734a904cfSMatt Spinler             .WillOnce(Throw(std::runtime_error("Fail")));
33834a904cfSMatt Spinler 
339993168deSMatt Spinler         EXPECT_CALL(dataIface, setFunctional).Times(0);
34034a904cfSMatt Spinler 
34148c44dbbSMatt Spinler         EXPECT_CALL(dataIface,
34248c44dbbSMatt Spinler                     assertLEDGroup("/xyz/openbmc_project/led/groups/"
34348c44dbbSMatt Spinler                                    "platform_system_attention_indicator",
34448c44dbbSMatt Spinler                                    true))
34548c44dbbSMatt Spinler             .Times(1);
34634a904cfSMatt Spinler 
34734a904cfSMatt Spinler         auto data = pelFactory(1, 'O', 0x20, 0xA400, 500);
34834a904cfSMatt Spinler         PEL pel{data};
34934a904cfSMatt Spinler 
35034a904cfSMatt Spinler         lightPath.activate(pel);
35134a904cfSMatt Spinler     }
35234a904cfSMatt Spinler 
353993168deSMatt Spinler     // Make setFunctional fail
35434a904cfSMatt Spinler     {
35534a904cfSMatt Spinler         MockDataInterface dataIface;
35634a904cfSMatt Spinler         service_indicators::LightPath lightPath{dataIface};
35734a904cfSMatt Spinler 
35834a904cfSMatt Spinler         EXPECT_CALL(dataIface, getInventoryFromLocCode("U42", 0, true))
359*bad056beSMatt Spinler             .WillOnce(
360*bad056beSMatt Spinler                 Return(std::vector<std::string>{"/system/chassis/processor"}));
36134a904cfSMatt Spinler 
36248c44dbbSMatt Spinler         EXPECT_CALL(dataIface,
363993168deSMatt Spinler                     setFunctional("/system/chassis/processor", false))
36434a904cfSMatt Spinler             .WillOnce(Throw(std::runtime_error("Fail")));
36534a904cfSMatt Spinler 
36634a904cfSMatt Spinler         auto data = pelFactory(1, 'O', 0x20, 0xA400, 500);
36734a904cfSMatt Spinler         PEL pel{data};
36834a904cfSMatt Spinler 
36934a904cfSMatt Spinler         lightPath.activate(pel);
37034a904cfSMatt Spinler     }
37176198a2eSSumit Kumar 
37276198a2eSSumit Kumar     // Test setCriticalAssociation fail
37376198a2eSSumit Kumar     {
37476198a2eSSumit Kumar         MockDataInterface dataIface;
37576198a2eSSumit Kumar         service_indicators::LightPath lightPath{dataIface};
37676198a2eSSumit Kumar 
37776198a2eSSumit Kumar         EXPECT_CALL(dataIface, getInventoryFromLocCode("U42", 0, true))
378*bad056beSMatt Spinler             .WillOnce(
379*bad056beSMatt Spinler                 Return(std::vector<std::string>{"/system/chassis/processor"}));
38076198a2eSSumit Kumar 
38176198a2eSSumit Kumar         EXPECT_CALL(dataIface,
38276198a2eSSumit Kumar                     setCriticalAssociation("/system/chassis/processor"))
38376198a2eSSumit Kumar             .WillOnce(Throw(std::runtime_error("Fail")));
38476198a2eSSumit Kumar 
38576198a2eSSumit Kumar         auto data = pelFactory(1, 'O', 0x20, 0xA400, 500);
38676198a2eSSumit Kumar         PEL pel{data};
38776198a2eSSumit Kumar 
38876198a2eSSumit Kumar         lightPath.activate(pel);
38976198a2eSSumit Kumar     }
39034a904cfSMatt Spinler }
391