From 3144e01c13b4a488c557a74849eafe4161566784 Mon Sep 17 00:00:00 2001 From: Santhosh Edukulla Date: Tue, 10 Dec 2013 20:25:23 +0530 Subject: [PATCH] CLOUDSTACK-5423: Fixed 5423 --- tools/marvin/marvin/configGenerator.py | 5 - tools/marvin/marvin/deployAndRun.py | 191 ++++++++++++------ ...aseExecuteEngine.py => tcExecuteEngine.py} | 43 +--- 3 files changed, 137 insertions(+), 102 deletions(-) rename tools/marvin/marvin/{TestCaseExecuteEngine.py => tcExecuteEngine.py} (63%) diff --git a/tools/marvin/marvin/configGenerator.py b/tools/marvin/marvin/configGenerator.py index 3f98aca9ff1..6d5b70d3108 100644 --- a/tools/marvin/marvin/configGenerator.py +++ b/tools/marvin/marvin/configGenerator.py @@ -93,11 +93,6 @@ class trafficType(object): if 'vmware' in labeldict.keys() else None self.simulator = labeldict['simulator']\ if 'simulator' in labeldict.keys() else None - #{ - # 'xen' : 'cloud-xen', - # 'kvm' : 'cloud-kvm', - # 'vmware' : 'cloud-vmware' - #} class pod(object): diff --git a/tools/marvin/marvin/deployAndRun.py b/tools/marvin/marvin/deployAndRun.py index 8a758a10e36..56747a7cb2d 100644 --- a/tools/marvin/marvin/deployAndRun.py +++ b/tools/marvin/marvin/deployAndRun.py @@ -15,82 +15,153 @@ # specific language governing permissions and limitations # under the License. -import deployDataCenter -import TestCaseExecuteEngine +from tcExecuteEngine import TestCaseExecuteEngine import sys +import os +import traceback +import time from argparse import ArgumentParser -if __name__ == "__main__": +from marvinInit import MarvinInit +from marvin.codes import (SUCCESS, + FAILED, + EXCEPTION, + UNKNOWN_ERROR + ) + +parser = None + + +def printAndExit(): + ''' + Prints pretty message for parser and exit + ''' + global parser + if parser is not None: + parser.print_usage() + exit(1) + + +def parseAndCheck(): + ''' + Parses,reads the options and verifies for the config file + ''' + global parser 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("-d", "--tcpath", dest="tcpath", + help="the test case directory or file path") parser.add_argument("-c", "--config", action="store", default="./datacenterCfg", dest="config", help="the path where the json config file generated,\ - by default is ./datacenterCfg") + 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") + it will only run testcase") parser.add_argument("-n", "--num", dest="number", - help="how many times you want run the test case") + help="how many times you want to run the tests") options = parser.parse_args() + cfg_file = options.config + tc_path = options.tcpath + load_flag = options.load + num_iter = 1 if options.number is None else int(options.number) - testResultLogFile = None - if options.result is not None: - testResultLogFile = options.result + ''' + Check if the config file is None or not and exit accordingly + ''' + if cfg_file is None: + printAndExit() + return {"cfg_file": cfg_file, + "load_flag": load_flag, + "tc_path": tc_path, + "num_iter": num_iter} - testCaseLogFile = None - if options.testcaselog is not None: - testCaseLogFile = options.testcaselog - deploy = deployDataCenter.deployDataCenters(options.config) - if options.load: - deploy.loadCfg() - else: - deploy.deploy() - iterates = 1 - if options.number is not None: - if options.number == "loop": - iterates = sys.maxint + +def startMarvin(cfg_file, load_flag): + ''' + Initialize the Marvin + ''' + try: + obj_marvininit = MarvinInit(cfg_file, load_flag) + if obj_marvininit.init() == SUCCESS: + testClient = obj_marvininit.getTestClient() + tcRunLogger = obj_marvininit.getLogger() + parsedConfig = obj_marvininit.getParsedConfig() + debugStream = obj_marvininit.getDebugFile() + return {"tc_client": testClient, + "tc_runlogger": tcRunLogger, + "tc_parsedcfg": parsedConfig, + "tc_debugstream": debugStream} else: - try: - iterates = int(options.number) - except: - iterates = 1 - - if options.testCaseFolder is None: - if options.module is None: - parser.print_usage() + print "\nMarvin Initialization Failed" exit(1) + except Exception, e: + print "\n Exception occurred while starting Marvin %s" % str(e) + exit(1) + + +def runTCs(num_iter, inp1, inp2): + ''' + Run Test Cases based upon number of iterations + ''' + n = 0 + while(n < num_iter): + engine = TestCaseExecuteEngine(inp2["tc_client"], + inp2["tc_parsedcfg"], + inp2["tc_runlogger"], + inp2["tc_debugstream"]) + if inp1["tc_file"] is not None: + engine.loadTestsFromFile(inp1["tc_file"]) else: - n = 0 - while(n < iterates): - engine = \ - TestCaseExecuteEngine.TestCaseExecuteEngine( - deploy.testClient, - deploy.getCfg( - ), - testCaseLogFile, - testResultLogFile) - engine.loadTestsFromFile(options.module) - engine.run() - n = n + 1 + engine.loadTestsFromDir(inp1["tc_dir"]) + engine.run() + n = n + 1 + + +def checkTCPath(tc_path): + ''' + Verifies if the tc_path is a folder or file and its existence + ''' + ret = {"tc_file": None, "tc_dir": None} + check = True + if tc_path is None: + printAndExit() else: - n = 0 - while(n < iterates): - engine = TestCaseExecuteEngine.TestCaseExecuteEngine( - deploy.testClient, - deploy.getCfg( - ), - testCaseLogFile, - testResultLogFile) - engine.loadTestsFromDir(options.testCaseFolder) - engine.run() - n = n + 1 + if os.path.isfile(tc_path): + ret["tc_file"] = tc_path + elif os.path.isdir(tc_path): + ret["tc_dir"] = tc_path + else: + check = False + if check is False: + print"\nTC Path is Invalid.So Exiting" + exit(1) + + return ret + +if __name__ == "__main__": + + ''' + 1. Parse and Check + ''' + out1 = parseAndCheck() + print "\nStep1 :Parsing Options And Check Went Fine" + + ''' + 2. Start Marvin + ''' + out2 = startMarvin(out1["cfg_file"], out1["load_flag"]) + print "\nStep2: Marvin Initialization Went Fine" + + ''' + 3. Check TC folder or Module and Path existence + ''' + out3 = checkTCPath(out1["tc_path"]) + print "\nStep3: TC Path Check Went Fine" + + ''' + 4. Run TCs + ''' + runTCs(out1["num_iter"], out3, out2) + print "\nStep4: TC Running Finished" diff --git a/tools/marvin/marvin/TestCaseExecuteEngine.py b/tools/marvin/marvin/tcExecuteEngine.py similarity index 63% rename from tools/marvin/marvin/TestCaseExecuteEngine.py rename to tools/marvin/marvin/tcExecuteEngine.py index f5af1fe2c1e..f959e7e935f 100644 --- a/tools/marvin/marvin/TestCaseExecuteEngine.py +++ b/tools/marvin/marvin/tcExecuteEngine.py @@ -22,14 +22,8 @@ import logging from functools import partial -def testCaseLogger(message, logger=None): - if logger is not None: - logger.debug(message) - - class TestCaseExecuteEngine(object): - def __init__(self, testclient, config, testcaseLogFile=None, - testResultLogFile=None): + def __init__(self, testclient, config, tc_logger=None, debug_stream=None): """ Initialize the testcase execution engine, just the basics here @var testcaseLogFile: client log file @@ -37,29 +31,11 @@ class TestCaseExecuteEngine(object): """ self.testclient = testclient self.config = config - self.logformat =\ - logging.Formatter( - "%(asctime)s - %(levelname)s - %(name)s - %(message)s") + self.tcRunLogger = tc_logger + self.debugStream = debug_stream self.loader = unittest.loader.TestLoader() self.suite = None - if testcaseLogFile is not None: - self.logfile = testcaseLogFile - self.logger = logging.getLogger("TestCaseExecuteEngine") - fh = logging.FileHandler(self.logfile) - fh.setFormatter(self.logformat) - self.logger.addHandler(fh) - self.logger.setLevel(logging.DEBUG) - if testResultLogFile is not None: - ch = logging.StreamHandler() - ch.setLevel(logging.ERROR) - ch.setFormatter(self.logformat) - self.logger.addHandler(ch) - fp = open(testResultLogFile, "w") - self.testResultLogFile = fp - else: - self.testResultLogFile = sys.stdout - def loadTestsFromDir(self, testDirectory): """ Load the test suites from a package with multiple test files """ self.suite = self.loader.discover(testDirectory) @@ -77,18 +53,11 @@ class TestCaseExecuteEngine(object): if isinstance(test, unittest.BaseTestSuite): self.injectTestCase(test) else: - #logger bears the name of the test class - testcaselogger = logging.getLogger("%s" % (test)) - fh = logging.FileHandler(self.logfile) - fh.setFormatter(self.logformat) - testcaselogger.addHandler(fh) - testcaselogger.setLevel(logging.DEBUG) - #inject testclient and logger into each unittest + self.tcRunLogger.name = test.__str__() setattr(test, "testClient", self.testclient) setattr(test, "config", self.config) - setattr(test, "debug", partial(testCaseLogger, - logger=testcaselogger)) + setattr(test, "debug", self.tcRunLogger.debug) setattr(test.__class__, "clstestclient", self.testclient) if hasattr(test, "user"): # attribute when test is entirely executed as user @@ -98,5 +67,5 @@ class TestCaseExecuteEngine(object): def run(self): if self.suite: - unittest.TextTestRunner(stream=self.testResultLogFile, + unittest.TextTestRunner(stream=self.debugStream, verbosity=2).run(self.suite)