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