1#!/usr/bin/env python3 -u
2import sys
3from robot.libraries.BuiltIn import BuiltIn
4import imp
5import string
6import random
7import subprocess
8from robot.utils import DotDict
9
10
11def random_mac():
12    r"""
13    Return random mac address in the following format.
14    Example: 00:01:6C:80:02:78
15    """
16    return ":".join(map(lambda x: "%02x" % x, (random.randint(0x00, 0xff)
17                                               for _ in range(6))))
18
19
20def random_ip():
21    r"""
22    Return random ip address in the following format.
23    Example: 9.3.128.100
24    """
25    return ".".join(map(str, (random.randint(0, 255)
26                              for _ in range(4))))
27
28
29def get_sensor(module_name, value):
30    m = imp.load_source('module.name', module_name)
31
32    for i in m.ID_LOOKUP['SENSOR']:
33
34        if m.ID_LOOKUP['SENSOR'][i] == value:
35            return i
36
37    return 0xFF
38
39
40def get_inventory_sensor(module_name, value):
41    m = imp.load_source('module.name', module_name)
42
43    value = string.replace(value, m.INVENTORY_ROOT, '<inventory_root>')
44
45    for i in m.ID_LOOKUP['SENSOR']:
46
47        if m.ID_LOOKUP['SENSOR'][i] == value:
48            return i
49
50    return 0xFF
51
52
53################################################################
54#  This will return the URI's of the FRU type
55#
56#  i.e.  get_inventory_list('../data/Palmetto.py')
57#
58#  [/org/openbmc/inventory//system/chassis/motherboard/cpu0/core0,
59#   /org/openbmc/inventory/system/chassis/motherboard/dimm0]
60################################################################
61def get_inventory_list(module_name):
62
63    inventory_list = []
64    m = imp.load_source('module.name', module_name)
65
66    for i in m.ID_LOOKUP['FRU']:
67        s = m.ID_LOOKUP['FRU'][i]
68        s = s.replace('<inventory_root>', m.INVENTORY_ROOT)
69        inventory_list.append(s)
70
71    return inventory_list
72
73
74################################################################
75#  This will return the URI's of the FRU type
76#
77#  i.e.  get_inventory_fru_type_list('../data/Witherspoon.py', 'CPU')
78#
79#  [/org/openbmc/inventory//system/chassis/motherboard/cpu0,
80#   /org/openbmc/inventory//system/chassis/motherboard/cpu1]
81################################################################
82def get_inventory_fru_type_list(module_name, fru):
83    inventory_list = []
84    m = imp.load_source('module.name', module_name)
85
86    for i in m.FRU_INSTANCES.keys():
87        if m.FRU_INSTANCES[i]['fru_type'] == fru:
88            s = i.replace('<inventory_root>', m.INVENTORY_ROOT)
89            inventory_list.append(s)
90
91    return inventory_list
92
93
94################################################################
95#  This will return the URI's of the FRU type that contain VPD
96#
97#  i.e.  get_vpd_inventory_list('../data/Palmetto.py', 'DIMM')
98#
99#  [/org/openbmc/inventory/system/chassis/motherboard/dimm0,
100#   /org/openbmc/inventory/system/chassis/motherboard/dimm1]
101################################################################
102def get_vpd_inventory_list(module_name, fru):
103    inventory_list = []
104    m = imp.load_source('module.name', module_name)
105
106    for i in m.ID_LOOKUP['FRU_STR']:
107        x = m.ID_LOOKUP['FRU_STR'][i]
108
109        if m.FRU_INSTANCES[x]['fru_type'] == fru:
110            s = x.replace('<inventory_root>', m.INVENTORY_ROOT)
111            inventory_list.append(s)
112
113    return inventory_list
114
115
116def call_keyword(keyword):
117    return BuiltIn().run_keyword(keyword)
118
119
120def main():
121    print(get_vpd_inventory_list('../data/Palmetto.py', 'DIMM'))
122
123
124if __name__ == "__main__":
125    main()
126
127
128def get_mtr_report(host=""):
129    r"""
130    Get an mtr report and return it as a dictionary of dictionaries.
131
132    The key for the top level dictionary will be the host DNS name.  The key
133    for the next level dictionary will be the field of a given row of the
134    report.
135
136    Example result:
137
138    report:
139      report[host_dummy-dnsname.com]:
140        report[host_dummy-dnsname.com][row_num]:  1
141        report[host_dummy-dnsname.com][host]:     host_dummy-dnsname.com
142        report[host_dummy-dnsname.com][loss]:     0.0
143        report[host_dummy-dnsname.com][snt]:      10
144        report[host_dummy-dnsname.com][last]:     0.2
145        report[host_dummy-dnsname.com][avg]:      3.5
146        report[host_dummy-dnsname.com][best]:     0.2
147        report[host_dummy-dnsname.com][wrst]:     32.5
148        report[host_dummy-dnsname.com][stdev]:    10.2
149      report[bmc-dummy-dnsname.com]:
150        report[bmc-dummy-dnsname.com][row_num]:     2
151        report[bmc-dummy-dnsname.com][host]:        bmc-dummy-dnsname.com
152        report[bmc-dummy-dnsname.com][loss]:        0.0
153        report[bmc-dummy-dnsname.com][snt]:         10
154        report[bmc-dummy-dnsname.com][last]:        0.5
155        report[bmc-dummy-dnsname.com][avg]:         0.5
156        report[bmc-dummy-dnsname.com][best]:        0.5
157        report[bmc-dummy-dnsname.com][wrst]:        0.5
158        report[bmc-dummy-dnsname.com][stdev]:       0.0
159
160    Description of arguments:
161    host   The DNS name or IP address to be passed to the mtr command.
162    """
163
164    # Run the mtr command.  Exclude the header line.  Trim leading space from
165    # each line.  Change all multiple spaces delims to single space delims.
166    cmd_buf = "mtr --report " + host +\
167        " | tail -n +2 | sed -r -e 's/^[ ]+//g' -e 's/[ ]+/ /g'"
168    sub_proc = subprocess.Popen(cmd_buf, shell=True, stdout=subprocess.PIPE,
169                                stderr=subprocess.STDOUT)
170    out_buf, err_buf = sub_proc.communicate()
171    shell_rc = sub_proc.returncode
172
173    # Split the output by line.
174    rows = out_buf.rstrip('\n').split("\n")
175
176    # Initialize report dictionary.
177    report = DotDict()
178    for row in rows:
179        # Process each row of mtr output.
180        # Create a list of fields by splitting on space delimiter.
181        row_list = row.split(" ")
182        # Create dictionary for the row.
183        row = DotDict()
184        row['row_num'] = row_list[0].rstrip('.')
185        row['host'] = row_list[1]
186        row['loss'] = row_list[2].rstrip('%')
187        row['snt'] = row_list[3]
188        row['last'] = row_list[4]
189        row['avg'] = row_list[5]
190        row['best'] = row_list[6]
191        row['wrst'] = row_list[7]
192        row['stdev'] = row_list[8]
193        report[row['host']] = row
194
195    # Return the full report as dictionary of dictionaries.
196    return report
197
198
199def get_mtr_row(host=""):
200    r"""
201    Run an mtr report and get a specified row and return it as a dictionary.
202
203    Example result:
204
205    row:
206      row[row_num]:              2
207      row[host]:                 bmc-dummy-dnsname.com
208      row[loss]:                 0.0
209      row[snt]:                  10
210      row[last]:                 0.5
211      row[avg]:                  0.5
212      row[best]:                 0.4
213      row[wrst]:                 0.7
214      row[stdev]:                0.1
215
216    Description of arguments:
217    host   The DNS name or IP address to be passed to the mtr command as
218           well as the indicating which row of the report to return.
219    """
220
221    report = get_mtr_report(host)
222
223    # The max length of host in output is 28 chars.
224    row = [value for key, value in report.items() if host[0:28] in key][0]
225
226    return row
227
228
229def list_to_set(fru_list=""):
230    r"""
231    Pack the list into a set tuple and return.
232
233    It may seem that this function is rather trivial. However, it simplifies
234    the code and improves robot program readability and achieve the result
235    required.
236
237    Example result:
238
239    set(['Version', 'PartNumber', 'SerialNumber', 'FieldReplaceable',
240    'BuildDate', 'Present', 'Manufacturer', 'PrettyName', 'Cached', 'Model'])
241
242    # Description of arguments.
243    fru_list   List of FRU's elements.
244    """
245    return set(fru_list)
246
247
248def min_list_value(value_list):
249    r"""
250    Returns the element from the list with minimum value.
251    """
252    return min(value_list)
253