blob: 46e9edfcd104b691bd125074bcec29725f649d2d [file] [log] [blame]
"""
Functions for the vpls tests
"""
import time
import json
def sanitizeConfig( config ):
"""
Take a python json object for vpls config and normalize it.
Things it does:
Converts all strings to the same format
Make sure each network has an encapsulation key:value
Makes sure encapsulation type is all uppercase
Make sure an empty list of interfaces is formated consistently
Sorts the list of interfaces
Sorts the list of networks
"""
# Convert to same string formats
config = json.loads( json.dumps( config ) )
for network in config:
encap = network.get( 'encapsulation', None )
if encap is None:
encap = "NONE"
network[ 'encapsulation' ] = encap.upper()
ifaces = network.get( 'interfaces' )
if ifaces == [ '' ]:
ifaces = []
else:
ifaces = sorted( ifaces )
network[ 'interfaces' ] = ifaces
config = sorted( config, key=lambda k: k[ 'name' ] )
return config
def verify( main ):
"""
Runs some tests to verify the vpls configurations.
- Compare sent vpls network configuration to what is stored in each:
- ONOS network configuration
- ONOS VPLS application configuration
- Ping between each pair of hosts to check connectivity
NOTE: This requires the expected/sent network config json for the vpls
application be stored in main.vplsConfig
"""
# Variables
app = main.params[ 'vpls' ][ 'name' ]
pprint = main.ONOSrest1.pprint
SLEEP = int( main.params[ 'SLEEP' ][ 'netcfg' ] )
main.step( "Check network configurations for vpls application" )
clusterResult = True
for node in main.RESTs:
result = False
getVPLS = utilities.retry( f=node.getNetCfg,
retValue=False,
kwargs={"subjectClass":"apps", "subjectKey":app},
sleep=SLEEP )
onosCfg = json.loads( getVPLS ).get( 'vpls' ).get( 'vplsList' )
onosCfg = pprint( sanitizeConfig( onosCfg ) )
sentCfg = pprint( sanitizeConfig( main.vplsConfig ) )
result = onosCfg == sentCfg
if result:
main.log.info( "ONOS NetCfg matches what was sent" )
else:
clusterResult = False
main.log.error( "ONOS NetCfg doesn't match what was sent" )
main.log.debug( "ONOS config: {}".format( onosCfg ) )
main.log.debug( "Sent config: {}".format( sentCfg ) )
utilities.assert_equals( expect=True,
actual=clusterResult,
onpass="Net Cfg added for vpls",
onfail="Net Cfg not added for vpls" )
main.step( "Check vpls app configurations" )
clusterResult = True
for node in main.CLIs:
result = False
#TODO Read from vpls show and match to pushed json
vpls = node.parseVplsShow()
parsedVpls = pprint( sanitizeConfig( vpls ) )
sentVpls = pprint( sanitizeConfig( main.vplsConfig ) )
result = parsedVpls == sentVpls
if result:
main.log.info( "VPLS config matches sent NetCfg" )
else:
clusterResult = False
main.log.error( "VPLS config doesn't match sent NetCfg" )
main.log.debug( "ONOS config: {}".format( parsedVpls ) )
main.log.debug( "Sent config: {}".format( sentVpls ) )
utilities.assert_equals( expect=True,
actual=clusterResult,
onpass="VPLS successfully configured",
onfail="VPLS not configured correctly" )
checkIntentState( main )
main.step( "Check connectivity" )
connectivityCheck = True
hosts = int( main.params[ 'vpls' ][ 'hosts' ] )
networks = []
for network in main.vplsConfig:
nodes = network.get( 'interfaces', None )
if nodes:
networks.append( nodes )
for i in range( 1, hosts + 1 ):
src = "h" + str( i )
for j in range( 1, hosts + 1 ):
if j == i:
continue
dst = "h" + str( j )
pingResult = main.Mininet1.pingHost( SRC=src, TARGET=dst )
expected = main.FALSE
for network in networks:
if src in network and dst in network:
expected = main.TRUE
break
if pingResult != expected:
connectivityCheck = False
main.log.error( "%s <-> %s: %s; Expected: %s" %
( src, dst, pingResult, expected ) )
utilities.assert_equals( expect=True,
actual=connectivityCheck,
onpass="Connectivity is as expected",
onfail="Connectivity is not as expected" )
# TODO: if encapsulation is set, look for that
# TODO: can we look at the intent keys?
def checkIntentState( main , bl=[] ):
# Print the intent states
intents = main.CLIs[ 0 ].intents()
count = 0
while count <= 5:
installedCheck = True
try:
i = 1
for intent in json.loads( intents ):
state = intent.get( 'state', None )
if "INSTALLED" not in state or ( "WITHDRAWN" not in state and "h" + str( i ) in bl ):
installedCheck = False
i += 1
except ( ValueError, TypeError ):
main.log.exception( "Error parsing intents" )
if installedCheck:
break
count += 1
return installedCheck
def getVplsHashtable( main, bl=[] ):
"""
Returns a hashtable of vpls to hosts
"""
result = {}
vplsConfig = main.vplsConfig
for v in vplsConfig:
interfaces = v[ 'interfaces' ][:]
for i in bl:
if i in interfaces:
interfaces.remove( i )
result[ v[ 'name' ] ] = interfaces
return result
def testConnectivityVpls( main, blacklist=[], isNodeUp=True ):
# Can't do intent check when onos node is stopped/killed yet
if isNodeUp:
main.step( "Check intent states" )
intentsCheck = utilities.retry( f=checkIntentState,
retValue=False,
args=( main, blacklist ),
sleep=main.timeSleep,
attempts=main.numAttempts )
utilities.assert_equals( expect=True,
actual=intentsCheck,
onpass="All Intents in installed state",
onfail="Not all Intents in installed state" )
main.step( "Testing connectivity..." )
vplsHashtable = getVplsHashtable( main, blacklist )
main.log.debug( "vplsHashtable: " + str( vplsHashtable ) )
result = True
for key in vplsHashtable:
pingResult = utilities.retry( f=main.Mininet1.pingallHosts,
retValue=False,
args=( vplsHashtable[ key ], ),
sleep=main.timeSleep,
attempts=main.numAttempts )
result = result and pingResult
utilities.assert_equals( expect=main.TRUE, actual=result,
onpass="Connectivity succeeded.",
onfail="Connectivity failed." )
return result
def compareApps( main ):
result = True
first = None
for cli in main.CLIs:
currentApps = cli.apps( summary=True, active=True )
if not result:
first = currentApps
else:
result = result and ( currentApps == first )
return result