# Copyright 2012 Citrix Systems, Inc. Licensed under the # Apache License, Version 2.0 (the "License"); you may not use this # file except in compliance with the License. Citrix Systems, Inc. # reserves all rights not expressly granted by the License. # You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # Automatically generated by addcopyright.py at 04/03/2012 import xml.dom.minidom import datetime from optparse import OptionParser import random import os import sys # Constants INDENT = " " INDENT2 = INDENT + INDENT class xml_to_python(object): def __init__(self, debug): ''' constructor ''' self.debug = debug self._output = False self.out_buffer = [] self.cmd_name = None self.cmd_name_var = None self.cmd_name_resp = None self.glos = [] def _write(self, output_string): ''' internal print function ''' self.out_buffer.append("%s\n" % output_string) def parse_parameters(self, dom): ''' process parameters of command ''' for param in dom.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: itemValue = None try: itemParam = item.getElementsByTagName("param")[0].childNodes[0].nodeValue.strip() except: itemParam = None # handle getparam and setparam and random attributes here... if item.getAttribute("getparam") == "true" and itemParam is not None: self._write("%s%s.%s = %s" % (INDENT, self.cmd_name_var, itemName, itemParam)) self.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) self._write("%s%s.%s = '%s-randomName'" % (INDENT, self.cmd_name_var, itemName, str(randValue))) if item.getAttribute("setparam") == "true" and itemParam is not None: self._write("%s%s = '%s-randomName'" % (INDENT, itemParam, str(randValue))) self.glos.append(itemParam) else: try: val = int(itemValue) except: val = "'%s'" % itemValue self._write("%s%s.%s = %s" % (INDENT, self.cmd_name_var, itemName, val)) def parse_returnvalue(self, dom): ''' process returnvalue section of command ''' for return_val in dom.getElementsByTagName("returnvalue"): for item in return_val.getElementsByTagName("item"): #if item.getAttribute("list") == "true": itemName = item.getElementsByTagName("name")[0].childNodes[0].nodeValue.strip() try: itemParam = item.getElementsByTagName("param")[0].childNodes[0].nodeValue.strip() except: print "parse_returnvalue: No 'param' found in : '" + item.toprettyxml() + "'" itemParam = None if item.getAttribute("setparam") == "true": self._write("%s%s = %s.%s" % (INDENT, itemParam, self.cmd_name_resp, itemName)) else: self._write("%sif %s != %s.%s:" % (INDENT, itemParam, self.cmd_name_resp, itemName)) self._write("%sprint %s.%s + \" does not match \" + %s" % ( INDENT2, self.cmd_name_resp, itemName, itemParam)) def parse_command(self, dom): ''' process command elements and their children ''' for cmd in dom.getElementsByTagName("command"): self.cmd_name = cmd.getElementsByTagName("name")[0].childNodes[0].nodeValue.strip() self.cmd_name_var = "_%s" % self.cmd_name self.cmd_name_resp = "resp_%s" % self.cmd_name try: testCaseName = cmd.getElementsByTagName("testcase")[0].childNodes[0].nodeValue.strip() except: print "parse_command: No 'testcase' found in: " + cmd.toprettyxml() testCaseName = None self._write("\n%s# %s" % (INDENT, testCaseName)) self._write("%s%s = %s.%sCmd()" % (INDENT, self.cmd_name_var, self.cmd_name, self.cmd_name)) self.parse_parameters(cmd) # now we execute command self._write("%s%s = apiClient.%s(%s)" % (INDENT, self.cmd_name_resp, self.cmd_name, self.cmd_name_var)) self._write("%sif %s is None:" % (INDENT, self.cmd_name_resp)) self._write("%sprint 'test [%s] failed'" % (INDENT2, testCaseName)) self._write("%selse:" % INDENT) self._write("%sprint 'test [%s] succeeded'" % (INDENT2, testCaseName)) self.parse_returnvalue(cmd) def generate_python_header(self, outfile): ''' generates python file header the basic stuff to bootstrap the script ''' now = datetime.datetime.now() outfile.write("# Generated by translator.py\n") outfile.write("# from %s\n" % options.xmlfile) outfile.write("# on %s\n\n" % str(now)) outfile.write("from cloudstackTestCase import *\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 set(self.glos): outfile.write("%s = None\n" % key) outfile.write("# End of globals\n\n") outfile.write("if __name__ == \"__main__\":\n") outfile.write("%s# Possible initialization parameters:\n" % INDENT) outfile.write("%s# cloudstackTestClient(mgtSvr=None, port=8096, apiKey = None, securityKey = None,\n" % INDENT) outfile.write("%s# asyncTimeout=3600, defaultWorkerThreads=10, logging=None)\n" % INDENT) outfile.write("%stestClient = cloudstackTestClient.cloudstackTestClient(\"localhost\")\n" % INDENT) outfile.write("%sapiClient = testClient.getApiClient()\n" % INDENT) def output_python(self, outfile): self.generate_python_header(outfile) for line in self.out_buffer: outfile.write(line) outfile.close() def parse_xmlFile(self, xmlFile, outfile): ''' parse_xmlFile, this is the main function of the translator ''' dom = xml.dom.minidom.parse(xmlFile) self.parse_command(dom) self.output_python(outfile) if __name__ == "__main__": opts = OptionParser() opts.add_option("-i", "--inputfile", dest="xmlfile", help="The XML file and it's path containing tests.", default="../../test/metadata/func/portforwarding.xml") opts.add_option("-o", "--output_file_path", dest="outpath", help="The path where we create the python file.") opts.add_option("-d", action="store_true", dest="debug", help="Don't create output file, but send output to stderr", default=False) (options, args) = opts.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) if options.debug == False: if options.outpath is None: options.outpath = "%s.py" % (os.path.basename(options.xmlfile)) else: if options.outpath.endswith('/'): options.outpath = "%s%s.py" % (options.outpath, os.path.basename(options.xmlfile)) else: options.outpath = "%s/%s.py" % (options.outpath, os.path.basename(options.xmlfile)) if os.path.exists(options.outpath): print "The output file already exists: %s" % options.outpath exit(1) outFile = open(options.outpath, "w") else: outFile = sys.stderr print("[Processing: %s Output: %s]" % (options.xmlfile, outFile.name)) processor = xml_to_python(options.debug) processor.parse_xmlFile(options.xmlfile, outFile)