1Contributing to OpenBMC Test Automation
2=======================================
3Guide to working on OpenBMC test automation. This document will always be a
4work-in-progress, feel free to propose changes.
5
6Submitting changes via Gerrit server
7------------------------------------
8-   Reference [OpenBMC docs](https://github.com/openbmc/docs/blob/master/contributing.md#submitting-changes-via-gerrit-server)
9
10Robot Coding Guidelines
11-----------------------
12-   For this project, we will write Robot keyword definitions in either Robot
13    or Python.  Robot code should be quite simple.  Therefore, if the algorithm
14    in question is the least bit complex, please write it in Python.
15-   Observe a maximum line length of 79 characters.
16-   Avoid trailing space at the end of any line of Robot code.
17-   Avoid the use of tabs.
18-   Robot supports delimiting cells with either two or more spaces or with a
19    pipe symbol (e.g. "\|"). Our team has chosen to use spaces rather than the
20    pipe character. Make sure all space delimiters in Robot code are the
21    **minimum** of two spaces. There may be some exceptions to this rule.
22
23    Exceptions to two-space delimiter rule:
24    - When you wish to line up resource, library or variable values:
25      ```
26      Library         Lib1
27      Resource        Resource1
28      *** Variables ***
29      ${var1}         ${EMPTY}
30      ```
31    - When you wish to line up fields for test templates:
32      ```
33      [Template]  Set System LED State
34      # LED Name  LED State
35      power       On
36      power       Off
37      ```
38    - When you wish to indent if/else or loop bodies for visual effect:
39      ```
40      Run Keyword If  '${this}' == '${that}'
41      ...    Log  Bla, bla...
42      ...  ELSE
43      ...    Run Keywords  Key1  parms
44      ...    AND  Key2  parms
45      ```
46-   When you define or call a Robot keyword, Robot pays no attention to spaces,
47    underscores or case.  However, our team will observe the following
48    conventions in both our definitions and our calls:
49    - Separate words with single spaces.
50    - Capitalize the first character of each word.
51    - Capitalize all characters in any word that is an acronym (e.g. JSON, BMC,
52      etc).
53
54    Examples:
55    ```
56    *** Keywords ***
57
58    This Is Correct
59
60        # This keyword name is correct.
61
62    this_is_incorrect
63
64        # This keyword name is incorrect because of 1) the
65        # underscores instead of spaces and 2) the failure to
66        # capitalize each word in the keyword.
67
68    soisthis
69
70        # This keyword name is incorrect because of 1) a failure to
71        # separate words with spaces and 2) a failure to capitalize
72        # each word in the keyword.
73
74    BMC Is An Acronym
75
76        # This keyword name is correct.  Note that "BMC" is an
77        # acronym and as such is entirely uppercase.
78    ```
79-   Documentation strings:
80    -  Each documentation string should be phrased as an **English command**.
81       Punctuate it correctly with the first word capitalized and a period at
82       the end.
83
84       Correct example:
85        ```
86        Boot BMC
87            [Documentation]  Boot the BMC.
88        ```
89        Incorrect example:
90        ```
91        Boot BMC
92            [Documentation]  This keyword boots the BMC.
93
94            # The doc string above is not phrased as a command.
95        ```
96    -   Doc strings should be just one terse, descriptive sentence.
97        Remember that this doc string shows up in the HTML log file.  Put
98        additional commentary below in standard comment lines.
99
100        Correct example:
101        ```
102        Stop SOL Console Logging
103
104            [Documentation]  Stop system console logging and return log output.
105        ```
106        Incorrect example:
107        ```
108        Stop SOL Console Logging
109
110            [Documentation]  Stop system console logging.  If there are multiple
111            ...              system console processes, they will all be
112            ...              stopped.  If there is no existing log file this
113            ...              keyword will return an error message to that
114            ...              effect (and write that message to targ_file_path,
115            ...              if specified).  NOTE: This keyword will not fail
116            ...              if there is no running system console process.
117
118            # This doc string is way too long.
119        ```
120-   Tags:
121    -   Create a tag for every test case with a tag name that mirrors the test case
122        name as follows:
123        ```
124        Create Intermediate File
125
126            [Tags]  Create_Intermediate_File
127        ```
128-   General variable naming conventions:
129    -   Variable names should be lower case with few exceptions:
130        -   Environment variables should be all upper case.
131        -   Variables intended to be set by Robot -v parameters may be all
132            upper case.
133    -   Words within a variable name should be separated by underscores:
134
135        Correct examples:
136        ```
137        ${host_name}
138        ${program_pid}
139        ```
140        Incorrect examples:
141        ```
142        ${HostName}
143        ${ProgramPid}
144        ```
145-   Special variable naming conventions.
146
147    For certain very commonly used kinds of variables, please observe these
148    conventions in order to achieve consistency throughout the code.
149
150    -   hosts
151
152        When a variable is intended to contain **either** an IP address **or**
153        a host name (either long or short), please give it a suffix of "_host".
154
155        Examples:
156        ```
157        openbmc_host
158        os_host
159        pdu_host
160        openbmc_serial_host
161        ```
162    -   host names
163
164        For host names (long or short, e.g. "bmc1" or "bmc1.ibm.com"), use a
165        suffix of _host_name.
166
167        Examples:
168        ```
169        openbmc_host_name
170        os_host_name
171        pdu_host_name
172        openbmc_serial_host_name
173        ```
174    -   Short host names
175
176        For short host names (e.g. "bmc1"), use a suffix of _host_short_name.
177
178        Examples:
179        ```
180        openbmc_host_short_name
181        os_host_short_name
182        pdu_host_short_name
183        openbmc_serial_host_short_name
184        ```
185    -   IP addresses
186
187        For IP addresses, use a suffix of _ip.
188
189        Example:
190        ```
191        openbmc_ip
192        os_ip
193        pdu_ip
194        openbmc_serial_ip
195        ```
196-   Files and directories:
197    -   Files:
198        -   If your variable is to contain only the file's name, use a suffix
199            of _file_name.
200
201            Examples:
202            ```
203            ffdc_file_name = "bmc1.170428.120200.ffdc"
204            ```
205        -   If your variable is to contain the path to a file, use a suffix of
206            _file_path.  Bear in mind that a file path can be relative or
207            absolute so that should not be a consideration in whether to use
208            the "_file_path" suffix.
209
210            Examples:
211            ```
212            status_file_path = "bmc1.170428.120200.status"
213            status_file_path = "subdir/bmc1.170428.120200.status"
214            status_file_path = "./bmc1.170428.120200.status"
215            status_file_path = "../bmc1.170428.120200.status"
216            status_file_path = "/home/user1/status/bmc1.170428.120200.status"
217            ```
218            To re-iterate, it doesn't matter whether the contents of the
219            variable are a relative or absolute path (as shown in the
220            examples above).  A file path is simply a value with enough
221            information in it for the program to find the file.
222
223        -   If the variable **must** contain an absolute path (which should be
224            the rare case), use a suffix _abs_file_path.
225
226    -   Directories:
227        -   Directory variables should follow the same conventions as file
228            variables.
229
230        -   If your variable is to contain only the directory's name, use a
231            suffix of _dir_name.
232
233            Example:
234            ```
235            ffdc_dir_name = "ffdc"
236            ```
237        -   If your variable is to contain the path to a directory, use a
238            suffix of _dir_path.  Bear in mind that a dir path can be
239            relative or absolute so that should not be a consideration in
240            whether to use _dir_path.
241
242            Examples:
243            ```
244            status_dir_path = "status/"
245            status_dir_path = "subdir/status"
246            status_dir_path = "./status/"
247            status_dir_path = "../status/"
248            status_dir_path = "/home/user1/status/"
249            ```
250            To re-iterate, it doesn't matter whether the contents of
251            the variable are a relative or absolute path (as shown in
252            the examples above).  A dir path is simply a value with
253            enough information in it for the program to find the
254            directory.
255
256        -   If the variable **must** contain an absolute path (which
257            should be the rare case), use a suffix _abs_dir_path.
258        -   IMPORTANT:  As a programming convention, do pre-
259            processing on all dir_path variables to ensure that they
260            contain a trailing slash.  If we follow that convention
261            religiously, that when changes are made in other parts of
262            the program, the programmer can count on the value having
263            a trailing slash.  Therefore they can safely do this kind
264            of thing:
265            ```
266            my_file_path = my_dir_path + my_file_name
267            ```
268-   Traditional comments (i.e. using the hashtag style comments)
269    -   Please leave one space following the hashtag.
270        ```
271        #wrong
272
273        # Right
274        ```
275    -   Please use proper English punction:
276        -   Capitalize the first word in the sentence or phrase.
277        -   End sentences (or stand-alone phrases) with a period.
278
279    -   Do not keep commented out code in your program.  Instead, remove it
280        entirely.
281
282Python Coding Guidelines
283-----------------------
284-   Run pep8 on all Python files and correct errors.
285
286    Example as run from a Linux command line:
287    ```
288    pep8 my_pgm.py
289
290    my_pgm.py:41:1: E302 expected 2 blank lines, found 1
291    my_pgm.py:58:52: W291 trailing whitespace
292    ```
293-   Include doc strings in every function and follow the guidelines in
294    https://www.python.org/dev/peps/pep-0257/.
295
296    Example:
297    ```
298        r"""
299        Return the function name associated with the indicated stack frame.
300
301        Description of argument(s):
302        stack_frame_ix                  The index of the stack frame whose
303                                        function name should be returned.  If
304                                        the caller does not specify a value,
305                                        this function will set the value to 1
306                                        which is the index of the caller's
307                                        stack frame.  If the caller is the
308                                        wrapper function "print_func_name",
309                                        this function will bump it up by 1.
310        """
311    ```
312-   As shown in the prior example, if your function has any arguments, include
313    a "Description of argument(s)" section.  This effectively serves as the
314    help text for anyone wanting to use or understand your function.  Include
315    real data examples wherever possible and applicable.
316-   Function definitions:
317    -   Put each function parameter on its own line:
318        ```
319        def func1(parm1,
320
321                  parm2):
322        ```
323-   Do not keep commented out code in your program.  Instead, remove it
324    entirely.
325