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
8from gen_arg import *
9from gen_print import *
10from gen_valid import *
11from robot.parsing.model import TestData
12
13import sys
14import os
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=";%(prog)s will print test suite information to stdout. This \
26                  information consists of any and/or all of the following: \
27                  the suite name, test case names, tag names and doc strings. \
28                  Example for generated test case names \
29                  tests/test_basic_poweron.robot \
30                  Verify Front And Rear LED At Standby \
31                  Power On Test \
32                  Check For Application Failures \
33                  Verify Uptime Average Against Threshold \
34                  Test SSH And IPMI Connections",
35    formatter_class=argparse.ArgumentDefaultsHelpFormatter,
36    prefix_chars='-+')
37
38parser.add_argument(
39    '--source_path',
40    '-s',
41    help='The robot test file or directory path.')
42
43parser.add_argument(
44    '--option',
45    '-o',
46    default="name",
47    help='Test case attribute name.  This may be any one of the following:\n'
48    + sprint_var(valid_options))
49
50# Populate stock_list with options we want.
51stock_list = [("test_mode", 0), ("quiet", 0), ("debug", 0)]
52
53
54def exit_function(signal_number=0,
55                  frame=None):
56    r"""
57    Execute whenever the program ends normally or with the signals that we
58    catch (i.e. TERM, INT).
59    """
60
61    dprint_executing()
62
63    dprint_var(signal_number)
64
65    qprint_pgm_footer()
66
67
68def signal_handler(signal_number,
69                   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 = [os.path.join(path, file)
112                      for (path, dirs, files) in os.walk(source_path)
113                      for file in files]
114
115    for file_path in file_paths:
116        print(file_path)
117        if "__init__.robot" in file_path:
118            continue
119        test_suite_obj = TestData(parent=None, source=file_path)
120        parse_test_file(test_suite_obj, option)
121
122
123def parse_test_file(test_suite_obj, option):
124    r"""
125    Extract test information from test suite object and print it to stdout in
126    the following format:
127
128    <Test Case name>
129    <Test Tags name>
130    <Test Documentation>
131
132    Description of argument(s):
133    test_suite_obj    Test data suite object.
134    option            Test case attribute instances such as "name",
135                      "tags" or "doc".
136    """
137
138    for testcase in test_suite_obj.testcase_table:
139        if option == "name":
140            print(testcase.name)
141        elif option == "tags":
142            print(testcase.tags)
143        elif option == "doc":
144            print(testcase.doc)
145        elif option == "all":
146            print(testcase.name)
147            print(testcase.tags)
148            print(testcase.doc)
149
150
151def main():
152
153    gen_get_options(parser, stock_list)
154
155    validate_parms()
156
157    qprint_pgm_header()
158
159    parse_test_suites(source_path, option)
160
161    return True
162
163
164# Main
165main()
166