1*** Settings ***
2Documentation  Open power domain keywords.
3
4Variables      ../data/variables.py
5Resource       ../lib/utils.robot
6Resource       ../lib/connection_client.robot
7
8*** Variables ***
9${functional_cpu_count}       ${0}
10${active_occ_count}           ${0}
11
12*** Keywords ***
13
14Get OCC Objects
15    [Documentation]  Get the OCC objects and return as a list.
16
17    # Example:
18    # {
19    #     "/org/open_power/control/occ0": {
20    #          "OccActive": 0
21    # },
22    #     "/org/open_power/control/occ1": {
23    #          "OccActive": 1
24    # }
25
26    ${occ_list}=  Get Endpoint Paths  ${OPENPOWER_CONTROL}  occ*
27
28    [Return]  ${occ_list}
29
30
31Get OCC Active State
32    [Documentation]  Get the OCC "OccActive" and return the attribute value.
33    [Arguments]  ${value}
34
35    # Description of argument(s):
36    # value       CPU position (e.g. "0, 1, 2").
37
38    ${cmd}=  Catenate  busctl get-property org.open_power.OCC.Control
39    ...   /org/open_power/control/occ${value} org.open_power.OCC.Status OccActive
40
41    ${cmd_output}  ${stderr}  ${rc} =  BMC Execute Command  ${cmd}
42    ...  print_out=1  print_err=1  ignore_err=1
43
44    # The command returns format  'b true'
45    Return From Keyword If  '${cmd_output.split(' ')[-1]}' == 'true'  ${1}
46
47    [Return]  ${0}
48
49
50Count Object Entries
51    [Documentation]  Count the occurrence number of a given object.
52    [Arguments]  ${object_base_uri_path}  ${object_name}
53
54    # Description of argument(s):
55    # object_base_uri_path    Object base path
56    #                         (e.g. "/org/open_power/control/").
57    # object_name             Object name (e.g. "occ", "cpu" etc).
58
59    ${object_list}=  Get Endpoint Paths
60    ...  ${object_base_uri_path}  ${object_name}
61    ${list_count}=  Get Length  ${object_list}
62    [Return]  ${list_count}
63
64
65Read Object Attribute
66    [Documentation]  Return object attribute data.
67    [Arguments]  ${object_base_uri_path}  ${attribute_name}
68
69    # Description of argument(s):
70    # object_base_uri_path       Object path.
71    #                   (e.g. "/org/open_power/control/occ0").
72    # attribute_name    Object attribute name.
73
74    ${resp}=  OpenBMC Get Request
75    ...  ${object_base_uri_path}/attr/${attribute_name}  quiet=${1}
76    Return From Keyword If  ${resp.status_code} != ${HTTP_OK}
77    ${content}=  To JSON  ${resp.content}
78    [Return]  ${content["data"]}
79
80
81Get Functional Processor Count
82    [Documentation]  Get functional processor count.
83
84    ${cpu_list}=  Redfish.Get Members List  /redfish/v1/Systems/system/Processors/  *cpu*
85
86    FOR  ${endpoint_path}  IN  @{cpu_list}
87       # {'Health': 'OK', 'State': 'Enabled'} get only matching status good.
88       ${cpu_status}=  Redfish.Get Attribute  ${endpoint_path}  Status
89       Continue For Loop If  '${cpu_status['Health']}' != 'OK' or '${cpu_status['State']}' != 'Enabled'
90       ${functional_cpu_count} =  Evaluate   ${functional_cpu_count} + 1
91    END
92
93    [Return]  ${functional_cpu_count}
94
95
96Get Active OCC State Count
97    [Documentation]  Get active OCC state count.
98
99    ${cpu_list}=  Redfish.Get Members List  /redfish/v1/Systems/system/Processors/  *cpu*
100
101    FOR  ${endpoint_path}  IN  @{cpu_list}
102       ${num}=  Set Variable  ${endpoint_path[-1]}
103       ${cmd}=  Catenate  busctl get-property org.open_power.OCC.Control
104       ...   /org/open_power/control/occ${num} org.open_power.OCC.Status OccActive
105
106       ${cmd_output}  ${stderr}  ${rc} =  BMC Execute Command  ${cmd}
107       ...  print_out=1  print_err=1  ignore_err=1
108
109       # The command returns format  'b true'
110       Continue For Loop If   '${cmd_output.split(' ')[-1]}' != 'true'
111       ${active_occ_count} =  Evaluate   ${active_occ_count} + 1
112    END
113
114    [Return]  ${active_occ_count}
115
116
117Match OCC And CPU State Count
118    [Documentation]  Get CPU functional count and verify OCC count active matches.
119
120    ${cpu_count}=  Get Functional Processor Count
121    Log To Console  Functional Processor count: ${cpu_count}
122
123    FOR  ${num}  IN RANGE  ${0}  ${cpu_count}
124       ${cmd}=  Catenate  busctl get-property org.open_power.OCC.Control
125       ...   /org/open_power/control/occ${num} org.open_power.OCC.Status OccActive
126
127       ${cmd_output}  ${stderr}  ${rc} =  BMC Execute Command  ${cmd}
128       ...  print_out=1  print_err=1  ignore_err=1
129
130       # The command returns format  'b true'
131       Continue For Loop If   '${cmd_output.split(' ')[-1]}' != 'true'
132       ${active_occ_count} =  Evaluate   ${active_occ_count} + 1
133    END
134
135    Log To Console  OCC Active count: ${active_occ_count}
136
137    Should Be Equal  ${active_occ_count}  ${cpu_count}
138    ...  msg=OCC count ${active_occ_count} and CPU Count ${cpu_count} mismatched.
139
140
141Verify OCC State
142    [Documentation]  Check OCC active state.
143    [Arguments]  ${expected_occ_active}=${1}
144    # Description of Argument(s):
145    # expected_occ_active  The expected occ_active value (i.e. 1/0).
146
147    # Example cpu_list data output:
148    #  /redfish/v1/Systems/system/Processors/cpu0
149    #  /redfish/v1/Systems/system/Processors/cpu1
150
151    ${cpu_list}=  Redfish.Get Members List  /redfish/v1/Systems/system/Processors/  cpu*
152
153    FOR  ${endpoint_path}  IN  @{cpu_list}
154       # {'Health': 'OK', 'State': 'Enabled'} get only matching status good.
155       ${cpu_status}=  Redfish.Get Attribute  ${endpoint_path}  Status
156       Continue For Loop If  '${cpu_status['Health']}' != 'OK' or '${cpu_status['State']}' != 'Enabled'
157       Log To Console  ${cpu_status}
158       ${num}=  Set Variable  ${endpoint_path[-1]}
159       ${occ_active}=  Get OCC Active State  ${num}
160       Should Be Equal  ${occ_active}  ${expected_occ_active}
161       ...  msg=OCC not in right state
162    END
163
164
165Get Sensors Aggregation Data
166    [Documentation]  Return open power sensors aggregation value list.
167    [Arguments]  ${object_base_uri_path}
168
169    # Description of argument(s):
170    # object_base_uri_path  An object path such as one of the elements
171    #                       returned by 'Get Sensors Aggregation URL List'
172    #                       (e.g. "/org/open_power/sensors/aggregation/per_30s/ps0_input_power/average").
173
174    # Example of aggregation [epoch,time] data:
175    # "Values": [
176    #    [
177    #        1517815708479,  <-- EPOCH
178    #        282             <-- Power value in watts
179    #    ],
180    #    [
181    #        1517815678238,
182    #        282
183    #    ],
184    #    [
185    #        1517815648102,
186    #        282
187    #    ],
188    # ],
189
190    ${resp}=  Read Attribute  ${object_base_uri_path}  Values  quiet=${1}
191    ${power_sensors_value_list}=  Create List
192    FOR  ${entry}  IN  @{resp}
193       Append To List  ${power_sensors_value_list}  ${entry[1]}
194    END
195    [Return]  ${power_sensors_value_list}
196
197
198Get Sensors Aggregation URL List
199    [Documentation]  Return the open power aggregation maximum list and the
200    ...  average list URIs.
201    [Arguments]  ${object_base_uri_path}
202
203    # Example of the 2 lists returned by this keyword:
204    # avgs:
205    #   avgs[0]: /org/open_power/sensors/aggregation/per_30s/ps0_input_power/average
206    #   avgs[1]: /org/open_power/sensors/aggregation/per_30s/ps1_input_power/average
207    # maxs:
208    #   maxs[0]: /org/open_power/sensors/aggregation/per_30s/ps1_input_power/maximum
209    #   maxs[1]: /org/open_power/sensors/aggregation/per_30s/ps0_input_power/maximum
210
211    # Description of argument(s):
212    # object_base_uri_path  Object path.
213    #                       base path "/org/open_power/sensors/"
214    #        (e.g. "base path + aggregation/per_30s/ps0_input_power/average")
215
216    # Example of open power sensor aggregation data as returned by the get
217    # request:
218    # /org/open_power/sensors/list
219    # [
220    #    "/org/open_power/sensors/aggregation/per_30s/ps0_input_power/average",
221    #    "/org/open_power/sensors/aggregation/per_30s/ps1_input_power/maximum",
222    #    "/org/open_power/sensors/aggregation/per_30s/ps0_input_power/maximum",
223    #    "/org/open_power/sensors/aggregation/per_30s/ps1_input_power/average"
224    # ]
225
226    ${resp}=  OpenBMC Get Request  ${object_base_uri_path}list  quiet=${1}
227    ${content}=  To JSON  ${resp.content}
228
229    ${power_supply_avg_list}=  Create List
230    ${power_supply_max_list}=  Create List
231
232    FOR  ${entry}  IN  @{content["data"]}
233        Run Keyword If  'average' in '${entry}'  Append To List  ${power_supply_avg_list}  ${entry}
234        Run Keyword If  'maximum' in '${entry}'  Append To List  ${power_supply_max_list}  ${entry}
235    END
236
237    [Return]  ${power_supply_avg_list}  ${power_supply_max_list}
238
239
240REST Verify No Gard Records
241    [Documentation]  Verify no gard records are present.
242
243    ${resp}=  Read Properties  ${OPENPOWER_CONTROL}gard/enumerate
244    Log Dictionary  ${resp}
245    Should Be Empty  ${resp}  msg=Found gard records.
246
247
248Inject OPAL TI
249    [Documentation]  OPAL terminate immediate procedure.
250    [Arguments]      ${stable_branch}=master
251    ...              ${repo_dir_path}=/tmp/repository
252    ...              ${repo_github_url}=https://github.com/open-power/op-test
253
254    # Description of arguments:
255    # stable_branch    Git branch to clone. (default: master)
256    # repo_dir_path    Directory path for repo tool (e.g. "op-test").
257    # repo_github_url  Github URL link (e.g. "https://github.com/open-power/op-test").
258
259    ${value}=  Generate Random String  4  [NUMBERS]
260
261    ${cmd_buf}=  Catenate  git clone --branch ${stable_branch} ${repo_github_url} ${repo_dir_path}/${value}
262    Shell Cmd  ${cmd_buf}
263
264    Open Connection for SCP
265    scp.Put File  ${repo_dir_path}/${value}/test_binaries/deadbeef  /tmp
266    Pdbg  -a putmem 0x300000f8 < /tmp/deadbeef
267
268    # Clean up the repo once done.
269    ${cmd_buf}=  Catenate  rm -rf ${repo_dir_path}${/}${value}
270    Shell Cmd  ${cmd_buf}
271