1*** Settings ***
2Documentation   This suite tests System Vital Product Data (VPD) using vpdtool.
3
4Library         ../../lib/vpd_utils.py
5Variables       ../../data/vpd_variables.py
6Resource        ../../lib/openbmc_ffdc.robot
7
8Test Teardown   FFDC On Test Case Fail
9
10Test Tags      VPD_Tool
11
12*** Variables ***
13
14${CMD_GET_PROPERTY_INVENTORY}  busctl get-property xyz.openbmc_project.Inventory.Manager
15${DR_WRITE_VALUE}              XYZ Component
16${PN_WRITE_VALUE}              XYZ1234
17${SN_WRITE_VALUE}              ABCD12345678
18@{fields}                      PN  SN  LocationCode
19@{vpd_fields}                  PN  SN
20
21*** Test Cases ***
22
23Verify System VPD Data Via Vpdtool
24    [Documentation]  Verify the system VPD details via vpdtool output.
25    [Tags]  Verify_System_VPD_Data_Via_Vpdtool
26    [Template]  Verify VPD Data Via Vpdtool
27
28    # Component     Field
29    System          Model
30    System          SerialNumber
31    System          LocationCode
32
33
34Verify VPD Component Read
35    [Documentation]  Verify details of all VPD component via vpdtool.
36    [Tags]  Verify_VPD_Component_Read
37
38    ${vpd_records}=  Vpdtool  -i
39    ${components}=  Get Dictionary Keys  ${vpd_records}
40    FOR  ${component}  IN  @{components}
41        Verify VPD Component Read Operation  ${component}
42    END
43
44
45Verify VPD Field Read
46    [Documentation]  Verify reading VPD field value via vpdtool.
47    [Tags]  Verify_VPD_Field_Read
48
49    ${vpd_records}=  Vpdtool  -i
50    ${components}=  Get Dictionary Keys  ${vpd_records}
51    FOR  ${component}  IN  @{components}
52       # Drive component field values response in ascii format
53       # due to that skipping here.
54       IF  'drive' in '${component}'
55           Continue FOR Loop
56       ELSE
57           Verify VPD Field Read Operation  ${component}
58       END
59    END
60
61
62Verify VPD Field Write
63    [Documentation]  Verify writing VPD field value via vpdtool.
64    [Tags]  Verify_VPD_Field_Write
65
66    ${components}=  Get Dictionary Keys  ${VPD_DETAILS}
67    FOR  ${component}  IN  @{components}
68        # VPD fields "DR", "CC" and "FN" will be added later.
69        @{vpd_fields}=  Create List  SN  PN
70        ${field}=  Evaluate  random.choice($vpd_fields)  random
71        Verify VPD Field Write Operation  ${component}  ${field}
72    END
73
74
75*** Keywords ***
76
77Verify VPD Component Read Operation
78    [Documentation]  Verify reading VPD details of given component via vpdtool.
79    [Arguments]  ${component}
80    # Description of arguments:
81    # component       VDP component (e.g. /system/chassis/motherboard/vdd_vrm1).
82
83    ${vpd_records}=  Vpdtool  -o -O ${component}
84
85    # Example output from 'Vpdtool  -o -O /system/chassis/motherboard/vdd_vrm1':
86    #  [/system/chassis/motherboard/vdd_vrm1]:
87    #    [DR]:                                         CPU POWER CARD
88    #    [type]:                                       xyz.openbmc_project.Inventory.Item.Vrm
89    #    [CC]:                                         E123
90    #    [FN]:                                         F123456
91    #    [LocationCode]:                               ABCD.XY1.1234567-P0
92    #    [SN]:                                         YL2E32010000
93    #    [PN]:                                         PN12345
94
95    ${vpdtool_res}=  Set To Dictionary  ${vpd_records}[${component}]
96    FOR  ${vpd_field}  IN  @{fields}
97        ${match_key_exists}=  Run Keyword And Return Status
98        ...  Dictionary Should Contain Key  ${vpdtool_res}  ${vpd_field}
99          IF  '${match_key_exists}' == 'True'
100              #  drive components busctl field response in ascii due to that checking only locationcode.
101              IF  'drive' in '${component}'
102                  ${vpd_field}=  Set Variable  LocationCode
103              END
104              # Skip check if VPD field is empty.
105              Run Keyword If  '${vpd_records['${component}']['${vpd_field}']}' == ''
106              ...  Continue For Loop
107
108              # Get VPD field values via busctl.
109              ${busctl_field}=  Set Variable If
110              ...  '${vpd_field}' == 'LocationCode'  com.ibm.ipzvpd.Location LocationCode
111              ...  '${vpd_field}' == 'PN'  xyz.openbmc_project.Inventory.Decorator.Asset PartNumber
112              ...  '${vpd_field}' == 'SN'  xyz.openbmc_project.Inventory.Decorator.Asset SerialNumber
113              ${cmd}=  Catenate  ${CMD_GET_PROPERTY_INVENTORY}
114              ...  /xyz/openbmc_project/inventory${component} ${busctl_field}
115              ${cmd_output}=  BMC Execute Command  ${cmd}
116              # Check whether the vpdtool response and busctl response matching.
117              Valid Value  vpd_records['${component}']['${vpd_field}']
118              ...  ['${cmd_output[0].split('"')[1].strip('"')}']
119          ELSE
120             Continue For Loop
121          END
122    END
123
124
125Verify VPD Field Read Operation
126    [Documentation]  Verify reading all VPD fields for given component via vpdtool.
127    [Arguments]  ${component}
128    # Description of arguments:
129    # component       VDP component (e.g. /system/chassis/motherboard/vdd_vrm1).
130
131    ${vpd_records}=  Vpdtool  -o -O ${component}
132    ${vpdtool_res}=  Set To Dictionary  ${vpd_records}[${component}]
133    FOR  ${field}  IN  @{vpd_fields}
134         ${match_key_exists}=  Run Keyword And Return Status
135         ...  Dictionary Should Contain Key  ${vpdtool_res}  ${field}
136         IF  '${match_key_exists}' == 'True'
137             ${vpd_records}=  Vpdtool  -r -O ${component} -R VINI -K ${field}
138             # Skip check if field value is empty.
139             Run Keyword If  '${vpd_records['${component}']['${field}']}' == ''
140             ...  Continue For Loop
141
142             ${busctl_field}=  Set Variable If
143             ...  '${field}' == 'PN'  xyz.openbmc_project.Inventory.Decorator.Asset PartNumber
144             ...  '${field}' == 'SN'  xyz.openbmc_project.Inventory.Decorator.Asset SerialNumber
145             ${cmd}=  Catenate  ${CMD_GET_PROPERTY_INVENTORY}
146             ...  /xyz/openbmc_project/inventory${component} ${busctl_field}
147             ${cmd_output}=  BMC Execute Command  ${cmd}
148
149             # Check vpdtool response and busctl response for the component field.
150             Valid Value  vpd_records['${component}']['${field}']
151             ...  ['${cmd_output[0].split('"')[1].strip('"')}']
152         ELSE
153            Continue For Loop
154         END
155    END
156
157
158Verify VPD Field Write Operation
159    [Documentation]  Verify writing VPD fields for given component via vpdtool.
160    [Arguments]  ${component}  ${field}
161    [Teardown]  Restore VPD Value  ${component}  ${field}  ${old_field_value}
162    # Description of arguments:
163    # component       VPD component (e.g. /system/chassis/motherboard/vdd_vrm1).
164    # field           VPD component field (e.g. PN, SN)
165
166    ${vpd_records}=  Vpdtool  -r -O ${component} -R VINI -K ${field}
167    ${old_field_value}=  Set Variable  ${vpd_records['${component}']['${field}']}
168
169    ${write_value}=  Set Variable If
170    ...  '${field}' == 'DR'  ${DR_WRITE_VALUE}
171    ...  '${field}' == 'PN'  ${PN_WRITE_VALUE}
172    ...  '${field}' == 'SN'  ${SN_WRITE_VALUE}
173
174    Vpdtool  -w -O ${component} -R VINI -K ${field} --value ${write_value}
175
176    Verify VPD Field Value  ${component}  ${field}
177
178
179Restore VPD Value
180    [Documentation]  Restore VPD's field value of given component.
181    [Arguments]  ${component}  ${field}  ${value}
182    # Description of arguments:
183    # component       VPD component (e.g. /system/chassis/motherboard/vdd_vrm1).
184    # field           VPD component field (e.g. PN, SN)
185    # value           VPD value to be restore.
186
187    Vpdtool  -w -O ${component} -R VINI -K ${field} --value ${value}
188
189
190Verify VPD Field Value
191    [Documentation]  Verify VPD field value via vpdtool.
192    [Arguments]  ${component}  ${field}
193    # Description of arguments:
194    # component       VDP component (e.g. /system/chassis/motherboard/vdd_vrm1).
195    # field           VPD field (e.g. DR, SN, PN)
196
197    ${vpd_records}=  Vpdtool  -r -O ${component} -R VINI -K ${field}
198
199    ${busctl_field}=  Set Variable If
200    ...  '${field}' == 'DR'  xyz.openbmc_project.Inventory.Item PrettyName
201    ...  '${field}' == 'PN'  xyz.openbmc_project.Inventory.Decorator.Asset PartNumber
202    ...  '${field}' == 'SN'  xyz.openbmc_project.Inventory.Decorator.Asset SerialNumber
203
204    ${cmd}=  Catenate  ${CMD_GET_PROPERTY_INVENTORY} /xyz/openbmc_project/inventory${component}
205    ...  ${busctl_field}
206    ${cmd_output}=  BMC Execute Command  ${cmd}
207
208    Valid Value  vpd_records['${component}']['${field}']  ['${cmd_output[0].split('"')[1].strip('"')}']
209
210
211Verify VPD Data Via Vpdtool
212    [Documentation]  Get VPD details of given component via vpdtool and verify it
213    ...              using busctl command.
214    [Arguments]  ${component}  ${field}
215    # Description of arguments:
216    # component       VPD component (e.g. System,Chassis etc).
217    # field           VPD field (e.g. Serialnumber,LocationCode etc).
218
219    ${component_url}=  Run Keyword If
220    ...  '${component}' == 'System'  Set Variable  /system
221
222    # Get VPD details of given component via vpd-tool.
223    ${vpd_records}=  Vpdtool  -o -O ${component_url}
224
225    # Get VPD details of given component via busctl command.
226    ${busctl_field}=  Set Variable If
227    ...  '${field}' == 'LocationCode'  com.ibm.ipzvpd.Location LocationCode
228    ...  '${field}' == 'Model'  xyz.openbmc_project.Inventory.Decorator.Asset Model
229    ...  '${field}' == 'SerialNumber'  xyz.openbmc_project.Inventory.Decorator.Asset SerialNumber
230
231    ${cmd}=  Catenate  ${CMD_GET_PROPERTY_INVENTORY} /xyz/openbmc_project/inventory/system
232    ...  ${busctl_field}
233    ${cmd_output}=  BMC Execute Command  ${cmd}
234    # Example of cmd_output:
235    #   [0]:                                            s "ABCD.XY1.1234567-P0"
236    #   [1]:
237    #   [2]:                                            0
238
239    # Cross check vpdtool output with busctl response.
240    Should Be Equal As Strings  ${vpd_records["/system"]["${field}"]}
241    ...  ${cmd_output[0].split('"')[1].strip('"')}
242