Exemple #1
0
class MarvinPlugin(Plugin):
    """
    Custom plugin for the cloudstackTestCases to be run using nose
    """

    name = "marvin"

    def __init__(self):
        self.__identifier = None
        self.__testClient = None
        self.__logFolderPath = None
        self.__parsedConfig = None
        '''
        Contains Config File
        '''
        self.__configFile = None
        '''
        Signifies the Zone against which all tests will be Run
        '''
        self.__zoneForTests = None
        '''
        Signifies the flag whether to deploy the New DC or Not
        '''
        self.__deployDcFlag = None
        self.conf = None
        self.__resultStream = stdout
        self.__testRunner = None
        self.__testResult = SUCCESS
        self.__startTime = None
        self.__testName = None
        self.__tcRunLogger = MarvinLog('marvin').getLogger()
        self.__testModName = ''
        self.__hypervisorType = None
        Plugin.__init__(self)

    def configure(self, options, conf):
        """enable the marvin plugin when the --with-marvin directive is given
        to nose. The enableOpt value is set from the command line directive and
        self.enabled (True|False) determines whether marvin's tests will run.
        By default non-default plugins like marvin will be disabled
        """
        self.enabled = True
        if hasattr(options, self.enableOpt):
            if not getattr(options, self.enableOpt):
                self.enabled = False
                return
        self.__configFile = options.configFile
        self.__deployDcFlag = options.deployDc
        self.__zoneForTests = options.zone
        self.__hypervisorType = options.hypervisor_type
        self.conf = conf
        if self.startMarvin() == FAILED:
            self.__tcRunLogger.error(
                'Starting Marvin Failed, exiting. Please Check')
            exit(1)

    def options(self, parser, env):
        """
        Register command line options
        """
        parser.add_option("--marvin-config",
                          action="store",
                          default=env.get('MARVIN_CONFIG', './datacenter.cfg'),
                          dest="configFile",
                          help="Marvin's configuration file is required."
                          "The config file containing the datacenter and "
                          "other management server "
                          "information is specified")
        parser.add_option("--deploy",
                          action="store_true",
                          default=False,
                          dest="deployDc",
                          help="Deploys the DC with Given Configuration."
                          "Requires only when DC needs to be deployed")
        parser.add_option("--zone",
                          action="store",
                          default=None,
                          dest="zone",
                          help="Runs all tests against this specified zone")
        parser.add_option("--hypervisor",
                          action="store",
                          default=None,
                          dest="hypervisor_type",
                          help="Runs all tests against the specified "
                          "zone and hypervisor Type")
        parser.add_option("--log-folder-path",
                          action="store",
                          default=None,
                          dest="logFolder",
                          help="Collects all logs under the user specified"
                          "folder")
        Plugin.options(self, parser, env)

    def wantClass(self, cls):
        if cls.__name__ == 'cloudstackTestCase':
            return False
        if issubclass(cls, cloudstackTestCase):
            return True
        return None

    def __checkImport(self, filename):
        '''
        @Name : __checkImport
        @Desc : Verifies if a test module is importable.
                Returns False or True based upon the result.
        '''
        try:
            if os.path.isfile(filename):
                ret = os.path.splitext(filename)
                if ret[1] == ".py":
                    os.system("python " + filename)
                    return True
            return False
        except ImportError as e:
            self.__tcRunLogger.exception("File %s has import errors: %s" %
                                         (filename, e))
            return False

    def wantFile(self, filename):
        '''
        @Desc : Only python files will be used as test modules
        '''
        return self.__checkImport(filename)

    def loadTestsFromTestCase(self, cls):
        if cls.__name__ != 'cloudstackTestCase':
            self.__identifier = cls.__name__
            self._injectClients(cls)

    def beforeTest(self, test):
        self.__testModName = test.__str__()
        self.__testName = test.__str__().split()[0]
        if not self.__testName:
            self.__testName = "test"
        self.__testClient.identifier = '-'. \
            join([self.__identifier, self.__testName])
        if self.__tcRunLogger:
            self.__tcRunLogger.name = test.__str__()

    def startTest(self, test):
        """
        Currently used to record start time for tests
        Dump Start Msg of TestCase to Log
        """
        self.__tcRunLogger.info("=== Started Test %s ===" %
                                str(self.__testName))
        self.__startTime = time.time()

    def printMsg(self, status, tname, err):
        if status in [FAILED, EXCEPTION] and self.__tcRunLogger:
            self.__tcRunLogger.fatal("%s: %s: %s" % (status, tname, err))
        write_str = "=== TestName: %s | Status : %s ===" % (tname, status)
        self.__resultStream.write(write_str)
        self.__tcRunLogger.info(write_str)

    def addSuccess(self, test, capt):
        '''
        Adds the Success Messages to logs
        '''
        self.printMsg(SUCCESS, self.__testName, "Test Case Passed")
        self.__testResult = SUCCESS

    def handleError(self, test, err):
        '''
        Adds Exception throwing test cases and information to log.
        '''
        self.printMsg(EXCEPTION, self.__testName, err)
        self.__testResult = EXCEPTION

    def prepareTestRunner(self, runner):
        if self.__testRunner:
            return self.__testRunner

    def handleFailure(self, test, err):
        '''
        Adds Failing test cases and information to log.
        '''
        self.printMsg(FAILED, self.__testName, err)
        self.__testResult = FAILED

    def startMarvin(self):
        '''
        @Name : startMarvin
        @Desc : Initializes the Marvin
                creates the test Client
                creates the runlogger for logging
                Parses the config and creates a parsedconfig
                Creates a debugstream for tc debug log
        '''
        try:
            obj_marvininit = MarvinInit(self.__configFile, self.__deployDcFlag,
                                        None, self.__zoneForTests,
                                        self.__hypervisorType)
            if obj_marvininit and obj_marvininit.init() == SUCCESS:
                self.__testClient = obj_marvininit.getTestClient()
                self.__parsedConfig = obj_marvininit.getParsedConfig()
                self.__resultStream = obj_marvininit.getResultFile()
                self.__testRunner = nose.core.TextTestRunner(
                    stream=self.__resultStream,
                    descriptions=True,
                    verbosity=2,
                    config=self.conf)
                return SUCCESS
            return FAILED
        except Exception as e:
            self.__tcRunLogger.exception(
                ("=== Start Marvin failed: %s ===" % e))
            return FAILED

    def stopTest(self, test):
        """
        Currently used to record end time for tests
        """
        endTime = time.time()
        if self.__startTime:
            totTime = int(endTime - self.__startTime)
            self.__tcRunLogger.info(
                "TestCaseName: %s; Time Taken: %s Seconds; StartTime: %s; EndTime: %s; Result: %s"
                % (self.__testName, str(totTime),
                   str(time.ctime(self.__startTime)), str(
                       time.ctime(endTime)), self.__testResult))

    def _injectClients(self, test):
        setattr(test, "debug", self.__tcRunLogger.debug)
        setattr(test, "info", self.__tcRunLogger.info)
        setattr(test, "warn", self.__tcRunLogger.warning)
        setattr(test, "error", self.__tcRunLogger.error)
        setattr(test, "testClient", self.__testClient)
        setattr(test, "config", self.__parsedConfig)
        if self.__testClient.identifier is None:
            self.__testClient.identifier = self.__identifier
        setattr(test, "clstestclient", self.__testClient)
        if hasattr(test, "user"):
            # when the class-level attr applied. all test runs as 'user'
            self.__testClient.getUserApiClient(test.UserName, test.DomainName,
                                               test.AcctType)

    def finalize(self, result):
        self.__tcRunLogger.info('=== finalize does nothing!  ===')
