xref: /openbmc/openbmc-test-automation/docs/redfish_coding_guidelines.md (revision c17b98729fa0f26a4b9bf0753c14772936007525)
112e33526SPatrick Williams# Redfish Coding Guidelines
2e9619fdeSMichael Walsh
3e9619fdeSMichael Walsh- For robot programs wishing to run Redfish commands, include the following in
4e9619fdeSMichael Walsh  your robot file:
5e9619fdeSMichael Walsh
6e9619fdeSMichael Walsh  ```
7e9619fdeSMichael Walsh  *** Settings ***
8e9619fdeSMichael Walsh
9e9619fdeSMichael Walsh  Resource                    bmc_redfish_resource.robot
10e9619fdeSMichael Walsh  ```
1112e33526SPatrick Williams
12e9619fdeSMichael Walsh- This git repository has some redfish wrapper modules:
13e9619fdeSMichael Walsh
14e9619fdeSMichael Walsh  - [redfish_plus.py](../lib/redfish_plus.py)
15e9619fdeSMichael Walsh  - [bmc_redfish.py](../lib/bmc_redfish.py)
16e9619fdeSMichael Walsh  - [bmc_redfish_utils.py](../lib/bmc_redfish_utils.py)
17e9619fdeSMichael Walsh  - Redfish wrapper module features:
18e9619fdeSMichael Walsh
19e9619fdeSMichael Walsh    For all Redfish REST requests (get, head, post, put, patch, delete):
20e9619fdeSMichael Walsh
2112e33526SPatrick Williams    - Support for python-like strings for all arguments which allows callers to
2212e33526SPatrick Williams      easily specify complex arguments such as lists or dictionaries.
23e9619fdeSMichael Walsh
24e9619fdeSMichael Walsh      So instead of coding this:
25e9619fdeSMichael Walsh
26e9619fdeSMichael Walsh      ```
27e9619fdeSMichael Walsh          ${ldap_type_dict}=  Create Dictionary  ServiceEnabled=${False}
28e9619fdeSMichael Walsh          ${body}=  Create Dictionary  ${LDAP_TYPE}=${ldap_type_dict}
29e9619fdeSMichael Walsh          Redfish.Patch  ${REDFISH_BASE_URI}AccountService  body=${body}
30e9619fdeSMichael Walsh      ```
31e9619fdeSMichael Walsh
32e9619fdeSMichael Walsh      You can do it in one fell swoop like this:
33e9619fdeSMichael Walsh
34e9619fdeSMichael Walsh      ```
35e9619fdeSMichael Walsh          Redfish.Patch  ${REDFISH_BASE_URI}AccountService  body={'${LDAP_TYPE}': {'ServiceEnabled': ${False}}}
36e9619fdeSMichael Walsh      ```
3712e33526SPatrick Williams
38e9619fdeSMichael Walsh    - Support for **valid_status_codes** argument and auto-failure:
39e9619fdeSMichael Walsh
4012e33526SPatrick Williams      As mentioned above, this argument may be either an actual robot/python
4112e33526SPatrick Williams      list or it may be a string value which python can translate into a list.
42e9619fdeSMichael Walsh
43e9619fdeSMichael Walsh      The default value is [${HTTP_OK}].
44e9619fdeSMichael Walsh
4512e33526SPatrick Williams      This means that the Redfish REST request will fail **automatically** if
4612e33526SPatrick Williams      the resulting status code is not found in the valid_status_codes list.
47e9619fdeSMichael Walsh
48e9619fdeSMichael Walsh      So instead of having to do this:
49e9619fdeSMichael Walsh
50e9619fdeSMichael Walsh      ```
51e9619fdeSMichael Walsh          ${resp}=  Redfish.Get  ${EVENT_LOG_URI}Entries
52e9619fdeSMichael Walsh          Should Be Equal As Strings  ${resp.status_code}  ${HTTP_OK}
53e9619fdeSMichael Walsh      ```
54e9619fdeSMichael Walsh
55e9619fdeSMichael Walsh      You can simply do this:
56e9619fdeSMichael Walsh
57e9619fdeSMichael Walsh      ```
58e9619fdeSMichael Walsh          ${resp}=  Redfish.Get  ${EVENT_LOG_URI}Entries
59e9619fdeSMichael Walsh      ```
60e9619fdeSMichael Walsh
6112e33526SPatrick Williams      If, for some reason, you **expect** your command to fail, you can specify
6212e33526SPatrick Williams      the expected status code or codes:
63e9619fdeSMichael Walsh
64e9619fdeSMichael Walsh      ```
65e9619fdeSMichael Walsh      Redfish.Patch  ${REDFISH_BASE_URI}UpdateService  body={'ApplyTime' : 'Invalid'}  valid_status_codes=[${HTTP_BAD_REQUEST}]
66e9619fdeSMichael Walsh      ```
6712e33526SPatrick Williams
68*c17b9872SPatrick Williams  - Login defaults for path, username and password are
69*c17b9872SPatrick Williams    https://${OPENBMC_HOST},
7012e33526SPatrick Williams    ${OPENBMC_USERNAME}, ${OPENBMC_PASSWORD}.
71e9619fdeSMichael Walsh  - Many utility functions are available. Examples:;
72e9619fdeSMichael Walsh
73e9619fdeSMichael Walsh    - get_properties
74e9619fdeSMichael Walsh    - get_attributes
75e9619fdeSMichael Walsh    - get_session_info
76e9619fdeSMichael Walsh    - list_request
77e9619fdeSMichael Walsh    - enumerate_request
78e9619fdeSMichael Walsh
7912e33526SPatrick Williams# Rules for use of Redfish.Login and Redfish.Logout
80e9619fdeSMichael Walsh
81e9619fdeSMichael WalshIt is desirable to avoid excessive redfish logins/logouts for the following
82e9619fdeSMichael Walshreasons:
8312e33526SPatrick Williams
84e9619fdeSMichael Walsh- It simplifies the code base.
8512e33526SPatrick Williams- It allows calling keywords and testcases to keep control over login parameters
8612e33526SPatrick Williams  like USERNAME, PASSWORD, etc. Consider the following example:
87e9619fdeSMichael Walsh
88e9619fdeSMichael Walsh  ```
89e9619fdeSMichael Walsh  # Login to redfish with non-standard username/password.
90e9619fdeSMichael Walsh  Redfish.Login  ${LDAP_USER}  ${LDAP_USER_PASSWORD}
91e9619fdeSMichael Walsh  # Run 'Some Keyword' while logged in as ${LDAP_USER}/${LDAP_USER_PASSWORD}.
92e9619fdeSMichael Walsh  Some Keyword
93e9619fdeSMichael Walsh  ```
9412e33526SPatrick Williams
95e9619fdeSMichael Walsh  If 'Some Keyword' in the example above does its own Redfish.Login, it will
96e9619fdeSMichael Walsh  thwart the stated purpose of the caller.
97e9619fdeSMichael Walsh
98e9619fdeSMichael Walsh**Rules:**
99e9619fdeSMichael Walsh
100e9619fdeSMichael Walsh- Login should be done once in Suite Setup:
101e9619fdeSMichael Walsh
102e9619fdeSMichael Walsh  ```
103e9619fdeSMichael Walsh  *** Keywords ***
104e9619fdeSMichael Walsh  Suite Setup Execution
105e9619fdeSMichael Walsh      Redfish.Login
106e9619fdeSMichael Walsh  ```
10712e33526SPatrick Williams
108e9619fdeSMichael Walsh- Logout should be done once in Suite Teardown:
109e9619fdeSMichael Walsh  ```
110e9619fdeSMichael Walsh  *** Keywords ***
111e9619fdeSMichael Walsh  Suite Teardown Execution
112e9619fdeSMichael Walsh      Redfish.Logout
113e9619fdeSMichael Walsh  ```
11412e33526SPatrick Williams- As a result of the first two rules, all keywords and testcases that call upon
11512e33526SPatrick Williams  redfish functions (e.g. Redfish.Get, Redfish.Patch, etc.) have a right to
11612e33526SPatrick Williams  expect that login/logout have already been handled. Therefore, such keywords
11712e33526SPatrick Williams  and testcases should NOT do logins and logouts themselves.
118e9619fdeSMichael Walsh- There may be exceptions to the above but they require justification (e.g. a
119e9619fdeSMichael Walsh  test whose purpose is to verify that it can login with an **alternate**
120e9619fdeSMichael Walsh  username, etc.).
121e9619fdeSMichael Walsh- Any keyword or test case which breaks the above rules is responsible for
122e9619fdeSMichael Walsh  setting things right (i.e. back to a logged in state).
123d7fb41d2SMichael Walsh
12412e33526SPatrick Williams# Rules for use of data/variables.py
125d7fb41d2SMichael Walsh
126d7fb41d2SMichael WalshAvoid defining variables in data/variables.py for Redfish URIs.
127d7fb41d2SMichael Walsh
12812e33526SPatrick WilliamsThere's no obvious benefit to using such variables. Conversely, with literal
12912e33526SPatrick Williamsvalues, it is much easier for the programmer to interpret the code.
130d7fb41d2SMichael Walsh
131d7fb41d2SMichael WalshConsider the following example.
132d7fb41d2SMichael Walsh
133d7fb41d2SMichael WalshHere's an excerpt from data/variables.py:
134d7fb41d2SMichael Walsh
135d7fb41d2SMichael Walsh```
136d7fb41d2SMichael Walsh# Redfish variables.
137d7fb41d2SMichael WalshREDFISH_BASE_URI = '/redfish/v1/'
138d7fb41d2SMichael Walsh...
139d7fb41d2SMichael WalshREDFISH_ACCOUNTS = 'AccountService/Accounts/'
140d7fb41d2SMichael WalshREDFISH_ACCOUNTS_URI = REDFISH_BASE_URI + REDFISH_ACCOUNTS
141d7fb41d2SMichael Walsh```
142d7fb41d2SMichael Walsh
143d7fb41d2SMichael WalshAnd here is a corresponding Robot code example:
144d7fb41d2SMichael Walsh
145d7fb41d2SMichael Walsh```
146d7fb41d2SMichael Walsh    # Rather than coding this:
147d7fb41d2SMichael Walsh    Redfish.Delete  ${REDFISH_ACCOUNTS_URI}user_user
148d7fb41d2SMichael Walsh
149d7fb41d2SMichael Walsh    # Code this:
150d7fb41d2SMichael Walsh    Redfish.Delete  /redfish/v1/AccountService/Accounts/user_user
151d7fb41d2SMichael Walsh```
152