From 3075d0cf569d8adeacb74dd77b7d9f3bd6707101 Mon Sep 17 00:00:00 2001 From: Prasanna Santhanam Date: Wed, 13 Mar 2013 11:49:08 +0530 Subject: [PATCH] marvin: argparse enhancement and unit-test-xml-reporting dependency removed 1. deployAndRun will use the more modern argparse module 2. improving logging within the remoteSSHClient, moving to debug and default logging to INFO 3. removing dependance on the xmlrunner. use nose --with-xunit instead Signed-off-by: Prasanna Santhanam --- tools/marvin/marvin/TestCaseExecuteEngine.py | 13 ++---- tools/marvin/marvin/deployAndRun.py | 40 ++++++++----------- tools/marvin/marvin/remoteSSHClient.py | 9 ++--- .../sandbox/demo/simulator/simulator_setup.py | 2 +- tools/marvin/marvin/testSetupSuccess.py | 2 +- tools/marvin/pom.xml | 39 +++++++++++++++++- tools/marvin/setup.py | 5 +-- 7 files changed, 64 insertions(+), 46 deletions(-) diff --git a/tools/marvin/marvin/TestCaseExecuteEngine.py b/tools/marvin/marvin/TestCaseExecuteEngine.py index 3c34c7efdfc..57438688486 100644 --- a/tools/marvin/marvin/TestCaseExecuteEngine.py +++ b/tools/marvin/marvin/TestCaseExecuteEngine.py @@ -16,7 +16,6 @@ # under the License. import unittest -import xmlrunner import os import sys import logging @@ -27,7 +26,7 @@ def testCaseLogger(message, logger=None): logger.debug(message) class TestCaseExecuteEngine(object): - def __init__(self, testclient, config, testcaseLogFile=None, testResultLogFile=None, format="text", xmlDir="xml-reports"): + def __init__(self, testclient, config, testcaseLogFile=None, testResultLogFile=None): """ Initialize the testcase execution engine, just the basics here @var testcaseLogFile: client log file @@ -38,7 +37,6 @@ class TestCaseExecuteEngine(object): self.logformat = logging.Formatter("%(asctime)s - %(levelname)s - %(name)s - %(message)s") self.loader = unittest.loader.TestLoader() self.suite = None - self.format = format if testcaseLogFile is not None: self.logfile = testcaseLogFile @@ -56,9 +54,7 @@ class TestCaseExecuteEngine(object): self.testResultLogFile = fp else: self.testResultLogFile = sys.stdout - if self.format == "xml" and (xmlDir is not None): - self.xmlDir = xmlDir - + def loadTestsFromDir(self, testDirectory): """ Load the test suites from a package with multiple test files """ self.suite = self.loader.discover(testDirectory) @@ -92,7 +88,4 @@ class TestCaseExecuteEngine(object): def run(self): if self.suite: - if self.format == "text": - unittest.TextTestRunner(stream=self.testResultLogFile, verbosity=2).run(self.suite) - elif self.format == "xml": - xmlrunner.XMLTestRunner(output=self.xmlDir).run(self.suite) + unittest.TextTestRunner(stream=self.testResultLogFile, verbosity=2).run(self.suite) diff --git a/tools/marvin/marvin/deployAndRun.py b/tools/marvin/marvin/deployAndRun.py index e7b005caf68..c83065aaca9 100644 --- a/tools/marvin/marvin/deployAndRun.py +++ b/tools/marvin/marvin/deployAndRun.py @@ -17,22 +17,22 @@ import deployDataCenter import TestCaseExecuteEngine -from optparse import OptionParser -import os - +from argparse import ArgumentParser if __name__ == "__main__": - parser = OptionParser() #TODO: deprecate and use the argparse module - - parser.add_option("-c", "--config", action="store", default="./datacenterCfg", dest="config", help="the path where the json config file generated, by default is ./datacenterCfg") - parser.add_option("-d", "--directory", dest="testCaseFolder", help="the test case directory") - parser.add_option("-r", "--result", dest="result", help="test result log file") - parser.add_option("-t", "--client", dest="testcaselog", help="test case log file") - parser.add_option("-l", "--load", dest="load", action="store_true", help="only load config, do not deploy, it will only run testcase") - parser.add_option("-f", "--file", dest="module", help="run tests in the given file") - parser.add_option("-x", "--xml", dest="xmlrunner", help="use the xml runner to generate xml reports and path to store xml files") - (options, args) = parser.parse_args() - + parser = ArgumentParser() + + parser.add_argument("-d", "--directory", dest="testCaseFolder", help="the test case directory") + parser.add_argument("-f", "--file", dest="module", help="run tests in the given file") + parser.add_argument("-r", "--result", dest="result", help="test result log file", default='/tmp/t.log') + parser.add_argument("-t", "--client", dest="testcaselog", help="test case log file", default='/tmp/r.log') + parser.add_argument("-c", "--config", action="store", default="./datacenterCfg", dest="config", + help="the path where the json config file generated, by default is ./datacenterCfg") + parser.add_argument("-l", "--load", dest="load", action="store_true", + help="only load config, do not deploy, it will only run testcase") + + options = parser.parse_args() + testResultLogFile = None if options.result is not None: testResultLogFile = options.result @@ -46,12 +46,6 @@ if __name__ == "__main__": else: deploy.deploy() - fmt = "text" - xmlDir = None - if options.xmlrunner is not None: - xmlDir = options.xmlrunner - fmt = "xml" - if options.testCaseFolder is None: if options.module is None: parser.print_usage() @@ -61,15 +55,13 @@ if __name__ == "__main__": TestCaseExecuteEngine.TestCaseExecuteEngine(deploy.testClient, deploy.getCfg(), testCaseLogFile, - testResultLogFile, fmt, - xmlDir) + testResultLogFile) engine.loadTestsFromFile(options.module) engine.run() else: engine = TestCaseExecuteEngine.TestCaseExecuteEngine(deploy.testClient, deploy.getCfg(), testCaseLogFile, - testResultLogFile, - fmt, xmlDir) + testResultLogFile) engine.loadTestsFromDir(options.testCaseFolder) engine.run() diff --git a/tools/marvin/marvin/remoteSSHClient.py b/tools/marvin/marvin/remoteSSHClient.py index 95a9adab53f..4fb2f0de8f0 100644 --- a/tools/marvin/marvin/remoteSSHClient.py +++ b/tools/marvin/marvin/remoteSSHClient.py @@ -23,7 +23,7 @@ import logging from contextlib import closing class remoteSSHClient(object): - def __init__(self, host, port, user, passwd, retries = 10): + def __init__(self, host, port, user, passwd, retries = 10, log_lvl=logging.INFO): self.host = host self.port = port self.user = user @@ -32,14 +32,14 @@ class remoteSSHClient(object): self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) self.logger = logging.getLogger('sshClient') ch = logging.StreamHandler() - ch.setLevel(logging.DEBUG) + ch.setLevel(log_lvl) self.logger.addHandler(ch) retry_count = retries while True: try: self.ssh.connect(str(host),int(port), user, passwd) - self.logger.debug("connecting to server %s with user %s passwd %s"%(str(host), user, passwd)) + self.logger.debug("SSH connect: %s@%s with passwd %s"%(user, str(host), passwd)) except paramiko.SSHException, sshex: if retry_count == 0: raise cloudstackException.InvalidParameterException(repr(sshex)) @@ -52,7 +52,6 @@ class remoteSSHClient(object): def execute(self, command): stdin, stdout, stderr = self.ssh.exec_command(command) - self.logger.debug("sending command %s to host %s"%(command, str(self.host))) output = stdout.readlines() errors = stderr.readlines() results = [] @@ -64,7 +63,7 @@ class remoteSSHClient(object): else: for strOut in output: results.append(strOut.rstrip()) - self.logger.debug("command %s returned %s"%(command, results)) + self.logger.debug("{Cmd: %s via Host: %s} {returns: %s}"%(command, str(self.host), results)) return results def scp(self, srcFile, destPath): diff --git a/tools/marvin/marvin/sandbox/demo/simulator/simulator_setup.py b/tools/marvin/marvin/sandbox/demo/simulator/simulator_setup.py index 0d341408aea..e4ec9b7b1b1 100644 --- a/tools/marvin/marvin/sandbox/demo/simulator/simulator_setup.py +++ b/tools/marvin/marvin/sandbox/demo/simulator/simulator_setup.py @@ -41,7 +41,6 @@ def describeResources(config): z.name = 'Sandbox-%s'%(config.get('environment', 'hypervisor')) z.networktype = 'Advanced' z.guestcidraddress = '10.1.1.0/24' - z.vlan = config.get('cloudstack', 'zone.vlan') vpcprovider = provider() vpcprovider.name = 'VpcVirtualRouter' @@ -50,6 +49,7 @@ def describeResources(config): pn.name = "Sandbox-pnet" pn.traffictypes = [traffictype("Guest"), traffictype("Management"), traffictype("Public")] pn.providers.append(vpcprovider) + pn.vlan = config.get('cloudstack', 'zone.vlan') z.physical_networks.append(pn) diff --git a/tools/marvin/marvin/testSetupSuccess.py b/tools/marvin/marvin/testSetupSuccess.py index 8a0034cfa9b..319fd21c582 100644 --- a/tools/marvin/marvin/testSetupSuccess.py +++ b/tools/marvin/marvin/testSetupSuccess.py @@ -75,7 +75,7 @@ class TestSetupSuccess(cloudstackTestCase): retry = retry - 1 delay(60) #wait a minute for retry self.assertNotEqual(retry, 0, "builtIn templates not ready in zone %s"%z.name) - + @classmethod def tearDownClass(cls): pass diff --git a/tools/marvin/pom.xml b/tools/marvin/pom.xml index a3bd5460fd5..194d7841030 100644 --- a/tools/marvin/pom.xml +++ b/tools/marvin/pom.xml @@ -65,8 +65,8 @@ - package - package + install + install exec @@ -117,7 +117,42 @@ exec + + ${basedir}/marvin + /usr/local/bin/nosetests + + --with-marvin + --marvin-config + ${user.dir}/${marvin.config} + --load + -a + tags=simulator + ${basedir}/../../test/integration/smoke/test_vm_life_cycle.py + + + diff --git a/tools/marvin/setup.py b/tools/marvin/setup.py index fea53d07f8a..f8198d7999b 100644 --- a/tools/marvin/setup.py +++ b/tools/marvin/setup.py @@ -37,7 +37,6 @@ setup(name="Marvin", install_requires=[ "mysql-connector-python", "paramiko", - "nose", - "unittest-xml-reporting>1.2" - ], + "nose" + ], )