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    ${cpu_count}=  Get Functional Processor Count
119    ${occ_count}=  Get Active OCC State Count
120    Should Be Equal  ${occ_count}  ${cpu_count}
121    ...  msg=OCC count ${occ_count} and CPU Count ${cpu_count} mismatched.
122
123
124Verify OCC State
125    [Documentation]  Check OCC active state.
126    [Arguments]  ${expected_occ_active}=${1}
127    # Description of Argument(s):
128    # expected_occ_active  The expected occ_active value (i.e. 1/0).
129
130    # Example cpu_list data output:
131    #  /redfish/v1/Systems/system/Processors/cpu0
132    #  /redfish/v1/Systems/system/Processors/cpu1
133
134    ${cpu_list}=  Redfish.Get Members List  /redfish/v1/Systems/system/Processors/  cpu*
135
136    FOR  ${endpoint_path}  IN  @{cpu_list}
137       # {'Health': 'OK', 'State': 'Enabled'} get only matching status good.
138       ${cpu_status}=  Redfish.Get Attribute  ${endpoint_path}  Status
139       Continue For Loop If  '${cpu_status['Health']}' != 'OK' or '${cpu_status['State']}' != 'Enabled'
140       Log To Console  ${cpu_status}
141       ${num}=  Set Variable  ${endpoint_path[-1]}
142       ${occ_active}=  Get OCC Active State  ${num}
143       Should Be Equal  ${occ_active}  ${expected_occ_active}
144       ...  msg=OCC not in right state
145    END
146
147
148Get Sensors Aggregation Data
149    [Documentation]  Return open power sensors aggregation value list.
150    [Arguments]  ${object_base_uri_path}
151
152    # Description of argument(s):
153    # object_base_uri_path  An object path such as one of the elements
154    #                       returned by 'Get Sensors Aggregation URL List'
155    #                       (e.g. "/org/open_power/sensors/aggregation/per_30s/ps0_input_power/average").
156
157    # Example of aggregation [epoch,time] data:
158    # "Values": [
159    #    [
160    #        1517815708479,  <-- EPOCH
161    #        282             <-- Power value in watts
162    #    ],
163    #    [
164    #        1517815678238,
165    #        282
166    #    ],
167    #    [
168    #        1517815648102,
169    #        282
170    #    ],
171    # ],
172
173    ${resp}=  Read Attribute  ${object_base_uri_path}  Values  quiet=${1}
174    ${power_sensors_value_list}=  Create List
175    FOR  ${entry}  IN  @{resp}
176       Append To List  ${power_sensors_value_list}  ${entry[1]}
177    END
178    [Return]  ${power_sensors_value_list}
179
180
181Get Sensors Aggregation URL List
182    [Documentation]  Return the open power aggregation maximum list and the
183    ...  average list URIs.
184    [Arguments]  ${object_base_uri_path}
185
186    # Example of the 2 lists returned by this keyword:
187    # avgs:
188    #   avgs[0]: /org/open_power/sensors/aggregation/per_30s/ps0_input_power/average
189    #   avgs[1]: /org/open_power/sensors/aggregation/per_30s/ps1_input_power/average
190    # maxs:
191    #   maxs[0]: /org/open_power/sensors/aggregation/per_30s/ps1_input_power/maximum
192    #   maxs[1]: /org/open_power/sensors/aggregation/per_30s/ps0_input_power/maximum
193
194    # Description of argument(s):
195    # object_base_uri_path  Object path.
196    #                       base path "/org/open_power/sensors/"
197    #        (e.g. "base path + aggregation/per_30s/ps0_input_power/average")
198
199    # Example of open power sensor aggregation data as returned by the get
200    # request:
201    # /org/open_power/sensors/list
202    # [
203    #    "/org/open_power/sensors/aggregation/per_30s/ps0_input_power/average",
204    #    "/org/open_power/sensors/aggregation/per_30s/ps1_input_power/maximum",
205    #    "/org/open_power/sensors/aggregation/per_30s/ps0_input_power/maximum",
206    #    "/org/open_power/sensors/aggregation/per_30s/ps1_input_power/average"
207    # ]
208
209    ${resp}=  OpenBMC Get Request  ${object_base_uri_path}list  quiet=${1}
210    ${content}=  To JSON  ${resp.content}
211
212    ${power_supply_avg_list}=  Create List
213    ${power_supply_max_list}=  Create List
214
215    FOR  ${entry}  IN  @{content["data"]}
216        Run Keyword If  'average' in '${entry}'  Append To List  ${power_supply_avg_list}  ${entry}
217        Run Keyword If  'maximum' in '${entry}'  Append To List  ${power_supply_max_list}  ${entry}
218    END
219
220    [Return]  ${power_supply_avg_list}  ${power_supply_max_list}
221
222
223REST Verify No Gard Records
224    [Documentation]  Verify no gard records are present.
225
226    ${resp}=  Read Properties  ${OPENPOWER_CONTROL}gard/enumerate
227    Log Dictionary  ${resp}
228    Should Be Empty  ${resp}  msg=Found gard records.
229
230
231Inject OPAL TI
232    [Documentation]  OPAL terminate immediate procedure.
233    [Arguments]      ${stable_branch}=master
234    ...              ${repo_dir_path}=/tmp/repository
235    ...              ${repo_github_url}=https://github.com/open-power/op-test
236
237    # Description of arguments:
238    # stable_branch    Git branch to clone. (default: master)
239    # repo_dir_path    Directory path for repo tool (e.g. "op-test").
240    # repo_github_url  Github URL link (e.g. "https://github.com/open-power/op-test").
241
242    ${value}=  Generate Random String  4  [NUMBERS]
243
244    ${cmd_buf}=  Catenate  git clone --branch ${stable_branch} ${repo_github_url} ${repo_dir_path}/${value}
245    Shell Cmd  ${cmd_buf}
246
247    Open Connection for SCP
248    scp.Put File  ${repo_dir_path}/${value}/test_binaries/deadbeef  /tmp
249    Pdbg  -a putmem 0x300000f8 < /tmp/deadbeef
250
251    # Clean up the repo once done.
252    ${cmd_buf}=  Catenate  rm -rf ${repo_dir_path}${/}${value}
253    Shell Cmd  ${cmd_buf}
254