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