mirror of
https://github.com/apache/cloudstack.git
synced 2025-11-02 11:52:28 +01:00
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:
parent
ed113ca844
commit
13857700d3
@ -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()
|
||||
|
||||
@ -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)
|
||||
|
||||
|
||||
29
tools/marvin/marvin/setup.py
Normal file
29
tools/marvin/marvin/setup.py
Normal 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'],
|
||||
)
|
||||
Loading…
x
Reference in New Issue
Block a user