blob: 7f0ca7c64061ba763df38d11eed1110394d858eb [file] [log] [blame]
"""
This file contains classes for CHOTestMonkey that are related to application event
Author: you@onlab.us
"""
from tests.CHOTestMonkey.dependencies.events.Event import EventType, EventStates, Event
from tests.CHOTestMonkey.dependencies.elements.ONOSElement import HostIntent, PointIntent
class IntentEvent( Event ):
def __init__( self ):
Event.__init__( self )
# The index of the ONOS CLI that is going to run the command
self.CLIIndex = 0
class HostIntentEvent( IntentEvent ):
def __init__( self ):
IntentEvent.__init__( self )
self.hostA = None
self.hostB = None
def startHostIntentEvent( self ):
return EventStates().PASS
def startEvent( self, args ):
with self.eventLock:
main.log.info( "%s - starting event" % ( self.typeString ) )
if self.typeIndex == EventType().APP_INTENT_HOST_ADD or self.typeIndex == EventType().APP_INTENT_HOST_DEL:
if len( args ) < 3:
main.log.warn( "%s - Not enough arguments: %s" % ( self.typeString, args ) )
return EventStates().ABORT
elif len( args ) > 3:
main.log.warn( "%s - Too many arguments: %s" % ( self.typeString, args ) )
return EventStates().ABORT
else:
if args[ 0 ] == args[ 1 ]:
main.log.warn( "%s - invalid argument: %s" % ( self.typeString, index ) )
return EventStates().ABORT
for host in main.hosts:
if host.name == args[ 0 ]:
self.hostA = host
elif host.name == args[ 1 ]:
self.hostB = host
if self.hostA != None and self.hostB != None:
break
if self.hostA == None:
main.log.warn( "Host %s does not exist: " % ( args[ 0 ] ) )
return EventStates().ABORT
if self.hostB == None:
main.log.warn( "Host %s does not exist: " % ( args[ 1 ] ) )
return EventStates().ABORT
index = int( args[ 2 ] )
if index < 1 or index > int( main.numCtrls ):
main.log.warn( "%s - invalid argument: %s" % ( self.typeString, index ) )
return EventStates().ABORT
if not main.controllers[ index - 1 ].isUp():
main.log.warn( self.typeString + " - invalid argument: onos %s is down" % ( controller.index ) )
return EventStates().ABORT
self.CLIIndex = index
return self.startHostIntentEvent()
class AddHostIntent( HostIntentEvent ):
"""
Add a host-to-host intent (bidirectional)
"""
def __init__( self ):
HostIntentEvent.__init__( self )
self.typeString = main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeString' ]
self.typeIndex= int( main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeIndex' ] )
def startHostIntentEvent( self ):
assert self.hostA != None and self.hostB != None
# Check whether there already exists some intent for the host pair
# For now we should avoid installing overlapping intents
for intent in main.intents:
if not intent.type == 'INTENT_HOST':
continue
if intent.hostA == self.hostA and intent.hostB == self.hostB or\
intent.hostB == self.hostA and intent.hostA == self.hostB:
main.log.warn( self.typeString + " - find an exiting intent for the host pair, abort installation" )
return EventStates().ABORT
controller = main.controllers[ self.CLIIndex - 1 ]
with controller.CLILock:
id = controller.CLI.addHostIntent( self.hostA.id, self.hostB.id )
if id == None:
main.log.warn( self.typeString + " - add host intent failed" )
return EventStates().FAIL
with main.variableLock:
newHostIntent = HostIntent( id, self.hostA, self.hostB )
main.intents.append( newHostIntent )
# Update host connectivity status
# TODO: should we check whether hostA and hostB are already correspondents?
self.hostB.correspondents.append( self.hostA )
self.hostA.correspondents.append( self.hostB )
return EventStates().PASS
class DelHostIntent( HostIntentEvent ):
"""
Delete a host-to-host intent (bidirectional)
"""
def __init__( self ):
HostIntentEvent.__init__( self )
self.typeString = main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeString' ]
self.typeIndex= int( main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeIndex' ] )
def startHostIntentEvent( self ):
assert self.hostA != None and self.hostB != None
targetIntent = None
for intent in main.intents:
if not intent.type == 'INTENT_HOST':
continue
if intent.hostA == self.hostA and intent.hostB == self.hostB or\
intent.hostB == self.hostA and intent.hostA == self.hostB:
targetIntent = intent
break
if targetIntent == None:
main.log.warn( self.typeString + " - intent does not exist" )
return EventStates().FAIL
controller = main.controllers[ self.CLIIndex - 1 ]
with controller.CLILock:
result = controller.CLI.removeIntent( targetIntent.id, purge=True )
if result == None or result == main.FALSE:
main.log.warn( self.typeString + " - delete host intent failed" )
return EventStates().FAIL
with main.variableLock:
main.intents.remove( targetIntent )
# Update host connectivity status
self.hostB.correspondents.remove( self.hostA )
self.hostA.correspondents.remove( self.hostB )
return EventStates().PASS
class PointIntentEvent( IntentEvent ):
def __init__( self ):
IntentEvent.__init__( self )
self.deviceA = None
self.deviceB = None
def startPointIntentEvent( self ):
return EventStates().PASS
def startEvent( self, args ):
with self.eventLock:
main.log.info( "%s - starting event" % ( self.typeString ) )
if self.typeIndex == EventType().APP_INTENT_POINT_ADD or self.typeIndex == EventType().APP_INTENT_POINT_DEL:
if len( args ) < 3:
main.log.warn( "%s - Not enough arguments: %s" % ( self.typeString, args ) )
return EventStates().ABORT
elif len( args ) > 3:
main.log.warn( "%s - Too many arguments: %s" % ( self.typeString, args ) )
return EventStates().ABORT
else:
for device in main.devices:
if device.name == args[ 0 ]:
self.deviceA = device
elif device.name == args[ 1 ]:
self.deviceB = device
if self.deviceA != None and self.deviceB != None:
break
if self.deviceA == None:
main.log.warn( "Device %s does not exist: " % ( args[ 0 ] ) )
return EventStates().ABORT
if self.deviceB == None:
main.log.warn( "Device %s does not exist: " % ( args[ 1 ] ) )
return EventStates().ABORT
index = int( args[ 2 ] )
if index < 1 or index > int( main.numCtrls ):
main.log.warn( "%s - invalid argument: %s" % ( self.typeString, index ) )
return EventStates().ABORT
if not main.controllers[ index - 1 ].isUp():
main.log.warn( self.typeString + " - invalid argument: onos %s is down" % ( controller.index ) )
return EventStates().ABORT
self.CLIIndex = index
return self.startPointIntentEvent()
class AddPointIntent( PointIntentEvent ):
"""
Add a point-to-point intent
"""
def __init__( self ):
PointIntentEvent.__init__( self )
self.typeString = main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeString' ]
self.typeIndex= int( main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeIndex' ] )
def startPointIntentEvent( self ):
assert self.deviceA != None and self.deviceB != None
controller = main.controllers[ self.CLIIndex - 1 ]
# TODO: the following check only work when we use default port number for point intents
# Check whether there already exists some intent for the device pair
# For now we should avoid installing overlapping intents
for intent in main.intents:
if not intent.type == 'INTENT_POINT':
continue
if intent.deviceA == self.deviceA and intent.deviceB == self.deviceB:
main.log.warn( self.typeString + " - find an exiting intent for the device pair, abort installation" )
return EventStates().ABORT
controller = main.controllers[ self.CLIIndex - 1 ]
with controller.CLILock:
# TODO: handle the case that multiple hosts attach to one device
id = controller.CLI.addPointIntent( self.deviceA.dpid, self.deviceB.dpid,
1, 1, '',
self.deviceA.hosts[ 0 ].mac,
self.deviceB.hosts[ 0 ].mac )
if id == None:
main.log.warn( self.typeString + " - add point intent failed" )
return EventStates().FAIL
with main.variableLock:
newPointIntent = PointIntent( id, self.deviceA, self.deviceB )
main.intents.append( newPointIntent )
# Update host connectivity status
for hostA in self.deviceA.hosts:
for hostB in self.deviceB.hosts:
hostA.correspondents.append( hostB )
return EventStates().PASS
class DelPointIntent( PointIntentEvent ):
"""
Delete a point-to-point intent
"""
def __init__( self ):
PointIntentEvent.__init__( self )
self.typeString = main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeString' ]
self.typeIndex= int( main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeIndex' ] )
def startPointIntentEvent( self ):
assert self.deviceA != None and self.deviceB != None
targetIntent = None
for intent in main.intents:
if not intent.type == 'INTENT_POINT':
continue
if intent.deviceA == self.deviceA and intent.deviceB == self.deviceB:
targetIntent = intent
break
if targetIntent == None:
main.log.warn( self.typeString + " - intent does not exist" )
return EventStates().FAIL
controller = main.controllers[ self.CLIIndex - 1 ]
with controller.CLILock:
result = controller.CLI.removeIntent( targetIntent.id, purge=True )
if result == None or result == main.FALSE:
main.log.warn( self.typeString + " - delete host intent failed" )
return EventStates().FAIL
with main.variableLock:
main.intents.remove( targetIntent )
# Update host connectivity status
for hostA in self.deviceA.hosts:
for hostB in self.deviceB.hosts:
hostA.correspondents.remove( hostB )
return EventStates().PASS