xref: /openbmc/openbmc-test-automation/lib/gen_arg.py (revision d0fd8838ea51df528b7c6f658b40b180eab35bd5)
1#!/usr/bin/env python
2
3r"""
4This module provides valuable argument processing functions like
5gen_get_options and sprint_args.
6"""
7
8import sys
9import __builtin__
10import atexit
11import signal
12import argparse
13
14import gen_print as gp
15
16default_string = '  The default value is "%(default)s".'
17
18
19###############################################################################
20def gen_get_options(parser,
21                    stock_list=[]):
22
23    r"""
24    Parse the command line arguments using the parser object passed and return
25    True/False (i.e. pass/fail).  Also set the following built in values:
26
27    __builtin__.quiet      This value is used by the qprint functions.
28    __builtin__.test_mode  This value is used by command processing functions.
29    __builtin__.debug      This value is used by the dprint functions.
30    __builtin__.arg_obj    This value is used by print_program_header, etc.
31    __builtin__.parser     This value is used by print_program_header, etc.
32
33    Description of arguments:
34    parser                          A parser object.  See argparse module
35                                    documentation for details.
36    stock_list                      The caller can use this parameter to
37                                    request certain stock parameters offered
38                                    by this function.  For example, this
39                                    function will define a "quiet" option upon
40                                    request.  This includes stop help text and
41                                    parm checking.  The stock_list is a list
42                                    of tuples each of which consists of an
43                                    arg_name and a default value.  Example:
44                                    stock_list = [("test_mode", 0), ("quiet",
45                                    1), ("debug", 0)]
46    """
47
48    # This is a list of stock parms that we support.
49    master_stock_list = ["quiet", "test_mode", "debug", "loglevel"]
50
51    # Process stock_list.
52    for ix in range(0, len(stock_list)):
53        if len(stock_list[ix]) < 1:
54            gp.print_error_report("Programmer error - stock_list[" + str(ix) +
55                                  "] is supposed to be a tuple containing at" +
56                                  " least one element which is the name of" +
57                                  " the desired stock parameter:\n" +
58                                  gp.sprint_var(stock_list))
59            return False
60        if type(stock_list[ix]) is tuple:
61            arg_name = stock_list[ix][0]
62            default = stock_list[ix][1]
63        else:
64            arg_name = stock_list[ix]
65            default = None
66
67        if arg_name not in master_stock_list:
68            gp.pvar(arg_name)
69            gp.print_error_report("Programmer error - \"" + arg_name +
70                                  "\" not found found in stock list:\n" +
71                                  gp.sprint_var(master_stock_list))
72            return False
73
74        if arg_name == "quiet":
75            if default is None:
76                default = 0
77            parser.add_argument(
78                '--quiet',
79                default=default,
80                type=int,
81                choices=[1, 0],
82                help='If this parameter is set to "1", %(prog)s' +
83                     ' will print only essential information, i.e. it will' +
84                     ' not echo parameters, echo commands, print the total' +
85                     ' run time, etc.' + default_string
86                )
87        elif arg_name == "test_mode":
88            if default is None:
89                default = 0
90            parser.add_argument(
91                '--test_mode',
92                default=default,
93                type=int,
94                choices=[1, 0],
95                help='This means that %(prog)s should go through all the' +
96                     ' motions but not actually do anything substantial.' +
97                     '  This is mainly to be used by the developer of' +
98                     ' %(prog)s.' + default_string
99                )
100        elif arg_name == "debug":
101            if default is None:
102                default = 0
103            parser.add_argument(
104                '--debug',
105                default=default,
106                type=int,
107                choices=[1, 0],
108                help='If this parameter is set to "1", %(prog)s will print' +
109                     ' additional debug information.  This is mainly to be' +
110                     ' used by the developer of %(prog)s.' + default_string
111                )
112        elif arg_name == "loglevel":
113            if default is None:
114                default = "info"
115            parser.add_argument(
116                '--loglevel',
117                default=default,
118                type=str,
119                choices=['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL',
120                         'debug', 'info', 'warning', 'error', 'critical'],
121                help='If this parameter is set to "1", %(prog)s will print' +
122                     ' additional debug information.  This is mainly to be' +
123                     ' used by the developer of %(prog)s.' + default_string
124                )
125
126    arg_obj = parser.parse_args()
127
128    __builtin__.quiet = 0
129    __builtin__.test_mode = 0
130    __builtin__.debug = 0
131    __builtin__.loglevel = 'WARNING'
132    for ix in range(0, len(stock_list)):
133        if type(stock_list[ix]) is tuple:
134            arg_name = stock_list[ix][0]
135            default = stock_list[ix][1]
136        else:
137            arg_name = stock_list[ix]
138            default = None
139        if arg_name == "quiet":
140            __builtin__.quiet = arg_obj.quiet
141        elif arg_name == "test_mode":
142            __builtin__.test_mode = arg_obj.test_mode
143        elif arg_name == "debug":
144            __builtin__.debug = arg_obj.debug
145        elif arg_name == "loglevel":
146            __builtin__.loglevel = arg_obj.loglevel
147
148    __builtin__.arg_obj = arg_obj
149    __builtin__.parser = parser
150
151    # For each command line parameter, create a corresponding global variable
152    # and assign it the appropriate value.  For example, if the command line
153    # contained "--last_name='Smith', we'll create a global variable named
154    # "last_name" with the value "Smith".
155    module = sys.modules['__main__']
156    for key in arg_obj.__dict__:
157        setattr(module, key, getattr(__builtin__.arg_obj, key))
158
159    return True
160
161###############################################################################
162
163
164# Put this in gen_opt.py or gen_parm.py or gen_arg.py.
165###############################################################################
166def sprint_args(arg_obj,
167                indent=0):
168
169    r"""
170    sprint_var all of the arguments found in arg_obj and return the result as
171    a string.
172
173    Description of arguments:
174    arg_obj                         An argument object such as is returned by
175                                    the argparse parse_args() method.
176    indent                          The number of spaces to indent each line
177                                    of output.
178    """
179
180    buffer = ""
181
182    for key in arg_obj.__dict__:
183        buffer += gp.sprint_varx(key, getattr(arg_obj, key), 0, indent)
184
185    return buffer
186
187###############################################################################
188
189
190###############################################################################
191def gen_post_validation(exit_function=None,
192                        signal_handler=None):
193
194    r"""
195    Do generic post-validation processing.  By "post", we mean that this is to
196    be called from a validation function after the caller has done any
197    validation desired.  If the calling program passes exit_function and
198    signal_handler parms, this function will register them.  In other words,
199    it will make the signal_handler functions get called for SIGINT and
200    SIGTERM and will make the exit_function function run prior to the
201    termination of the program.
202
203    Description of arguments:
204    exit_function                   A function object pointing to the caller's
205                                    exit function.
206    signal_handler                  A function object pointing to the caller's
207                                    signal_handler function.
208    """
209
210    if exit_function is not None:
211        atexit.register(exit_function)
212    if signal_handler is not None:
213        signal.signal(signal.SIGINT, signal_handler)
214        signal.signal(signal.SIGTERM, signal_handler)
215
216###############################################################################
217