import xml.dom.minidom import datetime from optparse import OptionParser import random import os import sys INDENT = " " INDENT2 = INDENT + INDENT INDENT3 = INDENT2 + INDENT outFile = None def getText(nodelist): if nodelist[0].childNodes is not None: return nodelist[0].childNodes[0].nodeValue else: return "" def get_doc(name): return xml.dom.minidom.parse(name) def parse_xmlFile(dom, outf, glos): testName = dom.documentElement.nodeName if outf is not None: outFile.write("# Generated by translator.py\n# from %s\n" % options.xmlfile) outFile.write("# on %s\n\n" % str(now)) outFile.write("from cloudstackTestCase import *\n") outFile.write("import cloudstackException\n") outFile.write("import cloudstackTestClient\n") outFile.write("import time\n\n") outFile.write("# These are global variables used in the script below\n") for key in glos: outFile.write("%s = None\n" % key) outFile.write("# End of globals\n\n") outFile.write("if __name__ == \"__main__\":\n\n") outFile.write("%s# Possible initialization parameters:\n" % INDENT) outFile.write("%s# cloudstackTestClient(mgtSvr=None, port=8096, apiKey = None, securityKey = None, asyncTimeout=3600, defaultWorkerThreads=10, logging=None)\n" % INDENT) outFile.write("%stestClient = cloudstackTestClient.cloudstackTestClient(\"localhost\")\n\n" % INDENT) outFile.write("%sapiclient = testClient.getApiClient()\n" % INDENT) else: glos = [] ## eventually, this should all be put in a class so we can isolate context better... # outFile.write("class %s(cloudstackTestCase):\n\n" % testName) # outFile.write("%sdef test_%s(self):\n" % (INDENT, testName)) # outFile.write("%sapiClient = self.testClient.getApiClient()\n" % INDENT2) for cmd in dom.getElementsByTagName("command"): cmd_name = cmd.getElementsByTagName("name")[0].childNodes[0].nodeValue.strip() cmd_name_var = "_%s" % cmd_name cmd_name_resp = "resp_%s" % cmd_name testCaseName = cmd.getElementsByTagName("testcase")[0].childNodes[0].nodeValue.strip() if outf is not None: outFile.write("\n%s# %s\n" % (INDENT, testCaseName)) if outf is not None: outFile.write("%s%s = %s.%sCmd()\n" % (INDENT, cmd_name_var, cmd_name, cmd_name)) for param in cmd.getElementsByTagName("parameters"): for item in param.getElementsByTagName("item"): itemName = item.getElementsByTagName("name")[0].childNodes[0].nodeValue.strip() itemParam = None itemValue = None # this could be handled much cleaner try: itemValue = item.getElementsByTagName("value")[0].childNodes[0].nodeValue.strip() except Exception: itemValue = None try: itemParam = item.getElementsByTagName("param")[0].childNodes[0].nodeValue.strip() except Exception: itemParam = None # handle getparam and setparam and random attributes here... if item.getAttribute("getparam") == "true" and itemParam is not None: if outf is not None: outFile.write("%s%s.%s = %s\n" % (INDENT, cmd_name_var, itemName, itemParam)) else: glos.append(itemParam) elif item.getAttribute("random") == "true" or item.getAttribute("randomnumber") == "true": # we should do this in the resulting python file. randValue = int(random.random() * 10000000) if outf is not None: outFile.write("%s%s.%s = '%s-randomName'\n" % (INDENT, cmd_name_var, itemName, str(randValue))) if item.getAttribute("setparam") == "true" and itemParam is not None: if outf is not None: outFile.write("%s%s = '%s-randomName'\n" % (INDENT, itemName, str(randValue))) else: glos.append(itemParam) else: try: val = int(itemValue) except Exception: val = "'%s'" % itemValue if outf is not None: outFile.write("%s%s.%s = %s\n" % (INDENT, cmd_name_var, itemName, val)) # now we execute command if outf is not None: outFile.write("%s%s = apiClient.%s(%s)\n" % (INDENT, cmd_name_resp, cmd_name, cmd_name_var)) for return_val in cmd.getElementsByTagName("returnvalue"): for item in return_val.getElementsByTagName("item"): #if item.getAttribute("list") == "true": itemName = item.getElementsByTagName("name")[0].childNodes[0].nodeValue.strip() itemParam = item.getElementsByTagName("param")[0].childNodes[0].nodeValue.strip() if item.getAttribute("setparam") == "true": if outf is not None: outFile.write("%s%s = %s.%s\n" % (INDENT, itemParam, cmd_name_resp, itemName)) else: if outf is not None: outFile.write("%sif %s != %s.%s:\n" % (INDENT, itemParam, cmd_name_resp, itemName)) outFile.write("%sprint %s.%s + \" does not match \" + %s\n" % (INDENT2, cmd_name_resp, itemName, itemValue)) return set(glos) if __name__ == "__main__": parser = OptionParser() parser.add_option("-i", "--inputfile", dest="xmlfile", help="The path to the XML file containing tests.", default="../../test/metadata/func/portforwarding.xml") parser.add_option("-o", "--output_file_path", dest="outfile", help="The path to the resulting python script file.") parser.add_option("-d", action="store_true", dest="debug", help="Don't create output file, but send output to stdout", default=False) (options, args) = parser.parse_args() if options.xmlfile is None or not os.path.exists(options.xmlfile): print "The input file MUST be specified and exist: %s" % options.xmlfile exit(1) now = datetime.datetime.now() if options.debug == False: if options.outfile is None: options.outfile = "%s.py" % (os.path.basename(options.xmlfile)) else: options.outfile = "%s%s.py" % (options.outfile, os.path.basename(options.xmlfile)) if os.path.exists(options.outfile): print "The output file already exists: %s" % options.outfile exit(1) outFile = open(options.outfile, "w") else: outFile = sys.stderr print "# Processing: %s Output: %s" % (options.xmlfile, outFile.name) dom = get_doc(options.xmlfile) glos = parse_xmlFile(dom, None, None) parse_xmlFile(dom, outFile, glos)