Framework of the new CHOtest
Change-Id: Ie5b58bfa2ed487386443692cbea0d469d7419c24
diff --git a/TestON/tests/CHOTestMonkey/dependencies/events/AppEvent.py b/TestON/tests/CHOTestMonkey/dependencies/events/AppEvent.py
new file mode 100644
index 0000000..7f0ca7c
--- /dev/null
+++ b/TestON/tests/CHOTestMonkey/dependencies/events/AppEvent.py
@@ -0,0 +1,246 @@
+"""
+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