Merge "Record events scheduled in CHOTestMonkey and enable replay from recorded event file"
diff --git a/TestON/tests/CHOTestMonkey/CHOTestMonkey.params b/TestON/tests/CHOTestMonkey/CHOTestMonkey.params
index 0805112..6c9ef4b 100644
--- a/TestON/tests/CHOTestMonkey/CHOTestMonkey.params
+++ b/TestON/tests/CHOTestMonkey/CHOTestMonkey.params
@@ -15,9 +15,10 @@
# 50. Set FlowObjective to True
# 51. Set FlowObjective to False
# 60. Rebalance devices across controllers
- # 70. Randomly generate events
+ # 70. Run randomly generated events
+ # 80. Replay events from log file
# 90. Sleep for some time
- # 100. Do something else
+ # 100. Do nothing
# Sample sequence: 0,1,2,3,[10,30,21,31,10,32,21,33,50,10,30,21,31,10,32,21,33,51,40,60,10,30,21,31,10,32,21,33,50,10,30,21,31,10,32,21,33,51,41,60]*500,100
<testcases>
0,1,2,3,70
@@ -391,6 +392,12 @@
<deviceDownWeight>2</deviceDownWeight>
</CASE70>
+ <CASE80>
+ <filePath>/home/admin/log-for-replay</filePath>
+ <sleepTime>0.1</sleepTime>
+ <skipChecks>on</skipChecks>
+ </CASE80>
+
<CASE90>
<sleepSec>60</sleepSec>
</CASE90>
diff --git a/TestON/tests/CHOTestMonkey/CHOTestMonkey.py b/TestON/tests/CHOTestMonkey/CHOTestMonkey.py
index 42c0ff7..8937a4a 100644
--- a/TestON/tests/CHOTestMonkey/CHOTestMonkey.py
+++ b/TestON/tests/CHOTestMonkey/CHOTestMonkey.py
@@ -794,7 +794,7 @@
events.append( 'device-down' )
for i in range( int( pow( hostIntentNum, 1.5 ) / 100 ) ):
events.append( 'del-host-intent' )
- for i in range( int( pow( pointIntentNum/2, 1.5 ) / 100 ) ):
+ for i in range( int( pow( pointIntentNum, 1.5 ) / 100 ) ):
events.append( 'del-point-intent' )
for i in range( pow( 2, downLinkNum ) - 1 ):
events.append( 'link-up' )
@@ -819,13 +819,13 @@
for i in range( n ):
cliIndex = random.sample( upControllers, 1 )[ 0 ]
main.eventGenerator.triggerEvent( EventType().APP_INTENT_POINT_ADD, EventScheduleMethod().RUN_BLOCK, 'random', 'random', cliIndex, 'bidirectional' )
- pointIntentNum += 1
+ pointIntentNum += 2
elif event == 'del-point-intent':
- n = random.randint( 5, pointIntentNum )
+ n = random.randint( 5, pointIntentNum / 2 )
for i in range( n ):
cliIndex = random.sample( upControllers, 1 )[ 0 ]
main.eventGenerator.triggerEvent( EventType().APP_INTENT_POINT_DEL, EventScheduleMethod().RUN_BLOCK, 'random', 'random', cliIndex, 'bidirectional' )
- pointIntentNum -= 1
+ pointIntentNum -= 2
elif event == 'link-down':
main.eventGenerator.triggerEvent( EventType().NETWORK_LINK_DOWN, EventScheduleMethod().RUN_BLOCK, 'random', 'random' )
downLinkNum += 1
@@ -855,6 +855,45 @@
onfail="Randomly generate events test failed" )
time.sleep( main.caseSleep )
+ def CASE80( self, main ):
+ """
+ Replay events from log file
+ """
+ import time
+ from tests.CHOTestMonkey.dependencies.events.Event import EventType
+ from tests.CHOTestMonkey.dependencies.EventScheduler import EventScheduleMethod
+
+ main.log.report( "Replay events from log file" )
+ main.log.report( "__________________________________________________" )
+ main.case( "Replay events from log file" )
+ main.step( "Replay events from log file" )
+ main.caseResult = main.TRUE
+ try:
+ f = open( main.params[ 'CASE80' ][ 'filePath' ], 'r' )
+ for line in f.readlines():
+ if 'CHOTestMonkey' in line and 'Event recorded' in line:
+ line = line.split()
+ eventIndex = int( line[ 9 ] )
+ eventName = line[ 10 ]
+ args = line[ 11: ]
+ assert eventName.startswith( 'CHECK' )\
+ or eventName.startswith( 'NETWORK' )\
+ or eventName.startswith( 'APP' )\
+ or eventName.startswith( 'ONOS' )
+ if main.params[ 'CASE80' ][ 'skipChecks' ] == 'on' and eventName.startswith( 'CHECK' ):
+ continue
+ with main.eventScheduler.idleCondition:
+ while not main.eventScheduler.isIdle():
+ main.eventScheduler.idleCondition.wait()
+ main.eventGenerator.triggerEvent( eventIndex, EventScheduleMethod().RUN_BLOCK, *args )
+ time.sleep( float( main.params[ 'CASE80' ][ 'sleepTime' ] ) )
+ except Exception as e:
+ print e
+ utilities.assert_equals( expect=main.TRUE,
+ actual=main.caseResult,
+ onpass="Replay from log file passed",
+ onfail="Replay from log file failed" )
+
def CASE90( self, main ):
"""
Sleep for some time
diff --git a/TestON/tests/CHOTestMonkey/dependencies/EventTrigger.py b/TestON/tests/CHOTestMonkey/dependencies/EventTrigger.py
index 0c3e0e0..27b8166 100644
--- a/TestON/tests/CHOTestMonkey/dependencies/EventTrigger.py
+++ b/TestON/tests/CHOTestMonkey/dependencies/EventTrigger.py
@@ -15,7 +15,7 @@
address = ( host, port )
conn = Client( address )
request = []
- request.append( 2 )
+ request.append( 1 )
request.append( type )
request.append( scheduleMethod )
for arg in args:
@@ -23,7 +23,9 @@
conn.send( request )
response = conn.recv()
while response == 11:
+ conn.close()
time.sleep( 1 )
+ conn = Client( address )
conn.send( request )
response = conn.recv()
if response == 10:
@@ -64,5 +66,19 @@
else:
pass
+def replayFromFile( filePath='/home/admin/event-list', sleepTime=1 ):
+ try:
+ f = open( filePath, 'r' )
+ for line in f.readlines():
+ event = line.split()
+ if event[ 3 ].startswith( 'CHECK' ):
+ continue
+ triggerEvent( event[ 3 ], 'RUN_BLOCK', *event[ 4: ] )
+ time.sleep( sleepTime )
+ f.close()
+ except Exception as e:
+ print e
+
if __name__ == '__main__':
- testLoop( 2 )
+ #testLoop( 2 )
+ replayFromFile()
diff --git a/TestON/tests/CHOTestMonkey/dependencies/events/AppEvent.py b/TestON/tests/CHOTestMonkey/dependencies/events/AppEvent.py
index 07c8cb6..4283ff6 100644
--- a/TestON/tests/CHOTestMonkey/dependencies/events/AppEvent.py
+++ b/TestON/tests/CHOTestMonkey/dependencies/events/AppEvent.py
@@ -63,7 +63,7 @@
def startEvent( self, args ):
with self.eventLock:
- main.log.info( "%s - starting event" % ( self.typeString ) )
+ #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 ) )
@@ -138,6 +138,7 @@
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
+ main.log.info( "Event recorded: {} {} {} {} {}".format( self.typeIndex, self.typeString, self.hostA.name, self.hostB.name, self.CLIIndex ) )
controller = main.controllers[ self.CLIIndex - 1 ]
with controller.CLILock:
id = controller.CLI.addHostIntent( self.hostA.id, self.hostB.id )
@@ -179,6 +180,7 @@
if targetIntent == None:
main.log.warn( self.typeString + " - intent does not exist" )
return EventStates().FAIL
+ main.log.info( "Event recorded: {} {} {} {} {}".format( self.typeIndex, self.typeString, self.hostA.name, self.hostB.name, self.CLIIndex ) )
controller = main.controllers[ self.CLIIndex - 1 ]
with controller.CLILock:
result = controller.CLI.removeIntent( targetIntent.id, purge=True )
@@ -204,7 +206,7 @@
def startEvent( self, args ):
with self.eventLock:
- main.log.info( "%s - starting event" % ( self.typeString ) )
+ #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 ) )
@@ -290,6 +292,7 @@
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
+ main.log.info( "Event recorded: {} {} {} {} {}".format( self.typeIndex, self.typeString, self.deviceA.name, self.deviceB.name, self.CLIIndex ) )
controller = main.controllers[ self.CLIIndex - 1 ]
with controller.CLILock:
srcMAC = ""
@@ -336,6 +339,7 @@
if targetIntent == None:
main.log.warn( self.typeString + " - intent does not exist" )
return EventStates().FAIL
+ main.log.info( "Event recorded: {} {} {} {} {}".format( self.typeIndex, self.typeString, self.deviceA.name, self.deviceB.name, self.CLIIndex ) )
controller = main.controllers[ self.CLIIndex - 1 ]
with controller.CLILock:
result = controller.CLI.removeIntent( targetIntent.id, purge=True )
diff --git a/TestON/tests/CHOTestMonkey/dependencies/events/CheckEvent.py b/TestON/tests/CHOTestMonkey/dependencies/events/CheckEvent.py
index fcbf23d..fa42e12 100755
--- a/TestON/tests/CHOTestMonkey/dependencies/events/CheckEvent.py
+++ b/TestON/tests/CHOTestMonkey/dependencies/events/CheckEvent.py
@@ -13,7 +13,7 @@
def startEvent( self, args ):
with self.eventLock:
- main.log.info( "%s - starting event" % ( self.typeString ) )
+ main.log.info( "Event recorded: {} {}".format( self.typeIndex, self.typeString ) )
result = self.startCheckEvent()
return result
diff --git a/TestON/tests/CHOTestMonkey/dependencies/events/NetworkEvent.py b/TestON/tests/CHOTestMonkey/dependencies/events/NetworkEvent.py
index 8ec62a1..ccab8a1 100644
--- a/TestON/tests/CHOTestMonkey/dependencies/events/NetworkEvent.py
+++ b/TestON/tests/CHOTestMonkey/dependencies/events/NetworkEvent.py
@@ -19,7 +19,7 @@
args are the names of the two link ends, e.g. ['s1', 's2']
"""
with self.eventLock:
- main.log.info( "%s - starting event" % ( self.typeString ) )
+ #main.log.info( "%s - starting event" % ( self.typeString ) )
if len( args ) < 2:
main.log.warn( "%s - Not enough arguments: %s" % ( self.typeString, args ) )
return EventStates().ABORT
@@ -84,6 +84,7 @@
elif self.linkA.isRemoved() or self.linkB.isRemoved():
main.log.warn( "Link Down - link has been removed" )
return EventStates().ABORT
+ main.log.info( "Event recorded: {} {} {} {}".format( self.typeIndex, self.typeString, self.linkA.deviceA.name, self.linkA.deviceB.name ) )
with main.mininetLock:
'''
result = main.Mininet1.link( END1=self.linkA.deviceA.name,
@@ -118,6 +119,7 @@
if self.linkA.isRemoved() or self.linkB.isRemoved():
main.log.warn( "Link Up - link has been removed" )
return EventStates().ABORT
+ main.log.info( "Event recorded: {} {} {} {}".format( self.typeIndex, self.typeString, self.linkA.deviceA.name, self.linkA.deviceB.name ) )
with main.mininetLock:
'''
result = main.Mininet1.link( END1=self.linkA.deviceA.name,
@@ -147,7 +149,7 @@
args are the names of the device, e.g. 's1'
"""
with self.eventLock:
- main.log.info( "%s - starting event" % ( self.typeString ) )
+ #main.log.info( "%s - starting event" % ( self.typeString ) )
if len( args ) < 1:
main.log.warn( "%s - Not enough arguments: %s" % ( self.typeString, args ) )
return EventStates().ABORT
@@ -199,6 +201,7 @@
if self.device.isRemoved():
main.log.warn( "Device Down - device has been removed" )
return EventStates().ABORT
+ main.log.info( "Event recorded: {} {} {}".format( self.typeIndex, self.typeString, self.device.name ) )
with main.mininetLock:
result = main.Mininet1.delSwitch( self.device.name )
if not result:
@@ -232,6 +235,7 @@
main.log.warn( "Device Up - device already up" )
return EventStates().ABORT
# Re-add the device
+ main.log.info( "Event recorded: {} {} {}".format( self.typeIndex, self.typeString, self.device.name ) )
with main.mininetLock:
result = main.Mininet1.addSwitch( self.device.name, dpid=self.device.dpid[3:] )
if not result:
diff --git a/TestON/tests/CHOTestMonkey/dependencies/events/ONOSEvent.py b/TestON/tests/CHOTestMonkey/dependencies/events/ONOSEvent.py
index f4e2a89..28960d2 100644
--- a/TestON/tests/CHOTestMonkey/dependencies/events/ONOSEvent.py
+++ b/TestON/tests/CHOTestMonkey/dependencies/events/ONOSEvent.py
@@ -11,7 +11,7 @@
def startEvent( self, args ):
with self.eventLock:
- main.log.info( "%s - starting event" % ( self.typeString ) )
+ #main.log.info( "%s - starting event" % ( self.typeString ) )
result = EventStates().PASS
if self.typeIndex == EventType().ONOS_ONOS_DOWN or self.typeIndex == EventType().ONOS_ONOS_UP:
if len( args ) < 1:
@@ -42,6 +42,7 @@
if not main.controllers[ self.ONOSIndex - 1 ].isUp():
main.log.warn( "ONOS Down - ONOS already down" )
return EventStates().ABORT
+ main.log.info( "Event recorded: {} {} {}".format( self.typeIndex, self.typeString, self.ONOSIndex ) )
with main.ONOSbenchLock:
result = main.ONOSbench.onosStop( main.controllers[ self.ONOSIndex - 1 ].ip )
if not result:
@@ -63,6 +64,7 @@
if main.controllers[ self.ONOSIndex - 1 ].isUp():
main.log.warn( "ONOS Up - ONOS already up" )
return EventStates().ABORT
+ main.log.info( "Event recorded: {} {} {}".format( self.typeIndex, self.typeString, self.ONOSIndex ) )
with main.ONOSbenchLock:
startResult = main.ONOSbench.onosStart( main.controllers[ self.ONOSIndex - 1 ].ip )
if not startResult:
@@ -92,7 +94,7 @@
def startEvent( self, args ):
with self.eventLock:
- main.log.info( "%s - starting event" % ( self.typeString ) )
+ #main.log.info( "%s - starting event" % ( self.typeString ) )
result = self.startCfgEvent( args )
return result
@@ -121,6 +123,7 @@
if index == -1:
main.log.warn( "%s - No available controllers" %s ( self.typeString ) )
return EventStates().ABORT
+ main.log.info( "Event recorded: {} {} {} {} {}".format( self.typeIndex, self.typeString, self.component, self.propName, self.value ) )
controller = main.controllers[ index - 1 ]
with controller.CLILock:
result = controller.CLI.setCfg( component=self.component,
@@ -158,6 +161,7 @@
if index == -1:
main.log.warn( "%s - No available controllers" %s ( self.typeString ) )
return EventStates().ABORT
+ main.log.info( "Event recorded: {} {} {} {} {}".format( self.typeIndex, self.typeString, self.component, self.propName, self.value ) )
controller = main.controllers[ index - 1 ]
with controller.CLILock:
result = controller.CLI.setCfg( component=self.component,
@@ -184,6 +188,7 @@
if index == -1:
main.log.warn( "%s - No available controllers" %s ( self.typeString ) )
return EventStates().ABORT
+ main.log.info( "Event recorded: {} {}".format( self.typeIndex, self.typeString ) )
controller = main.controllers[ index - 1 ]
with controller.CLILock:
result = controller.CLI.balanceMasters()