Return-Path: X-Original-To: apmail-incubator-cloudstack-commits-archive@minotaur.apache.org Delivered-To: apmail-incubator-cloudstack-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 44B8ECFC9 for ; Mon, 30 Jul 2012 10:07:22 +0000 (UTC) Received: (qmail 25583 invoked by uid 500); 30 Jul 2012 10:07:21 -0000 Delivered-To: apmail-incubator-cloudstack-commits-archive@incubator.apache.org Received: (qmail 25517 invoked by uid 500); 30 Jul 2012 10:07:21 -0000 Mailing-List: contact cloudstack-commits-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: cloudstack-dev@incubator.apache.org Delivered-To: mailing list cloudstack-commits@incubator.apache.org Received: (qmail 24998 invoked by uid 99); 30 Jul 2012 10:07:20 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 30 Jul 2012 10:07:20 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id 826131AF49; Mon, 30 Jul 2012 10:07:19 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: tsp@apache.org To: cloudstack-commits@incubator.apache.org X-Mailer: ASF-Git Admin Mailer Subject: [8/16] git commit: Plugin support to pick test cases using marvin. Message-Id: <20120730100719.826131AF49@tyr.zones.apache.org> Date: Mon, 30 Jul 2012 10:07:19 +0000 (UTC) Plugin support to pick test cases using marvin. Using this plugin Nose will drive tests and this also allows using other nose plugins. Cmd Line plugin support to be added Conflicts: tools/marvin/marvin/NoseTestExecuteEngine.py Project: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/commit/9af88ad4 Tree: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/tree/9af88ad4 Diff: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/diff/9af88ad4 Branch: refs/heads/master Commit: 9af88ad44d4465e3704fdb8917542a70f003b318 Parents: 0ab7a92 Author: Prasanna Santhanam Authored: Thu Jul 19 23:27:18 2012 +0530 Committer: Prasanna Santhanam Committed: Mon Jul 30 15:32:34 2012 +0530 ---------------------------------------------------------------------- tools/marvin/marvin/NoseTestExecuteEngine.py | 25 +++++---- tools/marvin/marvin/TestCaseExecuteEngine.py | 2 - tools/marvin/marvin/deployAndRun.py | 13 +++-- tools/marvin/marvin/marvinPlugin.py | 54 +++++++++++++++++++++ 4 files changed, 75 insertions(+), 19 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/9af88ad4/tools/marvin/marvin/NoseTestExecuteEngine.py ---------------------------------------------------------------------- diff --git a/tools/marvin/marvin/NoseTestExecuteEngine.py b/tools/marvin/marvin/NoseTestExecuteEngine.py index 25d5c93..5304afe 100644 --- a/tools/marvin/marvin/NoseTestExecuteEngine.py +++ b/tools/marvin/marvin/NoseTestExecuteEngine.py @@ -29,12 +29,13 @@ from nose.plugins.xunit import Xunit from nose.plugins.attrib import AttributeSelector from nose.plugins.multiprocess import MultiProcessTestRunner + class NoseTestExecuteEngine(object): """ Runs the CloudStack tests using nose as the execution engine """ - def __init__(self, testclient=None, workingdir=None, filename=None, clientLog=None, resultLog=None, format="text"): + def __init__(self, testclient=None, workingdir=None, filename=None, clientLog=None, resultLog=None, format="text", xmlDir='xml-reports'): self.testclient = testclient self.logformat = logging.Formatter("%(asctime)s - %(levelname)s - %(name)s - %(message)s") self.suite = [] @@ -57,15 +58,15 @@ class NoseTestExecuteEngine(object): self.testResultLogFile = sys.stderr if workingdir is not None: - self.loader = NoseCloudStackTestLoader() - self.loader.setClient(self.testclient) - self.loader.setClientLog(self.logfile) - self.suite = self.loader.loadTestsFromDir(workingdir) + self.workingdir = workingdir + self.test_picker = MarvinPlugin() + self.test_picker.setClient(self.testclient) + self.test_picker.setClientLog(self.logfile) elif filename is not None: - self.loader = NoseCloudStackTestLoader() - self.loader.setClient(self.testclient) - self.loader.setClientLog(self.logfile) - self.suite = self.loader.loadTestsFromFile(filename) + self.test_picker = MarvinPlugin() + self.test_picker.setClient(self.testclient) + self.test_picker.setClientLog(self.logfile) + self.filename = filename else: raise EnvironmentError("Need to give either a test directory or a test file") @@ -78,9 +79,11 @@ class NoseTestExecuteEngine(object): self.cfg.plugins = plug_mgr if format == "text": - self.runner = nose.core.TextTestRunner(stream=self.testResultLogFile, descriptions=1, verbosity=2, config=None) + self.runner = \ + nose.core.TextTestRunner(stream=self.testResultLogFile, + descriptions=1, verbosity=2, config=self.cfg) else: - self.runner = xmlrunner.XMLTestRunner(output='xml-reports', verbose=True) + self.runner = xmlrunner.XMLTestRunner(output=xmlDir, verbose=True) def runTests(self): options = ["--process-timeout=3600", "--with-xunit", "-a tags=advanced", "--processes=5"] #TODO: Add support for giving nose args http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/9af88ad4/tools/marvin/marvin/TestCaseExecuteEngine.py ---------------------------------------------------------------------- diff --git a/tools/marvin/marvin/TestCaseExecuteEngine.py b/tools/marvin/marvin/TestCaseExecuteEngine.py index 52a6dac..44a44aa 100644 --- a/tools/marvin/marvin/TestCaseExecuteEngine.py +++ b/tools/marvin/marvin/TestCaseExecuteEngine.py @@ -58,8 +58,6 @@ class TestCaseExecuteEngine(object): 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) http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/9af88ad4/tools/marvin/marvin/deployAndRun.py ---------------------------------------------------------------------- diff --git a/tools/marvin/marvin/deployAndRun.py b/tools/marvin/marvin/deployAndRun.py index 5b9e4dc..31faa09 100644 --- a/tools/marvin/marvin/deployAndRun.py +++ b/tools/marvin/marvin/deployAndRun.py @@ -22,7 +22,8 @@ from optparse import OptionParser import os if __name__ == "__main__": - parser = OptionParser() + + 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") @@ -31,7 +32,7 @@ if __name__ == "__main__": 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("-n", "--nose", dest="nose", action="store_true", help="run tests using nose") - parser.add_option("-x", "--xml", dest="xmlrunner", action="store", default="./xml-reports", help="use the xml runner to generate xml reports and path to store xml files") + 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() testResultLogFile = None @@ -47,8 +48,8 @@ if __name__ == "__main__": else: deploy.deploy() - format = "text" - xmlDir = "xml-reports" + format = "text" + xmlDir = None if options.xmlrunner is not None: xmlDir = options.xmlrunner format = "xml" @@ -59,7 +60,7 @@ if __name__ == "__main__": exit(1) else: if options.nose: - engine = NoseTestExecuteEngine.NoseTestExecuteEngine(deploy.testClient, testCaseLogFile, testResultLogFile, format) + engine = NoseTestExecuteEngine.NoseTestExecuteEngine(deploy.testClient, testCaseLogFile, testResultLogFile, format, xmlDir) engine.runTestsFromFile(options.module) else: engine = TestCaseExecuteEngine.TestCaseExecuteEngine(deploy.testClient, testCaseLogFile, testResultLogFile, format, xmlDir) @@ -67,7 +68,7 @@ if __name__ == "__main__": engine.run() else: if options.nose: - engine = NoseTestExecuteEngine.NoseTestExecuteEngine(deploy.testClient, clientLog=testCaseLogFile, resultLog=testResultLogFile, workingdir=options.testCaseFolder, format=format) + engine = NoseTestExecuteEngine.NoseTestExecuteEngine(deploy.testClient, clientLog=testCaseLogFile, resultLog=testResultLogFile, workingdir=options.testCaseFolder, format=format, xmlDir=xmlDir) engine.runTests() else: engine = TestCaseExecuteEngine.TestCaseExecuteEngine(deploy.testClient, testCaseLogFile, testResultLogFile, format, xmlDir) http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/9af88ad4/tools/marvin/marvin/marvinPlugin.py ---------------------------------------------------------------------- diff --git a/tools/marvin/marvin/marvinPlugin.py b/tools/marvin/marvin/marvinPlugin.py new file mode 100644 index 0000000..9d52362 --- /dev/null +++ b/tools/marvin/marvin/marvinPlugin.py @@ -0,0 +1,54 @@ +from cloudstackTestCase import cloudstackTestCase +from nose.plugins.base import Plugin +from functools import partial +import logging + +def testCaseLogger(message, logger=None): + if logger is not None: + logger.debug(message) + +class MarvinPlugin(Plugin): + """ + Custom test loader for the cloudstackTestCase to be loaded into nose + """ + + name = "marvin" + def configure(self, options, conf): + self.enabled = 1 + self.enableOpt = "--with-marvin" + return Plugin.configure(self, options, conf) + + def options(self, parser, env): + Plugin.options(self, parser, env) + + def __init__(self): + Plugin.__init__(self) + + def wantClass(self, cls): + if issubclass(cls, cloudstackTestCase): + return True + return None + + def loadTestsFromTestCase(self, cls): + self._injectClients(cls) + + def setClient(self, client): + if client: + self.testclient = client + + def setClientLog(self, clientlog): + if clientlog: + self.log = clientlog + + def _injectClients(self, test): + testcaselogger = logging.getLogger("testclient.testcase.%s" % test.__class__.__name__) + fh = logging.FileHandler(self.log) + fh.setFormatter(logging.Formatter("%(asctime)s - %(levelname)s - %(name)s - %(message)s")) + testcaselogger.addHandler(fh) + testcaselogger.setLevel(logging.DEBUG) + + setattr(test, "testClient", self.testclient) + setattr(test, "debug", partial(testCaseLogger, logger=testcaselogger)) + setattr(test, "clstestclient", self.testclient) + if hasattr(test, "UserName"): + self.testclient.createNewApiClient(test.UserName, test.DomainName, test.AcctType)