def Setup(interfaceParams):

    # Declare global (module-scope) variables.
    global sensorList

    # Parse the XML file to get the information regarding the sensors to test.
    # Validate file containing sensors to monitor.
    sensorListFile = Config.sensorListXmlFile  # File containing list of sensors to monitor.
    if (not os.path.isfile(sensorListFile)):
        UtilLogger.verboseLogger.error(
            "SensorReadingStressTest.py: File path " + sensorListFile +
            " is invalid.")
        return False

    xmlParserObj = XmlParser.XmlParser(sensorListFile)
    if not xmlParserObj.root:
        UtilLogger.verboseLogger.error("SensorReadingStressTest.py - XmlParser: " + \
                                       "failed to parse sensor list XML file.")
        return False

    # Store info regarding all sensors to be monitored in sensorList.
    for sensorEntry in xmlParserObj.root:
        sensorName = sensorEntry.attrib["name"]
        nominalValue = sensorEntry.attrib["nominal"]
        tolerance = sensorEntry.attrib["tolerance"]
        gotSensorIdSuccess, sensorId = IpmiUtil.GetIpmiUtilSensorId(
            interfaceParams, sensorName)
        if (not gotSensorIdSuccess):
            UtilLogger.verboseLogger.error("SensorReadingStressTest.py - Setup(): " + \
                                       "Failed to get sensor ID for sensor '%s'." % sensorName)
            return False
        sensorList.append(
            (sensorName, sensorId, float(nominalValue), float(tolerance)))

    return True
Exemplo n.º 2
0
def ValidateGPIOslotID(expectedData):
    global gpioTestPassOrFail, fileName
    global GPIOLen

    try:
        # remove two bits (bits [5:0] in the response)
        IPMISlotIDdataFilter = expectedData & 0x3f
        # incode to GPIO slot ID (PMDU_NODE_INCODE dictionary)
        SlotIdIncode = PMDU_NODE_INCODE.get(IPMISlotIDdataFilter)
        # GPIO slot ID binary bits
        GPIOSlotIDBin = "{0:06b}".format(SlotIdIncode)
        GPIOSlotID = list(GPIOSlotIDBin)
        # read slot id gpio definition from getgpioslotid.xml
        xmlParserObj = XmlParser.XmlParser(Config.J2010getGpioSlotIDFilePath)
        if not xmlParserObj.root:
            UtilLogger.verboseLogger.error(("[GPIOgetTest error]%s: failed to parse Xml file. Will not execute test." %(fileName)))
            return False

        gpioTestPassOrFail = True
        GPIOLen = len(GPIOSlotID)

        # Verify Get GPIO for each GPIO number listed in XML
        for gpioInfo in xmlParserObj.root:

            signal = gpioInfo.attrib['signal']
            gpio_pin = gpioInfo.attrib['gpio_pin']

            UtilLogger.verboseLogger.info("[GPIOgetTest info]%s: running Execute for Signal %s and gpio_pin %s" %(fileName, signal, gpio_pin))

            execCmds = ['\n']
            execCmds.append("gpioutil -p %s\n" %(gpio_pin))
            expectedSlotId = GPIOSlotID[GPIOLen-1]
            regexPattern = r'(\d)\s+j2010'

            (execPassOrFail, sshOutputs, parsedCmdOutputs) = Ssh.sshExecuteCommand( execCmds, username=Config.bmcUser, password=Config.bmcPassword, expectedOutput = expectedSlotId, regExpPattern = regexPattern )
            gpioTestPassOrFail &= execPassOrFail

            if (execPassOrFail): #timeout or channel not ready, it don't judge the result correct or not
                actualSlotId = parsedCmdOutputs
                if not actualSlotId:
                    UtilLogger.verboseLogger.error("%s: Signal Slot ID failed: Actual Slot Id was returned an empty string" %(fileName))
                    gpioTestPassOrFail = False

                if (actualSlotId == expectedSlotId):
                    UtilLogger.verboseLogger.info("%s: Signal Slot ID successful: '%s'; Slot ID value: %s" %(fileName, signal, parsedCmdOutputs))
                else:
                    UtilLogger.verboseLogger.error("%s: failed: %s slot ID is not correct " %(fileName, signal))
                    gpioTestPassOrFail = False
            else:
                UtilLogger.verboseLogger.error("%s: failed to find '%s' in response" %(fileName, signal))
                gpioTestPassOrFail = False

            GPIOLen = GPIOLen-1

    except Exception, e:
            UtilLogger.verboseLogger.error( fileName + ": Test failed with exception - " + str(e))
            gpioTestPassOrFail = False
