aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeels Hofmeyr <neels@hofmeyr.de>2017-10-18 02:45:10 +0200
committerNeels Hofmeyr <neels@hofmeyr.de>2017-10-18 03:43:21 +0200
commit08d645b01db09c14520a6000ce4833dbb74c0c88 (patch)
treecd0a7d1e5d4f61e3b9923aed0db9881c861d27be
parent32cbce1a163f4c5e084bbb5f02e5312cd78575c1 (diff)
osmo_verify_transcript: allow running/piping commands directly
To retrieve the VTY reference XML from 'show online-help', which we need for the osmo-gsm-manuals, it is useful to directly print the output of a single VTY command. I have also always wanted to be able to just type CTRL commands and get their results. Add --command and --output arguments to run specific commands and pipe to stdout instead of verifying a transcript file, in a way that works generically for both VTY and CTRL interface. The scripts' names are now a bit of a misnomer, to be tweaked separately. Change-Id: I2c31a87fa255092bcd06da239651cc50174c8faa
-rw-r--r--osmopy/osmo_verify_transcript_common.py106
-rwxr-xr-xosmopy/osmo_verify_transcript_ctrl.py6
-rwxr-xr-xosmopy/osmo_verify_transcript_vty.py16
3 files changed, 107 insertions, 21 deletions
diff --git a/osmopy/osmo_verify_transcript_common.py b/osmopy/osmo_verify_transcript_common.py
index d8e9860..71961e6 100644
--- a/osmopy/osmo_verify_transcript_common.py
+++ b/osmopy/osmo_verify_transcript_common.py
@@ -242,6 +242,13 @@ class Interact:
return 'Did not expect line %r' % got[g]
return True
+ def feed_commands(self, output, command_strs):
+ for command_str in command_strs:
+ for command in command_str.splitlines():
+ res = self.command(command)
+ output.write('\n'.join(res))
+ output.write('\n')
+
def end_process(proc):
if not proc:
return
@@ -285,30 +292,32 @@ class Application:
Application._devnull = open(os.devnull, 'w')
return Application._devnull
- def __init__(self, command_tuple, purge_output=True):
- self.command_tuple = command_tuple
+ def __init__(self, run_app_str, purge_output=True, quiet=False):
+ self.command_tuple = shlex.split(run_app_str)
self.purge_output = purge_output
+ self.quiet = quiet
def run(self):
out_err = None
if self.purge_output:
out_err = Application.devnull()
- print('Launching: cd %r; %s' % (os.getcwd(), ' '.join(self.command_tuple)))
+ if not self.quiet:
+ print('Launching: cd %r; %s' % (os.getcwd(), ' '.join(self.command_tuple)))
self.proc = subprocess.Popen(self.command_tuple, stdout=out_err, stderr=out_err)
def stop(self):
end_process(self.proc)
-def verify_application(command_tuple, interact, transcript_file, verbose):
+def verify_application(run_app_str, interact, transcript_file, verbose):
passed = None
application = None
sys.stdout.flush()
sys.stderr.flush()
- if command_tuple:
- application = Application(command_tuple, purge_output=not verbose)
+ if run_app_str:
+ application = Application(run_app_str, purge_output=not verbose)
application.run()
try:
@@ -330,7 +339,7 @@ def verify_application(command_tuple, interact, transcript_file, verbose):
def common_parser():
parser = argparse.ArgumentParser()
- parser.add_argument('-r', '--run', dest='command_str',
+ parser.add_argument('-r', '--run', dest='run_app_str',
help='command to run to launch application to test,'
' including command line arguments. If omitted, no'
' application is launched.')
@@ -344,19 +353,76 @@ def common_parser():
' FILES.')
parser.add_argument('-v', '--verbose', action='store_true',
help='Print commands and application output')
+ parser.add_argument('-O', '--output', dest='output_path',
+ help="Do not verify a transcript file, but directly"
+ " write command results to a file, '-' means stdout."
+ " If input files are provided, these must not be transcript"
+ " files, but bare commands, one per line, without"
+ " prompts nor expected results."
+ " If neither --command nor input files are"
+ " provided, read commands from stdin."
+ " Ignore '--update'.")
+ parser.add_argument('-c', '--command', dest='cmd_str',
+ help="Run this command instead of reading from a"
+ " transcript file, multiple commands may be separated"
+ " by ';'. Implies '-O -' unless -O is passed.")
parser.add_argument('transcript_files', nargs='*', help='transcript files to verify')
return parser
-def main(command_str, transcript_files, interact, verbose):
-
- if command_str:
- command_tuple = shlex.split(command_str)
+def run_commands(run_app_str, output_path, cmd_str, cmd_files, interact):
+ to_stdout = False
+ if output_path == '-':
+ to_stdout = True
+ output = sys.stdout
else:
- command_tuple = None
+ output = open(output_path, 'w')
+
+ application = None
+
+ if run_app_str:
+ application = Application(run_app_str, quiet=to_stdout)
+ application.run()
+
+ try:
+ interact.connect()
+
+ if cmd_str:
+ interact.feed_commands(output, cmd_str.split(';'))
+
+ for f_path in (cmd_files or []):
+ with open(f_path, 'r') as f:
+ interact.feed_commands(output, f.read().decode('utf-8').splitlines())
+
+ if not (cmd_str or cmd_files):
+ while True:
+ line = sys.stdin.readline()
+ if not line:
+ break;
+ interact.feed_commands(output, line.split(';'))
+ except:
+ traceback.print_exc()
+ finally:
+ if not to_stdout:
+ try:
+ output.close()
+ except:
+ traceback.print_exc()
+ try:
+ interact.close()
+ except:
+ traceback.print_exc()
+
+ if application:
+ try:
+ application.stop()
+ except:
+ traceback.print_exc()
+
+def verify_transcripts(run_app_str, transcript_files, interact, verbose):
results = []
for t in transcript_files:
- passed = verify_application(command_tuple=command_tuple,
+ passed = verify_application(run_app_str=run_app_str,
interact=interact,
transcript_file=t,
verbose=verbose)
@@ -372,4 +438,18 @@ def main(command_str, transcript_files, interact, verbose):
if not all_passed:
sys.exit(1)
+def main(run_app_str, output_path, cmd_str, transcript_files, interact, verbose):
+
+ # If there is a command to run, pipe to stdout by default.
+ # If there are no input files nor commands to run, read from stdin
+ # and write results to stdout.
+ if not output_path:
+ if cmd_str or (not cmd_str and not transcript_files):
+ output_path = '-'
+
+ if output_path:
+ run_commands(run_app_str, output_path, cmd_str, transcript_files, interact)
+ else:
+ verify_transcripts(run_app_str, transcript_files, interact, verbose)
+
# vim: tabstop=4 shiftwidth=4 expandtab nocin ai
diff --git a/osmopy/osmo_verify_transcript_ctrl.py b/osmopy/osmo_verify_transcript_ctrl.py
index 7afe4bf..3cf6880 100755
--- a/osmopy/osmo_verify_transcript_ctrl.py
+++ b/osmopy/osmo_verify_transcript_ctrl.py
@@ -112,9 +112,7 @@ if __name__ == '__main__':
interact = InteractCtrl(args.port, args.host, args.verbose, args.update, args.keep_ids)
- main(command_str=args.command_str,
- transcript_files=args.transcript_files,
- interact=interact,
- verbose=args.verbose)
+ main(args.run_app_str, args.output_path, args.cmd_str,
+ args.transcript_files, interact, args.verbose)
# vim: tabstop=4 shiftwidth=4 expandtab nocin ai
diff --git a/osmopy/osmo_verify_transcript_vty.py b/osmopy/osmo_verify_transcript_vty.py
index 636d600..28c83d0 100755
--- a/osmopy/osmo_verify_transcript_vty.py
+++ b/osmopy/osmo_verify_transcript_vty.py
@@ -179,13 +179,21 @@ if __name__ == '__main__':
help="Name used in application's telnet VTY prompt."
" If omitted, will attempt to determine the name from"
" the initial VTY prompt.")
+ parser.add_argument('-X', '--gen-xml-ref', dest='gen_xml', action='store_true',
+ help="Equivalent to '-c \"show online-help\" -O -',"
+ " can be used to generate the VTY reference file as"
+ " required by osmo-gsm-manuals.git.")
args = parser.parse_args()
+ if args.gen_xml:
+ if args.cmd_str:
+ raise Exception('It does not make sense to pass both --command and'
+ ' --gen-xml-ref.')
+ args.cmd_str = 'show online-help'
+
interact = InteractVty(args.prompt, args.port, args.host, args.verbose, args.update)
- main(command_str=args.command_str,
- transcript_files=args.transcript_files,
- interact=interact,
- verbose=args.verbose)
+ main(args.run_app_str, args.output_path, args.cmd_str,
+ args.transcript_files, interact, args.verbose)
# vim: tabstop=4 shiftwidth=4 expandtab nocin ai