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 fetch_all_pel_ids_for_src(src_id, severity):
69    r"""
70    Fetch all PEL IDs for the input SRC ID based on the severity type
71    in the list format.
72
73    Description of arguments:
74    src_id      SRC ID (e.g. BC20E504).
75    severity    PEL severity (e.g. "Predictive Error"
76                                   "Recovered Error").
77    """
78
79    try:
80        src_pel_ids = []
81        pel_data = peltool(" -l")
82        pel_id_list = pel_data.keys()
83        for pel_id in pel_id_list:
84            # Check if required SRC ID with severity is present
85            if ((pel_data[pel_id]["SRC"] == src_id) and (pel_data[pel_id]["Sev"] == severity)):
86                src_pel_ids.append(pel_id)
87
88        if not src_pel_ids:
89            raise peltool_exception(src_id + " with severity " + severity + " not present")
90    except Exception as e:
91        raise peltool_exception("Failed to fetch PEL ID for required SRC : " + str(e))
92    return src_pel_ids
93
94
95def verify_src_signature_and_threshold(pel_id, attn_type, signature_desc, th_limit):
96    r"""
97    Verifies SRC details for the given PEL ID based on the required
98    attention type, signature description, threshold limits.
99
100    Description of arguments:
101    pel_id          PEL ID for the required SRC details to verify.
102    attn_type       Attention type (e.g. RE, CS, UNIT_CS).
103    signature_desc  Signature description of the error inject.
104    th_limit        Threshold limit (e.g. 1, 5, 32).
105    """
106
107    try:
108        pel_cmd = " -i " + pel_id
109        src_data = peltool(pel_cmd)
110        src_dict = src_data["Primary SRC"]["SRC Details"]
111        usr_data = src_data["User Data 1"]
112
113        # Example for signature in recoverable error
114        #
115        # "SRC Details": {
116        # "Attention Type": "RECOVERABLE",
117        # "Node": 0,
118        # "Target Type": "TYPE_OMIC",
119        # "Target Instance": 0,
120        # "Signature": "MC_OMI_DL_FIR[1]: OMI-DL0 UE on data flit"
121        # }
122        if (attn_type == "RE"):
123            if (src_dict["Attention Type"] != "RECOVERABLE"):
124                raise peltool_exception("Required Attention type " + attn_type + " not found")
125
126        # Example for signature in system checkstop error
127        #
128        # "SRC Details": {
129        # "Primary Attention": "system checkstop",
130        # "Signature Description": {
131        #    "Chip Desc": "node 0 proc 0 (P10 2.0)",
132        #    "Signature": "EQ_L2_FIR(0)[7] L2 directory read UE",
133        #    "Attn Type": "checkstop"
134        # }
135
136        elif (attn_type == "CS"):
137            if (src_dict["Primary Attention"] != "system checkstop"):
138                raise peltool_exception("Required Attention type " + attn_type + " not found")
139
140        elif (attn_type == "UNIT_CS"):
141            if (src_dict["Attention Type"] != "UNIT_CS"):
142                raise peltool_exception("Required Attention type " + attn_type + " not found")
143        else:
144            raise peltool_exception("Required Attention type " + attn_type + " not found")
145
146        if signature_desc not in src_dict["Signature"]:
147            raise peltool_exception("Required Signature " + signature_desc + " not found")
148
149        if (int(th_limit) != usr_data["Error Count"]):
150            raise peltool_exception("Required Threshold limit " + th_limit + " not found")
151
152    except Exception as e:
153        raise peltool_exception("Failed to verify SRC details : " + str(e))
154    return True
155
156
157def fetch_all_src():
158    r"""
159    Fetch all SRC IDs from peltool in the list format.
160    """
161    try:
162        src_id = []
163        pel_data = peltool(" -l")
164        if pel_data:
165            pel_id_list = pel_data.keys()
166            for pel_id in pel_id_list:
167                src_id.append(pel_data[pel_id]["SRC"])
168        else:
169            raise peltool_exception("No PEL entry found ..")
170    except Exception as e:
171        raise peltool_exception("Failed to fetch all SRCs : " + str(e))
172    return src_id
173