From ade0233d579ca0a8eb7d498e02f0d55902bc0976 Mon Sep 17 00:00:00 2001 From: bradobro Date: Mon, 23 Jul 2012 16:04:28 +0000 Subject: [PATCH 1/2] Refactoring test-module to be more like ansible. --- hacking/test-module | 135 ++++++++++++++++++++++++++------------------ 1 file changed, 81 insertions(+), 54 deletions(-) diff --git a/hacking/test-module b/hacking/test-module index 398597fd135..7d6567fadf1 100755 --- a/hacking/test-module +++ b/hacking/test-module @@ -30,6 +30,7 @@ import sys import os import subprocess import traceback +import optparse import ansible.utils as utils import ansible.module_common as module_common @@ -38,67 +39,93 @@ try: except ImportError: import simplejson as json -modfile = None +def parse(): + """parse command line -if len(sys.argv) == 1: - print >>sys.stderr, "usage: test-module ./library/command [key=value ...]" - sys.exit(1) + :return : (options, args)""" + parser = optparse.OptionParser() -modfile = sys.argv[1] -if len(sys.argv) > 1: - args = " ".join(sys.argv[2:]) -else: - args = "" + parser.usage = "%prog [options] (-h for help)" -argspath = os.path.expanduser("~/.ansible_test_module_arguments") -argsfile = open(argspath, 'w') -argsfile.write(args) -argsfile.close() + parser.add_option('-m', '--module-name', dest='module_name', + help="module name to execute") + parser.add_option('-a', '--args', dest='module_args', default="", + help="module arguments") + parser.add_option('-D', '--debugger', dest='debugger', + help="path to python debugger (e.g. /usr/bin/pdb)") + options, args = parser.parse_args() + if not options.module_name: + parser.print_help() + sys.exit(1) + else: + return options, args -module_fh = open(modfile) -module_data = module_fh.read() -included_boilerplate = module_data.find(module_common.REPLACER) != -1 -module_fh.close() - -if included_boilerplate: - module_data = module_data.replace(module_common.REPLACER, module_common.MODULE_COMMON) - modfile2_path = os.path.expanduser("~/.ansible_module_generated") - print "* including generated source, if any, saving to: %s" % modfile2_path - print "* this will offset any line numbers in tracebacks!" - modfile2 = open(modfile2_path, 'w') - modfile2.write(module_data) - modfile2.close() - modfile = modfile2_path -else: - print "* module boilerplate substitution not requested in module, tracebacks will be unaltered" - -os.system("chmod +x %s" % modfile) -cmd = subprocess.Popen("%s %s" % (modfile, argspath), - shell=True, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) -(out, err) = cmd.communicate() - -try: - print "***********************************" - print "RAW OUTPUT" - print out - print err - results = utils.parse_json(out) +def write_argsfile( argstring): + """Write args to a file for the module's use. -except: + :return: full path to args file""" + argspath = os.path.expanduser("~/.ansible_test_module_arguments") + argsfile = open(argspath, 'w') + argsfile.write(argstring) + argsfile.close() + return argspath + +def boilerplate_module( modfile): + module_fh = open(modfile) + module_data = module_fh.read() + included_boilerplate = module_data.find(module_common.REPLACER) != -1 + module_fh.close() + + if included_boilerplate: + module_data = module_data.replace(module_common.REPLACER, module_common.MODULE_COMMON) + modfile2_path = os.path.expanduser("~/.ansible_module_generated") + print "* including generated source, if any, saving to: %s" % modfile2_path + print "* this will offset any line numbers in tracebacks/debuggers!" + modfile2 = open(modfile2_path, 'w') + modfile2.write(module_data) + modfile2.close() + modfile = modfile2_path + return modfile2_path + else: + print "* module boilerplate substitution not requested in module, line numbers will be unaltered" + return modfile + +def main(): + options, args = parse() + + argspath = write_argsfile( options.module_args) + modfile = boilerplate_module( options.module_name) + print argspath, modfile + sys.exit(0) + #===== run or debug the module + os.system("chmod +x %s" % modfile) + cmd = subprocess.Popen("%s %s" % (modfile, argspath), + shell=True, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + (out, err) = cmd.communicate() + + try: + print "***********************************" + print "RAW OUTPUT" + print out + print err + results = utils.parse_json(out) + + except: + print "***********************************" + print "INVALID OUTPUT FORMAT" + print out + traceback.print_exc() + sys.exit(1) + print "***********************************" - print "INVALID OUTPUT FORMAT" - print out - traceback.print_exc() - sys.exit(1) + print "PARSED OUTPUT" -print "***********************************" -print "PARSED OUTPUT" - -print utils.jsonify(results,format=True) - -sys.exit(0) + print utils.jsonify(results,format=True) + +if __name__ == "__main__": + main() From e8583833a79b58c7d0c73c79866d49a463b9d301 Mon Sep 17 00:00:00 2001 From: bradobro Date: Mon, 23 Jul 2012 16:28:06 +0000 Subject: [PATCH 2/2] test-module uses optparse with --debugger Refactored hacking/test-module 1. uses optparse 2. has --debugger option tested only with pdb on Python 2.7 --- hacking/test-module | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/hacking/test-module b/hacking/test-module index 7d6567fadf1..40dad456690 100755 --- a/hacking/test-module +++ b/hacking/test-module @@ -47,14 +47,14 @@ def parse(): parser.usage = "%prog [options] (-h for help)" - parser.add_option('-m', '--module-name', dest='module_name', - help="module name to execute") + parser.add_option('-m', '--module-path', dest='module_path', + help="path of module to execute") parser.add_option('-a', '--args', dest='module_args', default="", help="module arguments") parser.add_option('-D', '--debugger', dest='debugger', help="path to python debugger (e.g. /usr/bin/pdb)") options, args = parser.parse_args() - if not options.module_name: + if not options.module_path: parser.print_help() sys.exit(1) else: @@ -90,14 +90,8 @@ def boilerplate_module( modfile): print "* module boilerplate substitution not requested in module, line numbers will be unaltered" return modfile -def main(): - options, args = parse() - - argspath = write_argsfile( options.module_args) - modfile = boilerplate_module( options.module_name) - print argspath, modfile - sys.exit(0) - #===== run or debug the module +def runtest( modfile, argspath): + """Test run a module, piping it's output for reporting.""" os.system("chmod +x %s" % modfile) cmd = subprocess.Popen("%s %s" % (modfile, argspath), shell=True, @@ -124,6 +118,20 @@ def main(): print utils.jsonify(results,format=True) +def rundebug(debugger, modfile, argspath): + """Run interactively with console debugger.""" + subprocess.call( "%s %s %s" % (debugger, modfile, argspath), shell=True) + +def main(): + options, args = parse() + + argspath = write_argsfile( options.module_args) + modfile = boilerplate_module( options.module_path) + + if options.debugger: + rundebug( options.debugger, modfile, argspath) + else: + runtest( modfile, argspath) if __name__ == "__main__": main()