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