blob: e00d2906697b5b2cc5f1486c7aba4f06d6fcff07 [file] [log] [blame]
import json
import time
class HA():
def __init__( self ):
self.default = ''
def consistentCheck( self ):
"""
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
"""
try:
# Get onos counters results
onosCountersRaw = []
threads = []
for i in main.activeNodes:
t = main.Thread( target=utilities.retry,
name="counters-" + str( i ),
args=[ main.CLIs[i].counters, [ None ] ],
kwargs= { 'sleep': 5, 'attempts': 5,
'randomTime': True } )
threads.append( t )
t.start()
for t in threads:
t.join()
onosCountersRaw.append( t.result )
onosCounters = []
for i in range( len( main.activeNodes ) ):
try:
onosCounters.append( json.loads( onosCountersRaw[i] ) )
except ( ValueError, TypeError ):
main.log.error( "Could not parse counters response from ONOS" +
str( main.activeNodes[i] + 1 ) )
main.log.warn( repr( onosCountersRaw[ i ] ) )
onosCounters.append( [] )
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.
# { "ONOS1": [ { "name":"TestON-Partitions","value":56} ]
# }
# NOTE: There is an assumtion that all nodes are active
# based on the above for loops
for controller in enumerate( onosCounters ):
for key, value in controller[1].iteritems():
if 'TestON' in key:
node = 'ONOS' + str( controller[0] + 1 )
try:
testCounters[node].append( { key: value } )
except KeyError:
testCounters[node] = [ { key: value } ]
# compare the counters on each node
firstV = testCounters.values()[0]
tmp = [ v == firstV for k, v in testCounters.iteritems() ]
if all( tmp ):
consistent = main.TRUE
else:
consistent = main.FALSE
main.log.error( "ONOS nodes have different values for counters:\n" +
testCounters )
return ( onosCounters, consistent )
except Exception:
main.log.exception( "" )
main.cleanup()
main.exit()
def counterCheck( self, counterName, counterValue ):
"""
Checks that TestON counters are consistent across all nodes and that
specified counter is in ONOS with the given value
"""
try:
correctResults = main.TRUE
# Get onos counters results and consistentCheck
onosCounters, consistent = self.consistentCheck()
# Check for correct values
for i in range( len( main.activeNodes ) ):
current = onosCounters[i]
onosValue = None
try:
onosValue = current.get( counterName )
except AttributeError:
node = str( main.activeNodes[i] + 1 )
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 ) )
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