diff --git a/tools/testClient/translator.py b/tools/testClient/translator.py new file mode 100644 index 00000000000..fe5beee0c5e --- /dev/null +++ b/tools/testClient/translator.py @@ -0,0 +1,157 @@ +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) \ No newline at end of file