class MarvinPlugin(Plugin):
    """
    Custom plugin for the cloudstackTestCases to be run using nose
    """

    name = "marvin"

    def __init__(self):
        self.__identifier = None
        self.__testClient = None
        self.__logFolderPath = None
        self.__parsedConfig = None
        '''
        Contains Config File
        '''
        self.__configFile = None
        '''
        Signifies the Zone against which all tests will be Run
        '''
        self.__zoneForTests = None
        '''
        Signifies the flag whether to deploy the New DC or Not
        '''
        self.__deployDcFlag = None
        self.conf = None
        self.__resultStream = stdout
        self.__testRunner = None
        self.__testResult = SUCCESS
        self.__startTime = None
        self.__testName = None
        self.__tcRunLogger = MarvinLog('marvin').getLogger()
        self.__testModName = ''
        self.__hypervisorType = None
        Plugin.__init__(self)

    def configure(self, options, conf):
        """enable the marvin plugin when the --with-marvin directive is given
        to nose. The enableOpt value is set from the command line directive and
        self.enabled (True|False) determines whether marvin's tests will run.
        By default non-default plugins like marvin will be disabled
        """
        self.enabled = True
        if hasattr(options, self.enableOpt):
            if not getattr(options, self.enableOpt):
                self.enabled = False
                return
        self.__configFile = options.configFile
        self.__deployDcFlag = options.deployDc
        self.__zoneForTests = options.zone
        self.__hypervisorType = options.hypervisor_type
        self.conf = conf
        if self.startMarvin() == FAILED:
            self.__tcRunLogger.error('Starting Marvin Failed, exiting. Please Check')
            exit(1)

    def options(self, parser, env):
        """
        Register command line options
        """
        parser.add_option("--marvin-config", action="store",
                          default=env.get('MARVIN_CONFIG',
                                          './datacenter.cfg'),
                          dest="configFile",
                          help="Marvin's configuration file is required."
                               "The config file containing the datacenter and "
                               "other management server "
                               "information is specified")
        parser.add_option("--deploy", action="store_true",
                          default=False,
                          dest="deployDc",
                          help="Deploys the DC with Given Configuration."
                               "Requires only when DC needs to be deployed")
        parser.add_option("--zone", action="store",
                          default=None,
                          dest="zone",
                          help="Runs all tests against this specified zone")
        parser.add_option("--hypervisor", action="store",
                          default=None,
                          dest="hypervisor_type",
                          help="Runs all tests against the specified "
                               "zone and hypervisor Type")
        parser.add_option("--log-folder-path", action="store",
                          default=None,
                          dest="logFolder",
                          help="Collects all logs under the user specified"
                               "folder"
                          )
        Plugin.options(self, parser, env)

    def wantClass(self, cls):
        if cls.__name__ == 'cloudstackTestCase':
            return False
        if issubclass(cls, cloudstackTestCase):
            return True
        return None

    def __checkImport(self, filename):
        '''
        @Name : __checkImport
        @Desc : Verifies if a test module is importable.
                Returns False or True based upon the result.
        '''
        try:
            if os.path.isfile(filename):
                ret = os.path.splitext(filename)
                if ret[1] == ".py":
                    os.system("python " + filename)
                    return True
            return False
        except ImportError as e:
            self.__tcRunLogger.exception("File %s has import errors: %s" % (filename, e))
            return False

    def wantFile(self, filename):
        '''
        @Desc : Only python files will be used as test modules
        '''
        return self.__checkImport(filename)

    def loadTestsFromTestCase(self, cls):
        if cls.__name__ != 'cloudstackTestCase':
            self.__identifier = cls.__name__
            self._injectClients(cls)

    def beforeTest(self, test):
        self.__testModName = test.__str__()
        self.__testName = test.__str__().split()[0]
        if not self.__testName:
            self.__testName = "test"
        self.__testClient.identifier = '-'. \
            join([self.__identifier, self.__testName])
        if self.__tcRunLogger:
            self.__tcRunLogger.name = test.__str__()

    def startTest(self, test):
        """
        Currently used to record start time for tests
        Dump Start Msg of TestCase to Log
        """
        self.__tcRunLogger.info("=== Started Test %s ===" % str(self.__testName))
        self.__startTime = time.time()

    def printMsg(self, status, tname, err):
        if status in [FAILED, EXCEPTION] and self.__tcRunLogger:
            self.__tcRunLogger.fatal("%s: %s: %s" % (status, tname, err))
        write_str = "=== TestName: %s | Status : %s ===" % (tname, status)
        self.__resultStream.write(write_str)
        self.__tcRunLogger.info(write_str)

    def addSuccess(self, test, capt):
        '''
        Adds the Success Messages to logs
        '''
        self.printMsg(SUCCESS, self.__testName, "Test Case Passed")
        self.__testResult = SUCCESS

    def handleError(self, test, err):
        '''
        Adds Exception throwing test cases and information to log.
        '''
        self.printMsg(EXCEPTION, self.__testName, err)
        self.__testResult = EXCEPTION

    def prepareTestRunner(self, runner):
        if self.__testRunner:
            return self.__testRunner

    def handleFailure(self, test, err):
        '''
        Adds Failing test cases and information to log.
        '''
        self.printMsg(FAILED, self.__testName, err)
        self.__testResult = FAILED

    def startMarvin(self):
        '''
        @Name : startMarvin
        @Desc : Initializes the Marvin
                creates the test Client
                creates the runlogger for logging
                Parses the config and creates a parsedconfig
                Creates a debugstream for tc debug log
        '''
        try:
            obj_marvininit = MarvinInit(self.__configFile,
                                        self.__deployDcFlag,
                                        None,
                                        self.__zoneForTests,
                                        self.__hypervisorType)
            if obj_marvininit and obj_marvininit.init() == SUCCESS:
                self.__testClient = obj_marvininit.getTestClient()
                self.__parsedConfig = obj_marvininit.getParsedConfig()
                self.__resultStream = obj_marvininit.getResultFile()
                self.__testRunner = nose.core.TextTestRunner(
                    stream=self.__resultStream,
                    descriptions=True,
                    verbosity=2,
                    config=self.conf
                )
                return SUCCESS
            return FAILED
        except Exception as e:
            self.__tcRunLogger.exception(("=== Start Marvin failed: %s ===" % e))
            return FAILED

    def stopTest(self, test):
        """
        Currently used to record end time for tests
        """
        endTime = time.time()
        if self.__startTime:
            totTime = int(endTime - self.__startTime)
            self.__tcRunLogger.info(
                "TestCaseName: %s; Time Taken: %s Seconds; StartTime: %s; EndTime: %s; Result: %s" % (
                    self.__testName,
                    str(totTime),
                    str(time.ctime(self.__startTime)),
                    str(time.ctime(endTime)),
                    self.__testResult
                )
            )

    def _injectClients(self, test):
        setattr(test, "debug", self.__tcRunLogger.debug)
        setattr(test, "info", self.__tcRunLogger.info)
        setattr(test, "warn", self.__tcRunLogger.warning)
        setattr(test, "error", self.__tcRunLogger.error)
        setattr(test, "testClient", self.__testClient)
        setattr(test, "config", self.__parsedConfig)
        if self.__testClient.identifier is None:
            self.__testClient.identifier = self.__identifier
        setattr(test, "clstestclient", self.__testClient)
        if hasattr(test, "user"):
            # when the class-level attr applied. all test runs as 'user'
            self.__testClient.getUserApiClient(test.UserName,
                                               test.DomainName,
                                               test.AcctType)

    def finalize(self, result):
        self.__tcRunLogger.info('=== finalize does nothing!  ===')