Plugin-izing the testcase runner

* setup.py is the installer for marvin-nose plugin
* marvin-nose drive all tests using nose with other plugins like xunit, coverage, multiprocess execution etc
* -n option deprecated. All tests driven by nosetests --with-marvin
This commit is contained in:
Prasanna Santhanam 2012-07-23 19:23:04 +05:30 committed by Prasanna Santhanam
parent ed113ca844
commit 13857700d3
3 changed files with 95 additions and 29 deletions

View File

@ -17,7 +17,6 @@
import deployDataCenter
import TestCaseExecuteEngine
import NoseTestExecuteEngine
from optparse import OptionParser
import os
@ -31,7 +30,6 @@ if __name__ == "__main__":
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("-n", "--nose", dest="nose", action="store_true", help="run tests using nose")
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()
@ -59,18 +57,10 @@ if __name__ == "__main__":
parser.print_usage()
exit(1)
else:
if options.nose:
engine = NoseTestExecuteEngine.NoseTestExecuteEngine(deploy.testClient, testCaseLogFile, testResultLogFile, format, xmlDir)
engine.runTestsFromFile(options.module)
else:
engine = TestCaseExecuteEngine.TestCaseExecuteEngine(deploy.testClient, testCaseLogFile, testResultLogFile, format, xmlDir)
engine.loadTestsFromFile(options.module)
engine.run()
engine = TestCaseExecuteEngine.TestCaseExecuteEngine(deploy.testClient, testCaseLogFile, testResultLogFile, format, xmlDir)
engine.loadTestsFromFile(options.module)
engine.run()
else:
if options.nose:
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)
engine.loadTestsFromDir(options.testCaseFolder)
engine.run()
engine = TestCaseExecuteEngine.TestCaseExecuteEngine(deploy.testClient, testCaseLogFile, testResultLogFile, format, xmlDir)
engine.loadTestsFromDir(options.testCaseFolder)
engine.run()

View File

@ -1,7 +1,10 @@
from cloudstackTestCase import cloudstackTestCase
import marvin
import logging
import nose.core
from marvin.cloudstackTestCase import cloudstackTestCase
from marvin import deployDataCenter
from nose.plugins.base import Plugin
from functools import partial
import logging
def testCaseLogger(message, logger=None):
if logger is not None:
@ -9,21 +12,69 @@ def testCaseLogger(message, logger=None):
class MarvinPlugin(Plugin):
"""
Custom test loader for the cloudstackTestCase to be loaded into nose
Custom plugin for the cloudstackTestCases to be run using nose
"""
name = "marvin"
def configure(self, options, conf):
def configure(self, options, config):
self.enabled = 1
self.enableOpt = "--with-marvin"
return Plugin.configure(self, options, conf)
self.logformat = logging.Formatter("%(asctime)s - %(levelname)s - %(name)s - %(message)s")
if options.debug_log:
self.logger = logging.getLogger("NoseTestExecuteEngine")
self.debug_stream = logging.FileHandler(options.debug_log)
self.debug_stream.setFormatter(self.logformat)
self.logger.addHandler(self.debug_stream)
self.logger.setLevel(logging.DEBUG)
if options.result_log:
ch = logging.StreamHandler()
ch.setLevel(logging.ERROR)
ch.setFormatter(self.logformat)
self.logger.addHandler(ch)
self.result_stream = open(options.result_log, "w")
else:
self.result_stream = sys.stderr
deploy = deployDataCenter.deployDataCenters(options.config)
deploy.loadCfg() if options.load else deploy.deploy()
self.setClient(deploy.testClient)
cfg = nose.config.Config()
cfg.logStream = self.result_stream
cfg.debugLog = self.debug_stream
cfg.workingDir = options.test_dir
self.testrunner = nose.core.TextTestRunner(stream=self.result_stream, descriptions=True, verbosity=2, config=config)
def options(self, parser, env):
"""
Register command line options
"""
parser.add_option("--marvin-config", action="store",
default=env.get('MARVIN_CONFIG', './datacenter.cfg'),
dest="config",
help="Marvin's configuration file where the datacenter information is specified [MARVIN_CONFIG]")
parser.add_option("--result-log", action="store",
default=env.get('RESULT_LOG', 'result.log'),
dest="result_log",
help="The path to the results file where test summary will be written to [RESULT_LOG]")
parser.add_option("--client-log", action="store",
default=env.get('DEBUG_LOG', 'debug.log'),
dest="debug_log",
help="The path to the testcase debug logs [DEBUG_LOG]")
parser.add_option("--load", action="store_true", default=False, dest="load",
help="Only load the deployment configuration given")
Plugin.options(self, parser, env)
def __init__(self):
Plugin.__init__(self)
def prepareTestRunner(self, runner):
return self.testrunner
def wantClass(self, cls):
if issubclass(cls, cloudstackTestCase):
return True
@ -36,15 +87,10 @@ class MarvinPlugin(Plugin):
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 = logging.getLogger("testclient.testcase.%s" % test.__name__)
self.debug_stream.setFormatter(logging.Formatter("%(asctime)s - %(levelname)s - %(name)s - %(message)s"))
testcaselogger.addHandler(self.debug_stream)
testcaselogger.setLevel(logging.DEBUG)
setattr(test, "testClient", self.testclient)
@ -52,3 +98,4 @@ class MarvinPlugin(Plugin):
setattr(test, "clstestclient", self.testclient)
if hasattr(test, "UserName"):
self.testclient.createNewApiClient(test.UserName, test.DomainName, test.AcctType)

View File

@ -0,0 +1,29 @@
import os
from setuptools import setup
def read(fname):
return open(os.path.join(os.path.dirname(__file__), fname)).read().strip()
VERSION = '0.1.0'
setup(
name = "marvin-nose",
version = VERSION,
author = "Prasanna Santhanam",
author_email = "Prasanna.Santhanam@citrix.com",
description = "Run tests written using CloudStack's Marvin testclient",
license = 'ASL 2.0',
classifiers = [
"Intended Audience :: Developers",
"Topic :: Software Development :: Testing",
"Programming Language :: Python",
],
py_modules = ['marvinPlugin'],
zip_safe = False,
entry_points = {
'nose.plugins': ['marvinPlugin = marvinPlugin:MarvinPlugin']
},
install_requires = ['nose', 'marvin'],
)