Exemplo n.º 3
0
def Execute(interfaceParams):
    global testPassOrFail, fileName
    # Parse Get Gpio List xml file

    try:
        xmlParserObj = XmlParser.XmlParser(Config.G50getGpioListFilePath)
        if not xmlParserObj.root:
            UtilLogger.verboseLogger.error(("%s: failed to parse Xml file. Will not execute test." %(fileName)))
            return False
    
        testPassOrFail = True     
    
        # Verify Get GPIO for each GPIO number listed in XML
        for gpioInfo in xmlParserObj.root:    
            testPassOrFail &= True
            signal = gpioInfo.attrib['signal']
            theDirection = []
            theDirection = gpioInfo.attrib['direction'].split(',')
            expectedDirection = theDirection[0]

            UtilLogger.verboseLogger.info("%s: running Execute for Signal %s" %(fileName, signal))

            execCmds = ['\n']                      
            execCmds.append("gpioutil -n %s\n" %(signal))

            # Get GPIO Pin Direction
            regexPattern = r"DIRECTION: (\w+)"
            (execPassOrFail, sshOutputs, parsedCmdOutputs) = Ssh.sshExecuteCommand( execCmds, username=Config.bmcUser, password=Config.bmcPassword, expectedOutput = expectedDirection, regExpPattern = regexPattern )
            testPassOrFail &= execPassOrFail

            if (execPassOrFail):            
                actualDirection = parsedCmdOutputs                
                if not actualDirection:
                    UtilLogger.verboseLogger.error("%s: Signal Direction failed: Actual Direction was returned an empty string" %(fileName))
                    testPassOrFail = False
                    continue                                                          
                # Note:  pinDirection may contain several directions, seperated by
                #        a comma (i.e. "in,falling")
                pinDirections = expectedDirection.split(',')                                
                
                for pinDirection in pinDirections:
                    # Validate GPIO pin direction                                       
                    if pinDirection.strip() == actualDirection:
                        UtilLogger.verboseLogger.info("%s: Signal Direction successful: '%s'; Direction: %s" %(fileName, signal, actualDirection))                        
                        break
                    if pinDirection == pinDirections[-1]:
                        UtilLogger.verboseLogger.error("%s: Signal Direction failed : '%s'; Actual Direction: %s; Expected Direction(s): %s" %(fileName, signal, actualDirection, ','.join(pinDirections)))
                        testPassOrFail = False
            else:
                UtilLogger.verboseLogger.error("%s: failed to find '%s' in response" %(fileName, signal))
                testPassOrFail = False

    except Exception, e:
            UtilLogger.verboseLogger.error( fileName + ": Test failed with exception - " + str(e))
            testPassOrFail = False
def TempUpdate() -> None:
    
    resources = ParlamentResources()
    database = DatabaseConnector()
    parser = XmlParser()

    
    sessionsXml = resources.GetData('seimo_sesijos?ar_visos=T')
    sessions = parser.ParseSessionsFromXml(sessionsXml)
    for s in sessions:
        meetingsXml = resources.GetData('seimo_posedziai?sesijos_id=' + s.Id) 
        meetingDocuments = parser.ParseMeetingDocumentsFromXml(meetingsXml)
        database.WriteToDatabase(meetingDocuments, 'Meetings', meetingDocumentMap, ['MeetingId', 'Value'])
