Refactor HA tests
Move more code into functions
Retry some functions
Rename class file
Enable FlowObjective intent compiler
Cleanup flowTableComp and doen't short circuit in Mininet driver
Change-Id: I2a404b32469d137370e512a1c44f06dd8e9df23b
diff --git a/TestON/tests/HAfullNetPartition/HAfullNetPartition.params b/TestON/tests/HAfullNetPartition/HAfullNetPartition.params
index 4dc5a5e..5461243 100644
--- a/TestON/tests/HAfullNetPartition/HAfullNetPartition.params
+++ b/TestON/tests/HAfullNetPartition/HAfullNetPartition.params
@@ -24,7 +24,7 @@
<apps></apps>
<ONOS_Configuration>
<org.onosproject.net.intent.impl.compiler.IntentConfigurableRegistrator>
- <useFlowObjectives>false</useFlowObjectives>
+ <useFlowObjectives>true</useFlowObjectives>
</org.onosproject.net.intent.impl.compiler.IntentConfigurableRegistrator>
</ONOS_Configuration>
<ENV>
diff --git a/TestON/tests/HAfullNetPartition/HAfullNetPartition.py b/TestON/tests/HAfullNetPartition/HAfullNetPartition.py
index 12d8bbb..6ae0c7b 100644
--- a/TestON/tests/HAfullNetPartition/HAfullNetPartition.py
+++ b/TestON/tests/HAfullNetPartition/HAfullNetPartition.py
@@ -95,8 +95,8 @@
ONOS7Port = main.params[ 'CTRL' ][ 'port7' ]
try:
- from tests.HAsanity.dependencies.Counters import Counters
- main.Counters = Counters()
+ from tests.HAsanity.dependencies.HA import HA
+ main.HA = HA()
except Exception as e:
main.log.exception( e )
main.cleanup()
@@ -276,38 +276,12 @@
port=main.params[ 'MNtcpdump' ][ 'port' ] )
main.step( "Checking ONOS nodes" )
- nodesOutput = []
- nodeResults = main.TRUE
- threads = []
- for i in main.activeNodes:
- t = main.Thread( target=main.CLIs[i].nodes,
- name="nodes-" + str( i ),
- args=[ ] )
- threads.append( t )
- t.start()
+ nodeResults = utilities.retry( main.HA.nodesCheck,
+ False,
+ args=[main.activeNodes],
+ attempts=5 )
- for t in threads:
- t.join()
- nodesOutput.append( t.result )
- ips = [ main.nodes[node].ip_address for node in main.activeNodes ]
- ips.sort()
- for i in nodesOutput:
- try:
- current = json.loads( i )
- activeIps = []
- currentResult = main.FALSE
- for node in current:
- if node['state'] == 'READY':
- activeIps.append( node['ip'] )
- activeIps.sort()
- if ips == activeIps:
- currentResult = main.TRUE
- except ( ValueError, TypeError ):
- main.log.error( "Error parsing nodes output" )
- main.log.warn( repr( i ) )
- currentResult = main.FALSE
- nodeResults = nodeResults and currentResult
- utilities.assert_equals( expect=main.TRUE, actual=nodeResults,
+ utilities.assert_equals( expect=True, actual=nodeResults,
onpass="Nodes check successful",
onfail="Nodes check NOT successful" )
@@ -973,6 +947,7 @@
"functionality and check the state of " +\
"the intent"
+ onosCli = main.CLIs[ main.activeNodes[0] ]
main.step( "Check Intent state" )
installedCheck = False
loopCount = 0
@@ -1008,7 +983,6 @@
"INSTALLED state" )
main.step( "Ping across added host intents" )
- onosCli = main.CLIs[ main.activeNodes[0] ]
PingResult = main.TRUE
for i in range( 8, 18 ):
ping = main.Mininet1.pingHost( src="h" + str( i ),
@@ -2140,8 +2114,9 @@
for i in range( 28 ):
main.log.info( "Checking flow table on s" + str( i + 1 ) )
tmpFlows = main.Mininet1.getFlowTable( "s" + str( i + 1 ), version="1.3", debug=False )
- FlowTables = FlowTables and main.Mininet1.flowTableComp( flows[i], tmpFlows )
- if FlowTables == main.FALSE:
+ curSwitch = main.Mininet1.flowTableComp( flows[i], tmpFlows )
+ FlowTables = FlowTables and curSwitch
+ if curSwitch == main.FALSE:
main.log.warn( "Differences in flow table for switch: s{}".format( i + 1 ) )
utilities.assert_equals(
expect=main.TRUE,
@@ -2620,45 +2595,19 @@
# FIXME: move this to an ONOS state case
main.step( "Checking ONOS nodes" )
- nodesOutput = []
- nodeResults = main.TRUE
- threads = []
- for i in main.activeNodes:
- t = main.Thread( target=main.CLIs[i].nodes,
- name="nodes-" + str( i ),
- args=[ ] )
- threads.append( t )
- t.start()
+ nodeResults = utilities.retry( main.HA.nodesCheck,
+ False,
+ args=[main.activeNodes],
+ attempts=5 )
- for t in threads:
- t.join()
- nodesOutput.append( t.result )
- ips = [ main.nodes[node].ip_address for node in main.activeNodes ]
- ips.sort()
- for i in nodesOutput:
- try:
- current = json.loads( i )
- activeIps = []
- currentResult = main.FALSE
- for node in current:
- if node['state'] == 'READY':
- activeIps.append( node['ip'] )
- activeIps.sort()
- if ips == activeIps:
- currentResult = main.TRUE
- except ( ValueError, TypeError ):
- main.log.error( "Error parsing nodes output" )
- main.log.warn( repr( i ) )
- currentResult = main.FALSE
- nodeResults = nodeResults and currentResult
- utilities.assert_equals( expect=main.TRUE, actual=nodeResults,
+ utilities.assert_equals( expect=True, actual=nodeResults,
onpass="Nodes check successful",
onfail="Nodes check NOT successful" )
if not nodeResults:
- for cli in main.CLIs:
+ for i in main.activeNodes:
main.log.debug( "{} components not ACTIVE: \n{}".format(
- cli.name,
- cli.sendline( "scr:list | grep -v ACTIVE" ) ) )
+ main.CLIs[i].name,
+ main.CLIs[i].sendline( "scr:list | grep -v ACTIVE" ) ) )
def CASE9( self, main ):
"""
@@ -2978,26 +2927,8 @@
main.step( "Check that each node shows the same leader and candidates" )
failMessage = "Nodes have different leaderboards"
- def consistentLeaderboards( nodes ):
- TOPIC = 'org.onosproject.election'
- # FIXME: use threads
- #FIXME: should we retry outside the function?
- for n in range( 5 ): # Retry in case election is still happening
- leaderList = []
- # Get all leaderboards
- for cli in nodes:
- leaderList.append( cli.specificLeaderCandidate( TOPIC ) )
- # Compare leaderboards
- result = all( i == leaderList[0] for i in leaderList ) and\
- leaderList is not None
- main.log.debug( leaderList )
- main.log.warn( result )
- if result:
- return ( result, leaderList )
- time.sleep(5) #TODO: paramerterize
- main.log.error( "Inconsistent leaderboards:" + str( leaderList ) )
activeCLIs = [ main.CLIs[i] for i in main.activeNodes ]
- sameResult, oldLeaders = consistentLeaderboards( activeCLIs )
+ sameResult, oldLeaders = main.HA.consistentLeaderboards( activeCLIs )
if sameResult:
oldLeader = oldLeaders[ 0 ][ 0 ]
main.log.warn( oldLeader )
@@ -3033,7 +2964,7 @@
main.step( "Check that a new node was elected leader" )
failMessage = "Nodes have different leaders"
# Get new leaders and candidates
- newLeaderResult, newLeaders = consistentLeaderboards( activeCLIs )
+ newLeaderResult, newLeaders = main.HA.consistentLeaderboards( activeCLIs )
if newLeaders[ 0 ][ 0 ] == 'none':
main.log.error( "No leader was elected on at least 1 node" )
if not expectNoLeader:
@@ -3101,7 +3032,7 @@
# Get new leaders and candidates
reRunLeaders = []
time.sleep( 5 ) # Paremterize
- positionResult, reRunLeaders = consistentLeaderboards( activeCLIs )
+ positionResult, reRunLeaders = main.HA.consistentLeaderboards( activeCLIs )
# Check that the re-elected node is last on the candidate List
if oldLeader != reRunLeaders[ 0 ][ -1 ]:
@@ -3245,7 +3176,7 @@
" counter" )
main.step( "Counters we added have the correct values" )
- incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
+ incrementCheck = main.HA.counterCheck( pCounterName, pCounterValue )
utilities.assert_equals( expect=main.TRUE,
actual=incrementCheck,
onpass="Added counters are correct",
@@ -3345,7 +3276,7 @@
" counter" )
main.step( "Counters we added have the correct values" )
- incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
+ incrementCheck = main.HA.counterCheck( pCounterName, pCounterValue )
utilities.assert_equals( expect=main.TRUE,
actual=incrementCheck,
onpass="Added counters are correct",
diff --git a/TestON/tests/HAfullNetPartition/dependencies/Counters.py b/TestON/tests/HAfullNetPartition/dependencies/HA.py
similarity index 60%
rename from TestON/tests/HAfullNetPartition/dependencies/Counters.py
rename to TestON/tests/HAfullNetPartition/dependencies/HA.py
index 192b919..e00d290 100644
--- a/TestON/tests/HAfullNetPartition/dependencies/Counters.py
+++ b/TestON/tests/HAfullNetPartition/dependencies/HA.py
@@ -1,6 +1,7 @@
import json
+import time
-class Counters():
+class HA():
def __init__( self ):
self.default = ''
@@ -10,12 +11,12 @@
Checks that TestON counters are consistent across all nodes.
Returns the tuple (onosCounters, consistent)
- - onosCounters is the parsed json output of the counters command on all nodes
- - consistent is main.TRUE if all "TestON" counters are consitent across all
- nodes or main.FALSE
+ - onosCounters is the parsed json output of the counters command on
+ all nodes
+ - consistent is main.TRUE if all "TestON" counters are consitent across
+ all nodes or main.FALSE
"""
try:
- correctResults = main.TRUE
# Get onos counters results
onosCountersRaw = []
threads = []
@@ -42,8 +43,8 @@
testCounters = {}
# make a list of all the "TestON-*" counters in ONOS
- # lookes like a dict whose keys are the name of the ONOS node and values
- # are a list of the counters. I.E.
+ # lookes like a dict whose keys are the name of the ONOS node and
+ # values are a list of the counters. I.E.
# { "ONOS1": [ { "name":"TestON-Partitions","value":56} ]
# }
# NOTE: There is an assumtion that all nodes are active
@@ -86,20 +87,75 @@
onosValue = None
try:
onosValue = current.get( counterName )
- except AttributeError, e:
+ except AttributeError:
node = str( main.activeNodes[i] + 1 )
- main.log.error( "ONOS" + node + " counters result " +
- "is not as expected" )
+ main.log.exception( "ONOS" + node + " counters result " +
+ "is not as expected" )
correctResults = main.FALSE
if onosValue == counterValue:
main.log.info( counterName + " counter value is correct" )
else:
- main.log.error( counterName + " counter value is incorrect," +
- " expected value: " + str( counterValue )
- + " current value: " + str( onosValue ) )
+ main.log.error( counterName +
+ " counter value is incorrect," +
+ " expected value: " + str( counterValue ) +
+ " current value: " + str( onosValue ) )
correctResults = main.FALSE
return consistent and correctResults
except Exception:
main.log.exception( "" )
main.cleanup()
main.exit()
+
+ def consistentLeaderboards( self, nodes ):
+ TOPIC = 'org.onosproject.election'
+ # FIXME: use threads
+ #FIXME: should we retry outside the function?
+ for n in range( 5 ): # Retry in case election is still happening
+ leaderList = []
+ # Get all leaderboards
+ for cli in nodes:
+ leaderList.append( cli.specificLeaderCandidate( TOPIC ) )
+ # Compare leaderboards
+ result = all( i == leaderList[0] for i in leaderList ) and\
+ leaderList is not None
+ main.log.debug( leaderList )
+ main.log.warn( result )
+ if result:
+ return ( result, leaderList )
+ time.sleep(5) # TODO: paramerterize
+ main.log.error( "Inconsistent leaderboards:" + str( leaderList ) )
+ return ( result, leaderList )
+
+ def nodesCheck( self, nodes ):
+ nodesOutput = []
+ results = True
+ threads = []
+ for i in nodes:
+ t = main.Thread( target=main.CLIs[i].nodes,
+ name="nodes-" + str( i ),
+ args=[ ] )
+ threads.append( t )
+ t.start()
+
+ for t in threads:
+ t.join()
+ nodesOutput.append( t.result )
+ ips = [ main.nodes[node].ip_address for node in nodes ]
+ ips.sort()
+ for i in nodesOutput:
+ try:
+ current = json.loads( i )
+ activeIps = []
+ currentResult = False
+ for node in current:
+ if node['state'] == 'READY':
+ activeIps.append( node['ip'] )
+ activeIps.sort()
+ if ips == activeIps:
+ currentResult = True
+ except ( ValueError, TypeError ):
+ main.log.error( "Error parsing nodes output" )
+ main.log.warn( repr( i ) )
+ currentResult = False
+ results = results and currentResult
+ return results