1#!/usr/bin/env python3
2
3r"""
4PEL functions.
5"""
6
7import func_args as fa
8import bmc_ssh_utils as bsu
9import json
10import os
11import sys
12from robot.libraries.BuiltIn import BuiltIn
13
14base_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
15sys.path.append(base_path + "/data/")
16
17import pel_variables
18
19
20class peltool_exception(Exception):
21    r"""
22    Base class for peltool related exceptions.
23    """
24
25    def __init__(self, message):
26        self.message = message
27        super().__init__(self.message)
28
29
30def peltool(option_string, parse_json=True, **bsu_options):
31    r"""
32    Run peltool on the BMC with the caller's option string and return the result.
33
34    Example:
35
36    ${pel_results}=  Peltool  -l
37    Rprint Vars  pel_results
38
39    pel_results:
40      [0x50000031]:
41        [CompID]:                       0x1000
42        [PLID]:                         0x50000031
43        [Subsystem]:                    BMC Firmware
44        [Message]:                      An application had an internal failure
45        [SRC]:                          BD8D1002
46        [Commit Time]:                  02/25/2020  04:51:31
47        [Sev]:                          Unrecoverable Error
48        [CreatorID]:                    BMC
49
50    Description of argument(s):
51    option_string                   A string of options which are to be processed by the peltool command.
52    parse_json                      Indicates that the raw JSON data should parsed into a list of
53                                    dictionaries.
54    bsu_options                     Options to be passed directly to bmc_execute_command. See its prolog for
55                                    details.
56    """
57
58    bsu_options = fa.args_to_objects(bsu_options)
59    out_buf, stderr, rc = bsu.bmc_execute_command('peltool ' + option_string, **bsu_options)
60    if parse_json:
61        try:
62            return json.loads(out_buf)
63        except ValueError:
64            return {}
65    return out_buf
66
67
68def get_pel_data_from_bmc():
69    r"""
70    Returns PEL data from BMC else throws exception.
71    """
72    try:
73        pel_data = peltool(" -l")
74        if not pel_data:
75            print("No PEL data present in BMC ...")
76    except Exception as e:
77        raise peltool_exception("Failed to get PEL data from BMC : " + str(e))
78    return pel_data
79
80
81def fetch_all_pel_ids_for_src(src_id, severity):
82    r"""
83    Fetch all PEL IDs for the input SRC ID based on the severity type
84    in the list format.
85
86    Description of arguments:
87    src_id      SRC ID (e.g. BC20E504).
88    severity    PEL severity (e.g. "Predictive Error"
89                                   "Recovered Error").
90    """
91
92    try:
93        src_pel_ids = []
94        pel_data = peltool(" -l")
95        pel_id_list = pel_data.keys()
96        for pel_id in pel_id_list:
97            # Check if required SRC ID with severity is present
98            if ((pel_data[pel_id]["SRC"] == src_id) and (pel_data[pel_id]["Sev"] == severity)):
99                src_pel_ids.append(pel_id)
100
101        if not src_pel_ids:
102            raise peltool_exception(src_id + " with severity " + severity + " not present")
103    except Exception as e:
104        raise peltool_exception("Failed to fetch PEL ID for required SRC : " + str(e))
105    return src_pel_ids
106
107
108def verify_src_signature_and_threshold(pel_id, attn_type, signature_desc, th_limit):
109    r"""
110    Verifies SRC details for the given PEL ID based on the required
111    attention type, signature description, threshold limits.
112
113    Description of arguments:
114    pel_id          PEL ID for the required SRC details to verify.
115    attn_type       Attention type (e.g. RE, CS, UNIT_CS).
116    signature_desc  Signature description of the error inject.
117    th_limit        Threshold limit (e.g. 1, 5, 32).
118    """
119
120    try:
121        pel_cmd = " -i " + pel_id
122        src_data = peltool(pel_cmd)
123        src_dict = src_data["Primary SRC"]["SRC Details"]
124        usr_data = src_data["User Data 1"]
125
126        # Example for signature in recoverable error
127        #
128        # "SRC Details": {
129        # "Attention Type": "RECOVERABLE",
130        # "Node": 0,
131        # "Target Type": "TYPE_OMIC",
132        # "Target Instance": 0,
133        # "Signature": "MC_OMI_DL_FIR[1]: OMI-DL0 UE on data flit"
134        # }
135        if (attn_type == "RE"):
136            if (src_dict["Attention Type"] != "RECOVERABLE"):
137                raise peltool_exception("Required Attention type " + attn_type + " not found")
138
139        # Example for signature in system checkstop error
140        #
141        # "SRC Details": {
142        # "Primary Attention": "system checkstop",
143        # "Signature Description": {
144        #    "Chip Desc": "node 0 proc 0 (P10 2.0)",
145        #    "Signature": "EQ_L2_FIR(0)[7] L2 directory read UE",
146        #    "Attn Type": "checkstop"
147        # }
148
149        elif (attn_type == "CS"):
150            if (src_dict["Primary Attention"] != "system checkstop"):
151                raise peltool_exception("Required Attention type " + attn_type + " not found")
152
153        elif (attn_type == "UNIT_CS"):
154            if (src_dict["Attention Type"] != "UNIT_CS"):
155                raise peltool_exception("Required Attention type " + attn_type + " not found")
156        else:
157            raise peltool_exception("Required Attention type " + attn_type + " not found")
158
159        if signature_desc not in src_dict["Signature"]:
160            raise peltool_exception("Required Signature " + signature_desc + " not found")
161
162        if (int(th_limit) != usr_data["Error Count"]):
163            raise peltool_exception("Required Threshold limit " + th_limit + " not found")
164
165    except Exception as e:
166        raise peltool_exception("Failed to verify SRC details : " + str(e))
167    return True
168
169
170def fetch_all_src():
171    r"""
172    Fetch all SRC IDs from peltool in the list format.
173    """
174    try:
175        src_id = []
176        pel_data = peltool(" -l")
177        if pel_data:
178            pel_id_list = pel_data.keys()
179            for pel_id in pel_id_list:
180                src_id.append(pel_data[pel_id]["SRC"])
181        else:
182            raise peltool_exception("No PEL entry found ..")
183    except Exception as e:
184        raise peltool_exception("Failed to fetch all SRCs : " + str(e))
185    return src_id
186