Exemplo n.º 5
0
    def readSMFDConfigFiles(self):
        smfd_cfg_path = self.configMng.getConfValue("PATH",
                                                    "SMFD_AFDX_CFG_FOLDER")
        smfd_cfg_files = self.configMng.getItems("SMFD_AFDX_CFG_FILES")
        smfd_cfg_path = FileManager.joinPath(FileManager.getCurrentPath(),
                                             smfd_cfg_path)

        self.logMng.infoMesg("Read SMFD config files")
        for (smfd_id, cfg_file_name) in smfd_cfg_files:
            self.logMng.infoMesg("Read %s", cfg_file_name)
            self.smfdAfdxCfgPathDict[smfd_id] = {}
            self.smfdAfdxCfgPathDict[smfd_id]["path"] = FileManager.joinPath(
                smfd_cfg_path, cfg_file_name)
            self.smfdAfdxCfgPathDict[smfd_id]["xml"] = XmlParser.XmlParser()
            self.smfdAfdxCfgPathDict[smfd_id]["xml"].makeNormalizeXmlFile(
                self.smfdAfdxCfgPathDict[smfd_id]["path"])
Exemplo n.º 6
0
def Setup(interfaceParams):
    global fileName

    UtilLogger.verboseLogger.info("%s: running Setup fxn" % (fileName))

    # Test Variable
    sensorListFile = Config.J2010sensorListXmlFile
    xmlParserObj = XmlParser.XmlParser(sensorListFile)

    if not xmlParserObj.root:
        UtilLogger.verboseLogger.error(
            "SensorReadingStressTest.py - XmlParser: failed to parse sensor list XML file."
        )
        return False

    return True
Exemplo n.º 7
0
    def __init__(self):
        self.logMng = LoggingManager.LogHandler("CfgGen")
        self.logMng.logLevel("DEBUG")
        self.logMng.attachedStreamHandler()
        self.logMng.attachedFileHandler("CfgGen.log")
        self.logMng.infoMesg("Initialize AFDXConfigGenerator")

        self.configMng = ConfigManager.ConfigHandler()
        self.configMng.loadConfig("afdx_switch.conf")

        self.xmlParserMng = XmlParser.XmlParser()

        self.switchPortInfoList = []
        self.smfdCfgFileList = []
        self.smfdAfdxCfgPathDict = {}

        self.loadAFDXSwitchInfo()
Exemplo n.º 8
0
def Setup(interfaceParams):

    # Declare global (module-scope) variables.
    global sensorList

    # Parse the XML file to get the information regarding the sensors to test.
    # Validate file containing sensors to monitor.
    sensorListFile = Config.thresholdSensorListXmlFile  # File containing list of threshold sensors to monitor.
    if (not os.path.isfile(sensorListFile)):
        UtilLogger.verboseLogger.error("SensorThresholdStressTest.py: File path " + sensorListFile + " is invalid.")
        return False

    xmlParserObj = XmlParser.XmlParser(sensorListFile)
    if not xmlParserObj.root:
        UtilLogger.verboseLogger.error("SensorThresholdStressTest.py - XmlParser: " + \
                                       "failed to parse sensor list XML file.")
        return False

    # Store info regarding all sensors to be monitored in sensorList.
    for sensorEntry in xmlParserObj.root:
        sensorName = sensorEntry.attrib["name"]
        gotSensorIdSuccess, sensorId = IpmiUtil.GetIpmiUtilSensorId(interfaceParams, sensorName)
        if (not gotSensorIdSuccess):
            UtilLogger.verboseLogger.error("SensorThresholdStressTest.py - Setup(): " + \
                                       "Failed to get sensor ID for sensor '%s'." % sensorName)
            return False
        sensorInfo = IpmiUtil.SdrInfo([ sensorId[2] + sensorId[3], \
            sensorId[0] + sensorId[1] ], sensorName, interfaceParams)
        updatePassOrFail = sensorInfo.UpdateSdrInfo(interfaceParams) # Update SDR Info for sensor
        if updatePassOrFail:
            UtilLogger.verboseLogger.info("SensorThresholdStressTest.py - Setup(): " + \
                "Successfully received sensor thresholds for sensor '%s'." % sensorName)
        else:
            UtilLogger.verboseLogger.error("SensorThresholdStressTest.py - Setup(): " + \
                "Failed to get sensor thresholds for sensor '%s'." % sensorName)
        sensorList.append((sensorName, sensorId, sensorInfo))

    return True
Exemplo n.º 9
0
def _Validate(_):
    # Note:  Most of this code was stolen from IpmiUtil.py (VerifySelAgainstXmlList)

    # Test Variable
    sensorListFile = Config.J2010sensorListXmlFile
    xmlParserObj = XmlParser.XmlParser(sensorListFile)
    selPassOrFail = False
    unexpectedSels = None

    if not xmlParserObj.root:
        UtilLogger.verboseLogger.error(
            "SensorReadingStressTest.py - XmlParser: failed to parse sensor list XML file."
        )
        return False

    # Validate the returned SEL log events against list of SEL events
    # in input selListXml.

    selReqList = []  # List containing all required SEL events.
    # Each element in the list is a nested list [Event_Text, duplicate],
    # where Event_Text is an SEL event as a string, and duplicate
    # is an integer indicating whether the event is allowed to be
    # used as a duplicate or not (-1: allow as duplicate, 1: only
    # use once (no duplicate, hasn't been used yet), 0: can no longer
    # be used (no duplicate, already used once).
    selOptList = []  # List containing all optional SEL events.
    # Each element in the list is a nested list [Event_Text, duplicate],
    # where Event_Text is an SEL event as a string, and duplicate
    # is an integer indicating whether the event is allowed to be
    # used as a duplicate or not (-1: allow as duplicate, 1: only
    # use once (no duplicate, hasn't been used yet), 0: can no longer
    # be used (no duplicate, already used once).

    # Parse the input XML file to get selReqList and selOptList.
    for selEntry in xmlParserObj.root:
        required = (selEntry.attrib["required"] == "true")
        selText = selEntry.attrib["contains"]
        allowDupl = (selEntry.attrib["allowduplicates"] == "true")
        if (required):  # Required event log.
            if (allowDupl):
                selReqList.append([selText, -1])
            else:
                selReqList.append([selText, 1])
        else:  # Optional event log.
            if (allowDupl):
                selOptList.append([selText, -1])
            else:
                selOptList.append([selText, 1])

    # Ready to do the validation.
    # Verify whether all required event logs are in the list of actual event logs.
    AreAllReqIn = True  # Indicates wether all required events were found (True) in
    # list of actual event or not (False).
    actualSelList = []  # FIXME
    for event in selReqList:
        IsEventIn = False
        for actualEvent in actualSelList:
            if event[0] in actualEvent:
                IsEventIn = True
                break
        if not IsEventIn:
            AreAllReqIn = False
            break

    # Verify whether all actual events are either required or optional and nothing
    # else.
    AreAllActualIn = True  # Indicates whether all actual events are either required
    # or optional and nothing else (True) or not (False).
    unexpectedSels = []
    selValidList = selReqList + selOptList

    actualSelList = []

    for event in actualSelList:
        IsEventIn = False
        for validEvent in selValidList:
            if validEvent[0] in event:
                if (validEvent[1] == 0):
                    break  # Event already matched and cannot be duplicate, hence cannot
                    # be matched again.
                    # This SEL record (variable event) is a duplicate.
                if (validEvent[1] == 1):
                    validEvent[
                        1] = 0  # Mark event as already matched and no duplicate
                    # is allowed.
                IsEventIn = True
                break
        if not IsEventIn:
            AreAllActualIn = False
            unexpectedSels.append(event)
            # We don't break here in order to find all unexpected SEL events.

    # Ready to return results.
    if (AreAllReqIn and AreAllActualIn):
        selPassOrFail = True
        unexpectedSels = None
    elif (not AreAllActualIn):
        selPassOrFail = False
    else:  # AreAllActualIn = True, AreAllReqIn = False.
        selPassOrFail = False
        unexpectedSels = None

    return selPassOrFail, unexpectedSels
Exemplo n.º 10
0
def Execute(interfaceParams):

    # Define Test variables
    cmdPassOrFail = True
    respData = None

    # Define GetGpio variables
    cmdName = 'GetGpio'
    cmdNum = Config.cmdGetGpio
    netFn = Config.netFnOem30

    # Parse Get Gpio List xml file
    xmlParserObj = XmlParser.XmlParser(Config.C2010getGpioListFilePath)
    if not xmlParserObj.root:
        UtilLogger.verboseLogger.error("VerifyGetGpio: failed to parse Xml file." \
            + " Will not execute test.")
        return False

    # Verify Get GPIO for each GPIO number listed in XML
    for gpioInfo in xmlParserObj.root:

        # Define local variables
        gpioNum = gpioInfo.attrib["number"]
        gpioDir = gpioInfo.attrib["direction"]
        gpioDirIdx = 0
        gpioVal = gpioInfo.attrib["value"]
        gpioValIdx = 1

        # Define get gpio request raw byte as GPIO pin number
        rawBytesList = [gpioNum]

        # Send raw bytes via IpmiUtil
        gpioPassOrFail, respData = IpmiUtil.SendRawCmd(interfaceParams, \
            netFn, cmdNum, rawBytesList)

        # If completion code not success,
        # fail GPIO and move to next GPIO
        if not gpioPassOrFail:
            UtilLogger.verboseLogger.error(cmdName + \
                ": Command failed for GPIO pin number 0x" + gpioNum + \
                ". Completion Code: " + str(respData))
            cmdPassOrFail = False
            continue

        # Validate GPIO pin direction and GPIO pin value
        # Note: if GPIO pin value is set to 'x', GPIO pin value
        # will not be validated
        gpioPassOrFail = gpioDir == respData[gpioDirIdx] and \
            ((gpioVal == respData[gpioValIdx]) or (gpioVal == 'x'))
        if gpioPassOrFail:
            if gpioVal == 'x':
                UtilLogger.verboseLogger.info(cmdName + \
                ": Command passed for GPIO pin number 0x" + gpioNum + \
                ". Pin Direction: 0x" + respData[gpioDirIdx] + \
                " Pin Value ignored")
            else:
                UtilLogger.verboseLogger.info(cmdName + \
                ": Command passed for GPIO pin number 0x" + gpioNum + \
                ". Pin Direction: 0x" + respData[gpioDirIdx] + \
                " Pin Value: 0x" + respData[gpioValIdx])
        else:
            if gpioVal == 'x':
                UtilLogger.verboseLogger.info(cmdName + \
                    ": Command failed for GPIO pin number 0x" + gpioNum + \
                    ". Expected Pin Direction: 0x" + gpioDir + \
                    " Actual Pin Direction: 0x" + respData[gpioDirIdx] + \
                    ". Pin Value ignored")
            else:
                UtilLogger.verboseLogger.info(cmdName + \
                    ": Command failed for GPIO pin number 0x" + gpioNum + \
                    ". Expected Pin Direction: 0x" + gpioDir + \
                    " Actual Pin Direction: 0x" + respData[gpioDirIdx] + \
                    ". Expected Pin Value: 0x" + gpioVal + \
                    " Actual Pin Value: 0x" + respData[gpioValIdx])

        cmdPassOrFail &= gpioPassOrFail

    # Verify response
    if cmdPassOrFail:
        UtilLogger.verboseLogger.info(cmdName + \
            ": Command passed.")
    else:
        UtilLogger.verboseLogger.error(cmdName + \
            ": Command failed.")

    return cmdPassOrFail
