Adding new marvincli changes(draft)

This commit is contained in:
Santhosh Edukulla 2014-09-07 20:44:43 +05:30
parent 412791e09f
commit 6c4978c40c
2 changed files with 185 additions and 118 deletions

View File

@ -20,6 +20,7 @@ import os
from optparse import OptionParser
import cmd
import random
from collections import OrderedDict
from marvin.marvinInit import MarvinInit
from marvin.deployDataCenter import DeployDataCenters
from marvin.cloudstackException import GetDetailExceptionInfo
@ -31,73 +32,6 @@ from marvin.codes import (SUCCESS,
from marvin.tcExecuteEngine import TestCaseExecuteEngine
class MarvinCliHelp(object):
@classmethod
def do_printhelp(cls):
print "\n1. for building marvin from spec file and installing."
cls.help_build_and_install()
print "\n2. for syncing apis and installing marvin."
cls.help_sync_and_install()
print "\n3. for deploying a datacenter"
cls.help_deploydc()
print "\n4. for running test cases"
cls.help_runtest()
print "\n5. for deploying a datacenter (and) running tests"
cls.help_deploydc_and_runtest()
print "\n6. for generating apis from spec file"
cls.help_generateapis_from_apispecfile()
print "\n7. for generating apis from end point"
cls.help_generateapis_from_endpoint()
print "\n8. for printing marvincli version"
cls.help_printversion()
@classmethod
def print_msg(cls, msg):
print ShellColor.BOLD + ShellColor.RED + msg + ShellColor.END
@classmethod
def help_printversion(cls):
cls.print_msg("marvincli -v or --version")
@classmethod
def help_deploydc(cls):
cls.print_msg(
"marvincli [deploydc] \n\t[config-file=<marvin-config-file EX: advanced.cfg file>]")
@classmethod
def help_deploydc_and_runtest(cls, deploy=False):
msg = "marvincli [deploydc_and_runtest] \n\t[config-file=<path_to_marvin_cfg> \n\ttc-path=<test suite or test suite folder path>" \
"\n\tzone=<name of the zone> \n\thyp-type=<hypervisor_type> " \
"\n\trequired_hardware=<true\\false>]"
cls.print_msg(msg)
@classmethod
def help_generateapis_from_apispecfile(cls):
cls.print_msg(
"marvincli [generateapis_from_apispecfile] \n\t[cs-folder-path=<cloudstack code root dir EX: /root/cs-4.5/cloudstack/> \n\tapi-spec-file=<api spec file EX: /etc/cloud/cli/commands.xml>]")
@classmethod
def help_generateapis_from_endpoint(cls):
cls.print_msg(
"marvincli [generateapis_from_endpoint] \n\t[cs-folder-path=<cloudstack code root dir EX: /root/cs-4.5/cloudstack/> \n\tend-point=<CS Endpoint ip EX: localhost>]")
@classmethod
def help_runtest(cls):
cls.print_msg(
"marvincli [runtest] \n\t[config-file=<path_to_marvin_config> \n\ttc-path=test/integration/smoke \n\trequired_hardware=<true\\false> \n\tzone=<name of zone> \n\thyp-type=<xenserver\\kvm\\vmware> etc]")
@classmethod
def help_sync_and_install(cls):
cls.print_msg(
"marvincli [sync_and_install] \n\t[cs-folder-path=<cloudstack code root dir EX: /root/cs-4.5/cloudstack/> \n\tend-point=<CS installed host ip EX: localhost>]")
@classmethod
def help_build_and_install(cls):
cls.print_msg(
"marvincli [build_and_install] \n\t[cs-folder-path=<cloudstack code root dir EX: /root/cs-4.5/cloudstack/> \n\tapi-sync-file<api spec file generated by cs EX: /etc/cloud/cli/commands.xml>]")
class VerifyAndExit(object):
def __init__(self, msg):
@ -110,26 +44,113 @@ class VerifyAndExit(object):
if original_func(*args, **kwargs) == FAILED:
exit_check = True
except Exception as e:
print "---", e
print "===Exception.Please Check:===", e
exit_check = True
finally:
if exit_check:
print "==== %s ====" % self.msg
MarvinCliHelp.do_printhelp()
MarvinCliHelp.print_cmds_help()
sys.exit(1)
return new_function
class MarvinCliCommands(object):
cmds_info = {'deploydc': {'options': ['config-file'], 'help': 'config-file=<marvin-config-file EX: advanced.cfg file>'},
'deploydc_and_runtest': {'options': ['config-file', 'tc-path', 'zone', 'hyp-type', 'required_hardware'], 'help': ''},
'generateapis_from_endpoint': {'options': '', 'help': '[cs-folder-path=<cloudstack code root dir EX: /root/cs-4.5/cloudstack/> \n\tend-point=<CS Endpoint ip EX: localhost>]'},
'generateapis_from_apispecfile': {'options': '', 'help': '[cs-folder-path=<cloudstack code root dir EX: /root/cs-4.5/cloudstack/> \n\tapi-spec-file=<api spec file EX: /etc/cloud/cli/commands.xml>]'},
'runtest': {'options': '', 'help': '[config-file=<path_to_marvin_config> \n\ttc-path=test/integration/smoke \n\trequired_hardware=<true\\false> \n\tzone=<name of zone> \n\thyp-type=<xenserver\\kvm\\vmware> etc]'},
'sync_and_install': {'options': ['sync_and_install'], 'help': '[marvincli sync_and_install cs-folder-path=<cloudstack code root dir EX: /root/cs-4.5/cloudstack/> \n\tend-point=<CS installed host ip EX: localhost>]'},
'build_and_install': {'options': ['build_and_install'], 'help': '[marvincli build_and_install cs-folder-path=<cloudstack code root dir EX: /root/cs-4.5/cloudstack/> \n\tapi-sync-file<api spec file generated by cs EX: /etc/cloud/cli/commands.xml>]'},
'version': {'options': '', 'help': ''}
}
cmds_info = OrderedDict({
'deploydc':
{
'summary': 'for deploying a datacenter',
'options': ['*config-file'],
'help': 'marvincli deploydc config-file=<marvin-config-file EX: setup/dev/advanced.cfg file>',
'desc': 'deploys a data center using the config file provided'
},
'deploydc_and_runtest':
{
'summary': 'for deploying a datacenter (and) running tests, either test suite (or) directory of test suites',
'options': ['*config-file', '*tc-path', 'zone', 'hyp-type', 'required_hardware'],
'help': 'marvincli deploydc_and_runtest config-file=<path_to_marvin_cfg EX: setup/dev/advanced.cfg>'
'tc-path=<test suite or test suite folder path EX: test/integration/smoke/>'
'zone=<name of the zone> hyp-type=<hypervisor_type EX: xen,kvm,vmware etc> required_hardware=<true\\false>',
'desc': 'deploys a data center using the config file provided, and runs test cases using the test suite or directory of test suites provided. '
'If zone to run against is not provided, then default zone mentioned in config file is provided '
'If hyp-type information is not provided, first hypervisor from config file is taken. '
'If required_hardware option is not provided, then it is set to false'
},
'generateapis_from_endpoint':
{
'summary': 'for generating apis from cs end point',
'options': ['*cs-folder-path', 'end-point'],
'help': 'marvincli generateapis_from_endpoint cs-folder-path=<cloudstack code root dir EX: /root/cs-4.5/cloudstack/>'
'end-point=<CS Endpoint ip EX: localhost>',
'desc': 'generates cloudstackAPI directory with CS apis information from cloudstack endpoint. '
'If end-point information is not provided, localhost is considered as default'
},
'generateapis_from_apispecfile':
{
'summary': 'for generating apis from api spec file',
'options': ['*cs-folder-path', 'api-spec-file'],
'help': 'marvincli generateapis_from_apispecfile cs-folder-path=<cloudstack code root dir EX: /root/cs-4.5/cloudstack/>'
'api-spec-file=<api spec file EX: /etc/cloud/cli/commands.xml>',
'desc': 'generates cloudstackAPI directory with CS apis information from cloudstack api spec file. '
'If spec file information is not provided, /etc/cloud/cli/commands.xml is considered as default'
},
'runtest':
{
'summary': 'for running test cases, either test suite (or) directory of test suites',
'options': ['*config-file', '*tc-path', 'required_hardware', 'zone', 'hyp-type'],
'help': 'marvincli runtest config-file=<path_to_marvin_config> tc-path=test/integration/smoke'
'required_hardware=<true\\false> zone=<name of zone> hyp-type=<xenserver\\kvm\\vmware> etc',
'desc': 'runs marvin integration tests against CS using config file, test suite path or directory of test suites are provided as input for running tests',
},
'sync_and_install':
{
'summary': 'for syncing apis and installing marvin using cs endpoint',
'options': ['*cs-folder-path', 'end-point'],
'help': 'marvincli sync_and_install cs-folder-path = <cloudstack code root dir EX: /root/cs-4.5/cloudstack/>'
'end-point = <CS installed host ip EX: localhost>',
'desc': 'generates cloudstackAPI directory with CS apis information from cloudstack end-point (and) installs new marvin.'
'If end-point information is not provided, localhost is considered as default'
},
'build_and_install':
{
'summary': 'for building and installing marvin using spec file',
'options': ['*cs-folder-path', 'api-sync-file'],
'help': 'marvincli build_and_install cs-folder-path = <cloudstack code root dir EX: /root/cs-4.5/cloudstack/>'
'api-sync-file = <api spec file generated by cs EX: /etc/cloud/cli/commands.xml>',
'desc': 'generates cloudstackAPI directory with CS apis information from cloudstack api-spec-file (and) installs new marvin.'
'If api spec file information is not provided, /etc/cloud/cli/commands.xml is considered as default'
},
'version':
{
'summary': 'for printing marvincli version',
'options': ['-v (or) --version'],
'help': 'marvincli -v (or) marvincli --version',
'desc': 'prints the version of marvincli'
}
})
class MarvinCliHelp(object):
@classmethod
def print_cmds_help(cls):
msg = ''
for cmd_name, cmd_txt in MarvinCliCommands.cmds_info.items():
msg = msg + \
'\n----------------------------------------------------\n'
cmd_info = ShellColor.BOLD + ShellColor.RED + \
'cmd_name:%s' % str(cmd_name) + ShellColor.END
for key, value in cmd_txt.iteritems():
cmd_info = cmd_info + '\n' + \
str(key) + ' : ' + str(value).strip('\n')
msg = msg + cmd_info
# return ShellColor.BOLD + ShellColor.RED + msg + ShellColor.END
return msg
@classmethod
def print_msg(cls, msg):
if msg:
return ShellColor.BOLD + ShellColor.RED + msg + ShellColor.END
class ShellColor(object):
@ -163,7 +184,8 @@ class MarvinCli(cmd.Cmd, object):
self.__csFolder = "."
cmd.Cmd.__init__(self)
@VerifyAndExit("Invalid input options, please check")
@VerifyAndExit(
"cmd failed, may be invalid input options, please check help")
def parse_input_deploy(self, inputs=None):
'''
Parses,reads the options and verifies for the config file
@ -181,7 +203,8 @@ class MarvinCli(cmd.Cmd, object):
return SUCCESS
return FAILED
@VerifyAndExit("Invalid input options, please check")
@VerifyAndExit(
"cmd failed, may be invalid input options, please check help")
def parse_input_runtcs(self, inputs):
'''
Parses,reads the options and verifies for the config file
@ -193,7 +216,6 @@ class MarvinCli(cmd.Cmd, object):
(key, value) = item.split('=')
out_dict[key] = value
self.__configFile = out_dict.get('config-file', None)
self.__deployFlag = out_dict.get('deploy', False)
self.__zone = out_dict.get("zone", None)
self.__hypervisorType = out_dict.get("hyp-type", None)
self.__tcPath = out_dict.get("tc-path",)
@ -225,13 +247,13 @@ class MarvinCli(cmd.Cmd, object):
return FAILED
except Exception as e:
print "====Exception Occurred under start_marvin: %s ====" % \
GetDetailExceptionInfo(e)
GetDetailExceptionInfo(e)
return FAILED
def run_test_suites(self):
print "\n==== Started Running Test Cases ===="
xunit_out_path = "/tmp/marvin_xunit_out" + \
str(random.randrange(1, 10000)) + ".xml"
str(random.randrange(1, 10000)) + ".xml"
marvin_tc_run_cmd = "nosetests-2.7 -s --with-marvin --marvin-config=%s --with-xunit --xunit-file=%s %s -a tags=advanced, required_hardware=%s --zone=%s --hypervisor=%s"
if os.path.isfile(self.__tcPath):
marvin_tc_run_cmd = marvin_tc_run_cmd % (self.__configFile,
@ -252,16 +274,32 @@ class MarvinCli(cmd.Cmd, object):
'''
print "\n==== Running Test Cases Successful ===="
def do_deploy(self, args):
self.__deployFlag = True
self.parse_input_deploy(inputs=args)
self.start_marvin()
@VerifyAndExit(
"cmd failed, may be invalid input options, please check help")
def do_deploydc(self, args):
try:
self.__deployFlag = True
self.parse_input_deploy(inputs=args)
self.start_marvin()
return SUCCESS
except Exception as e:
print "==== deploy cmd failed :%s ==== " % str(e)
return FAILED
@VerifyAndExit(
"cmd failed, may be invalid input options, please check help")
def do_deploydc_and_runtest(self, args):
self.do_deploy(inputs=args)
self.parse_input_runtcs()
self.run_test_suites()
try:
self.do_deploy(inputs=args)
self.parse_input_runtcs()
self.run_test_suites()
return SUCCESS
except Exception as e:
print "==== deploydc cmd failed:%s ==== " % str(e)
return FAILED
@VerifyAndExit(
"cmd failed, may be invalid input options, please check help")
def do_generateapis_from_apispecfile(self, args):
api_spec_file = "/etc/cloud/cli/commands.xml"
cs_api_folder = "."
@ -281,11 +319,11 @@ class MarvinCli(cmd.Cmd, object):
if api_spec_file:
try:
cg.generateCodeFromXML(api_spec_file)
return
return SUCCESS
except Exception as e:
print "==== Generating apis from api spec file failed: %s ====" % str(e.message())
sys.exit(1)
sys.exit(1)
return FAILED
return FAILED
def create_marvin_api_folder(self, cs_folder_path='.'):
cs_api_folder = cs_folder_path + "/tools/marvin/marvin/cloudstackAPI"
@ -295,6 +333,8 @@ class MarvinCli(cmd.Cmd, object):
os.makedirs(cs_api_folder)
return cs_api_folder
@VerifyAndExit(
"cmd failed, may be invalid input options, please check help")
def do_generateapis_from_endpoint(self, args):
endpoint_url = 'http://%s:8096/client/api?command=listApis&\
response=json'
@ -312,36 +352,54 @@ response=json'
try:
endpoint_url = endpoint_url % str(cs_end_point)
cg.generateCodeFromJSON(endpoint_url)
return
return SUCCESS
except Exception as e:
print "==== Generating apis from end point failed: %s ====" % str(e.message())
sys.exit(1)
sys.exit(1)
return FAILED
return FAILED
@VerifyAndExit(
"cmd failed, may be invalid input options, please check help")
def do_runtest(self, args):
self.parse_input_runtcs(args)
self.start_marvin()
self.run_test_suites()
try:
self.parse_input_runtcs(args)
self.start_marvin()
self.run_test_suites()
return SUCCESS
except Exception as e:
print "==== run test failed: %s ====" % str(e.message())
return FAILED
def install_marvin(self):
if self.__csFolder:
marvin_setup_file_path = self.__csFolder + "/tools/marvin/setup.py"
# step2: Build and install the Marvin
try:
os.system("python %s install" % str(marvin_setup_file_path))
print "==== Marvin Installed Successfully ===="
except Exception as e:
print "==== Marvin Installation Failed ===="
print "==== Marvin Installed Successfully ===="
@VerifyAndExit(
"cmd failed, may be invalid input options, please check help")
def do_build_and_install(self, args):
# step1: Generate the apis from spec file first
self.do_generateapis_from_apispecfile(args)
self.install_marvin()
try:
self.do_generateapis_from_apispecfile(args)
self.install_marvin()
return SUCCESS
except Exception as e:
print "==== build from end point and install marvin failed: %s ====" % str(e)
return FAILED
@VerifyAndExit(
"cmd failed, may be invalid input options, please check help")
def do_sync_and_install(self, args):
# step1: Generate the apis from spec file first
self.do_generateapis_from_endpoint(args)
self.install_marvin()
try:
self.do_generateapis_from_endpoint(args)
self.install_marvin()
return SUCCESS
except Exception as e:
print "==== sync from spec file and install marvin failed: %s ====" % str(e)
return FAILED
class MarvinCliParser(OptionParser):
@ -349,9 +407,14 @@ class MarvinCliParser(OptionParser):
def format_help(self, formatter=None):
if formatter is None:
formatter = self.formatter
print MarvinCliHelp.print_msg("Usage: marvincli [cmd] [options].See, the below cmds for more information \n\n")
print MarvinCliHelp.do_printhelp()
return "\n===========================================================================\n"
result = []
if self.usage:
result.append(MarvinCliHelp.print_msg("\nUsage: marvincli [cmd] [options]. See, the below cmds for more information."
"(*) signifies mandatory fields \n\n"))
self.description = MarvinCliHelp.print_cmds_help()
if self.description:
result.append(self.format_description(formatter) + "\n")
return "".join(result)
def main():
@ -364,12 +427,14 @@ def main():
MarvinCliHelp.help_printversion()
sys.exit(0)
if len(sys.argv) > 1:
if sys.argv[1].lower() in ["deploydc", "deploydc_and_runtest", "generateapis_from_endpoint",
"generateapis_from_apispecfile", "runtest", "sync_and_install", "build_and_install"]:
MarvinCli().onecmd(' '.join(args))
else:
if sys.argv[1].lower() not in MarvinCliCommands.cmds_info.keys():
print "\n==== Invalid Command ===="
sys.exit(1)
args = ' '.join(args)
if '-h' in args or '--help' in args:
print MarvinCliCommands.cmds_info[sys.argv[0]]
else:
MarvinCli().onecmd(args)
sys.exit(0)
if __name__ == "__main__":

View File

@ -111,10 +111,12 @@ class MarvinInit:
if not self.__hypervisorType:
if self.__parsedConfig and self.__parsedConfig.zones is not None:
for zone in self.__parsedConfig.zones:
for pod in zone.pods and pod is not None:
for cluster in pod.clusters and cluster is not None:
self.__hypervisorType = cluster.hypervisor
break
for pod in zone.pods:
if pod is not None:
for cluster in pod.clusters:
if cluster is not None and cluster.hypervisor is not None:
self.__hypervisorType = cluster.hypervisor
break
if not self.__zoneForTests:
if self.__parsedConfig and self.__parsedConfig.zones is not None:
for zone in self.__parsedConfig.zones: