From d276c6ea83fa767a09f30221580d31a3ec1e520a Mon Sep 17 00:00:00 2001
From: Tomasz Bold <tomasz.bold@gmail.com>
Date: Thu, 23 Aug 2018 17:16:45 +0200
Subject: [PATCH] moved to Py unittest, modified flatSequncers in such a way
 that sequences having muliple parents are not repeated

Former-commit-id: 61e5ae41ace0226d7387594a66e09a994bd4fb5f
---
 Control/AthenaCommon/python/CFElements.py     | 159 ++++++++++--------
 Control/AthenaCommon/share/CFElementsTest.ref |   1 -
 2 files changed, 88 insertions(+), 72 deletions(-)
 delete mode 100644 Control/AthenaCommon/share/CFElementsTest.ref

diff --git a/Control/AthenaCommon/python/CFElements.py b/Control/AthenaCommon/python/CFElements.py
index 75a8c65db17..032446791ef 100755
--- a/Control/AthenaCommon/python/CFElements.py
+++ b/Control/AthenaCommon/python/CFElements.py
@@ -104,99 +104,116 @@ def flatSequencers( start ):
     """ Flattens sequences """
     
     def __inner( seq, collector ):
-        for c in seq.getChildren():        
+        if seq.name() not in collector:
+            collector[seq.name()] = []
+        for c in seq.getChildren():
             collector[seq.name()].append( c )
             if isSequence( c ):            
-                __inner( c, collector )
+                if c.name() in collector: # already visited
+                    pass
+                else:       
+                    __inner( c, collector )
 
     from collections import defaultdict
     c = defaultdict(list)
     __inner(start, c)
     return c
 
-
 # self test
-if __name__ == "__main__":
-    from AthenaCommon.Configurable import ConfigurablePyAlgorithm
-    top = parOR("top")
-    top += parOR("nest1")
-    top += seqAND("nest2")
-    top += ConfigurablePyAlgorithm("SomeAlg0")
-
-    f = findSubSequence(top, "top")
-    assert f, "Can not find sequence at start"
-    assert f.name() == "top", "Wrong sequence"
-    # a one level deep search
-    nest2 = findSubSequence( top, "nest2" )
-    assert nest2, "Can not find sub sequence" 
-    assert nest2.name() == "nest2", "Sub sequence incorrect"
-
-    nest2 += parOR("deep_nest1")
-    nest2 += parOR("deep_nest2")
+import unittest
+class TestCF( unittest.TestCase ):
+    def setUp( self ):
+        from AthenaCommon.Configurable import ConfigurablePyAlgorithm
+        from AthenaCommon.Configurable import Configurable
+        Configurable.configurableRun3Behavior=1
+
+        top = parOR("top")
+        top += parOR("nest1")
+        nest2 = seqAND("nest2")
+        top += nest2
+        top += ConfigurablePyAlgorithm("SomeAlg0")
+        nest2 += parOR("deep_nest1")
+        nest2 += parOR("deep_nest2")
+        
+        nest2 += ConfigurablePyAlgorithm("SomeAlg1")
+        nest2 += ConfigurablePyAlgorithm("SomeAlg2")
+        nest2 += ConfigurablePyAlgorithm("SomeAlg3")
+        self.top = top
+
+    def test_findTop( self ):
+        f = findSubSequence( self.top, "top")
+        self.assertIsNotNone( f, "Can not find sequence at start" )
+        self.assertEqual( f.name(), "top", "Wrong sequence" )
+        # a one level deep search
+        nest2 = findSubSequence( self.top, "nest2" )
+        self.assertIsNotNone( nest2, "Can not find sub sequence" )
+        self.assertEqual( nest2.name(), "nest2", "Sub sequence incorrect" )
+
+    def test_findDeep( self ):
+        # deeper search
+        d = findSubSequence( self.top, "deep_nest2")
+        self.assertIsNotNone( d, "Deep searching for sub seqeunce fails" )
+        self.assertEqual( d.name(), "deep_nest2", "Wrong sub sequence in deep search" )
+
+    def test_findMissing( self ):
+        # algorithm is not a sequence
+        d = findSubSequence( self.top, "SomeAlg1") 
+        self.assertIsNone( d, "Algorithm confused as a sequence" )
     
-    nest2 += ConfigurablePyAlgorithm("SomeAlg1")
-    nest2 += ConfigurablePyAlgorithm("SomeAlg2")
+        # no on demand creation
+        inexistent = findSubSequence( self.top, "not_there" )
+        self.assertIsNone( inexistent, "ERROR, found sub sequence that does not relay exist" )
+    
+        # owner finding
+        inexistent = findOwningSequence(self.top, "not_there")
+        self.assertIsNone( inexistent, "ERROR, found owner of inexistent sequence " )
 
-    # deeper search
-    d = findSubSequence(top, "deep_nest2")
-    assert d, "Deep searching for sub seqeunce fails"
-    assert d.name() == "deep_nest2", "Wrong sub sequence in deep search"
+    def test_findRespectingScope( self ):
+        owner = findOwningSequence( self.top, "deep_nest1")
+        self.assertEqual( owner.name(), "nest2", "Wrong owner %s" % owner.name() )
 
-    d += ConfigurablePyAlgorithm("SomeAlg3")
+        owner = findOwningSequence( self.top, "deep_nest2")
+        self.assertEqual( owner.name(), "nest2", "Wrong owner %s" % owner.name() )
 
-    # algorithm is not a sequence
-    d = findSubSequence(top, "SomeAlg1") 
-    assert d == None, "Algorithm confused as a sequence"
-    
-    # no on demand creation
-    inexistent = findSubSequence(top, "not_there")
-    assert inexistent == None, "ERROR, found sub sequence that does not relay exist %s" % inexistent.name()
-    
-    # owner finding
-    inexistent = findOwningSequence(top, "not_there")
-    assert inexistent == None, "ERROR, found owner of inexistent sequence %s"% inexistent.name()
-
-    owner = findOwningSequence(top, "deep_nest1")
-    assert owner.name() == "nest2", "Wrong owner %s" % owner.name()
+        owner = findOwningSequence( self.top, "SomeAlg1")
+        self.assertEqual( owner.name(), "nest2", "Wrong owner %s" % owner.name() )
 
-    owner = findOwningSequence(top, "deep_nest2")
-    assert owner.name() == "nest2", "Wrong owner %s" % owner.name()
+        owner = findOwningSequence( self.top, "SomeAlg0")
+        self.assertEqual( owner.name() , "top", "Wrong owner %s" % owner.name() )
 
-    owner = findOwningSequence(top, "SomeAlg1")
-    assert owner.name() == "nest2", "Wrong owner %s" % owner.name()
+    def test_flatCollectors( self ):
+        flat = flatAlgorithmSequences( self.top )
+        #print "here", flat.keys()
+        expected = [ "top", "nest2" ]
+        self.assertEqual( set( flat.keys() ), set( expected ), "To many or to few sequences in flat structure, present: %s expected: %s "% ( " ".join( flat.keys() ), " ".join( expected ) ) )
 
-    owner = findOwningSequence(top, "SomeAlg0")
-    assert owner.name() == "top", "Wrong owner %s" % owner.name()
+        expected = [ "top", "nest1", "nest2", "deep_nest1", "deep_nest2" ]
+        flat = flatSequencers( self.top )
+        self.assertEqual( set( flat.keys() ), set( expected ), "To many or to few sequences in flat structure, present: %s expected: %s "% ( " ".join( flat.keys() ), " ".join( expected ) ) )
 
-    flat = flatAlgorithmSequences( top )
-    expected = [ "top", "nest2", "deep_nest2" ]
-    assert set( flat.keys() ) == set( expected ), "To many or to few sequences in flat structure, present %s expected %s "% ( " ".join( flat.keys() ), " ".join( expected ) )    
+    def test_findAlgorithms( self ):
+        a1 = findAlgorithm( self.top, "SomeAlg0" )
+        self.assertIsNotNone( a1, "Can't find algorithm present in sequence" )
 
-    flat = flatSequencers(top)
-    assert set( flat.keys() ) == set( expected ), "To many or to few sequences in flat structure, present %s expected %s "% ( " ".join( flat.keys() ), " ".join( expected ) )    
+        a1 = findAlgorithm( self.top, "SomeAlg1" )
+        self.assertIsNotNone( a1, "Can't find nested algorithm " )
 
-    a1 = findAlgorithm( top, "SomeAlg0" )
-    assert a1, "Can't find algorithm present in sequence"
-    a1 = findAlgorithm( top, "SomeAlg1" )
-    assert a1, "Can't find nested algorithm "
+        nest2 = findSubSequence( self.top, "nest2" )
 
-    a1 = findAlgorithm( nest2, "SomeAlg0" )
-    assert a1 == None, "Finding algorithm that is in the upper sequence"
+        a1 = findAlgorithm( nest2, "SomeAlg0" )
+        self.assertIsNone( a1, "Finding algorithm that is in the upper sequence" )
     
-    a1 = findAlgorithm( nest2, "NonexistentAlg" )
-    assert a1 == None, "Finding algorithm that is does not exist"
+        a1 = findAlgorithm( nest2, "NonexistentAlg" )
+        self.assertIsNone( a1, "Finding algorithm that is does not exist" )
              
-    a1 = findAlgorithm( top, "SomeAlg0", 1)
-    assert a1, "Could not find algorithm within the required nesting depth == 1"
-
-    a1 = findAlgorithm( top, "SomeAlg1", 1)
-    assert a1 == None, "Could find algorithm even if it is deep in sequences structure"
-
-    a1 = findAlgorithm( top, "SomeAlg1", 2)
-    assert a1, "Could not find algorithm within the required nesting depth == 2"
+        a1 = findAlgorithm( self.top, "SomeAlg0", 1)
+        self.assertIsNotNone( a1, "Could not find algorithm within the required nesting depth == 1" )
 
-    a1 = findAlgorithm( top, "SomeAlg3", 2)
-    assert a1 == None, "Could find algorithm evn if it is deep in sequences structure"    
+        a1 = findAlgorithm( self.top, "SomeAlg1", 1)
+        self.assertIsNone( a1, "Could find algorithm even if it is deep in sequences structure" )
 
+        a1 = findAlgorithm( self.top, "SomeAlg1", 2)
+        self.assertIsNotNone( a1, "Could not find algorithm within the required nesting depth == 2" )
 
-    print ("All OK")
+        a1 = findAlgorithm( self.top, "SomeAlg3", 2)
+        self.assertIsNotNone( a1 == None, "Could find algorithm evn if it is deep in sequences structure" )
diff --git a/Control/AthenaCommon/share/CFElementsTest.ref b/Control/AthenaCommon/share/CFElementsTest.ref
deleted file mode 100644
index 6d94a024a06..00000000000
--- a/Control/AthenaCommon/share/CFElementsTest.ref
+++ /dev/null
@@ -1 +0,0 @@
-All OK
-- 
GitLab