Exemplo n.º 11
0
    def run(self):
        conf = Config()
        conf.addFromArg(sys.argv[1:])
        self.initConfFromXls(conf)
        self.initSomeConf(conf)

        self.tempdir = tempfile.mkdtemp('GoogleTest', 'temp', '/tmp')
        docmd('mkdir %s/image' % self.tempdir)
        docmd('mkdir %s/attach' % self.tempdir)
        docmd('mkdir %s/result' % self.tempdir)
        conf.getConf('tempdir', 'temp dir', self.tempdir)

        sendTo = conf.getConf('sendto', 'Send mail to <self|all>')

        version = conf.getConf('version', 'current version')
        persoversion = conf.getConf('persoversion', 'Test Type').upper()
        projectName = conf.getConf('project',
                                   'Project name in check list file name')
        testtype = conf.getConf('testtype', 'Test Type').upper()

        resultRootPath = self.getResultRootPath(conf)
        print resultRootPath

        resultDirName = conf.getConf('resultdirname', 'test result dir name')
        xmlpath = '%s%s' % (resultRootPath + 'results/', resultDirName + '/')
        xmlzip = resultRootPath + 'results/' + resultDirName + '.zip'
        logs = resultRootPath + 'logs/' + resultDirName
        if testtype == 'CTS':
            xmlname = xmlpath + 'testResult.xml'
        elif testtype == 'GTS':
            xmlname = xmlpath + 'xtsTestResult.xml'
        print xmlname

        print 'Begin to analyse xml, please waiting...'
        xmlParser = XmlParser(xmlname)
        result_devices_dic = xmlParser.get_result_devices_dic(xmlname, conf)
        result_summary_dic = xmlParser.get_result_summary_dic(xmlname)
        testpackage_result_dic = xmlParser.get_testpackage_result_dic(xmlname)
        total_fail_num = xmlParser.get_total_fail_num()

        workbook = xlwt.Workbook()
        worksheet = workbook.add_sheet('Google_Test_Report')
        create_testcase_report(worksheet, total_fail_num, result_devices_dic,
                               result_summary_dic, testpackage_result_dic)
        workbook.save(
            '%s/attach/Google_%s_TestReport_%s_v%s+%s.xls' %
            (self.tempdir, testtype, projectName, version, persoversion))

        extAttachFileStr = conf.getConf('extattach', 'External attach files',
                                        'none')
        if extAttachFileStr != 'none':
            for fileName in extAttachFileStr.split(','):
                docmd('cp %s %s/attach' %
                      (projBuildRoot + 'v' + version + '/' + fileName.strip(),
                       self.tempdir))
        docmd(
            'cp %smisc/SuperSpamReleaseMailFootLogoOneTouch.jpg %s/image/ReleaseMailLogo.jpg'
            % (getToolPath(), self.tempdir))
        docmd('cp %s %s/result' % (xmlzip, self.tempdir))
        docmd('cp -r %s %s/result' % (logs, self.tempdir))

        os.system(
            'ssh [email protected] "(rm -rfv /var/www/data/google_CTS_results/%s/%s/v%s+%s;mkdir -p /var/www/data/google_CTS_results/%s/%s/v%s+%s)"'
            % (projectName, testtype, version, persoversion, projectName,
               testtype, version, persoversion))
        docmd(
            'scp -r %s/result/* [email protected]:/var/www/data/google_CTS_results/%s/%s/v%s+%s'
            % (self.tempdir, projectName, testtype, version, persoversion))

        self.__sendMail(conf, result_summary_dic, testpackage_result_dic)
