Skip to content
Snippets Groups Projects
Commit 8d6be2f0 authored by Benjamin Michael Wynne's avatar Benjamin Michael Wynne Committed by Vakhtang Tsulaia
Browse files

Refactor HLT CF tests into a separate file

parent 41f06ee3
No related branches found
No related tags found
No related merge requests found
# Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
"""
A set of config-time tests to be run on the HLT top sequence
"""
from AthenaCommon.CFElements import isSequence
from TriggerJobOpts.TriggerConfig import collectViewMakers
def findViewAlgs( inputNodes, viewNodes ):
""" Make lists of algorithms that run in views, and those that don't """
allAlgs = []
viewAlgs = []
# Examine all nodes
for node in inputNodes:
# If node is a sequence, explore further
if isSequence( node ):
# Identify view CF nodes
if node.getName() in viewNodes.keys():
# Retrieve view algorithms
# (views don't nest, so will be returned in first list)
newViewAlgs, dummy = findViewAlgs( node.getChildren(), {} )
viewAlgs += newViewAlgs
# Record the fact that the view node is found
viewNodes[ node.getName() ] = True
# Explore the tree
else:
newAlgs, newViewAlgs = findViewAlgs( node.getChildren(), viewNodes )
allAlgs += newAlgs
viewAlgs += newViewAlgs
# Node is an algorithm
else:
allAlgs += [ node.getName() ]
return allAlgs, viewAlgs
def checkVDV( inputNodes, ancestorNames, allEVCAs ):
""" Try to make sure each VDV has a correctly-configred EVCA upstream """
for node in inputNodes:
# Node is a VDV
if "AthViews__ViewDataVerifier" in type( node ).__name__:
# Check that VDV has a corresponding, correctly-configured EVCA
foundEVCA = False
for name in ancestorNames:
if name in allEVCAs.keys():
# Check EVCA properties
if not hasattr( allEVCAs[ name ], "RequireParentView" ) or not allEVCAs[ name ].RequireParentView:
raise RuntimeError( "ViewDataVerifier alg " + node.name() + " has upstream EventViewCreatorAlgorithm " + allEVCAs[ name ].name() + " with RequireParentView = False" )
foundEVCA = True
break
if not foundEVCA:
raise RuntimeError( "ViewDataVerifier alg " + node.name() + " has no corresponding upstream EventViewCreatorAlgorithm" )
# Node is an EVCA
if "EventViewCreatorAlgorithm" in type( node ).__name__:
# Store EVCA in a dictionary by the node it refers to
if node.ViewNodeName in allEVCAs.keys():
if node.name() != allEVCAs[ node.ViewNodeName ].name():
raise RuntimeError( "Found duplicate view node name " + node.ViewNodeName + " configured for EVCAs " + node.name() + " and " + allEVCAs[ node.ViewNodeName ].name() )
allEVCAs[ node.ViewNodeName ] = node
# Explore nested CF
if isSequence( node ):
checkVDV( node.getChildren(), ancestorNames + [node.name()], allEVCAs )
def testHLTTree( inputSequence ):
""" Run all config tests """
viewMakers = collectViewMakers( inputSequence )
# List all CF nodes to be used with EventViews (and whether they are found)
viewNodes = {}
for viewMaker in viewMakers:
viewNodes[ viewMaker.ViewNodeName ] = False
originalLength = len( viewNodes )
# Identify the algorithms that will run in EventViews
wholeEventAlgs, viewAlgs = findViewAlgs( inputSequence.getChildren(), viewNodes )
# Check that all view nodes are found
if len( viewNodes ) != originalLength:
raise RuntimeError( "Something went wrong with view config inspection" )
for viewNode in viewNodes.keys():
if not viewNodes[ viewNode ]:
raise RuntimeError( "EventView CF node " + viewNode + " was not found attached to the test sequence" )
# Look for view algs in the whole event context
for viewAlgName in viewAlgs:
if viewAlgName in wholeEventAlgs:
from AthenaCommon.AlgSequence import dumpSequence
dumpSequence( inputSequence )
raise RuntimeError( viewAlgName + " is attached to an EventView node, but also runs in the whole event context" )
# Make sure that VDVs are configured correctly
checkVDV( inputSequence.getChildren(), [inputSequence.name()], {} )
......@@ -26,7 +26,7 @@
"""
# Classes to configure the CF graph, via Nodes
from AthenaCommon.CFElements import parOR, seqAND, seqOR, isSequence
from AthenaCommon.CFElements import parOR, seqAND, seqOR
from AthenaCommon.Logging import logging
from AthenaCommon.AlgSequence import dumpSequence
from TriggerMenuMT.HLTMenuConfig.Menu.HLTCFDot import stepCF_DataFlow_to_dot, stepCF_ControlFlow_to_dot, all_DataFlow_to_dot
......@@ -111,72 +111,6 @@ def createCFTree(CFseq):
## CORE of Decision Handling
#######################################
def findViewAlgs( inputNodes, viewNodes ):
""" Make lists of algorithms that run in views, and those that don't """
allAlgs = []
viewAlgs = []
# Examine all nodes
for node in inputNodes:
# If node is a sequence, explore further
if isSequence( node ):
# Identify view CF nodes
if node.getName() in viewNodes.keys():
# Retrieve view algorithms
# (views don't nest, so will be returned in first list)
newViewAlgs, dummy = findViewAlgs( node.getChildren(), {} )
viewAlgs += newViewAlgs
# Record the fact that the view node is found
viewNodes[ node.getName() ] = True
# Explore the tree
else:
newAlgs, newViewAlgs = findViewAlgs( node.getChildren(), viewNodes )
allAlgs += newAlgs
viewAlgs += newViewAlgs
# Node is an algorithm
else:
allAlgs += [ node.getName() ]
return allAlgs, viewAlgs
def checkVDV( inputNodes, parentName, allEVCAs ):
""" Try to make sure each VDV has a correctly-configred EVCA upstream """
for node in inputNodes:
# Node is a VDV
if "AthViews__ViewDataVerifier" in type( node ).__name__:
# Check that VDV has a corresponding, correctly-configured EVCA
if parentName in allEVCAs.keys():
if not hasattr( allEVCAs[ parentName ], "RequireParentView" ) or not allEVCAs[ parentName ].RequireParentView:
raise RuntimeError( "ViewDataVerifier alg " + node.name() + " has upstream EventViewCreatorAlgorithm with RequireParentView = False" )
else:
raise RuntimeError( "ViewDataVerifier alg " + node.name() + " has no corresponding upstream EventViewCreatorAlgorithm" )
# Node is an EVCA
if "EventViewCreatorAlgorithm" in type( node ).__name__:
# Store EVCA in a dictionary by the node it refers to
if node.ViewNodeName in allEVCAs.keys():
if node.name() != allEVCAs[ node.ViewNodeName ].name():
raise RuntimeError( "Found duplicate view node name " + node.ViewNodeName + " configured for EVCAs " + node.name() + " and " + allEVCAs[ node.ViewNodeName ].name() )
allEVCAs[ node.ViewNodeName ] = node
# Explore nested CF
if isSequence( node ):
checkVDV( node.getChildren(), node.name(), allEVCAs )
def makeHLTTree(HLTChains, newJO=False, triggerConfigHLT = None):
""" creates the full HLT tree"""
......@@ -270,31 +204,10 @@ def makeHLTTree(HLTChains, newJO=False, triggerConfigHLT = None):
topSequence += hltTop
# List all CF nodes to be used with EventViews (and whether they are found)
viewNodes = {}
for viewMaker in viewMakers:
viewNodes[ viewMaker.ViewNodeName ] = False
originalLength = len( viewNodes )
# Identify the algorithms that will run in EventViews
wholeEventAlgs, viewAlgs = findViewAlgs( topSequence.getChildren(), viewNodes )
# Check that all view nodes are found
if len( viewNodes ) != originalLength:
raise RuntimeError( "Something went wrong with view config inspection" )
for viewNode in viewNodes.keys():
if not viewNodes[ viewNode ]:
raise RuntimeError( "EventView CF node " + viewNode + " was not found attached to the topSequence" )
# Look for view algs in the whole event context
for viewAlgName in viewAlgs:
if viewAlgName in wholeEventAlgs:
from AthenaCommon.AlgSequence import dumpSequence
dumpSequence(topSequence)
raise RuntimeError( viewAlgName + " is attached to an EventView node, but also runs in the whole event context" )
# Make sure that VDVs are configured correctly
checkVDV( topSequence.getChildren(), topSequence.name(), {} )
# Test the configuration
from TriggerMenuMT.HLTMenuConfig.Menu.CFValidation import testHLTTree
testHLTTree( topSequence )
def matrixDisplay( allSeq ):
from collections import defaultdict
......
# Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
from TriggerMenuMT.HLTMenuConfig.Menu.HLTCFConfig import findViewAlgs
from TriggerMenuMT.HLTMenuConfig.Menu.CFValidation import findViewAlgs, checkVDV
from AthenaCommon.AlgSequence import AlgSequence
from AthenaCommon.CFElements import seqOR
import AthenaCommon.CfgMgr as CfgMgr
......@@ -11,32 +11,60 @@ class ViewCFTest( unittest.TestCase ):
def runTest( self ):
topSequence = AlgSequence()
viewTestAlg1 = CfgMgr.AthViews__ViewTestAlg("viewTestAlg1")
viewTestAlg2 = CfgMgr.AthViews__ViewTestAlg("viewTestAlg2")
evca1 = CfgMgr.EventViewCreatorAlgorithm("evca1")
evca2 = CfgMgr.EventViewCreatorAlgorithm("evca2")
vdv1 = CfgMgr.AthViews__ViewDataVerifier("vdv1")
vdv2 = CfgMgr.AthViews__ViewDataVerifier("vdv2")
# Add an algorithm to a sequence
topSequence += seqOR( "makeViewSequence" )
topSequence.makeViewSequence += viewTestAlg1
topSequence.makeViewSequence += evca1
#topSequence.makeViewSequence += evca2
# Return the algorithm assuming it's in a view, or not
self.assertEqual( findViewAlgs( topSequence.getChildren(), {} ),
( [ "viewTestAlg1" ], [] ) )
( [ "evca1" ], [] ) )
self.assertEqual( findViewAlgs( topSequence.getChildren(), {"makeViewSequence":False} ),
( [], [ "viewTestAlg1" ] ) )
( [], [ "evca1" ] ) )
# Add a nested sequence
topSequence.makeViewSequence += seqOR( "nestedSequence" )
topSequence.makeViewSequence.nestedSequence += viewTestAlg2
topSequence.makeViewSequence += seqOR( "viewSequence" )
topSequence.makeViewSequence.viewSequence += vdv1
# Return the algorithms depending on where the view is entered
self.assertEqual( findViewAlgs( topSequence.getChildren(), {} ),
( [ "viewTestAlg1", "viewTestAlg2" ], [] ) )
( [ "evca1", "vdv1" ], [] ) )
self.assertEqual( findViewAlgs( topSequence.getChildren(), {"makeViewSequence":False} ),
( [], [ "viewTestAlg1", "viewTestAlg2" ] ) )
self.assertEqual( findViewAlgs( topSequence.getChildren(), {"nestedSequence":False} ),
( [ "viewTestAlg1" ], [ "viewTestAlg2" ] ) )
( [], [ "evca1", "vdv1" ] ) )
self.assertEqual( findViewAlgs( topSequence.getChildren(), {"viewSequence":False} ),
( [ "evca1" ], [ "vdv1" ] ) )
# Check that the test finds view nodes by name
viewNodeDict = {"makeViewSequence":False, "aFakeNode":False}
findViewAlgs( topSequence.getChildren(), viewNodeDict )
self.assertEqual( viewNodeDict, {"makeViewSequence":True, "aFakeNode":False} )
# Check misconfigured EVCA
evca1.ViewNodeName = "aFakeNode"
with self.assertRaisesRegexp( RuntimeError, "no corresponding upstream EventViewCreatorAlgorithm" ):
checkVDV( topSequence, [topSequence.name()], {} )
evca1.ViewNodeName = "viewSequence"
with self.assertRaisesRegexp( RuntimeError, "RequireParentView = False" ):
checkVDV( topSequence, [topSequence.name()], {} )
evca1.RequireParentView = True
checkVDV( topSequence, [topSequence.name()], {} )
# Check for nested view CF working
topSequence.makeViewSequence.viewSequence += seqOR( "nestedSequence" )
topSequence.makeViewSequence.viewSequence.nestedSequence += vdv2
checkVDV( topSequence, [topSequence.name()], {} )
# Check duplicate EVCA config
evca2.ViewNodeName = "aFakeNode"
topSequence.makeViewSequence += evca2
checkVDV( topSequence, [topSequence.name()], {} )
evca2.ViewNodeName = "viewSequence"
with self.assertRaisesRegexp( RuntimeError, "Found duplicate view node name" ):
checkVDV( topSequence, [topSequence.name()], {} )
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment