xref: /openbmc/openbmc-test-automation/bin/generate_testsuite_info.py (revision 5731818de0ce446ceaafc7e75ae39da1b69942ae)
1#!/usr/bin/env python3
2
3r"""
4Use robot framework API to extract test data from test suites.
5Refer to https://robot-framework.readthedocs.io/en/3.0.1/autodoc/robot.parsing.html
6"""
7
8import os
9import sys
10
11from gen_arg import *
12from gen_print import *
13from gen_valid import *
14from robot.parsing.model import TestData
15
16sys.path.append(os.path.join(os.path.dirname(__file__), "../lib"))
17
18# Set exit_on_error for gen_valid functions.
19set_exit_on_error(True)
20
21valid_options = ["name", "tags", "doc", "all"]
22
23parser = argparse.ArgumentParser(
24    usage="%(prog)s [OPTIONS]",
25    description=(
26        ";%(prog)s will print test suite information to stdout. This          "
27        "         information consists of any and/or all of the following:    "
28        "               the suite name, test case names, tag names and doc"
29        " strings.                   Example for generated test case names    "
30        "               tests/test_basic_poweron.robot                  "
31        " Verify Front And Rear LED At Standby                   Power On Test"
32        "                   Check For Application Failures                  "
33        " Verify Uptime Average Against Threshold                   Test SSH"
34        " And IPMI Connections"
35    ),
36    formatter_class=argparse.ArgumentDefaultsHelpFormatter,
37    prefix_chars="-+",
38)
39
40parser.add_argument(
41    "--source_path", "-s", help="The robot test file or directory path."
42)
43
44parser.add_argument(
45    "--option",
46    "-o",
47    default="name",
48    help="Test case attribute name.  This may be any one of the following:\n"
49    + sprint_var(valid_options),
50)
51
52# Populate stock_list with options we want.
53stock_list = [("test_mode", 0), ("quiet", 0), ("debug", 0)]
54
55
56def exit_function(signal_number=0, frame=None):
57    r"""
58    Execute whenever the program ends normally or with the signals that we
59    catch (i.e. TERM, INT).
60    """
61
62    dprint_executing()
63
64    dprint_var(signal_number)
65
66    qprint_pgm_footer()
67
68
69def signal_handler(signal_number, frame):
70    r"""
71    Handle signals.  Without a function to catch a SIGTERM or SIGINT, the
72    program would terminate immediately with return code 143 and without
73    calling the exit_function.
74    """
75
76    # Our convention is to set up exit_function with atexit.register() so
77    # there is no need to explicitly call exit_function from here.
78
79    dprint_executing()
80
81    # Calling exit prevents us from returning to the code that was running
82    # when the signal was received.
83    exit(0)
84
85
86def validate_parms():
87    r"""
88    Validate program parameters, etc.  Return True or False (i.e. pass/fail)
89    accordingly.
90    """
91
92    valid_path(source_path)
93
94    valid_value(option, valid_values=valid_options)
95
96    gen_post_validation(exit_function, signal_handler)
97
98
99def parse_test_suites(source_path, option):
100    r"""
101    Parse the robot files and extract test data output.
102
103    Description of argument(s):
104    source_path   The path to a robot file or a directory of robot files.
105    option        Test case attribute instances such as "name",
106                  "tags" or "doc".
107    """
108    if os.path.isfile(source_path):
109        file_paths = [source_path]
110    else:
111        file_paths = [
112            os.path.join(path, file)
113            for (path, dirs, files) in os.walk(source_path)
114            for file in files
115        ]
116
117    for file_path in file_paths:
118        print(file_path)
119        if "__init__.robot" in file_path:
120            continue
121        test_suite_obj = TestData(parent=None, source=file_path)
122        parse_test_file(test_suite_obj, option)
123
124
125def parse_test_file(test_suite_obj, option):
126    r"""
127    Extract test information from test suite object and print it to stdout in
128    the following format:
129
130    <Test Case name>
131    <Test Tags name>
132    <Test Documentation>
133
134    Description of argument(s):
135    test_suite_obj    Test data suite object.
136    option            Test case attribute instances such as "name",
137                      "tags" or "doc".
138    """
139
140    for testcase in test_suite_obj.testcase_table:
141        if option == "name":
142            print(testcase.name)
143        elif option == "tags":
144            print(testcase.tags)
145        elif option == "doc":
146            print(testcase.doc)
147        elif option == "all":
148            print(testcase.name)
149            print(testcase.tags)
150            print(testcase.doc)
151
152
153def main():
154    gen_get_options(parser, stock_list)
155
156    validate_parms()
157
158    qprint_pgm_header()
159
160    parse_test_suites(source_path, option)
161
162    return True
163
164
165# Main
166main()
167