diff options
Diffstat (limited to 'packages/Python/lldbsuite/test/test_runner/test/inferior.py')
-rwxr-xr-x | packages/Python/lldbsuite/test/test_runner/test/inferior.py | 146 |
1 files changed, 146 insertions, 0 deletions
diff --git a/packages/Python/lldbsuite/test/test_runner/test/inferior.py b/packages/Python/lldbsuite/test/test_runner/test/inferior.py new file mode 100755 index 000000000000..4207bac300fd --- /dev/null +++ b/packages/Python/lldbsuite/test/test_runner/test/inferior.py @@ -0,0 +1,146 @@ +#!/usr/bin/env python +"""Inferior program used by process control tests.""" + +from __future__ import print_function + +import argparse +import datetime +import signal +import subprocess +import sys +import time + + +def parse_args(command_line): + """Parses the command line arguments given to it. + + @param command_line a list of command line arguments to be parsed. + + @return the argparse options dictionary. + """ + parser = argparse.ArgumentParser() + parser.add_argument( + "--ignore-signal", + "-i", + dest="ignore_signals", + metavar="SIGNUM", + action="append", + type=int, + default=[], + help="ignore the given signal number (if possible)") + parser.add_argument( + "--launch-child-share-handles", + action="store_true", + help=("launch a child inferior.py that shares stdout/stderr/stdio and " + "never returns")) + parser.add_argument( + "--never-return", + action="store_true", + help="run in an infinite loop, never return") + parser.add_argument( + "--return-code", + "-r", + type=int, + default=0, + help="specify the return code for the inferior upon exit") + parser.add_argument( + "--sleep", + "-s", + metavar="SECONDS", + dest="sleep_seconds", + type=float, + help="sleep for SECONDS seconds before returning") + parser.add_argument( + "--verbose", "-v", action="store_true", + help="log verbose operation details to stdout") + return parser.parse_args(command_line) + + +def handle_ignore_signals(options, signals): + """Ignores any signals provided to it. + + @param options the command line options parsed by the program. + General used to check flags for things like verbosity. + + @param signals the list of signals to ignore. Can be None or zero-length. + Entries should be type int. + """ + if signals is None: + return + + for signum in signals: + if options.verbose: + print("disabling signum {}".format(signum)) + signal.signal(signum, signal.SIG_IGN) + + +def handle_sleep(options, sleep_seconds): + """Sleeps the number of seconds specified, restarting as needed. + + @param options the command line options parsed by the program. + General used to check flags for things like verbosity. + + @param sleep_seconds the number of seconds to sleep. If None + or <= 0, no sleeping will occur. + """ + if sleep_seconds is None: + return + + if sleep_seconds <= 0: + return + + end_time = datetime.datetime.now() + datetime.timedelta(0, sleep_seconds) + if options.verbose: + print("sleep end time: {}".format(end_time)) + + # Do sleep in a loop: signals can interrupt. + while datetime.datetime.now() < end_time: + # We'll wrap this in a try/catch so we don't encounter + # a race if a signal (ignored) knocks us out of this + # loop and causes us to return. + try: + sleep_interval = end_time - datetime.datetime.now() + sleep_seconds = sleep_interval.total_seconds() + if sleep_seconds > 0: + time.sleep(sleep_seconds) + except: # pylint: disable=bare-except + pass + + +def handle_launch_children(options): + if options.launch_child_share_handles: + # Launch the child, share our file handles. + # We won't bother reaping it since it will likely outlive us. + subprocess.Popen([sys.executable, __file__, "--never-return"]) + + +def handle_never_return(options): + if not options.never_return: + return + + # Loop forever. + while True: + try: + time.sleep(10) + except: # pylint: disable=bare-except + # Ignore + pass + + +def main(command_line): + """Drives the main operation of the inferior test program. + + @param command_line the command line options to process. + + @return the exit value (program return code) for the process. + """ + options = parse_args(command_line) + handle_ignore_signals(options, options.ignore_signals) + handle_launch_children(options) + handle_sleep(options, options.sleep_seconds) + handle_never_return(options) + + return options.return_code + +if __name__ == "__main__": + sys.exit(main(sys.argv[1:])) |