You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by sa...@apache.org on 2014/09/07 17:15:25 UTC

[2/2] git commit: updated refs/heads/master to 6c4978c

Adding new marvincli changes(draft)


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/6c4978c4
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/6c4978c4
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/6c4978c4

Branch: refs/heads/master
Commit: 6c4978c40c14bd0d0753623b55071bb6a864e033
Parents: 412791e
Author: Santhosh Edukulla <sa...@gmail.com>
Authored: Sun Sep 7 20:44:43 2014 +0530
Committer: Santhosh Edukulla <sa...@gmail.com>
Committed: Sun Sep 7 20:44:43 2014 +0530

----------------------------------------------------------------------
 tools/marvin/marvin/deployAndRun.py | 293 +++++++++++++++++++------------
 tools/marvin/marvin/marvinInit.py   |  10 +-
 2 files changed, 185 insertions(+), 118 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6c4978c4/tools/marvin/marvin/deployAndRun.py
----------------------------------------------------------------------
diff --git a/tools/marvin/marvin/deployAndRun.py b/tools/marvin/marvin/deployAndRun.py
index 611e167..5955bc9 100644
--- a/tools/marvin/marvin/deployAndRun.py
+++ b/tools/marvin/marvin/deployAndRun.py
@@ -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__":

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6c4978c4/tools/marvin/marvin/marvinInit.py
----------------------------------------------------------------------
diff --git a/tools/marvin/marvin/marvinInit.py b/tools/marvin/marvin/marvinInit.py
index e888484..c6ee1a2 100644
--- a/tools/marvin/marvin/marvinInit.py
+++ b/tools/marvin/marvin/marvinInit.py
@@ -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: