1*e7e9171eSGeorge Keishing#!/usr/bin/env python3 -u
2b29d2e84SChris Austenimport sys
3b29d2e84SChris Austenfrom robot.libraries.BuiltIn import BuiltIn
4b29d2e84SChris Austenimport imp
5b29d2e84SChris Austenimport string
6757d80c1SRahul Maheshwariimport random
78b270ecfSMichael Walshimport subprocess
88b270ecfSMichael Walshfrom robot.utils import DotDict
98b270ecfSMichael Walsh
10b29d2e84SChris Austen
11757d80c1SRahul Maheshwaridef random_mac():
12757d80c1SRahul Maheshwari    r"""
13757d80c1SRahul Maheshwari    Return random mac address in the following format.
14757d80c1SRahul Maheshwari    Example: 00:01:6C:80:02:78
15757d80c1SRahul Maheshwari    """
16757d80c1SRahul Maheshwari    return ":".join(map(lambda x: "%02x" % x, (random.randint(0x00, 0xff)
17757d80c1SRahul Maheshwari                                               for _ in range(6))))
18757d80c1SRahul Maheshwari
19096cd565SGunnar Mills
20757d80c1SRahul Maheshwaridef random_ip():
21757d80c1SRahul Maheshwari    r"""
22757d80c1SRahul Maheshwari    Return random ip address in the following format.
23757d80c1SRahul Maheshwari    Example: 9.3.128.100
24757d80c1SRahul Maheshwari    """
25757d80c1SRahul Maheshwari    return ".".join(map(str, (random.randint(0, 255)
26757d80c1SRahul Maheshwari                              for _ in range(4))))
27b29d2e84SChris Austen
28096cd565SGunnar Mills
29b29d2e84SChris Austendef get_sensor(module_name, value):
30b29d2e84SChris Austen    m = imp.load_source('module.name', module_name)
31b29d2e84SChris Austen
32b29d2e84SChris Austen    for i in m.ID_LOOKUP['SENSOR']:
33b29d2e84SChris Austen
34b29d2e84SChris Austen        if m.ID_LOOKUP['SENSOR'][i] == value:
35b29d2e84SChris Austen            return i
36b29d2e84SChris Austen
37b29d2e84SChris Austen    return 0xFF
38b29d2e84SChris Austen
39b29d2e84SChris Austen
40b29d2e84SChris Austendef get_inventory_sensor(module_name, value):
41b29d2e84SChris Austen    m = imp.load_source('module.name', module_name)
42b29d2e84SChris Austen
43b29d2e84SChris Austen    value = string.replace(value, m.INVENTORY_ROOT, '<inventory_root>')
44b29d2e84SChris Austen
45b29d2e84SChris Austen    for i in m.ID_LOOKUP['SENSOR']:
46b29d2e84SChris Austen
47b29d2e84SChris Austen        if m.ID_LOOKUP['SENSOR'][i] == value:
48b29d2e84SChris Austen            return i
49b29d2e84SChris Austen
50b29d2e84SChris Austen    return 0xFF
51b29d2e84SChris Austen
52b29d2e84SChris Austen
53b29d2e84SChris Austen################################################################
54b29d2e84SChris Austen#  This will return the URI's of the FRU type
55b29d2e84SChris Austen#
56b29d2e84SChris Austen#  i.e.  get_inventory_list('../data/Palmetto.py')
57b29d2e84SChris Austen#
58b29d2e84SChris Austen#  [/org/openbmc/inventory//system/chassis/motherboard/cpu0/core0,
59b29d2e84SChris Austen#   /org/openbmc/inventory/system/chassis/motherboard/dimm0]
60b29d2e84SChris Austen################################################################
61b29d2e84SChris Austendef get_inventory_list(module_name):
62b29d2e84SChris Austen
63004ad3c9SJoy Onyerikwu    inventory_list = []
64b29d2e84SChris Austen    m = imp.load_source('module.name', module_name)
65b29d2e84SChris Austen
66b29d2e84SChris Austen    for i in m.ID_LOOKUP['FRU']:
67b29d2e84SChris Austen        s = m.ID_LOOKUP['FRU'][i]
68b29d2e84SChris Austen        s = s.replace('<inventory_root>', m.INVENTORY_ROOT)
69004ad3c9SJoy Onyerikwu        inventory_list.append(s)
70b29d2e84SChris Austen
71004ad3c9SJoy Onyerikwu    return inventory_list
72b29d2e84SChris Austen
73b29d2e84SChris Austen
74b29d2e84SChris Austen################################################################
75b29d2e84SChris Austen#  This will return the URI's of the FRU type
76b29d2e84SChris Austen#
77be3cdfd0SGeorge Keishing#  i.e.  get_inventory_fru_type_list('../data/Witherspoon.py', 'CPU')
78b29d2e84SChris Austen#
79b29d2e84SChris Austen#  [/org/openbmc/inventory//system/chassis/motherboard/cpu0,
80b29d2e84SChris Austen#   /org/openbmc/inventory//system/chassis/motherboard/cpu1]
81b29d2e84SChris Austen################################################################
82b29d2e84SChris Austendef get_inventory_fru_type_list(module_name, fru):
83004ad3c9SJoy Onyerikwu    inventory_list = []
84b29d2e84SChris Austen    m = imp.load_source('module.name', module_name)
85b29d2e84SChris Austen
86b29d2e84SChris Austen    for i in m.FRU_INSTANCES.keys():
87b29d2e84SChris Austen        if m.FRU_INSTANCES[i]['fru_type'] == fru:
88b29d2e84SChris Austen            s = i.replace('<inventory_root>', m.INVENTORY_ROOT)
89004ad3c9SJoy Onyerikwu            inventory_list.append(s)
90b29d2e84SChris Austen
91004ad3c9SJoy Onyerikwu    return inventory_list
92b29d2e84SChris Austen
93b29d2e84SChris Austen
94b29d2e84SChris Austen################################################################
95b29d2e84SChris Austen#  This will return the URI's of the FRU type that contain VPD
96b29d2e84SChris Austen#
97b29d2e84SChris Austen#  i.e.  get_vpd_inventory_list('../data/Palmetto.py', 'DIMM')
98b29d2e84SChris Austen#
99b29d2e84SChris Austen#  [/org/openbmc/inventory/system/chassis/motherboard/dimm0,
100b29d2e84SChris Austen#   /org/openbmc/inventory/system/chassis/motherboard/dimm1]
101b29d2e84SChris Austen################################################################
102b29d2e84SChris Austendef get_vpd_inventory_list(module_name, fru):
103004ad3c9SJoy Onyerikwu    inventory_list = []
104b29d2e84SChris Austen    m = imp.load_source('module.name', module_name)
105b29d2e84SChris Austen
106b29d2e84SChris Austen    for i in m.ID_LOOKUP['FRU_STR']:
107b29d2e84SChris Austen        x = m.ID_LOOKUP['FRU_STR'][i]
108b29d2e84SChris Austen
109b29d2e84SChris Austen        if m.FRU_INSTANCES[x]['fru_type'] == fru:
110b29d2e84SChris Austen            s = x.replace('<inventory_root>', m.INVENTORY_ROOT)
111004ad3c9SJoy Onyerikwu            inventory_list.append(s)
112b29d2e84SChris Austen
113004ad3c9SJoy Onyerikwu    return inventory_list
114b29d2e84SChris Austen
115b29d2e84SChris Austen
116b29d2e84SChris Austendef call_keyword(keyword):
117b29d2e84SChris Austen    return BuiltIn().run_keyword(keyword)
118b29d2e84SChris Austen
119b29d2e84SChris Austen
120b29d2e84SChris Austendef main():
12136efbc04SGeorge Keishing    print(get_vpd_inventory_list('../data/Palmetto.py', 'DIMM'))
122b29d2e84SChris Austen
123b29d2e84SChris Austen
124b29d2e84SChris Austenif __name__ == "__main__":
125b29d2e84SChris Austen    main()
1268b270ecfSMichael Walsh
1278b270ecfSMichael Walsh
1288b270ecfSMichael Walshdef get_mtr_report(host=""):
1298b270ecfSMichael Walsh    r"""
1308b270ecfSMichael Walsh    Get an mtr report and return it as a dictionary of dictionaries.
1318b270ecfSMichael Walsh
1328b270ecfSMichael Walsh    The key for the top level dictionary will be the host DNS name.  The key
1338b270ecfSMichael Walsh    for the next level dictionary will be the field of a given row of the
1348b270ecfSMichael Walsh    report.
1358b270ecfSMichael Walsh
1368b270ecfSMichael Walsh    Example result:
1378b270ecfSMichael Walsh
1388b270ecfSMichael Walsh    report:
139fb4b1256SGeorge Keishing      report[host_dummy-dnsname.com]:
140fb4b1256SGeorge Keishing        report[host_dummy-dnsname.com][row_num]:  1
141fb4b1256SGeorge Keishing        report[host_dummy-dnsname.com][host]:     host_dummy-dnsname.com
142fb4b1256SGeorge Keishing        report[host_dummy-dnsname.com][loss]:     0.0
143fb4b1256SGeorge Keishing        report[host_dummy-dnsname.com][snt]:      10
144fb4b1256SGeorge Keishing        report[host_dummy-dnsname.com][last]:     0.2
145fb4b1256SGeorge Keishing        report[host_dummy-dnsname.com][avg]:      3.5
146fb4b1256SGeorge Keishing        report[host_dummy-dnsname.com][best]:     0.2
147fb4b1256SGeorge Keishing        report[host_dummy-dnsname.com][wrst]:     32.5
148fb4b1256SGeorge Keishing        report[host_dummy-dnsname.com][stdev]:    10.2
149fb4b1256SGeorge Keishing      report[bmc-dummy-dnsname.com]:
150fb4b1256SGeorge Keishing        report[bmc-dummy-dnsname.com][row_num]:     2
151fb4b1256SGeorge Keishing        report[bmc-dummy-dnsname.com][host]:        bmc-dummy-dnsname.com
152fb4b1256SGeorge Keishing        report[bmc-dummy-dnsname.com][loss]:        0.0
153fb4b1256SGeorge Keishing        report[bmc-dummy-dnsname.com][snt]:         10
154fb4b1256SGeorge Keishing        report[bmc-dummy-dnsname.com][last]:        0.5
155fb4b1256SGeorge Keishing        report[bmc-dummy-dnsname.com][avg]:         0.5
156fb4b1256SGeorge Keishing        report[bmc-dummy-dnsname.com][best]:        0.5
157fb4b1256SGeorge Keishing        report[bmc-dummy-dnsname.com][wrst]:        0.5
158fb4b1256SGeorge Keishing        report[bmc-dummy-dnsname.com][stdev]:       0.0
1598b270ecfSMichael Walsh
1608b270ecfSMichael Walsh    Description of arguments:
1618b270ecfSMichael Walsh    host   The DNS name or IP address to be passed to the mtr command.
1628b270ecfSMichael Walsh    """
1638b270ecfSMichael Walsh
164acc7c56eSGunnar Mills    # Run the mtr command.  Exclude the header line.  Trim leading space from
1658b270ecfSMichael Walsh    # each line.  Change all multiple spaces delims to single space delims.
1668b270ecfSMichael Walsh    cmd_buf = "mtr --report " + host +\
1678b270ecfSMichael Walsh        " | tail -n +2 | sed -r -e 's/^[ ]+//g' -e 's/[ ]+/ /g'"
1688b270ecfSMichael Walsh    sub_proc = subprocess.Popen(cmd_buf, shell=True, stdout=subprocess.PIPE,
1698b270ecfSMichael Walsh                                stderr=subprocess.STDOUT)
1708b270ecfSMichael Walsh    out_buf, err_buf = sub_proc.communicate()
1718b270ecfSMichael Walsh    shell_rc = sub_proc.returncode
1728b270ecfSMichael Walsh
1738b270ecfSMichael Walsh    # Split the output by line.
1748b270ecfSMichael Walsh    rows = out_buf.rstrip('\n').split("\n")
1758b270ecfSMichael Walsh
1768b270ecfSMichael Walsh    # Initialize report dictionary.
1778b270ecfSMichael Walsh    report = DotDict()
1788b270ecfSMichael Walsh    for row in rows:
1798b270ecfSMichael Walsh        # Process each row of mtr output.
1808b270ecfSMichael Walsh        # Create a list of fields by splitting on space delimiter.
1818b270ecfSMichael Walsh        row_list = row.split(" ")
1828b270ecfSMichael Walsh        # Create dictionary for the row.
1838b270ecfSMichael Walsh        row = DotDict()
1848b270ecfSMichael Walsh        row['row_num'] = row_list[0].rstrip('.')
1858b270ecfSMichael Walsh        row['host'] = row_list[1]
1868b270ecfSMichael Walsh        row['loss'] = row_list[2].rstrip('%')
1878b270ecfSMichael Walsh        row['snt'] = row_list[3]
1888b270ecfSMichael Walsh        row['last'] = row_list[4]
1898b270ecfSMichael Walsh        row['avg'] = row_list[5]
1908b270ecfSMichael Walsh        row['best'] = row_list[6]
1918b270ecfSMichael Walsh        row['wrst'] = row_list[7]
1928b270ecfSMichael Walsh        row['stdev'] = row_list[8]
1938b270ecfSMichael Walsh        report[row['host']] = row
1948b270ecfSMichael Walsh
1958b270ecfSMichael Walsh    # Return the full report as dictionary of dictionaries.
1968b270ecfSMichael Walsh    return report
1978b270ecfSMichael Walsh
1988b270ecfSMichael Walsh
1998b270ecfSMichael Walshdef get_mtr_row(host=""):
2008b270ecfSMichael Walsh    r"""
2018b270ecfSMichael Walsh    Run an mtr report and get a specified row and return it as a dictionary.
2028b270ecfSMichael Walsh
2038b270ecfSMichael Walsh    Example result:
2048b270ecfSMichael Walsh
2058b270ecfSMichael Walsh    row:
2068b270ecfSMichael Walsh      row[row_num]:              2
207fb4b1256SGeorge Keishing      row[host]:                 bmc-dummy-dnsname.com
2088b270ecfSMichael Walsh      row[loss]:                 0.0
2098b270ecfSMichael Walsh      row[snt]:                  10
2108b270ecfSMichael Walsh      row[last]:                 0.5
2118b270ecfSMichael Walsh      row[avg]:                  0.5
2128b270ecfSMichael Walsh      row[best]:                 0.4
2138b270ecfSMichael Walsh      row[wrst]:                 0.7
2148b270ecfSMichael Walsh      row[stdev]:                0.1
2158b270ecfSMichael Walsh
2168b270ecfSMichael Walsh    Description of arguments:
2178b270ecfSMichael Walsh    host   The DNS name or IP address to be passed to the mtr command as
2188b270ecfSMichael Walsh           well as the indicating which row of the report to return.
2198b270ecfSMichael Walsh    """
2208b270ecfSMichael Walsh
2218b270ecfSMichael Walsh    report = get_mtr_report(host)
2228b270ecfSMichael Walsh
2238b270ecfSMichael Walsh    # The max length of host in output is 28 chars.
2248b270ecfSMichael Walsh    row = [value for key, value in report.items() if host[0:28] in key][0]
2258b270ecfSMichael Walsh
2268b270ecfSMichael Walsh    return row
2278b270ecfSMichael Walsh
228efa97357SGeorge Keishing
229efa97357SGeorge Keishingdef list_to_set(fru_list=""):
230efa97357SGeorge Keishing    r"""
231efa97357SGeorge Keishing    Pack the list into a set tuple and return.
232efa97357SGeorge Keishing
233efa97357SGeorge Keishing    It may seem that this function is rather trivial. However, it simplifies
234efa97357SGeorge Keishing    the code and improves robot program readability and achieve the result
235efa97357SGeorge Keishing    required.
236efa97357SGeorge Keishing
237efa97357SGeorge Keishing    Example result:
238efa97357SGeorge Keishing
239efa97357SGeorge Keishing    set(['Version', 'PartNumber', 'SerialNumber', 'FieldReplaceable',
240efa97357SGeorge Keishing    'BuildDate', 'Present', 'Manufacturer', 'PrettyName', 'Cached', 'Model'])
241efa97357SGeorge Keishing
242efa97357SGeorge Keishing    # Description of arguments.
243efa97357SGeorge Keishing    fru_list   List of FRU's elements.
244efa97357SGeorge Keishing    """
245efa97357SGeorge Keishing    return set(fru_list)
246efa97357SGeorge Keishing
24781ae45b6SGeorge Keishing
24881ae45b6SGeorge Keishingdef min_list_value(value_list):
24981ae45b6SGeorge Keishing    r"""
25081ae45b6SGeorge Keishing    Returns the element from the list with minimum value.
25181ae45b6SGeorge Keishing    """
25281ae45b6SGeorge Keishing    return min(value_list)
253