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