Exemplo n.º 12
0
def _VerifySelAgainstXmlList(interfaceParams, selListXml):

    # Validate input parameters.
    assert selListXml != None
    assert os.path.isfile(selListXml)

    # Initialize results.
    selPassOrFail = False
    unexpectedSels = None

    # Get Sel entries
    cmdPassOrFail, LogFromZipFile = _GetAndUnZip()

    if cmdPassOrFail:
        cmdPassOrFail, BMCLogs, BMCLogsNumber = LogParser(LogFromZipFile)
    else:
        return selPassOrFail, unexpectedSels

    if cmdPassOrFail:
        UtilLogger.verboseLogger.info("%s: Get log data success!" % (fileName))
    else:
        UtilLogger.verboseLogger.error("%s: Parsing log failed!" % (fileName))
        return selPassOrFail, unexpectedSels

    actualSelList = []
    for Log in BMCLogs:
        actualSelList.append(Log['Message'])

    # Validate the returned SEL log events against list of SEL events
    # in input selListXml.
    selReqList = []  # List containing all required SEL events.
    # Each element in the list is a nested list [Event_Text, duplicate],
    # where Event_Text is an SEL event as a string, and duplicate
    # is an integer indicating whether the event is allowed to be
    # used as a duplicate or not (-1: allow as duplicate, 1: only
    # use once (no duplicate, hasn't been used yet), 0: can no longer
    # be used (no duplicate, already used once).
    selOptList = []  # List containing all optional SEL events.
    # Each element in the list is a nested list [Event_Text, duplicate],
    # where Event_Text is an SEL event as a string, and duplicate
    # is an integer indicating whether the event is allowed to be
    # used as a duplicate or not (-1: allow as duplicate, 1: only
    # use once (no duplicate, hasn't been used yet), 0: can no longer
    # be used (no duplicate, already used once).
    # Parse the input XML file to get selReqList and selOptList.
    xmlParserObj = XmlParser.XmlParser(selListXml)
    if not xmlParserObj.root:
        UtilLogger.verboseLogger.error("%s: failed to parse input XML file." %
                                       (fileName))
        return selPassOrFail, unexpectedSels
    for selEntry in xmlParserObj.root:
        required = (selEntry.attrib["required"] == "true")
        selText = selEntry.attrib["contains"]
        allowDupl = (selEntry.attrib["allowduplicates"] == "true")
        if required:  # Required event log.
            if allowDupl:
                selReqList.append([selText, -1])
            else:
                selReqList.append([selText, 1])
        else:  # Optional event log.
            if allowDupl:
                selOptList.append([selText, -1])
            else:
                selOptList.append([selText, 1])

    # Ready to do the validation.
    # Verify whether all required event logs are in the list of actual event logs.
    AreAllReqIn = True  # Indicates wether all required events were found (True) in
    # list of actual event or not (False).
    for event in selReqList:
        IsEventIn = False
        for actualEvent in actualSelList:
            if event[0] in actualEvent:
                IsEventIn = True
                break
        if not IsEventIn:
            AreAllReqIn = False
            break

    # Verify whether all actual events are either required or optional and nothing
    # else.
    AreAllActualIn = True  # Indicates whether all actual events are either required
    # or optional and nothing else (True) or not (False).
    unexpectedSels = []
    selValidList = selReqList + selOptList
    for event in actualSelList:
        IsEventIn = False
        for validEvent in selValidList:
            if validEvent[0] in event:
                if validEvent[1] == 0:
                    break  # Event already matched and cannot be duplicate, hence cannot
                    # be matched again.
                    # This SEL record (variable event) is a duplicate.
                if validEvent[1] == 1:
                    validEvent[
                        1] = 0  # Mark event as already matched and no duplicate
                    # is allowed.
                IsEventIn = True
                break
        if not IsEventIn:
            AreAllActualIn = False
            unexpectedSels.append(event)
            # We don't break here in order to find all unexpected SEL events.

    # Ready to return results.
    if AreAllReqIn and AreAllActualIn:
        selPassOrFail = True
        unexpectedSels = None
    elif not AreAllActualIn:
        selPassOrFail = False
    else:  # AreAllActualIn = True, AreAllReqIn = False.
        selPassOrFail = False
        unexpectedSels = None

    return selPassOrFail, unexpectedSels