Home | History | Annotate | Download | only in testGenerator
      1 # Copyright (c) 2014-2015, Intel Corporation
      2 # All rights reserved.
      3 #
      4 # Redistribution and use in source and binary forms, with or without modification,
      5 # are permitted provided that the following conditions are met:
      6 #
      7 # 1. Redistributions of source code must retain the above copyright notice, this
      8 # list of conditions and the following disclaimer.
      9 #
     10 # 2. Redistributions in binary form must reproduce the above copyright notice,
     11 # this list of conditions and the following disclaimer in the documentation and/or
     12 # other materials provided with the distribution.
     13 #
     14 # 3. Neither the name of the copyright holder nor the names of its contributors
     15 # may be used to endorse or promote products derived from this software without
     16 # specific prior written permission.
     17 #
     18 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
     19 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     20 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     21 # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
     22 # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     23 # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     24 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
     25 # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     27 # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     28 
     29 from clientsimulator.criterion.ExclusiveCriterion import ExclusiveCriterion
     30 from clientsimulator.configuration.ConfigParser import ConfigParser
     31 from clientsimulator.testGenerator.SubprocessLogger import SubprocessLoggerThread
     32 from clientsimulator.testGenerator.SubprocessLogger import ScriptLoggerThread
     33 import logging
     34 import json
     35 import time
     36 import os
     37 
     38 
     39 class TestLauncher:
     40 
     41     """ Class which interacts with the system to launch tests """
     42 
     43     def __init__(self,
     44                  criterionClasses,
     45                  configParser,
     46                  consoleLogger):
     47         """
     48             Here we create commands to launch thanks to the config Parser
     49 
     50             :param criterionClasses: runtime generated criterion classes
     51             :type criterionClasses: list of types
     52             :param configParser: object which allows to get config parameters
     53             :type configParser: ConfigParser
     54             :param consoleLogger: console log handler
     55             :type consoleLogger: Handler
     56         """
     57         self.__criterionClasses = criterionClasses
     58         self.__configParser = configParser
     59 
     60         # Prepare basic commands
     61         halCommand = ["remote-process",
     62                       "localhost",
     63                       configParser["TestPlatformPort"]]
     64         setCriteriaCommand = halCommand + ["setCriterionState"]
     65         testPlatformHostCommand = ["remote-process",
     66                                    "localhost",
     67                                    configParser["TestPlatformPort"]]
     68 
     69         self.__logFileName = configParser["LogFile"]
     70 
     71         # Commands
     72         self.__startTestPlatformCmd = [configParser["PrefixCommand"],
     73                                        "test-platform",
     74                                        configParser["PfwConfFile"],
     75                                        configParser["TestPlatformPort"]]
     76 
     77         self.__createCriterionCmd = [configParser["PrefixCommand"]]
     78         self.__createCriterionCmd.extend(testPlatformHostCommand)
     79 
     80         self.__startPseudoHALCmd = [configParser["PrefixCommand"]]
     81         self.__startPseudoHALCmd.extend(testPlatformHostCommand)
     82         self.__startPseudoHALCmd.append("start")
     83 
     84         self.__setCriterionCmd = [configParser["PrefixCommand"]]
     85         self.__setCriterionCmd.extend(setCriteriaCommand)
     86 
     87         self.__applyConfigurationsCmd = [configParser["PrefixCommand"]]
     88         self.__applyConfigurationsCmd.extend(halCommand)
     89         self.__applyConfigurationsCmd.append("applyConfigurations")
     90 
     91         # Command used to generate coverage
     92         self.__coverageCmd = [
     93             "eval",
     94             os.path.join(configParser["CoverageDir"], "aplog2coverage.sh"),
     95             "-d",
     96             configParser["PfwDomainConfFile"],
     97             "-e.",
     98             self.__logFileName,
     99             "-f",
    100             "-o",
    101             configParser["CoverageFile"]
    102         ]
    103 
    104         # Prepare script Commands
    105         # Loading possible scripts
    106         self.__rawScripts = {}
    107         if configParser["ScriptsFile"]:
    108             with open(configParser["ScriptsFile"], 'r') as scriptFile:
    109                 self.__rawScripts = json.load(scriptFile)
    110 
    111         self.__availableLaunchType = ["asynchronous", "synchronous"]
    112 
    113         self.__consoleLogger = consoleLogger
    114         self.__logger = logging.getLogger(__name__)
    115         self.__logger.addHandler(consoleLogger)
    116 
    117     @property
    118     def scripts(self):
    119         return self.__rawScripts.keys()
    120 
    121     def init(self, criterionClasses, isVerbose):
    122         """ Initialise the Pseudo HAL """
    123 
    124         self.__logger.info("Pseudo Hal Initialisation")
    125         # Test platform is launched asynchronously and not as script
    126         self.__call_process(self.__startTestPlatformCmd, True)
    127         # wait Initialisation
    128         time.sleep(1)
    129 
    130         for criterionClass in criterionClasses:
    131             if ExclusiveCriterion in criterionClass.__bases__:
    132                 createSlctCriterionCmd = "createExclusiveSelectionCriterionFromStateList"
    133             else:
    134                 createSlctCriterionCmd = "createInclusiveSelectionCriterionFromStateList"
    135 
    136             createCriterionArgs = [
    137                 createSlctCriterionCmd,
    138                 criterionClass.__name__] + criterionClass.allowedValues()
    139 
    140             self.__call_process(
    141                 self.__createCriterionCmd + createCriterionArgs)
    142 
    143         self.__call_process(self.__startPseudoHALCmd)
    144 
    145     def executeTestVector(self, criterions):
    146         """ Launch the Test """
    147         for criterion in criterions:
    148             if ExclusiveCriterion in criterion.__class__.__bases__:
    149                 criterionValue = [criterion.currentValue]
    150             else:
    151                 criterionValue = criterion.currentValue
    152             # If no value given, we add "" to the command to set the default state
    153             criterionValueArg = list(criterionValue) if list(criterionValue) else ["\"\""]
    154             setCriterionArgs = [criterion.__class__.__name__] + criterionValueArg
    155             self.__call_process(self.__setCriterionCmd + setCriterionArgs)
    156 
    157         # Applying conf
    158         self.__call_process(self.__applyConfigurationsCmd)
    159 
    160     def executeScript(self, scriptName):
    161         """ Launching desired test scripts """
    162 
    163         (script, launchType) = self.__rawScripts[scriptName]
    164 
    165         if not launchType in self.__availableLaunchType:
    166             errorMessage = "Launch type ({}) for script {} isn't recognized. ".format(
    167                 launchType,
    168                 scriptName)
    169             errorMessage += "Default value ({}) has been applied.".format(
    170                 self.__availableLaunchType[0])
    171 
    172             self.__logger.error(errorMessage)
    173             launchType = self.__availableLaunchType[0]
    174 
    175         # Create and launch the command to use the desired script
    176         # A script's path is absolute or relative to the "ScriptsFile" file.
    177         self.__call_process(
    178             ["eval", os.path.join(
    179                 os.path.dirname(self.__configParser["ScriptsFile"]),
    180                 script)],
    181             launchType == self.__availableLaunchType[0],
    182             True)
    183 
    184     def generateCoverage(self):
    185         """ Launch Coverage Tool on generated Log and save results in dedicated file  """
    186         self.__logger.debug("Generating coverage file")
    187         self.__call_process(self.__coverageCmd)
    188 
    189     def __call_process(self, cmd, isAsynchronous=False, isScriptThread=False):
    190         """ Private function which call a shell command """
    191 
    192         if isScriptThread:
    193             self.__logger.info("Launching script : {}".format(' '.join(cmd)))
    194             launcher = ScriptLoggerThread(cmd, self.__consoleLogger)
    195         else:
    196             self.__logger.debug("Launching command : {}".format(' '.join(cmd)))
    197             launcher = SubprocessLoggerThread(cmd, self.__consoleLogger)
    198 
    199         launcher.start()
    200 
    201         if not isAsynchronous:
    202             # if the process is synchronous, we wait him before continuing
    203             launcher.join()
    204