Framework of the new CHOtest
Change-Id: Ie5b58bfa2ed487386443692cbea0d469d7419c24
diff --git a/TestON/drivers/common/cli/emulator/mininetclidriver.py b/TestON/drivers/common/cli/emulator/mininetclidriver.py
index 85b8ecd..b6fbded 100644
--- a/TestON/drivers/common/cli/emulator/mininetclidriver.py
+++ b/TestON/drivers/common/cli/emulator/mininetclidriver.py
@@ -617,6 +617,60 @@
main.cleanup()
main.exit()
+ def pingHostSetAlternative( self, dstIPList, wait=1, IPv6=False ):
+ """
+ Description:
+ Ping a set of destination host from host CLI.
+ Logging into a Mininet host CLI is required before calling this funtion.
+ Params:
+ dstIPList is a list of destination ip addresses
+ Returns:
+ main.TRUE if the destination host is reachable
+ main.FALSE otherwise
+ """
+ isReachable = main.TRUE
+ wait = int( wait )
+ cmd = "ping"
+ if IPv6:
+ cmd = cmd + "6"
+ cmd = cmd + " -c 1 -i 1 -W " + str( wait )
+ try:
+ for dstIP in dstIPList:
+ pingCmd = cmd + " " + dstIP
+ self.handle.sendline( pingCmd )
+ i = self.handle.expect( [ self.hostPrompt,
+ '\*\*\* Unknown command: ' + pingCmd,
+ pexpect.TIMEOUT ],
+ timeout=wait + 1 )
+ if i == 0:
+ response = self.handle.before
+ if not re.search( ',\s0\%\spacket\sloss', response ):
+ main.log.debug( "Ping failed between %s and %s" % ( self.name, dstIP ) )
+ isReachable = main.FALSE
+ elif i == 1:
+ main.log.error( self.name + ": function should be called from host CLI instead of Mininet CLI" )
+ main.cleanup()
+ main.exit()
+ elif i == 2:
+ main.log.error( self.name + ": timeout when waiting for response" )
+ isReachable = main.FALSE
+ else:
+ main.log.error( self.name + ": unknown response: " + self.handle.before )
+ isReachable = main.FALSE
+ except pexpect.TIMEOUT:
+ main.log.exception( self.name + ": TIMEOUT exception" )
+ isReachable = main.FALSE
+ except pexpect.EOF:
+ main.log.error( self.name + ": EOF exception found" )
+ main.log.error( self.name + ": " + self.handle.before )
+ main.cleanup()
+ main.exit()
+ except Exception:
+ main.log.exception( self.name + ": Uncaught exception!" )
+ main.cleanup()
+ main.exit()
+ return isReachable
+
def checkIP( self, host ):
"""
Verifies the host's ip configured or not."""
diff --git a/TestON/tests/CHO/CHOtest/CHOtest.params b/TestON/tests/CHO/CHOtest/CHOtest.params
index 45d0fef..9cf0709 100644
--- a/TestON/tests/CHO/CHOtest/CHOtest.params
+++ b/TestON/tests/CHO/CHOtest/CHOtest.params
@@ -18,7 +18,7 @@
# 19X. IPv6 ping across Point,Multi-single,Single-Multi Intents
<testcases>
- 1,21,3,48,148,[5,61,161,72,172,82,182,10,5,91,191,73,173,83,183,10]*20,200,20,3,47,147,[5,60,160,70,170,80,180,10,5,90,190,71,171,81,181,10]*20,200,22,3,49,149,[5,62,162,74,174,84,184,10,5,92,192,75,175,85,185,10]*20
+ 1,20,3,47,147,[5,60,160,70,170,80,180,10,5,90,190,71,171,81,181,10]*500
</testcases>
<DEPENDENCY>
diff --git a/TestON/tests/CHOTestMonkey/CHOTestMonkey.params b/TestON/tests/CHOTestMonkey/CHOTestMonkey.params
new file mode 100644
index 0000000..7d7457b
--- /dev/null
+++ b/TestON/tests/CHOTestMonkey/CHOTestMonkey.params
@@ -0,0 +1,378 @@
+<PARAMS>
+ # 0. Initialize CHOTestMonkey
+ # 1. Load topology and balances all switches
+ # 2. Collect and store device and link data from ONOS
+ # 3. Collect and store host data from ONOS
+ # 10. Run all enabled checks
+ # 20. Bring down/up links and check topology and ping
+ # 21. Bring down/up a group of links and check topology and ping
+ # 30. Install host intents and check intent states and ping
+ # 31. Uninstall host intents and check intent states
+ # 32. Install point intents and check intent states and ping
+ # 33. Uninstall point intents and check intent states
+ # 40. Randomly bring down one ONOS node
+ # 41. Randomly bring up one ONOS node that is down
+ # 50. Set FlowObjective to True
+ # 51. Set FlowObjective to False
+ # 60. Rebalance devices across controllers
+ # 90. Sleep for some time
+ # 100. Do something else
+ # 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,100,[10,40,60,10,30,21,31,41,90,60]*500,100
+ </testcases>
+
+ <TEST>
+ <topo>1</topo>
+ <IPv6>on</IPv6>
+ <numCtrl>3</numCtrl>
+ <pauseTest>off</pauseTest>
+ <caseSleep>0</caseSleep>
+ <setIPv6CfgSleep>5</setIPv6CfgSleep>
+ <loadTopoSleep>5</loadTopoSleep>
+ <ipv6Prefix>1000::</ipv6Prefix>
+ <ipv4Prefix>10.1.</ipv4Prefix>
+ <karafCliTimeout>7200000</karafCliTimeout>
+ <testDuration>86400</testDuration>
+ <package>off</package>
+ <autoPull>off</autoPull>
+ <branch>master</branch>
+ </TEST>
+
+ <EVENT>
+ <Event>
+ <status>on</status>
+ <typeIndex>0</typeIndex>
+ <typeString>NULL</typeString>
+ <CLI>null</CLI>
+ <CLIParamNum>0</CLIParamNum>
+ <rerunInterval>5</rerunInterval>
+ <maxRerunNum>5</maxRerunNum>
+ </Event>
+
+ <TestPause>
+ <status>on</status>
+ <typeIndex>1</typeIndex>
+ <typeString>TEST_PAUSE</typeString>
+ <CLI>pause-test</CLI>
+ <CLIParamNum>0</CLIParamNum>
+ </TestPause>
+
+ <TestResume>
+ <status>on</status>
+ <typeIndex>2</typeIndex>
+ <typeString>TEST_RESUME</typeString>
+ <CLI>resume-test</CLI>
+ <CLIParamNum>0</CLIParamNum>
+ </TestResume>
+
+ <TestSleep>
+ <status>on</status>
+ <typeIndex>3</typeIndex>
+ <typeString>TEST_SLEEP</typeString>
+ <CLI>sleep</CLI>
+ <CLIParamNum>1</CLIParamNum>
+ </TestSleep>
+
+ <IntentCheck>
+ <status>on</status>
+ <typeIndex>10</typeIndex>
+ <typeString>CHECK_INTENT</typeString>
+ <CLI>check-intent</CLI>
+ <CLIParamNum>0</CLIParamNum>
+ <rerunInterval>5</rerunInterval>
+ <maxRerunNum>5</maxRerunNum>
+ </IntentCheck>
+
+ <TrafficCheck>
+ <status>on</status>
+ <typeIndex>12</typeIndex>
+ <typeString>CHECK_TRAFFIC</typeString>
+ <CLI>check-traffic</CLI>
+ <CLIParamNum>0</CLIParamNum>
+ <rerunInterval>5</rerunInterval>
+ <maxRerunNum>5</maxRerunNum>
+ <pingWait>1</pingWait>
+ <pingTimeout>10</pingTimeout>
+ </TrafficCheck>
+
+ <TopoCheck>
+ <status>on</status>
+ <typeIndex>13</typeIndex>
+ <typeString>CHECK_TOPO</typeString>
+ <CLI>check-topo</CLI>
+ <CLIParamNum>0</CLIParamNum>
+ <rerunInterval>5</rerunInterval>
+ <maxRerunNum>5</maxRerunNum>
+ </TopoCheck>
+
+ <ONOSCheck>
+ <status>on</status>
+ <typeIndex>14</typeIndex>
+ <typeString>CHECK_ONOS</typeString>
+ <CLI>check-onos</CLI>
+ <CLIParamNum>0</CLIParamNum>
+ <rerunInterval>5</rerunInterval>
+ <maxRerunNum>5</maxRerunNum>
+ </ONOSCheck>
+
+ <LinkDown>
+ <status>on</status>
+ <typeIndex>20</typeIndex>
+ <typeString>NETWORK_LINK_DOWN</typeString>
+ <CLI>link-down</CLI>
+ <CLIParamNum>2</CLIParamNum>
+ </LinkDown>
+
+ <LinkUp>
+ <status>on</status>
+ <typeIndex>21</typeIndex>
+ <typeString>NETWORK_LINK_UP</typeString>
+ <CLI>link-up</CLI>
+ <CLIParamNum>2</CLIParamNum>
+ </LinkUp>
+
+ <DeviceDown>
+ <status>on</status>
+ <typeIndex>22</typeIndex>
+ <typeString>NETWORK_DEVICE_DOWN</typeString>
+ <CLI>device-down</CLI>
+ <CLIParamNum>1</CLIParamNum>
+ </DeviceDown>
+
+ <DeviceUp>
+ <status>on</status>
+ <typeIndex>23</typeIndex>
+ <typeString>NETWORK_DEVICE_UP</typeString>
+ <CLI>device-up</CLI>
+ <CLIParamNum>1</CLIParamNum>
+ </DeviceUp>
+
+ <AddHostIntent>
+ <status>on</status>
+ <typeIndex>30</typeIndex>
+ <typeString>APP_INTENT_HOST_ADD</typeString>
+ <CLI>add-host-intent</CLI>
+ <CLIParamNum>3</CLIParamNum>
+ <rerunInterval>5</rerunInterval>
+ <maxRerunNum>5</maxRerunNum>
+ </AddHostIntent>
+
+ <DelHostIntent>
+ <status>on</status>
+ <typeIndex>31</typeIndex>
+ <typeString>APP_INTENT_HOST_DEL</typeString>
+ <CLI>del-host-intent</CLI>
+ <CLIParamNum>3</CLIParamNum>
+ <rerunInterval>5</rerunInterval>
+ <maxRerunNum>5</maxRerunNum>
+ </DelHostIntent>
+
+ <AddPointIntent>
+ <status>on</status>
+ <typeIndex>32</typeIndex>
+ <typeString>APP_INTENT_POINT_ADD</typeString>
+ <CLI>add-point-intent</CLI>
+ <CLIParamNum>3</CLIParamNum>
+ <rerunInterval>5</rerunInterval>
+ <maxRerunNum>5</maxRerunNum>
+ </AddPointIntent>
+
+ <DelPointIntent>
+ <status>on</status>
+ <typeIndex>33</typeIndex>
+ <typeString>APP_INTENT_POINT_DEL</typeString>
+ <CLI>del-point-intent</CLI>
+ <CLIParamNum>3</CLIParamNum>
+ <rerunInterval>5</rerunInterval>
+ <maxRerunNum>5</maxRerunNum>
+ </DelPointIntent>
+
+ <ONOSDown>
+ <status>on</status>
+ <typeIndex>40</typeIndex>
+ <typeString>ONOS_ONOS_DOWN</typeString>
+ <CLI>onos-down</CLI>
+ <CLIParamNum>1</CLIParamNum>
+ <rerunInterval>5</rerunInterval>
+ <maxRerunNum>5</maxRerunNum>
+ </ONOSDown>
+
+ <ONOSUp>
+ <status>on</status>
+ <typeIndex>41</typeIndex>
+ <typeString>ONOS_ONOS_UP</typeString>
+ <CLI>onos-up</CLI>
+ <CLIParamNum>1</CLIParamNum>
+ <rerunInterval>5</rerunInterval>
+ <maxRerunNum>5</maxRerunNum>
+ </ONOSUp>
+
+ <SetCfg>
+ <status>on</status>
+ <typeIndex>42</typeIndex>
+ <typeString>ONOS_SET_CFG</typeString>
+ <CLI>set-cfg</CLI>
+ <CLIParamNum>3</CLIParamNum>
+ <rerunInterval>5</rerunInterval>
+ <maxRerunNum>5</maxRerunNum>
+ </SetCfg>
+
+ <SetFlowObj>
+ <status>on</status>
+ <typeIndex>43</typeIndex>
+ <typeString>ONOS_SET_FLOWOBJ</typeString>
+ <CLI>set-flowobj</CLI>
+ <CLIParamNum>1</CLIParamNum>
+ <rerunInterval>5</rerunInterval>
+ <maxRerunNum>5</maxRerunNum>
+ </SetFlowObj>
+
+ <BalanceMasters>
+ <status>on</status>
+ <typeIndex>44</typeIndex>
+ <typeString>ONOS_BALANCE_MASTERS</typeString>
+ <CLI>balance-masters</CLI>
+ <CLIParamNum>0</CLIParamNum>
+ <rerunInterval>5</rerunInterval>
+ <maxRerunNum>5</maxRerunNum>
+ </BalanceMasters>
+
+ <addAllChecks>
+ <status>on</status>
+ <typeIndex>110</typeIndex>
+ <typeString>CHECK_ALL</typeString>
+ <CLI>check-all</CLI>
+ <CLIParamNum>0</CLIParamNum>
+ </addAllChecks>
+
+ <randomLinkToggle>
+ <status>on</status>
+ <typeIndex>120</typeIndex>
+ <typeString>NETWORK_LINK_RANDOM_TOGGLE</typeString>
+ <CLI>link-toggle-random</CLI>
+ <CLIParamNum>1</CLIParamNum>
+ <sleepBeforeCheck>10</sleepBeforeCheck>
+ </randomLinkToggle>
+
+ <randomLinkGroupToggle>
+ <status>on</status>
+ <typeIndex>121</typeIndex>
+ <typeString>NETWORK_LINK_GROUP_RANDOM_TOGGLE</typeString>
+ <CLI>link-group-toggle-random</CLI>
+ <CLIParamNum>3</CLIParamNum>
+ <sleepBeforeCheck>10</sleepBeforeCheck>
+ </randomLinkGroupToggle>
+
+ <randomDeviceToggle>
+ <status>on</status>
+ <typeIndex>122</typeIndex>
+ <typeString>NETWORK_DEVICE_RANDOM_TOGGLE</typeString>
+ <CLI>device-toggle-random</CLI>
+ <CLIParamNum>1</CLIParamNum>
+ <sleepBeforeCheck>10</sleepBeforeCheck>
+ </randomDeviceToggle>
+
+ <randomDeviceGroupToggle>
+ <status>on</status>
+ <typeIndex>123</typeIndex>
+ <typeString>NETWORK_DEVICE_GROUP_RANDOM_TOGGLE</typeString>
+ <CLI>device-group-toggle-random</CLI>
+ <CLIParamNum>3</CLIParamNum>
+ <sleepBeforeCheck>10</sleepBeforeCheck>
+ </randomDeviceGroupToggle>
+
+ <installAllHostIntents>
+ <status>on</status>
+ <typeIndex>130</typeIndex>
+ <typeString>APP_INTENT_HOST_ADD_ALL</typeString>
+ <CLI>add-all-host-intents</CLI>
+ <CLIParamNum>0</CLIParamNum>
+ <sleepBeforeCheck>10</sleepBeforeCheck>
+ </installAllHostIntents>
+
+ <removeAllHostIntents>
+ <status>on</status>
+ <typeIndex>131</typeIndex>
+ <typeString>APP_INTENT_HOST_DEL_ALL</typeString>
+ <CLI>del-all-host-intents</CLI>
+ <CLIParamNum>0</CLIParamNum>
+ <sleepBeforeCheck>5</sleepBeforeCheck>
+ </removeAllHostIntents>
+
+ <installAllPointIntents>
+ <status>on</status>
+ <typeIndex>132</typeIndex>
+ <typeString>APP_INTENT_POINT_ADD_ALL</typeString>
+ <CLI>add-all-point-intents</CLI>
+ <CLIParamNum>0</CLIParamNum>
+ <sleepBeforeCheck>10</sleepBeforeCheck>
+ </installAllPointIntents>
+
+ <removeAllPointIntents>
+ <status>on</status>
+ <typeIndex>133</typeIndex>
+ <typeString>APP_INTENT_POINT_DEL_ALL</typeString>
+ <CLI>del-all-point-intents</CLI>
+ <CLIParamNum>0</CLIParamNum>
+ <sleepBeforeCheck>5</sleepBeforeCheck>
+ </removeAllPointIntents>
+
+ <randomONOSToggle>
+ <status>on</status>
+ <typeIndex>140</typeIndex>
+ <typeString>ONOS_ONOS_RANDOM_TOGGLE</typeString>
+ <CLI>onos-toggle-random</CLI>
+ <CLIParamNum>1</CLIParamNum>
+ <sleepBeforeCheck>10</sleepBeforeCheck>
+ </randomONOSToggle>
+ </EVENT>
+
+ <SCHEDULER>
+ <pendingEventsCapacity>1</pendingEventsCapacity>
+ <runningEventsCapacity>10</runningEventsCapacity>
+ <scheduleLoopSleep>0.1</scheduleLoopSleep>
+ </SCHEDULER>
+
+ <GENERATOR>
+ <listenerPort>6000</listenerPort>
+ <insertEventRetryInterval>1</insertEventRetryInterval>
+ </GENERATOR>
+
+ <TOPO>
+ <topo0>
+ <fileName>topoTripleIpv6.py</fileName>
+ </topo0>
+
+ <topo1>
+ <fileName>topoAttIpv6.py</fileName>
+ </topo1>
+
+ <topo2>
+ <fileName>topoChordalIpv6.py</fileName>
+ </topo2>
+
+ <topo3>
+ <fileName>topoSpineIpv6.py</fileName>
+ </topo3>
+
+ <topo4>
+ <fileName>topoRingIpv6.py</fileName>
+ </topo4>
+ </TOPO>
+
+ <CASE20>
+ <linkToggleNum>5</linkToggleNum>
+ <linkDownUpInterval>1</linkDownUpInterval>
+ </CASE20>
+
+ <CASE21>
+ <linkGroupSize>5</linkGroupSize>
+ <linkDownDownInterval>1</linkDownDownInterval>
+ <linkDownUpInterval>1</linkDownUpInterval>
+ </CASE21>
+
+ <CASE90>
+ <sleepSec>60</sleepSec>
+ </CASE90>
+</PARAMS>
diff --git a/TestON/tests/CHOTestMonkey/CHOTestMonkey.py b/TestON/tests/CHOTestMonkey/CHOTestMonkey.py
new file mode 100644
index 0000000..314bde9
--- /dev/null
+++ b/TestON/tests/CHOTestMonkey/CHOTestMonkey.py
@@ -0,0 +1,806 @@
+"""
+CHOTestMonkey class
+Author: you@onlab.us
+"""
+
+import sys
+import os
+import re
+import time
+import json
+import itertools
+
+class CHOTestMonkey:
+
+ def __init__( self ):
+ self.default = ''
+
+ def CASE0( self, main ):
+ """
+ Startup sequence:
+ apply cell <name>
+ git pull
+ mvn clean install
+ onos-package
+ onos-verify-cell
+ onos-uninstall
+ onos-install
+ onos-start-cli
+ Set IPv6 cfg parameters for Neighbor Discovery
+ start event scheduler
+ start event listener
+ """
+ import time
+ from threading import Lock, Condition
+ from tests.CHOTestMonkey.dependencies.elements.ONOSElement import Controller
+ from tests.CHOTestMonkey.dependencies.EventGenerator import EventGenerator
+ from tests.CHOTestMonkey.dependencies.EventScheduler import EventScheduler
+
+ gitPull = main.params[ 'TEST' ][ 'autoPull' ]
+ onosPackage = main.params[ 'TEST' ][ 'package' ]
+ gitBranch = main.params[ 'TEST' ][ 'branch' ]
+ karafTimeout = main.params[ 'TEST' ][ 'karafCliTimeout' ]
+ main.enableIPv6 = main.params[ 'TEST' ][ 'IPv6' ]
+ main.enableIPv6 = True if main.enableIPv6 == "on" else False
+ main.caseSleep = int( main.params[ 'TEST' ][ 'caseSleep' ] )
+ main.numCtrls = main.params[ 'TEST' ][ 'numCtrl' ]
+ main.controllers = []
+ for i in range( 1, int( main.numCtrls ) + 1 ):
+ newController = Controller( i )
+ newController.setCLI( getattr( main, 'ONOScli' + str( i ) ) )
+ main.controllers.append( newController )
+ main.devices = []
+ main.links = []
+ main.hosts = []
+ main.intents = []
+ main.enabledEvents = {}
+ for eventName in main.params[ 'EVENT' ].keys():
+ if main.params[ 'EVENT' ][ eventName ][ 'status' ] == 'on':
+ main.enabledEvents[ int( main.params[ 'EVENT' ][ eventName ][ 'typeIndex' ] ) ] = eventName
+ print main.enabledEvents
+ main.eventScheduler = EventScheduler()
+ main.eventGenerator = EventGenerator()
+ main.variableLock = Lock()
+ main.mininetLock = Lock()
+ main.ONOSbenchLock = Lock()
+ main.threadID = 0
+ main.eventID = 0
+ main.caseResult = main.TRUE
+
+ main.case( "Set up test environment" )
+ main.log.report( "Set up test environment" )
+ main.log.report( "_______________________" )
+
+ main.step( "Apply Cell environment for ONOS" )
+ if ( main.onoscell ):
+ cellName = main.onoscell
+ cellResult = main.ONOSbench.setCell( cellName )
+ utilities.assert_equals( expect=main.TRUE,
+ actual=cellResult,
+ onpass="Test step PASS",
+ onfail="Test step FAIL" )
+ else:
+ main.log.error( "Please provide onoscell option at TestON CLI to run CHO tests" )
+ main.log.error( "Example: ~/TestON/bin/cli.py run CHOTestMonkey onoscell <cellName>" )
+ main.cleanup()
+ main.exit()
+
+ main.step( "Git checkout and pull " + gitBranch )
+ if gitPull == 'on':
+ checkoutResult = main.ONOSbench.gitCheckout( gitBranch )
+ pullResult = main.ONOSbench.gitPull()
+ cpResult = ( checkoutResult and pullResult )
+ else:
+ checkoutResult = main.TRUE
+ pullResult = main.TRUE
+ main.log.info( "Skipped git checkout and pull as they are disabled in params file" )
+ cpResult = ( checkoutResult and pullResult )
+ utilities.assert_equals( expect=main.TRUE,
+ actual=cpResult,
+ onpass="Test step PASS",
+ onfail="Test step FAIL" )
+
+ main.step( "mvn clean & install" )
+ if gitPull == 'on':
+ mvnResult = main.ONOSbench.cleanInstall()
+ else:
+ mvnResult = main.TRUE
+ main.log.info( "Skipped mvn clean install as it is disabled in params file" )
+ utilities.assert_equals( expect=main.TRUE,
+ actual=mvnResult,
+ onpass="Test step PASS",
+ onfail="Test step FAIL" )
+ main.ONOSbench.getVersion( report=True )
+
+ main.step( "Create ONOS package" )
+ if onosPackage == 'on':
+ packageResult = main.ONOSbench.onosPackage()
+ else:
+ packageResult = main.TRUE
+ main.log.info( "Skipped onos package as it is disabled in params file" )
+ utilities.assert_equals( expect=main.TRUE,
+ actual=packageResult,
+ onpass="Test step PASS",
+ onfail="Test step FAIL" )
+
+ main.step( "Uninstall ONOS package on all Nodes" )
+ uninstallResult = main.TRUE
+ for i in range( int( main.numCtrls ) ):
+ main.log.info( "Uninstalling package on ONOS Node IP: " + main.onosIPs[i] )
+ uResult = main.ONOSbench.onosUninstall( main.onosIPs[i] )
+ utilities.assert_equals( expect=main.TRUE,
+ actual=uResult,
+ onpass="Test step PASS",
+ onfail="Test step FAIL" )
+ uninstallResult = ( uninstallResult and uResult )
+
+ main.step( "Install ONOS package on all Nodes" )
+ installResult = main.TRUE
+ for i in range( int( main.numCtrls ) ):
+ main.log.info( "Installing package on ONOS Node IP: " + main.onosIPs[i] )
+ iResult = main.ONOSbench.onosInstall( node=main.onosIPs[i] )
+ utilities.assert_equals( expect=main.TRUE,
+ actual=iResult,
+ onpass="Test step PASS",
+ onfail="Test step FAIL" )
+ installResult = ( installResult and iResult )
+
+ main.step( "Start ONOS CLI on all nodes" )
+ cliResult = main.TRUE
+ startCliResult = main.TRUE
+ pool = []
+ for controller in main.controllers:
+ t = main.Thread( target=controller.startCLI,
+ threadID=main.threadID,
+ name="startOnosCli",
+ args=[ ] )
+ pool.append(t)
+ t.start()
+ main.threadID = main.threadID + 1
+ for t in pool:
+ t.join()
+ startCliResult = startCliResult and t.result
+ if not startCliResult:
+ main.log.info( "ONOS CLI did not start up properly" )
+ main.cleanup()
+ main.exit()
+ else:
+ main.log.info( "Successful CLI startup" )
+ startCliResult = main.TRUE
+ utilities.assert_equals( expect=main.TRUE,
+ actual=startCliResult,
+ onpass="Test step PASS",
+ onfail="Test step FAIL" )
+
+ main.step( "Set IPv6 cfg parameters for Neighbor Discovery" )
+ setIPv6CfgSleep = int( main.params[ 'TEST' ][ 'setIPv6CfgSleep' ] )
+ if main.enableIPv6:
+ time.sleep( setIPv6CfgSleep )
+ cfgResult1 = main.controllers[ 0 ].CLI.setCfg( "org.onosproject.proxyarp.ProxyArp",
+ "ipv6NeighborDiscovery",
+ "true" )
+ time.sleep( setIPv6CfgSleep )
+ cfgResult2 = main.controllers[ 0 ].CLI.setCfg( "org.onosproject.provider.host.impl.HostLocationProvider",
+ "ipv6NeighborDiscovery",
+ "true" )
+ else:
+ main.log.info( "Skipped setting IPv6 cfg parameters as it is disabled in params file" )
+ cfgResult1 = main.TRUE
+ cfgResult2 = main.TRUE
+ cfgResult = cfgResult1 and cfgResult2
+ utilities.assert_equals( expect=main.TRUE,
+ actual=cfgResult,
+ onpass="ipv6NeighborDiscovery cfg is set to true",
+ onfail="Failed to cfg set ipv6NeighborDiscovery" )
+
+ main.step( "Start a thread for the scheduler" )
+ t = main.Thread( target=main.eventScheduler.startScheduler,
+ threadID=main.threadID,
+ name="startScheduler",
+ args=[] )
+ t.start()
+ stepResult = main.TRUE
+ with main.variableLock:
+ main.threadID = main.threadID + 1
+
+ utilities.assert_equals( expect=main.TRUE,
+ actual=stepResult,
+ onpass="Test step PASS",
+ onfail="Test step FAIL" )
+
+ main.step( "Start a thread to listen to and handle network, ONOS and application events" )
+ t = main.Thread( target=main.eventGenerator.startListener,
+ threadID=main.threadID,
+ name="startListener",
+ args=[] )
+ t.start()
+ with main.variableLock:
+ main.threadID = main.threadID + 1
+
+ caseResult = installResult and uninstallResult and startCliResult and cfgResult
+ utilities.assert_equals( expect=main.TRUE,
+ actual=caseResult,
+ onpass="Set up test environment PASS",
+ onfail="Set up test environment FAIL" )
+
+ def CASE1( self, main ):
+ """
+ Load Mininet topology and balances all switches
+ """
+ import re
+ import time
+ import copy
+
+ main.topoIndex = "topo" + str ( main.params[ 'TEST' ][ 'topo' ] )
+
+ main.log.report( "Load Mininet topology and Balance all Mininet switches across controllers" )
+ main.log.report( "________________________________________________________________________" )
+ main.case( "Assign and Balance all Mininet switches across controllers" )
+
+ main.step( "Start Mininet topology" )
+ newTopo = main.params[ 'TOPO' ][ main.topoIndex ][ 'fileName' ]
+ mininetDir = main.Mininet1.home + "/custom/"
+ topoPath = main.testDir + "/" + main.TEST + "/dependencies/topologies/" + newTopo
+ main.ONOSbench.secureCopy( main.Mininet1.user_name, main.Mininet1.ip_address, topoPath, mininetDir, direction="to" )
+ topoPath = mininetDir + newTopo
+ startStatus = main.Mininet1.startNet( topoFile = topoPath )
+ main.mininetSwitches = main.Mininet1.getSwitches()
+ main.mininetHosts = main.Mininet1.getHosts()
+ main.mininetLinks = main.Mininet1.getLinks()
+ utilities.assert_equals( expect=main.TRUE,
+ actual=startStatus,
+ onpass="Start Mininet topology test PASS",
+ onfail="Start Mininet topology test FAIL" )
+
+ main.step( "Assign switches to controllers" )
+ switchMastership = main.TRUE
+ for switchName in main.mininetSwitches.keys():
+ main.Mininet1.assignSwController( sw=switchName, ip=main.onosIPs )
+ response = main.Mininet1.getSwController( switchName )
+ print( "Response is " + str( response ) )
+ if re.search( "tcp:" + main.onosIPs[ 0 ], response ):
+ switchMastership = switchMastership and main.TRUE
+ else:
+ switchMastership = main.FALSE
+ utilities.assert_equals( expect=main.TRUE,
+ actual=switchMastership,
+ onpass="Assign switches to controllers test PASS",
+ onfail="Assign switches to controllers test FAIL" )
+ # Waiting here to make sure topology converges across all nodes
+ sleep = int( main.params[ 'TEST' ][ 'loadTopoSleep' ] )
+ time.sleep( sleep )
+
+ main.step( "Balance devices across controllers" )
+ balanceResult = main.ONOScli1.balanceMasters()
+ # giving some breathing time for ONOS to complete re-balance
+ time.sleep( sleep )
+
+ caseResult = ( startStatus and switchMastership and balanceResult )
+ utilities.assert_equals( expect=main.TRUE,
+ actual=caseResult,
+ onpass="Starting new Att topology test PASS",
+ onfail="Starting new Att topology test FAIL" )
+
+ def CASE2( self, main ):
+ """
+ Collect and store device and link data from ONOS
+ """
+ import json
+ from tests.CHOTestMonkey.dependencies.elements.NetworkElement import Device, Link
+
+ main.log.report( "Collect and Store topology details from ONOS" )
+ main.log.report( "____________________________________________________________________" )
+ main.case( "Collect and Store Topology Details from ONOS" )
+ topoResult = main.TRUE
+ topologyOutput = main.ONOScli1.topology()
+ topologyResult = main.ONOScli1.getTopology( topologyOutput )
+ ONOSDeviceNum = int( topologyResult[ 'devices' ] )
+ ONOSLinkNum = int( topologyResult[ 'links' ] )
+ mininetSwitchNum = len( main.mininetSwitches )
+ mininetLinkNum = ( len( main.mininetLinks ) - len( main.mininetHosts ) ) * 2
+ if mininetSwitchNum == ONOSDeviceNum and mininetLinkNum == ONOSLinkNum:
+ main.step( "Collect and store device data" )
+ stepResult = main.TRUE
+ dpidToName = {}
+ for key, value in main.mininetSwitches.items():
+ dpidToName[ 'of:' + str( value[ 'dpid' ] ) ] = key
+ devicesRaw = main.ONOScli1.devices()
+ devices = json.loads( devicesRaw )
+ deviceInitIndex = 0
+ for device in devices:
+ name = dpidToName[ device[ 'id' ] ]
+ newDevice = Device( deviceInitIndex, name, device[ 'id' ] )
+ print newDevice
+ main.devices.append( newDevice )
+ deviceInitIndex += 1
+ utilities.assert_equals( expect=main.TRUE,
+ actual=stepResult,
+ onpass="Successfully collected and stored device data",
+ onfail="Failed to collect and store device data" )
+
+ main.step( "Collect and store link data" )
+ stepResult = main.TRUE
+ linksRaw = main.ONOScli1.links()
+ links = json.loads( linksRaw )
+ linkInitIndex = 0
+ for link in links:
+ for device in main.devices:
+ if device.dpid == link[ 'src' ][ 'device' ]:
+ deviceA = device
+ elif device.dpid == link[ 'dst' ][ 'device' ]:
+ deviceB = device
+ assert deviceA != None and deviceB != None
+ newLink = Link( linkInitIndex, deviceA, link[ 'src' ][ 'port' ], deviceB, link[ 'dst' ][ 'port' ] )
+ print newLink
+ main.links.append( newLink )
+ linkInitIndex += 1
+ # Set backward links and outgoing links of devices
+ for linkA in main.links:
+ linkA.deviceA.outgoingLinks.append( linkA )
+ if linkA.backwardLink != None:
+ continue
+ for linkB in main.links:
+ if linkB.backwardLink != None:
+ continue
+ if linkA.deviceA == linkB.deviceB and\
+ linkA.deviceB == linkB.deviceA and\
+ linkA.portA == linkB.portB and\
+ linkA.portB == linkB.portA:
+ linkA.setBackwardLink( linkB )
+ linkB.setBackwardLink( linkA )
+ utilities.assert_equals( expect=main.TRUE,
+ actual=stepResult,
+ onpass="Successfully collected and stored link data",
+ onfail="Failed to collect and store link data" )
+ else:
+ main.log.info( "Devices (expected): %s, Links (expected): %s" % ( mininetSwitchNum, mininetLinkNum ) )
+ main.log.info( "Devices (actual): %s, Links (actual): %s" % ( ONOSDeviceNum, ONOSLinkNum ) )
+ topoResult = main.FALSE
+
+ caseResult = topoResult
+ utilities.assert_equals( expect=main.TRUE,
+ actual=caseResult,
+ onpass="Saving ONOS topology data test PASS",
+ onfail="Saving ONOS topology data test FAIL" )
+
+ if not caseResult:
+ main.log.info("Topology does not match, exiting test...")
+ main.cleanup()
+ main.exit()
+
+ def CASE3( self, main ):
+ """
+ Collect and store host data from ONOS
+ """
+ import json
+ from tests.CHOTestMonkey.dependencies.elements.NetworkElement import Host
+
+ main.log.report( "Collect and store host adta from ONOS" )
+ main.log.report( "______________________________________________" )
+ main.case( "Use fwd app and pingall to discover all the hosts, then collect and store host data" )
+
+ main.step( "Enable Reactive forwarding" )
+ appResult = main.controllers[ 0 ].CLI.activateApp( "org.onosproject.fwd" )
+ cfgResult1 = main.TRUE
+ cfgResult2 = main.TRUE
+ if main.enableIPv6:
+ cfgResult1 = main.controllers[ 0 ].CLI.setCfg( "org.onosproject.fwd.ReactiveForwarding", "ipv6Forwarding", "true" )
+ cfgResult2 = main.controllers[ 0 ].CLI.setCfg( "org.onosproject.fwd.ReactiveForwarding", "matchIpv6Address", "true" )
+ stepResult = appResult and cfgResult1 and cfgResult2
+ utilities.assert_equals( expect=main.TRUE,
+ actual=stepResult,
+ onpass="Successfully enabled reactive forwarding",
+ onfail="Failed to enable reactive forwarding" )
+
+ main.step( "Discover hosts using pingall" )
+ stepResult = main.TRUE
+ main.Mininet1.pingall()
+ if main.enableIPv6:
+ ping6Result = main.Mininet1.pingall( protocol="IPv6" )
+ hosts = main.controllers[ 0 ].CLI.hosts()
+ hosts = json.loads( hosts )
+ if not len( hosts ) == len( main.mininetHosts ):
+ stepResult = main.FALSE
+ utilities.assert_equals( expect=main.TRUE,
+ actual=stepResult,
+ onpass="Host discovery PASS",
+ onfail="Host discovery FAIL" )
+ if not stepResult:
+ main.log.debug( hosts )
+ main.cleanup()
+ main.exit()
+
+ main.step( "Disable Reactive forwarding" )
+ appResult = main.controllers[ 0 ].CLI.deactivateApp( "org.onosproject.fwd" )
+ stepResult = appResult
+ utilities.assert_equals( expect=main.TRUE,
+ actual=stepResult,
+ onpass="Successfully deactivated fwd app",
+ onfail="Failed to deactivate fwd app" )
+
+ main.step( "Collect and store host data" )
+ stepResult = main.TRUE
+ macToName = {}
+ for key, value in main.mininetHosts.items():
+ macToName[ value[ 'interfaces' ][ 0 ][ 'mac' ].upper() ] = key
+ dpidToDevice = {}
+ for device in main.devices:
+ dpidToDevice[ device.dpid ] = device
+ hostInitIndex = 0
+ for host in hosts:
+ name = macToName[ host[ 'mac' ] ]
+ dpid = host[ 'location' ][ 'elementId' ]
+ device = dpidToDevice[ dpid ]
+ newHost = Host( hostInitIndex,
+ name, host[ 'id' ], host[ 'mac' ],
+ device, host[ 'location' ][ 'port' ],
+ host[ 'vlan' ], host[ 'ipAddresses' ] )
+ print newHost
+ main.hosts.append( newHost )
+ main.devices[ device.index ].hosts.append( newHost )
+ hostInitIndex += 1
+ utilities.assert_equals( expect=main.TRUE,
+ actual=stepResult,
+ onpass="Successfully collected and stored host data",
+ onfail="Failed to collect and store host data" )
+
+ main.step( "Create one host component for each host and then start host cli" )
+ for host in main.hosts:
+ main.Mininet1.createHostComponent( host.name )
+ hostHandle = getattr( main, host.name )
+ main.log.info( "Starting CLI on host " + str( host.name ) )
+ startCLIResult = hostHandle.startHostCli()
+ host.setHandle( hostHandle )
+ stepResult = startCLIResult
+ utilities.assert_equals( expect=main.TRUE,
+ actual=startCLIResult,
+ onpass="Host CLI started",
+ onfail="Failed to start host CLI" )
+
+ def CASE10( self, main ):
+ """
+ Run all enabled checks
+ """
+ import time
+ from tests.CHOTestMonkey.dependencies.events.Event import EventType
+ from tests.CHOTestMonkey.dependencies.EventScheduler import EventScheduleMethod
+
+ main.log.report( "Run all enabled checks" )
+ main.log.report( "__________________________________________________" )
+ main.case( "Run all enabled checks" )
+ main.step( "Run all enabled checks" )
+ main.caseResult = main.TRUE
+ main.eventGenerator.triggerEvent( EventType().CHECK_ALL, EventScheduleMethod().RUN_BLOCK )
+ # Wait for the scheduler to become idle before going to the next testcase
+ with main.eventScheduler.idleCondition:
+ while not main.eventScheduler.isIdle():
+ main.eventScheduler.idleCondition.wait()
+ utilities.assert_equals( expect=main.TRUE,
+ actual=main.caseResult,
+ onpass="All enabled checks passed",
+ onfail="Not all enabled checks passed" )
+ time.sleep( main.caseSleep )
+
+ def CASE20( self, main ):
+ """
+ Bring down/up links and check topology and ping
+ """
+ import time
+ from tests.CHOTestMonkey.dependencies.events.Event import EventType
+ from tests.CHOTestMonkey.dependencies.EventScheduler import EventScheduleMethod
+
+ main.log.report( "Bring down/up links and check topology and ping" )
+ main.log.report( "__________________________________________________" )
+ main.case( "Bring down/up links and check topology and ping" )
+ main.step( "Bring down/up links and check topology and ping" )
+ main.caseResult = main.TRUE
+ linkToggleNum = int( main.params[ 'CASE20' ][ 'linkToggleNum' ] )
+ linkDownUpInterval = int( main.params[ 'CASE20' ][ 'linkDownUpInterval' ] )
+ for i in range( 0, linkToggleNum ):
+ main.eventGenerator.triggerEvent( EventType().NETWORK_LINK_RANDOM_TOGGLE, EventScheduleMethod().RUN_BLOCK, linkDownUpInterval )
+ with main.eventScheduler.idleCondition:
+ while not main.eventScheduler.isIdle():
+ main.eventScheduler.idleCondition.wait()
+ utilities.assert_equals( expect=main.TRUE,
+ actual=main.caseResult,
+ onpass="Toggle network links test passed",
+ onfail="Toggle network links test failed" )
+ time.sleep( main.caseSleep )
+
+ def CASE21( self, main ):
+ """
+ Bring down/up a group of links and check topology and ping
+ """
+ import time
+ from tests.CHOTestMonkey.dependencies.events.Event import EventType
+ from tests.CHOTestMonkey.dependencies.EventScheduler import EventScheduleMethod
+
+ main.log.report( "Bring down/up a group of links and check topology and ping" )
+ main.log.report( "__________________________________________________" )
+ main.case( "Bring down/up a group of links and check topology and ping" )
+ main.step( "Bring down/up a group of links and check topology and ping" )
+ main.caseResult = main.TRUE
+ linkGroupSize = int( main.params[ 'CASE21' ][ 'linkGroupSize' ] )
+ linkDownDownInterval = int( main.params[ 'CASE21' ][ 'linkDownDownInterval' ] )
+ linkDownUpInterval = int( main.params[ 'CASE21' ][ 'linkDownUpInterval' ] )
+ main.eventGenerator.triggerEvent( EventType().NETWORK_LINK_GROUP_RANDOM_TOGGLE, EventScheduleMethod().RUN_BLOCK, linkGroupSize, linkDownDownInterval, linkDownUpInterval )
+ with main.eventScheduler.idleCondition:
+ while not main.eventScheduler.isIdle():
+ main.eventScheduler.idleCondition.wait()
+ utilities.assert_equals( expect=main.TRUE,
+ actual=main.caseResult,
+ onpass="Toggle network link group test passed",
+ onfail="Toggle network link group test failed" )
+ time.sleep( main.caseSleep )
+
+ def CASE30( self, main ):
+ """
+ Install host intents and check intent states and ping
+ """
+ import time
+ from tests.CHOTestMonkey.dependencies.events.Event import EventType
+ from tests.CHOTestMonkey.dependencies.EventScheduler import EventScheduleMethod
+
+ main.log.report( "Install host intents and check intent states and ping" )
+ main.log.report( "__________________________________________________" )
+ main.case( "Install host intents and check intent states and ping" )
+ main.step( "Install host intents and check intent states and ping" )
+ main.caseResult = main.TRUE
+ main.eventGenerator.triggerEvent( EventType().APP_INTENT_HOST_ADD_ALL, EventScheduleMethod().RUN_BLOCK )
+ with main.eventScheduler.idleCondition:
+ while not main.eventScheduler.isIdle():
+ main.eventScheduler.idleCondition.wait()
+ utilities.assert_equals( expect=main.TRUE,
+ actual=main.caseResult,
+ onpass="Install host intents test passed",
+ onfail="Install host intents test failed" )
+ time.sleep( main.caseSleep )
+
+ def CASE31( self, main ):
+ """
+ Uninstall host intents and check intent states and ping
+ """
+ import time
+ from tests.CHOTestMonkey.dependencies.events.Event import EventType
+ from tests.CHOTestMonkey.dependencies.EventScheduler import EventScheduleMethod
+
+ main.log.report( "Uninstall host intents and check intent states and ping" )
+ main.log.report( "__________________________________________________" )
+ main.case( "Uninstall host intents and check intent states and ping" )
+ main.step( "Uninstall host intents and check intent states and ping" )
+ main.caseResult = main.TRUE
+ main.eventGenerator.triggerEvent( EventType().APP_INTENT_HOST_DEL_ALL, EventScheduleMethod().RUN_BLOCK )
+ with main.eventScheduler.idleCondition:
+ while not main.eventScheduler.isIdle():
+ main.eventScheduler.idleCondition.wait()
+ utilities.assert_equals( expect=main.TRUE,
+ actual=main.caseResult,
+ onpass="Uninstall host intents test passed",
+ onfail="Uninstall host intents test failed" )
+ time.sleep( main.caseSleep )
+
+ def CASE32( self, main ):
+ """
+ Install point intents and check intent states and ping
+ """
+ import time
+ from tests.CHOTestMonkey.dependencies.events.Event import EventType
+ from tests.CHOTestMonkey.dependencies.EventScheduler import EventScheduleMethod
+
+ main.log.report( "Install point intents and check intent states and ping" )
+ main.log.report( "__________________________________________________" )
+ main.case( "Install point intents and check intent states and ping" )
+ main.step( "Install point intents and check intent states and ping" )
+ main.caseResult = main.TRUE
+ main.eventGenerator.triggerEvent( EventType().APP_INTENT_POINT_ADD_ALL, EventScheduleMethod().RUN_BLOCK )
+ with main.eventScheduler.idleCondition:
+ while not main.eventScheduler.isIdle():
+ main.eventScheduler.idleCondition.wait()
+ utilities.assert_equals( expect=main.TRUE,
+ actual=main.caseResult,
+ onpass="Install point intents test passed",
+ onfail="Install point intents test failed" )
+ time.sleep( main.caseSleep )
+
+ def CASE33( self, main ):
+ """
+ Uninstall point intents and check intent states and ping
+ """
+ import time
+ from tests.CHOTestMonkey.dependencies.events.Event import EventType
+ from tests.CHOTestMonkey.dependencies.EventScheduler import EventScheduleMethod
+
+ main.log.report( "Uninstall point intents and check intent states and ping" )
+ main.log.report( "__________________________________________________" )
+ main.case( "Uninstall point intents and check intent states and ping" )
+ main.step( "Uninstall point intents and check intent states and ping" )
+ main.caseResult = main.TRUE
+ main.eventGenerator.triggerEvent( EventType().APP_INTENT_POINT_DEL_ALL, EventScheduleMethod().RUN_BLOCK )
+ with main.eventScheduler.idleCondition:
+ while not main.eventScheduler.isIdle():
+ main.eventScheduler.idleCondition.wait()
+ utilities.assert_equals( expect=main.TRUE,
+ actual=main.caseResult,
+ onpass="Uninstall point intents test passed",
+ onfail="Uninstall point intents test failed" )
+ time.sleep( main.caseSleep )
+
+ def CASE40( self, main ):
+ """
+ Randomly bring down one ONOS node
+ """
+ import time
+ import random
+ from tests.CHOTestMonkey.dependencies.events.Event import EventType
+ from tests.CHOTestMonkey.dependencies.EventScheduler import EventScheduleMethod
+
+ main.log.report( "Randomly bring down one ONOS node" )
+ main.log.report( "__________________________________________________" )
+ main.case( "Randomly bring down one ONOS node" )
+ main.step( "Randomly bring down one ONOS node" )
+ main.caseResult = main.TRUE
+ availableControllers = []
+ for controller in main.controllers:
+ if controller.isUp():
+ availableControllers.append( controller.index )
+ if len( availableControllers ) == 0:
+ main.log.warn( "No available controllers" )
+ main.caseResult = main.FALSE
+ else:
+ index = random.sample( availableControllers, 1 )
+ main.eventGenerator.triggerEvent( EventType().ONOS_ONOS_DOWN, EventScheduleMethod().RUN_BLOCK, index[ 0 ] )
+ with main.eventScheduler.idleCondition:
+ while not main.eventScheduler.isIdle():
+ main.eventScheduler.idleCondition.wait()
+ utilities.assert_equals( expect=main.TRUE,
+ actual=main.caseResult,
+ onpass="Randomly bring down ONOS test passed",
+ onfail="Randomly bring down ONOS test failed" )
+ time.sleep( main.caseSleep )
+
+ def CASE41( self, main ):
+ """
+ Randomly bring up one ONOS node that is down
+ """
+ import time
+ import random
+ from tests.CHOTestMonkey.dependencies.events.Event import EventType
+ from tests.CHOTestMonkey.dependencies.EventScheduler import EventScheduleMethod
+
+ main.log.report( "Randomly bring up one ONOS node that is down" )
+ main.log.report( "__________________________________________________" )
+ main.case( "Randomly bring up one ONOS node that is down" )
+ main.step( "Randomly bring up one ONOS node that is down" )
+ main.caseResult = main.TRUE
+ targetControllers = []
+ for controller in main.controllers:
+ if not controller.isUp():
+ targetControllers.append( controller.index )
+ if len( targetControllers ) == 0:
+ main.log.warn( "All controllers are up" )
+ main.caseResult = main.FALSE
+ else:
+ index = random.sample( targetControllers, 1 )
+ main.eventGenerator.triggerEvent( EventType().ONOS_ONOS_UP, EventScheduleMethod().RUN_BLOCK, index[ 0 ] )
+ with main.eventScheduler.idleCondition:
+ while not main.eventScheduler.isIdle():
+ main.eventScheduler.idleCondition.wait()
+ utilities.assert_equals( expect=main.TRUE,
+ actual=main.caseResult,
+ onpass="Randomly bring up ONOS test passed",
+ onfail="Randomly bring up ONOS test failed" )
+ time.sleep( main.caseSleep )
+
+ def CASE50( self, main ):
+ """
+ Set FlowObjective to True
+ """
+ import time
+ from tests.CHOTestMonkey.dependencies.events.Event import EventType
+ from tests.CHOTestMonkey.dependencies.EventScheduler import EventScheduleMethod
+
+ main.log.report( "Set FlowObjective to True" )
+ main.log.report( "__________________________________________________" )
+ main.case( "Set FlowObjective to True" )
+ main.step( "Set FlowObjective to True" )
+ main.caseResult = main.TRUE
+ main.eventGenerator.triggerEvent( EventType().ONOS_SET_FLOWOBJ, EventScheduleMethod().RUN_BLOCK, 'true' )
+ with main.eventScheduler.idleCondition:
+ while not main.eventScheduler.isIdle():
+ main.eventScheduler.idleCondition.wait()
+ utilities.assert_equals( expect=main.TRUE,
+ actual=main.caseResult,
+ onpass="Set FlowObjective test passed",
+ onfail="Set FlowObjective test failed" )
+ time.sleep( main.caseSleep )
+
+ def CASE51( self, main ):
+ """
+ Set FlowObjective to False
+ """
+ import time
+ from tests.CHOTestMonkey.dependencies.events.Event import EventType
+ from tests.CHOTestMonkey.dependencies.EventScheduler import EventScheduleMethod
+
+ main.log.report( "Set FlowObjective to False" )
+ main.log.report( "__________________________________________________" )
+ main.case( "Set FlowObjective to False" )
+ main.step( "Set FlowObjective to False" )
+ main.caseResult = main.TRUE
+ main.eventGenerator.triggerEvent( EventType().ONOS_SET_FLOWOBJ, EventScheduleMethod().RUN_BLOCK, 'false' )
+ with main.eventScheduler.idleCondition:
+ while not main.eventScheduler.isIdle():
+ main.eventScheduler.idleCondition.wait()
+ utilities.assert_equals( expect=main.TRUE,
+ actual=main.caseResult,
+ onpass="Set FlowObjective test passed",
+ onfail="Set FlowObjective test failed" )
+ time.sleep( main.caseSleep )
+
+ def CASE60( self, main ):
+ """
+ Balance device masters
+ """
+ import time
+ from tests.CHOTestMonkey.dependencies.events.Event import EventType
+ from tests.CHOTestMonkey.dependencies.EventScheduler import EventScheduleMethod
+
+ main.log.report( "Balance device masters" )
+ main.log.report( "__________________________________________________" )
+ main.case( "Balance device masters" )
+ main.step( "Balance device masters" )
+ main.caseResult = main.TRUE
+ main.eventGenerator.triggerEvent( EventType().ONOS_BALANCE_MASTERS, EventScheduleMethod().RUN_BLOCK )
+ with main.eventScheduler.idleCondition:
+ while not main.eventScheduler.isIdle():
+ main.eventScheduler.idleCondition.wait()
+ utilities.assert_equals( expect=main.TRUE,
+ actual=main.caseResult,
+ onpass="Balance masters test passed",
+ onfail="Balance masters test failed" )
+ time.sleep( main.caseSleep )
+
+ def CASE90( self, main ):
+ """
+ Sleep for some time
+ """
+ import time
+ from tests.CHOTestMonkey.dependencies.events.Event import EventType
+ from tests.CHOTestMonkey.dependencies.EventScheduler import EventScheduleMethod
+
+ main.log.report( "Sleep for some time" )
+ main.log.report( "__________________________________________________" )
+ main.case( "Sleep for some time" )
+ main.step( "Sleep for some time" )
+ main.caseResult = main.TRUE
+ sleepSec = int( main.params[ 'CASE90' ][ 'sleepSec' ] )
+ main.eventGenerator.triggerEvent( EventType().TEST_SLEEP, EventScheduleMethod().RUN_BLOCK, sleepSec )
+ with main.eventScheduler.idleCondition:
+ while not main.eventScheduler.isIdle():
+ main.eventScheduler.idleCondition.wait()
+ utilities.assert_equals( expect=main.TRUE,
+ actual=main.caseResult,
+ onpass="Sleep test passed",
+ onfail="Sleep test failed" )
+ time.sleep( main.caseSleep )
+
+ def CASE100( self, main ):
+ """
+ Do something else?
+ """
+ import time
+
+ main.log.report( "Do something else?" )
+ main.log.report( "__________________________________________________" )
+ main.case( "..." )
+
+ main.step( "Wait until the test stops" )
+
+ main.caseResult = main.TRUE
+ utilities.assert_equals( expect=main.TRUE,
+ actual=main.caseResult,
+ onpass="Test PASS",
+ onfail="Test FAIL" )
+
+ testDuration = int( main.params[ 'TEST' ][ 'testDuration' ] )
+ time.sleep( testDuration )
diff --git a/TestON/tests/CHOTestMonkey/CHOTestMonkey.topo b/TestON/tests/CHOTestMonkey/CHOTestMonkey.topo
new file mode 100644
index 0000000..7c7cfd7
--- /dev/null
+++ b/TestON/tests/CHOTestMonkey/CHOTestMonkey.topo
@@ -0,0 +1,50 @@
+<TOPOLOGY>
+ <COMPONENT>
+
+ <ONOSbench>
+ <host>localhost</host>
+ <user>admin</user>
+ <password></password>
+ <type>OnosDriver</type>
+ <connect_order>1</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOSbench>
+
+ <ONOScli1>
+ <host>localhost</host>
+ <user>admin</user>
+ <password></password>
+ <type>OnosCliDriver</type>
+ <connect_order>2</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOScli1>
+
+ <ONOScli2>
+ <host>localhost</host>
+ <user>admin</user>
+ <password></password>
+ <type>OnosCliDriver</type>
+ <connect_order>3</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOScli2>
+
+ <ONOScli3>
+ <host>localhost</host>
+ <user>admin</user>
+ <password></password>
+ <type>OnosCliDriver</type>
+ <connect_order>4</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOScli3>
+
+ <Mininet1>
+ <host>OCN</host>
+ <user>admin</user>
+ <password></password>
+ <type>MininetCliDriver</type>
+ <connect_order>10</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </Mininet1>
+
+ </COMPONENT>
+</TOPOLOGY>
\ No newline at end of file
diff --git a/TestON/tests/CHOTestMonkey/README b/TestON/tests/CHOTestMonkey/README
new file mode 100644
index 0000000..cfd85e7
--- /dev/null
+++ b/TestON/tests/CHOTestMonkey/README
@@ -0,0 +1,33 @@
+CHO TEST MONKEY
+
+Summary:
+ This is a long-term regression test that is aimed to run for weeks
+ at a time. It's goal is to find memory leaks or bugs that otherwise
+ cannot be easily seen with short-term tests.
+ CHOTestMonkey is the 2016 version of CHOtest. The suffix "Monkey"
+ implies both the Chaos Monkey style testing and the year of the
+ Monkey 2016.
+
+Topology:
+ Att topology - 25 switches and 25 hosts and its structure is
+ designed to simulate a real world configuration.
+ Chordal topology - 25 swithces and 25 hosts and because of its
+ chordal graph structure, it's particulary useful
+ in testing the rerouting capability of ONOS.
+ Leaf-spine topology - 78 switches and 68 hosts and designed to
+ simulate modern data centers.
+
+Pre-requisites:
+ To run out-of-the box this test requires 3 NODES. The cell file
+ must be passed through the startup test command, e.g.,
+
+ ./cli.py run CHOTestMonkey onoscell <cell name>.
+
+ Passwordless login must be set from TestStation "sdn" root user.
+ This test relies on the topology files to start Mininet located in
+ the dependencies/topologies folder. Be sure to check that each
+ topology file can be loaded properly by Mininet by using this
+ command:
+
+ sudo ~/dependencies/topologies/<topology name>
+
diff --git a/TestON/tests/CHOTestMonkey/__init__.py b/TestON/tests/CHOTestMonkey/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/TestON/tests/CHOTestMonkey/__init__.py
diff --git a/TestON/tests/CHOTestMonkey/dependencies/EventGenerator.py b/TestON/tests/CHOTestMonkey/dependencies/EventGenerator.py
new file mode 100644
index 0000000..fb72d00
--- /dev/null
+++ b/TestON/tests/CHOTestMonkey/dependencies/EventGenerator.py
@@ -0,0 +1,559 @@
+"""
+This file contains the event generator class for CHOTestMonkey
+Author: you@onlab.us
+"""
+from threading import Lock, Condition
+from tests.CHOTestMonkey.dependencies.events.Event import EventType, EventStates, Event
+from tests.CHOTestMonkey.dependencies.EventScheduler import EventScheduleMethod
+from tests.CHOTestMonkey.dependencies.GraphHelper import GraphHelper
+
+class MessageType:
+ def __init__( self ):
+ self.map = {}
+ # This message type is used for requesting an event injection from outside CHOTestMonkey
+ self.EVENT_REQUEST = 1
+ self.map[ 1 ] = 'EVENT_REQUEST'
+ # This message tyoe will force the event generator to accept the event injection request for debugging purpose
+ self.EVENT_REQUEST_DEBUG = 2
+ self.map[ 2 ] = 'EVENT_REQUEST_DEBUG'
+ # This message type implies the event generator has inserted the event
+ self.EVENT_INSERTED = 10
+ self.map[ 10 ] = 'EVENT_INSERTED'
+ # This message type implies CHOTestMonkey has refused the event injection request
+ # due to, e.g. too many pending events in the scheduler
+ self.EVENT_DENIED = 11
+ self.map[ 11 ] = 'EVENT_DENIED'
+ # The followings are error messages
+ self.UNKNOWN_MESSAGE = 20
+ self.map[ 20 ] = 'UNKNOWN_MESSAGE'
+ self.UNKNOWN_EVENT_TYPE = 21
+ self.map[ 21 ] = 'UNKNOWN_EVENT_TYPE'
+ self.UNKNOWN_SCHEDULE_METHOD = 22
+ self.map[ 22 ] = 'UNKNOWN_SCHEDULE_METHOD'
+ self.NOT_ENOUGH_ARGUMENT = 23
+ self.map[ 23 ] = 'NOT_ENOUGH_ARGUMENT'
+
+class EventGenerator:
+ def __init__( self ):
+ self.default = ''
+ self.eventGeneratorLock = Lock()
+
+ def startListener( self ):
+ """
+ Listen to event triggers
+ """
+ from multiprocessing.connection import Listener
+ import time
+
+ host = "localhost"
+ port = int( main.params[ 'GENERATOR' ][ 'listenerPort' ] )
+ address = ( host, port )
+ listener = Listener( address )
+ main.log.info( "Event Generator - Event listener start listening on %s:%s" % ( host, port ) )
+
+ while 1:
+ conn = listener.accept()
+ t = main.Thread( target=self.handleConnection,
+ threadID=main.threadID,
+ name="handleConnection",
+ args=[ conn ])
+ t.start()
+ with main.variableLock:
+ main.threadID += 1
+ listener.close()
+
+ def handleConnection( self, conn ):
+ """
+ Handle connections from event triggers
+ """
+ request = conn.recv()
+ if isinstance( request, list ) and ( request[ 0 ] == MessageType().EVENT_REQUEST or request[ 0 ] == MessageType().EVENT_REQUEST_DEBUG ):
+ if len( request ) < 3:
+ response = MessageType().NOT_ENOUGH_ARGUMENT
+ elif request[ 0 ] == MessageType().EVENT_REQUEST and not main.eventScheduler.isAvailable():
+ response = MessageType().EVENT_DENIED
+ else:
+ typeString = str( request[ 1 ] )
+ scheduleMethodString = str( request[ 2 ] )
+ if len( request ) > 3:
+ args = request[ 3: ]
+ else:
+ args = None
+ for key, value in EventType().map.items():
+ if value == typeString:
+ typeIndex = key
+ break
+ if not value == typeString:
+ response = MessageType().UNKNOWN_EVENT_TYPE
+ else:
+ for key, value in EventScheduleMethod().map.items():
+ if value == scheduleMethodString:
+ scheduleMethod = key
+ break
+ if not value == scheduleMethodString:
+ response = MessageType().UNKNOWN_SCHEDULE_METHOD
+ else:
+ self.insertEvent( typeIndex, scheduleMethod, args )
+ response = MessageType().EVENT_INSERTED
+ else:
+ response = MessageType().UNKNOWN_MESSAGE
+ conn.send( response )
+ conn.close()
+
+ def triggerEvent( self, typeIndex, scheduleMethod, *args ):
+ """
+ This function triggers an event from inside of CHOTestMonkey
+ """
+ import time
+ if not typeIndex in EventType().map.keys():
+ main.log.warn( "Event Generator - Unknown event type: " + str( typeIndex ) )
+ return
+ if not scheduleMethod in EventScheduleMethod().map.keys():
+ main.log.warn( "Event Generator - Unknown event schedule method: " + str( scheduleMethod ) )
+ return
+ while not main.eventScheduler.isAvailable():
+ time.sleep( int( main.params[ 'GENERATOR' ][ 'insertEventRetryInterval' ] ) )
+ self.insertEvent( typeIndex, scheduleMethod, list( args ) )
+
+ def insertEvent( self, typeIndex, scheduleMethod, args=None ):
+ """
+ This function inserts an event into the scheduler
+ """
+ if typeIndex > 100:
+ # Handle group events
+ if not typeIndex in main.enabledEvents.keys():
+ main.log.warn( "Event Generator - event type %s not enabled" % ( typeIndex ) )
+ return
+ function = getattr( self, main.enabledEvents[ typeIndex ] )
+ assert function != None, "Event Generator - funtion for group event " + typeIndex + " not found"
+ function( scheduleMethod, args )
+ else:
+ # Add individual events to the scheduler
+ main.eventScheduler.scheduleEvent( typeIndex, scheduleMethod, args )
+
+ def insertAllChecks( self, args=None ):
+ """
+ Acquire eventGeneratorLock before calling this funtion
+ """
+ for eventType in main.enabledEvents.keys():
+ if eventType < 100 and EventType().map[ eventType ].startswith( 'CHECK' ):
+ main.eventScheduler.scheduleEvent( eventType,
+ EventScheduleMethod().RUN_NON_BLOCK,
+ args )
+
+ def addAllChecks( self, scheduleMethod, args=None ):
+ """
+ The function adds all check events into the scheduler
+ """
+ with self.eventGeneratorLock:
+ if scheduleMethod == EventScheduleMethod().RUN_BLOCK:
+ main.eventScheduler.scheduleEvent( EventType().NULL, EventScheduleMethod().RUN_BLOCK )
+ self.insertAllChecks( args )
+ if scheduleMethod == EventScheduleMethod().RUN_BLOCK:
+ main.eventScheduler.scheduleEvent( EventType().NULL, EventScheduleMethod().RUN_BLOCK )
+
+ def randomLinkToggle( self, scheduleMethod, args=[ 5 ], blocking=True ):
+ """
+ The function randomly adds a link down-up event pair into the scheduler
+ After each individual link event, all checks are inserted into the scheduler
+ param:
+ args[0] is the average interval between link down and link up events
+ blocking means blocking other events from being scheduled between link down and link up
+ """
+ import random
+ import time
+
+ if len( args ) < 1:
+ main.log.warn( "Event Generator - Not enough arguments for randomLinkToggle: %s" % ( args ) )
+ elif len( args ) > 1:
+ main.log.warn( "Event Generator - Too many arguments for randomLinkToggle: %s" % ( args ) )
+ else:
+ downUpAvgInterval = int( args[ 0 ] )
+ with main.variableLock:
+ graphHelper = GraphHelper()
+ availableLinks = graphHelper.getNonCutEdges()
+ if len( availableLinks ) == 0:
+ main.log.warn( "All links are cut edges, aborting event" )
+ return
+ link = random.sample( availableLinks, 1 )
+
+ self.eventGeneratorLock.acquire()
+ main.eventScheduler.scheduleEvent( EventType().NETWORK_LINK_DOWN,
+ scheduleMethod,
+ [ link[ 0 ].deviceA.name, link[ 0 ].deviceB.name ] )
+ with main.variableLock:
+ link[ 0 ].setPendingDown()
+ link[ 0 ].backwardLink.setPendingDown()
+ sleepTime = int( main.params[ 'EVENT' ][ 'randomLinkToggle' ][ 'sleepBeforeCheck' ] )
+ main.eventScheduler.scheduleEvent( EventType().TEST_SLEEP, EventScheduleMethod().RUN_BLOCK, [ sleepTime ] )
+ self.insertAllChecks( EventScheduleMethod().RUN_NON_BLOCK )
+ if scheduleMethod == EventScheduleMethod().RUN_BLOCK:
+ # Insert a NULL BLOCK event
+ main.eventScheduler.scheduleEvent( EventType().NULL, EventScheduleMethod().RUN_BLOCK )
+ downUpInterval = abs( random.gauss( downUpAvgInterval, 1 ) )
+ if not blocking:
+ self.eventGeneratorLock.release()
+ time.sleep( downUpInterval )
+ self.eventGeneratorLock.acquire()
+ else:
+ time.sleep( downUpInterval )
+ main.eventScheduler.scheduleEvent( EventType().NETWORK_LINK_UP,
+ scheduleMethod,
+ [ link[ 0 ].deviceA.name, link[ 0 ].deviceB.name ] )
+ main.eventScheduler.scheduleEvent( EventType().TEST_SLEEP, EventScheduleMethod().RUN_BLOCK, [ sleepTime ] )
+ self.insertAllChecks( EventScheduleMethod().RUN_NON_BLOCK )
+ if scheduleMethod == EventScheduleMethod().RUN_BLOCK:
+ main.eventScheduler.scheduleEvent( EventType().NULL, EventScheduleMethod().RUN_BLOCK )
+ self.eventGeneratorLock.release()
+
+ def randomLinkGroupToggle( self, scheduleMethod, args=None, blocking=True ):
+ """
+ The function randomly adds a group of link down-up events into the scheduler
+ After each link down or up, all checks are inserted into the scheduler
+ param:
+ args[0] is the number of links that are to be brought down
+ args[1] is the average interval between link down events
+ args[2] is the average interval between link group down and group up events
+ blocking means blocking other events from being scheduled between link events
+ """
+ import random
+ import time
+
+ if len( args ) < 3:
+ main.log.warn( "Event Generator - Not enough arguments for randomLinkGroupToggle: %s" % ( args ) )
+ elif len( args ) > 3:
+ main.log.warn( "Event Generator - Too many arguments for randomLinkGroupToggle: %s" % ( args ) )
+ else:
+ linkGroupSize = int( args[ 0 ] )
+ downDownAvgInterval = int( args[ 1 ] )
+ downUpAvgInterval = int( args[ 2 ] )
+ downLinks = []
+ for i in range( 0, linkGroupSize ):
+ with main.variableLock:
+ graphHelper = GraphHelper()
+ availableLinks = graphHelper.getNonCutEdges()
+ if len( availableLinks ) == 0:
+ main.log.warn( "All links are cut edges, aborting event" )
+ continue
+ link = random.sample( availableLinks, 1 )
+ if i == 0:
+ self.eventGeneratorLock.acquire()
+ main.eventScheduler.scheduleEvent( EventType().NETWORK_LINK_DOWN,
+ scheduleMethod,
+ [ link[ 0 ].deviceA.name, link[ 0 ].deviceB.name ] )
+ with main.variableLock:
+ link[ 0 ].setPendingDown()
+ link[ 0 ].backwardLink.setPendingDown()
+ downLinks.append( link[ 0 ] )
+ sleepTime = int( main.params[ 'EVENT' ][ 'randomLinkGroupToggle' ][ 'sleepBeforeCheck' ] )
+ main.eventScheduler.scheduleEvent( EventType().TEST_SLEEP, EventScheduleMethod().RUN_BLOCK, [ sleepTime ] )
+ self.insertAllChecks( EventScheduleMethod().RUN_NON_BLOCK )
+ if scheduleMethod == EventScheduleMethod().RUN_BLOCK:
+ # Insert a NULL BLOCK event
+ main.eventScheduler.scheduleEvent( EventType().NULL, EventScheduleMethod().RUN_BLOCK )
+ downDownInterval = abs( random.gauss( downDownAvgInterval, 1 ) )
+ if not blocking:
+ self.eventGeneratorLock.release()
+ time.sleep( downDownInterval )
+ self.eventGeneratorLock.acquire()
+ else:
+ time.sleep( downDownInterval )
+
+ downUpInterval = abs( random.gauss( downUpAvgInterval, 1 ) )
+ if not blocking:
+ self.eventGeneratorLock.release()
+ time.sleep( downUpInterval )
+ self.eventGeneratorLock.acquire()
+ else:
+ time.sleep( downUpInterval )
+
+ for link in downLinks:
+ main.eventScheduler.scheduleEvent( EventType().NETWORK_LINK_UP,
+ scheduleMethod,
+ [ link.deviceA.name, link.deviceB.name ] )
+ main.eventScheduler.scheduleEvent( EventType().TEST_SLEEP, EventScheduleMethod().RUN_BLOCK, [ sleepTime ] )
+ self.insertAllChecks( EventScheduleMethod().RUN_NON_BLOCK )
+ if scheduleMethod == EventScheduleMethod().RUN_BLOCK:
+ main.eventScheduler.scheduleEvent( EventType().NULL, EventScheduleMethod().RUN_BLOCK )
+ upUpInterval = abs( random.gauss( downDownAvgInterval, 1 ) )
+ if not blocking:
+ self.eventGeneratorLock.release()
+ time.sleep( upUpInterval )
+ self.eventGeneratorLock.acquire()
+ else:
+ time.sleep( upUpInterval )
+ self.eventGeneratorLock.release()
+
+ def randomDeviceToggle( self, scheduleMethod, args=[ 5 ], blocking=True ):
+ """
+ The function randomly removes a device and then adds it back
+ After each individual device event, all checks are inserted into the scheduler
+ param:
+ args[0] is the average interval between device down and device up events
+ blocking means blocking other events from being scheduled between device down and device up
+ """
+ import random
+ import time
+
+ if len( args ) < 1:
+ main.log.warn( "Event Generator - Not enough arguments for randomDeviceToggle: %s" % ( args ) )
+ elif len( args ) > 1:
+ main.log.warn( "Event Generator - Too many arguments for randomDeviceToggle: %s" % ( args ) )
+ else:
+ downUpAvgInterval = int( args[ 0 ] )
+ with main.variableLock:
+ graphHelper = GraphHelper()
+ availableDevices = graphHelper.getNonCutVertices()
+ if len( availableDevices ) == 0:
+ main.log.warn( "All devices are Cut vertices, aborting event" )
+ return
+ device = random.sample( availableDevices, 1 )
+
+ self.eventGeneratorLock.acquire()
+ main.eventScheduler.scheduleEvent( EventType().NETWORK_DEVICE_DOWN,
+ scheduleMethod,
+ [ device[ 0 ].name ] )
+ with main.variableLock:
+ device[ 0 ].setPendingDown()
+ sleepTime = int( main.params[ 'EVENT' ][ 'randomLinkToggle' ][ 'sleepBeforeCheck' ] )
+ main.eventScheduler.scheduleEvent( EventType().TEST_SLEEP, EventScheduleMethod().RUN_BLOCK, [ sleepTime ] )
+ self.insertAllChecks( EventScheduleMethod().RUN_NON_BLOCK )
+ if scheduleMethod == EventScheduleMethod().RUN_BLOCK:
+ # Insert a NULL BLOCK event
+ main.eventScheduler.scheduleEvent( EventType().NULL, EventScheduleMethod().RUN_BLOCK )
+ downUpInterval = abs( random.gauss( downUpAvgInterval, 1 ) )
+ if not blocking:
+ self.eventGeneratorLock.release()
+ time.sleep( downUpInterval )
+ self.eventGeneratorLock.acquire()
+ else:
+ time.sleep( downUpInterval )
+ main.eventScheduler.scheduleEvent( EventType().NETWORK_DEVICE_UP,
+ scheduleMethod,
+ [ device[ 0 ].name ] )
+ main.eventScheduler.scheduleEvent( EventType().TEST_SLEEP, EventScheduleMethod().RUN_BLOCK, [ sleepTime ] )
+ self.insertAllChecks( EventScheduleMethod().RUN_NON_BLOCK )
+ if scheduleMethod == EventScheduleMethod().RUN_BLOCK:
+ main.eventScheduler.scheduleEvent( EventType().NULL, EventScheduleMethod().RUN_BLOCK )
+ self.eventGeneratorLock.release()
+
+ def randomDeviceGroupToggle( self, scheduleMethod, args=None, blocking=True ):
+ """
+ The function randomly adds a group of device down-up events into the scheduler
+ After each device down or up, all checks are inserted into the scheduler
+ param:
+ args[0] is the number of devices that are to be brought down
+ args[1] is the average interval between device down events
+ args[2] is the average interval between device group down and group up events
+ blocking means blocking other events from being scheduled between device events
+ """
+ import random
+ import time
+
+ if len( args ) < 3:
+ main.log.warn( "Event Generator - Not enough arguments for randomDeviceGroupToggle: %s" % ( args ) )
+ elif len( args ) > 3:
+ main.log.warn( "Event Generator - Too many arguments for randomDeviceGroupToggle: %s" % ( args ) )
+ else:
+ deviceGroupSize = int( args[ 0 ] )
+ downDownAvgInterval = int( args[ 1 ] )
+ downUpAvgInterval = int( args[ 2 ] )
+ downDevices = []
+ for i in range( 0, deviceGroupSize ):
+ with main.variableLock:
+ graphHelper = GraphHelper()
+ availableDevices = graphHelper.getNonCutVertices()
+ if len( availableDevices ) == 0:
+ main.log.warn( "All devices are cut vertices, aborting event" )
+ continue
+ device = random.sample( availableDevices, 1 )
+ if i == 0:
+ self.eventGeneratorLock.acquire()
+ main.eventScheduler.scheduleEvent( EventType().NETWORK_DEVICE_DOWN,
+ scheduleMethod,
+ [ device[ 0 ].name ] )
+ with main.variableLock:
+ device[ 0 ].setPendingDown()
+ downDevices.append( device[ 0 ] )
+ sleepTime = int( main.params[ 'EVENT' ][ 'randomLinkGroupToggle' ][ 'sleepBeforeCheck' ] )
+ main.eventScheduler.scheduleEvent( EventType().TEST_SLEEP, EventScheduleMethod().RUN_BLOCK, [ sleepTime ] )
+ self.insertAllChecks( EventScheduleMethod().RUN_NON_BLOCK )
+ if scheduleMethod == EventScheduleMethod().RUN_BLOCK:
+ # Insert a NULL BLOCK event
+ main.eventScheduler.scheduleEvent( EventType().NULL, EventScheduleMethod().RUN_BLOCK )
+ downDownInterval = abs( random.gauss( downDownAvgInterval, 1 ) )
+ if not blocking:
+ self.eventGeneratorLock.release()
+ time.sleep( downDownInterval )
+ self.eventGeneratorLock.acquire()
+ else:
+ time.sleep( downDownInterval )
+
+ downUpInterval = abs( random.gauss( downUpAvgInterval, 1 ) )
+ if not blocking:
+ self.eventGeneratorLock.release()
+ time.sleep( downUpInterval )
+ self.eventGeneratorLock.acquire()
+ else:
+ time.sleep( downUpInterval )
+
+ for device in downDevices:
+ main.eventScheduler.scheduleEvent( EventType().NETWORK_DEVICE_UP,
+ scheduleMethod,
+ [ device.name ] )
+ main.eventScheduler.scheduleEvent( EventType().TEST_SLEEP, EventScheduleMethod().RUN_BLOCK, [ sleepTime ] )
+ self.insertAllChecks( EventScheduleMethod().RUN_NON_BLOCK )
+ if scheduleMethod == EventScheduleMethod().RUN_BLOCK:
+ main.eventScheduler.scheduleEvent( EventType().NULL, EventScheduleMethod().RUN_BLOCK )
+ upUpInterval = abs( random.gauss( downDownAvgInterval, 1 ) )
+ if not blocking:
+ self.eventGeneratorLock.release()
+ time.sleep( upUpInterval )
+ self.eventGeneratorLock.acquire()
+ else:
+ time.sleep( upUpInterval )
+ self.eventGeneratorLock.release()
+
+ def installAllHostIntents( self, scheduleMethod, args=None ):
+ """
+ This function installs host intents for all host pairs
+ After all intent events are inserted, this funciton also insert intent and traffic checks
+ """
+ import itertools
+
+ with self.eventGeneratorLock:
+ if scheduleMethod == EventScheduleMethod().RUN_BLOCK:
+ main.eventScheduler.scheduleEvent( EventType().NULL, EventScheduleMethod().RUN_BLOCK )
+ availableControllers = []
+ for controller in main.controllers:
+ if controller.isUp():
+ availableControllers.append( controller.index )
+ if len( availableControllers ) == 0:
+ main.log.warn( "Event Generator - No available controllers" )
+ return
+ hostCombos = list( itertools.combinations( main.hosts, 2 ) )
+ for i in xrange( 0, len( hostCombos ), len( availableControllers ) ):
+ for CLIIndex in availableControllers:
+ if i >= len( hostCombos ):
+ break
+ main.eventScheduler.scheduleEvent( EventType().APP_INTENT_HOST_ADD,
+ EventScheduleMethod().RUN_NON_BLOCK,
+ [ hostCombos[ i ][ 0 ].name, hostCombos[ i ][ 1 ].name, CLIIndex ] )
+ i += 1
+ # Pending checks after installing all intents
+ if scheduleMethod == EventScheduleMethod().RUN_BLOCK:
+ main.eventScheduler.scheduleEvent( EventType().NULL, EventScheduleMethod().RUN_BLOCK )
+ sleepTime = int( main.params[ 'EVENT' ][ 'installAllHostIntents' ][ 'sleepBeforeCheck' ] )
+ main.eventScheduler.scheduleEvent( EventType().TEST_SLEEP, EventScheduleMethod().RUN_BLOCK, [ sleepTime ] )
+ main.eventScheduler.scheduleEvent( EventType().CHECK_INTENT, EventScheduleMethod().RUN_NON_BLOCK )
+ main.eventScheduler.scheduleEvent( EventType().CHECK_TRAFFIC, EventScheduleMethod().RUN_NON_BLOCK )
+ if scheduleMethod == EventScheduleMethod().RUN_BLOCK:
+ main.eventScheduler.scheduleEvent( EventType().NULL, EventScheduleMethod().RUN_BLOCK )
+
+ def removeAllHostIntents( self, scheduleMethod, args=None ):
+ """
+ This function removes host intents for all host pairs
+ After all intent events are inserted, this funciton also insert intent and traffic checks
+ """
+ import itertools
+
+ with self.eventGeneratorLock:
+ if scheduleMethod == EventScheduleMethod().RUN_BLOCK:
+ main.eventScheduler.scheduleEvent( EventType().NULL, EventScheduleMethod().RUN_BLOCK )
+ availableControllers = []
+ for controller in main.controllers:
+ if controller.isUp():
+ availableControllers.append( controller.index )
+ if len( availableControllers ) == 0:
+ main.log.warn( "Event Generator - No available controllers" )
+ return
+ hostCombos = list( itertools.combinations( main.hosts, 2 ) )
+ for i in xrange( 0, len( hostCombos ), len( availableControllers ) ):
+ for CLIIndex in availableControllers:
+ if i >= len( hostCombos ):
+ break
+ main.eventScheduler.scheduleEvent( EventType().APP_INTENT_HOST_DEL,
+ EventScheduleMethod().RUN_NON_BLOCK,
+ [ hostCombos[ i ][ 0 ].name, hostCombos[ i ][ 1 ].name, CLIIndex ] )
+ i += 1
+ # Pending checks after removing all intents
+ if scheduleMethod == EventScheduleMethod().RUN_BLOCK:
+ main.eventScheduler.scheduleEvent( EventType().NULL, EventScheduleMethod().RUN_BLOCK )
+ sleepTime = int( main.params[ 'EVENT' ][ 'removeAllHostIntents' ][ 'sleepBeforeCheck' ] )
+ main.eventScheduler.scheduleEvent( EventType().TEST_SLEEP, EventScheduleMethod().RUN_BLOCK, [ sleepTime ] )
+ main.eventScheduler.scheduleEvent( EventType().CHECK_INTENT, EventScheduleMethod().RUN_NON_BLOCK )
+ main.eventScheduler.scheduleEvent( EventType().CHECK_TRAFFIC, EventScheduleMethod().RUN_NON_BLOCK )
+ if scheduleMethod == EventScheduleMethod().RUN_BLOCK:
+ main.eventScheduler.scheduleEvent( EventType().NULL, EventScheduleMethod().RUN_BLOCK )
+
+ def installAllPointIntents( self, scheduleMethod, args=None ):
+ """
+ This function installs point intents for all device pairs
+ After all intent events are inserted, this funciton also insert intent and traffic checks
+ """
+ import itertools
+
+ with self.eventGeneratorLock:
+ if scheduleMethod == EventScheduleMethod().RUN_BLOCK:
+ main.eventScheduler.scheduleEvent( EventType().NULL, EventScheduleMethod().RUN_BLOCK )
+ availableControllers = []
+ for controller in main.controllers:
+ if controller.isUp():
+ availableControllers.append( controller.index )
+ if len( availableControllers ) == 0:
+ main.log.warn( "Event Generator - No available controllers" )
+ return
+ deviceCombos = list( itertools.permutations( main.devices, 2 ) )
+ for i in xrange( 0, len( deviceCombos ), len( availableControllers ) ):
+ for CLIIndex in availableControllers:
+ if i >= len( deviceCombos ):
+ break
+ main.eventScheduler.scheduleEvent( EventType().APP_INTENT_POINT_ADD,
+ EventScheduleMethod().RUN_NON_BLOCK,
+ [ deviceCombos[ i ][ 0 ].name, deviceCombos[ i ][ 1 ].name, CLIIndex ] )
+ i += 1
+ # Pending checks after installing all intents
+ if scheduleMethod == EventScheduleMethod().RUN_BLOCK:
+ main.eventScheduler.scheduleEvent( EventType().NULL, EventScheduleMethod().RUN_BLOCK )
+ sleepTime = int( main.params[ 'EVENT' ][ 'installAllPointIntents' ][ 'sleepBeforeCheck' ] )
+ main.eventScheduler.scheduleEvent( EventType().TEST_SLEEP, EventScheduleMethod().RUN_BLOCK, [ sleepTime ] )
+ main.eventScheduler.scheduleEvent( EventType().CHECK_INTENT, EventScheduleMethod().RUN_NON_BLOCK )
+ main.eventScheduler.scheduleEvent( EventType().CHECK_TRAFFIC, EventScheduleMethod().RUN_NON_BLOCK )
+ if scheduleMethod == EventScheduleMethod().RUN_BLOCK:
+ main.eventScheduler.scheduleEvent( EventType().NULL, EventScheduleMethod().RUN_BLOCK )
+
+ def removeAllPointIntents( self, scheduleMethod, args=None ):
+ """
+ This function removes point intents for all device pairs
+ After all intent events are inserted, this funciton also insert intent and traffic checks
+ """
+ import itertools
+
+ with self.eventGeneratorLock:
+ if scheduleMethod == EventScheduleMethod().RUN_BLOCK:
+ main.eventScheduler.scheduleEvent( EventType().NULL, EventScheduleMethod().RUN_BLOCK )
+ availableControllers = []
+ for controller in main.controllers:
+ if controller.isUp():
+ availableControllers.append( controller.index )
+ if len( availableControllers ) == 0:
+ main.log.warn( "Event Generator - No available controllers" )
+ return
+ deviceCombos = list( itertools.permutations( main.devices, 2 ) )
+ for i in xrange( 0, len( deviceCombos ), len( availableControllers ) ):
+ for CLIIndex in availableControllers:
+ if i >= len( deviceCombos ):
+ break
+ main.eventScheduler.scheduleEvent( EventType().APP_INTENT_POINT_DEL,
+ EventScheduleMethod().RUN_NON_BLOCK,
+ [ deviceCombos[ i ][ 0 ].name, deviceCombos[ i ][ 1 ].name, CLIIndex ] )
+ i += 1
+ # Pending checks after removing all intents
+ if scheduleMethod == EventScheduleMethod().RUN_BLOCK:
+ main.eventScheduler.scheduleEvent( EventType().NULL, EventScheduleMethod().RUN_BLOCK )
+ sleepTime = int( main.params[ 'EVENT' ][ 'removeAllPointIntents' ][ 'sleepBeforeCheck' ] )
+ main.eventScheduler.scheduleEvent( EventType().TEST_SLEEP, EventScheduleMethod().RUN_BLOCK, [ sleepTime ] )
+ main.eventScheduler.scheduleEvent( EventType().CHECK_INTENT, EventScheduleMethod().RUN_NON_BLOCK )
+ main.eventScheduler.scheduleEvent( EventType().CHECK_TRAFFIC, EventScheduleMethod().RUN_NON_BLOCK )
+ if scheduleMethod == EventScheduleMethod().RUN_BLOCK:
+ main.eventScheduler.scheduleEvent( EventType().NULL, EventScheduleMethod().RUN_BLOCK )
diff --git a/TestON/tests/CHOTestMonkey/dependencies/EventScheduler.py b/TestON/tests/CHOTestMonkey/dependencies/EventScheduler.py
new file mode 100644
index 0000000..7e4c95c
--- /dev/null
+++ b/TestON/tests/CHOTestMonkey/dependencies/EventScheduler.py
@@ -0,0 +1,197 @@
+"""
+This file contains the event scheduler class for CHOTestMonkey
+Author: you@onlab.us
+"""
+from threading import Lock, Condition
+from tests.CHOTestMonkey.dependencies.events.Event import EventType, EventStates, Event
+from tests.CHOTestMonkey.dependencies.events.TestEvent import *
+from tests.CHOTestMonkey.dependencies.events.CheckEvent import *
+from tests.CHOTestMonkey.dependencies.events.NetworkEvent import *
+from tests.CHOTestMonkey.dependencies.events.AppEvent import *
+from tests.CHOTestMonkey.dependencies.events.ONOSEvent import *
+
+class EventScheduleMethod:
+ def __init__( self ):
+ self.map = {}
+ self.RUN_NON_BLOCK = 1
+ self.map[ 1 ] = 'RUN_NON_BLOCK'
+ self.RUN_BLOCK = -1
+ self.map[ -1 ] = 'RUN_BLOCK'
+
+class EventTuple:
+ def __init__( self, id, className, typeString, typeIndex, scheduleMethod, args, rerunInterval, maxRerunNum ):
+ self.default = ''
+ self.id = 0
+ self.className = className
+ self.typeString = typeString
+ self.typeIndex = typeIndex
+ self.scheduleMethod = scheduleMethod
+ self.args = args
+ self.rerunInterval = rerunInterval
+ self.maxRerunNum = maxRerunNum
+
+ def startEvent( self ):
+ assert self.className in globals().keys()
+ event = globals()[ self.className ]
+ return event().startEvent( self.args )
+
+class EventScheduler:
+ def __init__( self ):
+ self.default = ''
+ self.pendingEvents = []
+ self.pendingEventsCondition = Condition()
+ self.runningEvents = []
+ self.runningEventsCondition = Condition()
+ self.isRunning = True
+ self.idleCondition = Condition()
+ self.pendingEventsCapacity = int( main.params[ 'SCHEDULER' ][ 'pendingEventsCapacity' ] )
+ self.runningEventsCapacity = int( main.params[ 'SCHEDULER' ][ 'runningEventsCapacity' ] )
+ self.scheduleLoopSleep = float( main.params[ 'SCHEDULER' ][ 'scheduleLoopSleep' ] )
+
+ def scheduleEvent( self, typeIndex, scheduleMethod, args=None, index=-1 ):
+ """
+ Insert an event to pendingEvents
+ param:
+ index: the position to insert into pendingEvents, default value -1 implies the tail of pendingEvents
+ """
+ if not typeIndex in main.enabledEvents.keys():
+ main.log.warn( "Event Scheduler - event type %s not enabled" % ( typeIndex ) )
+ return
+ if main.enabledEvents[ typeIndex ] in main.params[ 'EVENT' ].keys():
+ if 'rerunInterval' in main.params[ 'EVENT' ][ main.enabledEvents[ typeIndex ] ].keys():
+ rerunInterval = int( main.params[ 'EVENT' ][ main.enabledEvents[ typeIndex ] ][ 'rerunInterval' ] )
+ maxRerunNum = int( main.params[ 'EVENT' ][ main.enabledEvents[ typeIndex ] ][ 'maxRerunNum' ] )
+ else:
+ rerunInterval = int( main.params[ 'EVENT' ][ 'Event' ][ 'rerunInterval' ] )
+ maxRerunNum = int( main.params[ 'EVENT' ][ 'Event' ][ 'maxRerunNum' ] )
+ eventTuple = EventTuple( main.eventID, main.enabledEvents[ typeIndex ], EventType().map[ typeIndex ], typeIndex, scheduleMethod, args, rerunInterval, maxRerunNum )
+ with main.variableLock:
+ main.eventID += 1
+ main.log.debug( "Event Scheduler - Event added: %s, %s, %s" % ( typeIndex,
+ scheduleMethod,
+ args ) )
+ with self.pendingEventsCondition:
+ if index == -1:
+ self.pendingEvents.append( eventTuple )
+ elif index > -1 and index <= len( self.pendingEvents ):
+ self.pendingEvents.insert( index, eventTuple )
+ else:
+ main.log.warn( "Event Scheduler - invalid index when isnerting event: %s" % ( index ) )
+ self.pendingEventsCondition.notify()
+ self.printEvents()
+
+ def startScheduler( self ):
+ """
+ Start the loop which schedules the events in pendingEvents
+ """
+ import time
+
+ while 1:
+ with self.pendingEventsCondition:
+ while len( self.pendingEvents ) == 0:
+ self.pendingEventsCondition.wait()
+ eventTuple = self.pendingEvents[ 0 ]
+ main.log.debug( "Event Scheduler - Scheduling event: %s, %s, %s" % ( eventTuple.typeIndex,
+ eventTuple.scheduleMethod,
+ eventTuple.args ) )
+ if eventTuple.scheduleMethod == EventScheduleMethod().RUN_NON_BLOCK:
+ # Run NON_BLOCK events using threads
+ with self.pendingEventsCondition:
+ self.pendingEvents.remove( eventTuple )
+ t = main.Thread( target=self.startEvent,
+ threadID=main.threadID,
+ name="startEvent",
+ args=[ eventTuple ])
+ t.start()
+ with main.variableLock:
+ main.threadID += 1
+ elif eventTuple.scheduleMethod == EventScheduleMethod().RUN_BLOCK:
+ # Wait for all other events before start
+ with self.runningEventsCondition:
+ while not len( self.runningEvents ) == 0:
+ self.runningEventsCondition.wait()
+ # BLOCK events will temporarily block the following events until finish running
+ with self.pendingEventsCondition:
+ self.pendingEvents.remove( eventTuple )
+ self.startEvent( eventTuple )
+ else:
+ with self.pendingEventsCondition:
+ self.pendingEvents.remove( eventTuple )
+ time.sleep( self.scheduleLoopSleep )
+
+ def startEvent( self, eventTuple ):
+ """
+ Start a network/ONOS/application event
+ """
+ import time
+
+ with self.runningEventsCondition:
+ self.runningEvents.append( eventTuple )
+ self.printEvents()
+ rerunNum = 0
+ result = eventTuple.startEvent()
+ while result == EventStates().FAIL and rerunNum < eventTuple.maxRerunNum:
+ time.sleep( eventTuple.rerunInterval )
+ rerunNum += 1
+ main.log.debug( eventTuple.typeString + ": retry number " + str( rerunNum ) )
+ result = eventTuple.startEvent()
+ if result == EventStates().FAIL:
+ main.log.error( eventTuple.typeString + " failed" )
+ main.caseResult = main.FALSE
+ if main.params[ 'TEST' ][ 'pauseTest' ] == 'on':
+ #self.isRunning = False
+ #main.log.error( "Event Scheduler - Test paused. To resume test, run \'resume-test\' command in CLI debugging mode" )
+ main.stop()
+ with self.runningEventsCondition:
+ self.runningEvents.remove( eventTuple )
+ if len( self.runningEvents ) == 0:
+ self.runningEventsCondition.notify()
+ with self.pendingEventsCondition:
+ if len( self.pendingEvents ) == 0:
+ with self.idleCondition:
+ self.idleCondition.notify()
+ self.printEvents()
+
+ def printEvents( self ):
+ """
+ Print all the events in pendingEvents and runningEvents
+ """
+ events = " ["
+ with self.runningEventsCondition:
+ for index in range( 0, len( self.runningEvents ) - 1 ):
+ events += str( self.runningEvents[ index ].typeIndex )
+ events += ", "
+ if len( self.runningEvents ) > 0:
+ events += str( self.runningEvents[ -1 ].typeIndex )
+ events += "]"
+ events += " ["
+ with self.pendingEventsCondition:
+ for index in range( 0, len( self.pendingEvents ) - 1 ):
+ events += str( self.pendingEvents[ index ].typeIndex )
+ events += ", "
+ if len( self.pendingEvents ) > 0:
+ events += str( self.pendingEvents[ -1 ].typeIndex )
+ events += "]"
+ main.log.debug( "Event Scheduler - Events: " + events )
+
+ def isAvailable( self ):
+ with self.pendingEventsCondition:
+ with self.runningEventsCondition:
+ return len( self.pendingEvents ) < self.pendingEventsCapacity and\
+ len( self.runningEvents ) < self.runningEventsCapacity and\
+ self.isRunning
+
+ def isIdle( self ):
+ with self.pendingEventsCondition:
+ with self.runningEventsCondition:
+ return len( self.pendingEvents ) == 0 and\
+ len( self.runningEvents ) == 0 and\
+ self.isRunning
+
+ def setPendingEventsCapacity( self, capacity ):
+ self.pendingEventsCapacity = capacity
+
+ def setRunningState( self, state ):
+ assert state == True or state == False
+ self.isRunning = state
+
diff --git a/TestON/tests/CHOTestMonkey/dependencies/EventTrigger.py b/TestON/tests/CHOTestMonkey/dependencies/EventTrigger.py
new file mode 100644
index 0000000..0c3e0e0
--- /dev/null
+++ b/TestON/tests/CHOTestMonkey/dependencies/EventTrigger.py
@@ -0,0 +1,68 @@
+"""
+Insert network/ONOS/app events into CHOTestMonkey
+Author: you@onlab.us
+"""
+import time
+import random
+from multiprocessing.connection import Client
+
+def triggerEvent( type, scheduleMethod, *args ):
+ """
+ This function inserts an event into CHOTestMonkey
+ """
+ host = "localhost"
+ port = 6000
+ address = ( host, port )
+ conn = Client( address )
+ request = []
+ request.append( 2 )
+ request.append( type )
+ request.append( scheduleMethod )
+ for arg in args:
+ request.append( arg )
+ conn.send( request )
+ response = conn.recv()
+ while response == 11:
+ time.sleep( 1 )
+ conn.send( request )
+ response = conn.recv()
+ if response == 10:
+ print "Event inserted:", type, scheduleMethod, args
+ elif response == 20:
+ print "Unknown message to server"
+ elif response == 21:
+ print "Unknown event type to server"
+ elif response == 22:
+ print "Unknown schedule method to server"
+ elif response == 23:
+ print "Not enough argument"
+ else:
+ print "Unknown response from server:", response
+ conn.close()
+
+def testLoop( sleepTime=5 ):
+ downLinkNum = 0
+ downDeviceNum = 0
+ while True:
+ r = random.random()
+ if r < 0.2:
+ triggerEvent( 'NETWORK_LINK_DOWN', 'RUN_BLOCK', 'random', 'random' )
+ downLinkNum += 1
+ time.sleep( sleepTime )
+ elif r < 0.4:
+ triggerEvent( 'NETWORK_DEVICE_DOWN', 'RUN_BLOCK', 'random' )
+ downDeviceNum += 1
+ time.sleep( sleepTime * 2 )
+ elif r < 0.7 and downLinkNum > 0:
+ triggerEvent( 'NETWORK_LINK_UP', 'RUN_BLOCK', 'random', 'random' )
+ downLinkNum -= 1
+ time.sleep( sleepTime )
+ elif downDeviceNum > 0:
+ triggerEvent( 'NETWORK_DEVICE_UP', 'RUN_BLOCK', 'random' )
+ downDeviceNum -= 1
+ time.sleep( sleepTime * 2 )
+ else:
+ pass
+
+if __name__ == '__main__':
+ testLoop( 2 )
diff --git a/TestON/tests/CHOTestMonkey/dependencies/GraphHelper.py b/TestON/tests/CHOTestMonkey/dependencies/GraphHelper.py
new file mode 100644
index 0000000..13f110b
--- /dev/null
+++ b/TestON/tests/CHOTestMonkey/dependencies/GraphHelper.py
@@ -0,0 +1,133 @@
+"""
+Graph algorithm implementations for CHOTestMonkey
+Author: you@onlab.us
+"""
+class GraphHelper:
+ """
+ This class implements graph algorithms for CHOTestMonkey.
+ It reads main.devices and main.links as vertices and edges.
+ Currently it offers functions for finding (non-)cut-edges and vertices,
+ which is realized based on chain-decomposition algorithm
+ """
+ def __init__( self ):
+ # Depth-first index of each node
+ self.DFI = []
+ # Parent vertex and egde of each node in depth-first search tree
+ self.parentDeviceInDFS = []
+ self.parentLinkInDFS = []
+ # Data structures for chain-decomposition algorithm
+ self.backEdges = {}
+ self.chains = []
+ self.currentDFI = 0
+ self.upDevices = []
+ for device in main.devices:
+ if device.isUp():
+ self.upDevices.append( device )
+ for i in range( len( main.devices ) ):
+ self.DFI.append( -1 )
+ self.parentDeviceInDFS.append( None )
+ self.parentLinkInDFS.append( None )
+
+ def genDFIandBackEdge( self, device ):
+ """
+ This function runs a depth-first search and get DFI of each node
+ as well as collect the back edges
+ """
+ self.DFI[ device.index ] = self.currentDFI
+ self.currentDFI += 1
+ for link in device.outgoingLinks:
+ if not link.isUp():
+ continue
+ backwardLink = link.backwardLink
+ neighbor = link.deviceB
+ if neighbor == self.parentDeviceInDFS[ device.index ]:
+ continue
+ elif self.DFI[ neighbor.index ] == -1:
+ self.parentDeviceInDFS[ neighbor.index ] = device
+ self.parentLinkInDFS[ neighbor.index ] = backwardLink
+ self.genDFIandBackEdge( neighbor )
+ else:
+ key = self.DFI[ neighbor.index ]
+ if key in self.backEdges.keys():
+ if not link in self.backEdges[ key ] and\
+ not backwardLink in self.backEdges[ key ]:
+ self.backEdges[ key ].append( backwardLink )
+ else:
+ tempKey = self.DFI[ device.index ]
+ if tempKey in self.backEdges.keys():
+ if not link in self.backEdges[ tempKey ] and\
+ not backwardLink in self.backEdges[ tempKey ]:
+ self.backEdges[ key ] = [ backwardLink ]
+ else:
+ self.backEdges[ key ] = [ backwardLink ]
+
+ def findChains( self ):
+ """
+ This function finds all the 'chains' for chain-decomposition algorithm
+ """
+ keyList = self.backEdges.keys()
+ keyList.sort()
+ deviceIsVisited = []
+ for i in range( len( main.devices ) ):
+ deviceIsVisited.append( 0 )
+ for key in keyList:
+ backEdgeList = self.backEdges[ key ]
+ for link in backEdgeList:
+ chain = []
+ currentLink = link
+ sourceDevice = link.deviceA
+ while True:
+ currentDevice = currentLink.deviceA
+ nextDevice = currentLink.deviceB
+ deviceIsVisited[ currentDevice.index ] = 1
+ chain.append( currentLink )
+ if nextDevice == sourceDevice or deviceIsVisited[ nextDevice.index ] == 1:
+ break
+ currentLink = self.parentLinkInDFS[ nextDevice.index ]
+ self.chains.append( chain )
+
+ def getNonCutEdges( self ):
+ """
+ This function returns all non-cut-edges of a graph
+ """
+ assert len( self.upDevices ) != 0
+ self.genDFIandBackEdge( self.upDevices[ 0 ] )
+ self.findChains()
+ nonCutEdges = []
+ for chain in self.chains:
+ for link in chain:
+ nonCutEdges.append( link )
+ return nonCutEdges
+
+ def getNonCutVertices( self ):
+ """
+ This function returns all non-cut-vertices of a graph
+ """
+ nonCutEdges = self.getNonCutEdges()
+ nonCutVertices = []
+ for device in self.upDevices:
+ deviceIsNonCut = True
+ for link in device.outgoingLinks:
+ if link.isUp() and not ( link in nonCutEdges or link.backwardLink in nonCutEdges ):
+ deviceIsNonCut = False
+ break
+ if deviceIsNonCut:
+ nonCutVertices.append( device )
+ return nonCutVertices
+
+ def printDFI( self ):
+ print self.DFI
+
+ def printParentInDFS( self ):
+ print self.parentInDFS
+
+ def printBackEdges( self ):
+ print self.backEdges
+
+ def printChains( self ):
+ chainIndex = 0
+ for chain in self.chains:
+ print chainIndex
+ for link in chain:
+ print link
+ chainIndex += 1
diff --git a/TestON/tests/CHOTestMonkey/dependencies/__init__.py b/TestON/tests/CHOTestMonkey/dependencies/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/TestON/tests/CHOTestMonkey/dependencies/__init__.py
diff --git a/TestON/tests/CHOTestMonkey/dependencies/cli.py b/TestON/tests/CHOTestMonkey/dependencies/cli.py
new file mode 100644
index 0000000..d1a8448
--- /dev/null
+++ b/TestON/tests/CHOTestMonkey/dependencies/cli.py
@@ -0,0 +1,109 @@
+"""
+Start CLI for CHOTestMonkey
+Author: you@onlab.us
+"""
+from multiprocessing.connection import Client
+
+commandMap = {}
+paramNum = {}
+
+def triggerEvent( debugMode, name, scheduleMethod, args ):
+ """
+ This function inserts an event from CLI to CHOTestMonkey
+ """
+ host = "localhost"
+ port = 6000
+ address = ( host, port )
+ conn = Client( address )
+ request = []
+ if debugMode:
+ request.append( 2 )
+ else:
+ request.append( 1 )
+ request.append( name )
+ request.append( scheduleMethod )
+ for arg in args:
+ request.append( arg )
+ conn.send( request )
+ response = conn.recv()
+ return response
+
+def startCLI():
+ debugMode = False
+ while 1:
+ try:
+ if debugMode:
+ cmd = raw_input("CHOTestMonkey-debug>")
+ else:
+ cmd = raw_input("CHOTestMonkey>")
+ except EOFError:
+ print "exit"
+ return
+ except Exception:
+ print "Uncaught exception!"
+ return
+
+ if cmd == 'help':
+ print 'Supported commands:'
+ print 'help'
+ print 'debug'
+ print 'exit'
+ for command in commandMap.keys():
+ print command
+ elif cmd == '':
+ pass
+ elif cmd == 'debug':
+ debugMode = True
+ elif cmd == 'exit':
+ if debugMode:
+ debugMode = False
+ else:
+ return
+ else:
+ cmdList = cmd.split( ' ' )
+ if cmdList[ 0 ] in commandMap.keys():
+ num = paramNum[ cmdList[ 0 ] ]
+ name = commandMap[ cmdList[ 0 ] ]
+ if len( cmdList ) < num + 1:
+ print 'not enough arguments'
+ elif len( cmdList ) > num + 1:
+ print 'Too many arguments'
+ else:
+ result = triggerEvent( debugMode, name, 'RUN_BLOCK', cmdList[ 1: ] )
+ if result == 10:
+ pass
+ elif result == 11:
+ print "Scheduler busy...Try later or use debugging mode by entering \'debug\'"
+ elif result == 20:
+ print "Unknown message to server"
+ elif result == 21:
+ print "Unknown event type to server"
+ elif result == 22:
+ print "Unknown schedule method to server"
+ elif result == 23:
+ print "Not enough argument"
+ else:
+ print "Unknown response from server"
+ else:
+ print 'Unknown command'
+
+if __name__ == '__main__':
+ import xml.etree.ElementTree
+ try:
+ root = xml.etree.ElementTree.parse( '../CHOTestMonkey.params' ).getroot()
+ except Exception:
+ print "Uncaught exception!"
+ for child in root:
+ if child.tag == 'EVENT':
+ for event in child:
+ for item in event:
+ if item.tag == 'CLI':
+ CLI = str( item.text )
+ if item.tag == 'typeString':
+ name = str( item.text )
+ if item.tag == 'CLIParamNum':
+ num = int( item.text )
+ commandMap[ CLI ] = name
+ paramNum[ CLI ] = num
+ startCLI()
+
diff --git a/TestON/tests/CHOTestMonkey/dependencies/elements/NetworkElement.py b/TestON/tests/CHOTestMonkey/dependencies/elements/NetworkElement.py
new file mode 100644
index 0000000..2a18ac7
--- /dev/null
+++ b/TestON/tests/CHOTestMonkey/dependencies/elements/NetworkElement.py
@@ -0,0 +1,80 @@
+"""
+This file contains device, host and link class for CHOTestMonkey
+Author: you@onlab.us
+"""
+
+class NetworkElement:
+ def __init__( self, index ):
+ self.default = ''
+ self.index = index
+ self.status = 'up'
+
+ def isUp( self ):
+ return self.status == 'up'
+
+ def isDown( self ):
+ return self.status == 'down'
+
+ def isRemoved( self ):
+ return self.status == 'removed'
+
+ def setPendingDown( self ):
+ self.status = 'pending_down'
+
+ def setRemoved( self ):
+ self.status = 'removed'
+
+ def bringDown( self ):
+ self.status = 'down'
+
+ def bringUp( self ):
+ self.status = 'up'
+
+class Device( NetworkElement ):
+ def __init__( self, index, name, dpid ):
+ NetworkElement.__init__( self, index )
+ self.name = name
+ self.dpid = dpid
+ self.hosts = []
+ # For each bidirectional link, we only store one direction here
+ self.outgoingLinks = []
+
+ def __str__( self ):
+ return "name: " + self.name + ", dpid: " + self.dpid
+
+class Host( NetworkElement ):
+ def __init__( self, index, name, id, mac, device, devicePort, vlan, ipAddresses ):
+ NetworkElement.__init__( self, index )
+ self.name = name
+ self.id = id
+ self.mac = mac
+ self.device = device
+ self.devicePort = devicePort
+ self.vlan = vlan
+ self.ipAddresses = ipAddresses
+ self.correspondents = []
+ self.handle = None
+
+ def __str__( self ):
+ return "name: " + self.name + ", mac: " + self.mac + ", device: " + self.device.dpid + ", ipAddresses: " + str( self.ipAddresses )
+
+ def setHandle( self, handle ):
+ self.handle = handle
+
+class Link( NetworkElement ):
+ """
+ Unidirectional link
+ """
+ def __init__( self, index, deviceA, portA, deviceB, portB ):
+ NetworkElement.__init__( self, index )
+ self.backwardLink = None
+ self.deviceA = deviceA
+ self.portA = portA
+ self.deviceB = deviceB
+ self.portB = portB
+
+ def __str__( self ):
+ return self.deviceA.dpid + "/" + self.portA + " - " + self.deviceB.dpid + "/" + self.portB
+
+ def setBackwardLink( self, link ):
+ self.backwardLink = link
diff --git a/TestON/tests/CHOTestMonkey/dependencies/elements/ONOSElement.py b/TestON/tests/CHOTestMonkey/dependencies/elements/ONOSElement.py
new file mode 100644
index 0000000..699a17d
--- /dev/null
+++ b/TestON/tests/CHOTestMonkey/dependencies/elements/ONOSElement.py
@@ -0,0 +1,61 @@
+"""
+This file contains intent class for CHOTestMonkey
+Author: you@onlab.us
+"""
+from threading import Lock
+
+class Controller:
+ def __init__( self, index ):
+ self.default = ''
+ self.index = index
+ self.ip = main.onosIPs[ index - 1 ]
+ self.CLI = None
+ self.CLILock = Lock()
+ self.status = 'up'
+
+ def setCLI( self, CLI ):
+ self.CLI = CLI
+
+ def startCLI( self ):
+ return self.CLI.startOnosCli( self.ip )
+
+ def isUp( self ):
+ return self.status == 'up'
+
+ def bringDown( self ):
+ self.status = 'down'
+
+ def bringUp( self ):
+ self.status = 'up'
+
+class Intent:
+ def __init__( self, id ):
+ self.default = ''
+ self.type = 'INTENT'
+ self.id = id
+
+ def isHostIntent( self ):
+ return self.type == 'INTENT_HOST'
+
+ def isPointIntent( self ):
+ return self.type == 'INTENT_POINT'
+
+class HostIntent( Intent ):
+ def __init__( self, id, hostA, hostB ):
+ Intent.__init__( self, id )
+ self.type = 'INTENT_HOST'
+ self.hostA = hostA
+ self.hostB = hostB
+
+ def __str__( self ):
+ return "ID: " + self.id
+
+class PointIntent( Intent ):
+ def __init__( self, id, deviceA, deviceB ):
+ Intent.__init__( self, id )
+ self.type = 'INTENT_POINT'
+ self.deviceA = deviceA
+ self.deviceB = deviceB
+
+ def __str__( self ):
+ return "ID: " + self.id
diff --git a/TestON/tests/CHOTestMonkey/dependencies/elements/__init__.py b/TestON/tests/CHOTestMonkey/dependencies/elements/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/TestON/tests/CHOTestMonkey/dependencies/elements/__init__.py
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
diff --git a/TestON/tests/CHOTestMonkey/dependencies/events/CheckEvent.py b/TestON/tests/CHOTestMonkey/dependencies/events/CheckEvent.py
new file mode 100644
index 0000000..e48f674
--- /dev/null
+++ b/TestON/tests/CHOTestMonkey/dependencies/events/CheckEvent.py
@@ -0,0 +1,235 @@
+"""
+This file contains classes for CHOTestMonkey that are related to check event
+Author: you@onlab.us
+"""
+from tests.CHOTestMonkey.dependencies.events.Event import EventType, EventStates, Event
+
+class CheckEvent( Event ):
+ def __init__( self ):
+ Event.__init__( self )
+
+ def startCheckEvent( self ):
+ return EventStates().PASS
+
+ def startEvent( self, args ):
+ with self.eventLock:
+ main.log.info( "%s - starting event" % ( self.typeString ) )
+ result = self.startCheckEvent()
+ return result
+
+class IntentCheck( CheckEvent ):
+ def __init__( self ):
+ CheckEvent.__init__( self )
+ self.typeString = main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeString' ]
+ self.typeIndex = int( main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeIndex' ] )
+
+ def startCheckEvent( self, args=None ):
+ checkResult = EventStates().PASS
+ intentIDs = []
+ for intent in main.intents:
+ if intent.isHostIntent():
+ deviceA = intent.hostA.device
+ deviceB = intent.hostB.device
+ elif intent.isPointIntent():
+ deviceA = intent.deviceA
+ deviceB = intent.deviceB
+ # Exclude the intents that are to or from removed devices/hosts
+ if not deviceA.isRemoved() and not deviceB.isRemoved():
+ intentIDs.append( intent.id )
+ for controller in main.controllers:
+ if controller.isUp():
+ with controller.CLILock:
+ intentState = controller.CLI.checkIntentState( intentsId=intentIDs )
+ if not intentState:
+ main.log.warn( "Intent Check - Not all intents are in INSTALLED state on ONOS%s" % ( controller.index ) )
+ checkResult = EventStates().FAIL
+ #TODO: check flows?
+ return checkResult
+
+class TopoCheck( CheckEvent ):
+ def __init__( self ):
+ CheckEvent.__init__( self )
+ self.typeString = main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeString' ]
+ self.typeIndex = int( main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeIndex' ] )
+
+ def startCheckEvent( self, args=None ):
+ import json
+ checkResult = EventStates().PASS
+ upLinkNum = 0
+ upDeviceNum = 0
+ upHostNum = 0
+ with main.variableLock:
+ for link in main.links:
+ if not link.isDown() and not link.isRemoved():
+ upLinkNum += 1
+ for device in main.devices:
+ if not device.isDown() and not device.isRemoved():
+ upDeviceNum += 1
+ for host in main.hosts:
+ if not host.isDown() and not host.isRemoved():
+ upHostNum += 1
+ clusterNum = 1
+ for controller in main.controllers:
+ if controller.isUp():
+ with controller.CLILock:
+ topologyOutput = controller.CLI.topology()
+ topoState = controller.CLI.checkStatus( topologyOutput, upDeviceNum, upLinkNum )
+ #if not topoState:
+ # main.log.warn( "Topo Check - link or device number discoverd by ONOS%s is incorrect" % ( controller.index ) )
+ # checkResult = EventStates().FAIL
+ # Check links
+ links = controller.CLI.links()
+ links = json.loads( links )
+ if not len( links ) == upLinkNum:
+ checkResult = EventStates().FAIL
+ main.log.warn( "Topo Check - link number discoverd by ONOS%s is incorrect: %s expected and %s actual" % ( controller.index, upLinkNum, len( links ) ) )
+ # Check devices
+ devices = controller.CLI.devices()
+ devices = json.loads( devices )
+ availableDeviceNum = 0
+ for device in devices:
+ if device[ 'available' ] == True:
+ availableDeviceNum += 1
+ if not availableDeviceNum == upDeviceNum:
+ checkResult = EventStates().FAIL
+ main.log.warn( "Topo Check - device number discoverd by ONOS%s is incorrect: %s expected and %s actual" % ( controller.index, upDeviceNum, availableDeviceNum ) )
+ # Check hosts
+ hosts = controller.CLI.hosts()
+ hosts = json.loads( hosts )
+ if not len( hosts ) == upHostNum:
+ checkResult = EventStates().FAIL
+ main.log.warn( "Topo Check - host number discoverd by ONOS%s is incorrect: %s expected and %s actual" % ( controller.index, upHostNum, len( hosts ) ) )
+ # Check clusters
+ clusters = controller.CLI.clusters()
+ clusters = json.loads( clusters )
+ if not len( clusters ) == clusterNum:
+ checkResult = EventStates().FAIL
+ main.log.warn( "Topo Check - cluster number discoverd by ONOS%s is incorrect: %s expected and %s actual" % ( controller.index, clusterNum, len( clusters ) ) )
+ return checkResult
+
+class ONOSCheck( CheckEvent ):
+ def __init__( self ):
+ CheckEvent.__init__( self )
+ self.typeString = main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeString' ]
+ self.typeIndex= int( main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeIndex' ] )
+
+ def startCheckEvent( self, args=None ):
+ import json
+ checkResult = EventStates().PASS
+ topics = []
+ # TODO: Other topics?
+ for i in range( 14 ):
+ topics.append( "intent-partition-" + str( i ) )
+ dpidToAvailability = {}
+ dpidToMaster = {}
+ for device in main.devices:
+ if device.isDown() or device.isRemoved():
+ dpidToAvailability[ device.dpid ] = False
+ else:
+ dpidToAvailability[ device.dpid ] = True
+ dpidToMaster[ device.dpid ] = 'unknown'
+ # Check mastership, leaders and node states on each controller node
+ for controller in main.controllers:
+ if controller.isUp():
+ # Check mastership
+ with controller.CLILock:
+ roles = controller.CLI.roles()
+ roles = json.loads( roles )
+ for device in roles:
+ dpid = device[ 'id' ]
+ if dpidToMaster[ dpid ] == 'unknown':
+ dpidToMaster[ dpid ] = device[ 'master' ]
+ elif dpidToMaster[ dpid ] != device[ 'master' ]:
+ checkResult = EventStates().FAIL
+ main.log.warn( "ONOS Check - Mastership of %s on ONOS%s is inconsistent with that on ONOS1" % ( device.name, controller.index ) )
+ if dpidToAvailability[ dpid ] and device[ 'master' ] == "none":
+ checkResult = EventStates().FAIL
+ main.log.warn( "ONOS Check - Device %s has no master on ONOS%s" % ( device.name, controller.index ) )
+ # Check leaders
+ with controller.CLILock:
+ leaders = controller.CLI.leaders()
+ leaders = json.loads( leaders )
+ ONOSTopics = [ j['topic'] for j in leaders ]
+ for topic in topics:
+ if topic not in ONOSTopics:
+ checkResult = EventStates().FAIL
+ main.log.warn( "ONOS Check - Topic %s not in leaders on ONOS%s" % ( topic, controller.index ) )
+ # Check node state
+ with controller.CLILock:
+ nodes = controller.CLI.nodes()
+ nodes = json.loads( nodes )
+ ipToState = {}
+ for node in nodes:
+ ipToState[ node[ 'ip' ] ] = node[ 'state' ]
+ for c in main.controllers:
+ if c.isUp() and ipToState[ c.ip ] == 'READY':
+ pass
+ elif not c.isUp() and ipToState[ c.ip ] == 'INACTIVE':
+ pass
+ else:
+ checkResult = EventStates().FAIL
+ main.log.warn( "ONOS Check - ONOS%s shows wrong node state: ONOS%s is %s but state is %s" % ( controller.index, c.index, c.status, ipToState[ c.ip ] ) )
+ # TODO: check partitions?
+ return checkResult
+
+class TrafficCheck( CheckEvent ):
+ def __init__( self ):
+ CheckEvent.__init__( self )
+ self.typeString = main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeString' ]
+ self.typeIndex= int( main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeIndex' ] )
+
+ def startCheckEvent( self, args=None ):
+ checkResult = EventStates().PASS
+ pool = []
+ wait = int( main.params[ 'EVENT' ][ 'TrafficCheck' ][ 'pingWait' ] )
+ timeout = int( main.params[ 'EVENT' ][ 'TrafficCheck' ][ 'pingTimeout' ] )
+ dstIPv4List = {}
+ dstIPv6List = {}
+ upHosts = []
+ for host in main.hosts:
+ if host.isUp():
+ upHosts.append( host )
+ for host in upHosts:
+ dstIPv4List[ host.index ] = []
+ dstIPv6List[ host.index ] = []
+ for correspondent in host.correspondents:
+ if not correspondent in upHosts:
+ continue
+ for ipAddress in correspondent.ipAddresses:
+ if ipAddress.startswith( str( main.params[ 'TEST' ][ 'ipv6Prefix' ] ) ):
+ dstIPv6List[ host.index ].append( ipAddress )
+ elif ipAddress.startswith( str( main.params[ 'TEST' ][ 'ipv4Prefix' ] ) ):
+ dstIPv4List[ host.index ].append( ipAddress )
+ thread = main.Thread( target=host.handle.pingHostSetAlternative,
+ threadID=main.threadID,
+ name="pingHostSetAlternative",
+ args=[ dstIPv4List[ host.index ], 1 ] )
+ pool.append( thread )
+ thread.start()
+ with main.variableLock:
+ main.threadID += 1
+ for thread in pool:
+ thread.join( 10 )
+ if not thread.result:
+ checkResult = EventStates().FAIL
+ main.log.warn( "Traffic Check - ping failed" )
+
+ if not main.enableIPv6:
+ return checkResult
+ # Check ipv6 ping
+ for host in upHosts:
+ thread = main.Thread( target=host.handle.pingHostSetAlternative,
+ threadID=main.threadID,
+ name="pingHostSetAlternative",
+ args=[ dstIPv6List[ host.index ], 1, True ] )
+ pool.append( thread )
+ thread.start()
+ with main.variableLock:
+ main.threadID += 1
+ for thread in pool:
+ thread.join( 10 )
+ if not thread.result:
+ checkResult = EventStates().FAIL
+ main.log.warn( "Traffic Check - ping6 failed" )
+ return checkResult
+
diff --git a/TestON/tests/CHOTestMonkey/dependencies/events/Event.py b/TestON/tests/CHOTestMonkey/dependencies/events/Event.py
new file mode 100644
index 0000000..2abd77f
--- /dev/null
+++ b/TestON/tests/CHOTestMonkey/dependencies/events/Event.py
@@ -0,0 +1,43 @@
+"""
+This file contains the Event class for CHOTestMonkey
+Author: you@onlab.us
+"""
+from threading import Lock
+
+class EventType:
+ def __init__( self ):
+ self.map = {}
+ # Group events (>100) should be divided into individual events by the generator before going to the scheduler
+ self.NULL = 0
+ for eventName in main.params[ 'EVENT' ].keys():
+ typeString = main.params[ 'EVENT' ][ eventName ][ 'typeString' ]
+ typeIndex = int( main.params[ 'EVENT' ][ eventName ][ 'typeIndex' ] )
+ setattr( self, typeString, typeIndex )
+ self.map[ typeIndex ] = typeString
+
+class EventStates:
+ def __init__( self ):
+ self.map = {}
+ self.FAIL = 0
+ self.map[ 0 ] = 'FAIL'
+ self.PASS = 1
+ self.map[ 1 ] = 'PASS'
+ self.ABORT = -1
+ self.map[ -1 ] = 'ABORT'
+
+class Event:
+ """
+ Event class for CHOTestMonkey
+ It is the super class for CheckEvent and NetworkEvent
+ """
+ def __init__( self ):
+ self.typeString = main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeString' ]
+ self.typeIndex = int( main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeIndex' ] )
+ self.eventLock = Lock()
+ self.variableLock = Lock()
+
+ def startEvent( self, args=None ):
+ """
+ Start running the event
+ """
+ return EventStates().PASS
diff --git a/TestON/tests/CHOTestMonkey/dependencies/events/NetworkEvent.py b/TestON/tests/CHOTestMonkey/dependencies/events/NetworkEvent.py
new file mode 100644
index 0000000..46b37e7
--- /dev/null
+++ b/TestON/tests/CHOTestMonkey/dependencies/events/NetworkEvent.py
@@ -0,0 +1,289 @@
+"""
+This file contains classes for CHOTestMonkey that are related to network event
+Author: you@onlab.us
+"""
+from tests.CHOTestMonkey.dependencies.events.Event import EventType, EventStates, Event
+from tests.CHOTestMonkey.dependencies.elements.NetworkElement import NetworkElement, Device, Host, Link
+from tests.CHOTestMonkey.dependencies.GraphHelper import GraphHelper
+
+class LinkEvent( Event ):
+ def __init__( self ):
+ Event.__init__( self )
+ self.linkA = None
+ self.linkB = None
+
+ def startLinkEvent( self ):
+ return EventStates().PASS
+
+ def startEvent( self, args ):
+ """
+ args are the names of the two link ends, e.g. ['s1', 's2']
+ """
+ with self.eventLock:
+ 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
+ elif len( args ) > 2:
+ main.log.warn( "%s - Too many arguments: %s" % ( self.typeString, args ) )
+ return EventStates().ABORT
+ if args[ 0 ] == 'random' or args[ 1 ] == 'random':
+ import random
+ if self.typeIndex == EventType().NETWORK_LINK_DOWN:
+ with main.variableLock:
+ graphHelper = GraphHelper()
+ availableLinks = graphHelper.getNonCutEdges()
+ if len( availableLinks ) == 0:
+ main.log.warn( "All links are cut edges, aborting event" )
+ return EventStates().ABORT
+ linkList = random.sample( availableLinks, 1 )
+ self.linkA = linkList[ 0 ]
+ self.linkB = linkList[ 0 ].backwardLink
+ elif self.typeIndex == EventType().NETWORK_LINK_UP:
+ with main.variableLock:
+ downLinks = []
+ for link in main.links:
+ if link.isDown():
+ downLinks.append( link )
+ if len( downLinks ) == 0:
+ main.log.warn( "None of the links are in 'down' state, aborting event" )
+ return EventStates().ABORT
+ linkList = random.sample( downLinks, 1 )
+ self.linkA = linkList[ 0 ]
+ self.linkB = linkList[ 0 ].backwardLink
+ elif args[ 0 ] == args[ 1 ]:
+ main.log.warn( "%s - invalid arguments: %s" % ( self.typeString, args ) )
+ return EventStates().ABORT
+ else:
+ for link in main.links:
+ if link.deviceA.name == args[ 0 ] and link.deviceB.name == args[ 1 ]:
+ self.linkA = link
+ elif link.deviceA.name == args[ 1 ] and link.deviceB.name == args[ 0 ]:
+ self.linkB = link
+ if self.linkA != None and self.linkB != None:
+ break
+ if self.linkA == None or self.linkB == None:
+ main.log.warn( "Bidirectional link %s - %s does not exist: " % ( args[ 0 ], args[ 1 ] ) )
+ return EventStates().ABORT
+ main.log.debug( "%s - %s" % ( self.typeString, self.linkA ) )
+ return self.startLinkEvent()
+
+class LinkDown( LinkEvent ):
+ """
+ Generate a link down event giving the two ends of the link
+ """
+ def __init__( self ):
+ LinkEvent.__init__( self )
+ self.typeString = main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeString' ]
+ self.typeIndex = int( main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeIndex' ] )
+
+ def startLinkEvent( self ):
+ # TODO: do we need to handle a unidirectional link?
+ assert self.linkA != None and self.linkB != None
+ with main.variableLock:
+ if self.linkA.isDown() or self.linkB.isDown():
+ main.log.warn( "Link Down - link already down" )
+ return EventStates().ABORT
+ elif self.linkA.isRemoved() or self.linkB.isRemoved():
+ main.log.warn( "Link Down - link has been removed" )
+ return EventStates().ABORT
+ with main.mininetLock:
+ result = main.Mininet1.link( END1=self.linkA.deviceA.name,
+ END2=self.linkA.deviceB.name,
+ OPTION="down")
+ if not result:
+ main.log.warn( "%s - failed to bring down link" % ( self.typeString ) )
+ return EventStates().FAIL
+ with main.variableLock:
+ self.linkA.bringDown()
+ self.linkB.bringDown()
+ return EventStates().PASS
+
+class LinkUp( LinkEvent ):
+ """
+ Generate a link up event giving the two ends of the link
+ """
+ def __init__( self ):
+ LinkEvent.__init__( self )
+ self.typeString = main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeString' ]
+ self.typeIndex = int( main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeIndex' ] )
+
+ def startLinkEvent( self ):
+ assert self.linkA != None and self.linkB != None
+ with main.variableLock:
+ if self.linkA.isUp() or self.linkB.isUp():
+ main.log.warn( "Link Up - link already up" )
+ return EventStates().ABORT
+ if self.linkA.isRemoved() or self.linkB.isRemoved():
+ main.log.warn( "Link Up - link has been removed" )
+ return EventStates().ABORT
+ with main.mininetLock:
+ result = main.Mininet1.link( END1=self.linkA.deviceA.name,
+ END2=self.linkA.deviceB.name,
+ OPTION="up")
+ if not result:
+ main.log.warn( "%s - failed to bring up link" % ( self.typeString ) )
+ return EventStates().FAIL
+ with main.variableLock:
+ self.linkA.bringUp()
+ self.linkB.bringUp()
+ return EventStates().PASS
+
+class DeviceEvent( Event ):
+ def __init__( self ):
+ Event.__init__( self )
+ self.device = None
+
+ def startDeviceEvent( self ):
+ return EventStates().PASS
+
+ def startEvent( self, args ):
+ """
+ args are the names of the device, e.g. 's1'
+ """
+ with self.eventLock:
+ 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
+ elif len( args ) > 1:
+ main.log.warn( "%s - Too many arguments: %s" % ( self.typeString, args ) )
+ return EventStates().ABORT
+ if args[ 0 ] == 'random':
+ import random
+ if self.typeIndex == EventType().NETWORK_DEVICE_DOWN:
+ with main.variableLock:
+ graphHelper = GraphHelper()
+ availableDevices = graphHelper.getNonCutVertices()
+ if len( availableDevices ) == 0:
+ main.log.warn( "All devices are cut vertices, aborting event" )
+ return EventStates().ABORT
+ deviceList = random.sample( availableDevices, 1 )
+ self.device = deviceList[ 0 ]
+ elif self.typeIndex == EventType().NETWORK_DEVICE_UP:
+ with main.variableLock:
+ removedDevices = []
+ for device in main.devices:
+ if device.isRemoved():
+ removedDevices.append( device )
+ if len( removedDevices ) == 0:
+ main.log.warn( "None of the devices are removed, aborting event" )
+ return EventStates().ABORT
+ deviceList = random.sample( removedDevices, 1 )
+ self.device = deviceList[ 0 ]
+ else:
+ for device in main.devices:
+ if device.name == args[ 0 ]:
+ self.device = device
+ if self.device == None:
+ main.log.warn( "Device %s does not exist: " % ( args[ 0 ] ) )
+ return EventStates().ABORT
+ main.log.debug( "%s - %s" % ( self.typeString, self.device ) )
+ return self.startDeviceEvent()
+
+class DeviceDown( DeviceEvent ):
+ """
+ Generate a device down event (which actually removes this device for now) giving its name
+ """
+ def __init__( self ):
+ DeviceEvent.__init__( self )
+ self.typeString = main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeString' ]
+ self.typeIndex = int( main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeIndex' ] )
+
+ def startDeviceEvent( self ):
+ assert self.device != None
+ with main.variableLock:
+ if self.device.isRemoved():
+ main.log.warn( "Device Down - device has been removed" )
+ return EventStates().ABORT
+ with main.mininetLock:
+ result = main.Mininet1.delSwitch( self.device.name )
+ if not result:
+ main.log.warn( "%s - failed to bring down device" % ( self.typeString ) )
+ return EventStates().FAIL
+ with main.variableLock:
+ self.device.setRemoved()
+ for link in self.device.outgoingLinks:
+ link.setRemoved()
+ link.backwardLink.setRemoved()
+ for host in self.device.hosts:
+ host.setRemoved()
+ return EventStates().PASS
+
+class DeviceUp( DeviceEvent ):
+ """
+ Generate a device up event (which re-adds this device in case the device is removed) giving its name
+ """
+ def __init__( self ):
+ DeviceEvent.__init__( self )
+ self.typeString = main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeString' ]
+ self.typeIndex = int( main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeIndex' ] )
+
+ def startDeviceEvent( self ):
+ assert self.device != None
+ with main.variableLock:
+ if self.device.isUp():
+ main.log.warn( "Device Up - device already up" )
+ return EventStates().ABORT
+ # Re-add the device
+ with main.mininetLock:
+ result = main.Mininet1.addSwitch( self.device.name, dpid=self.device.dpid[3:] )
+ if not result:
+ main.log.warn( "%s - failed to re-add device" % ( self.typeString ) )
+ return EventStates().FAIL
+ with main.variableLock:
+ self.device.bringUp()
+ # Re-add links
+ # We add host-device links first since we did the same in mininet topology file
+ # TODO: a more rubust way is to add links according to the port info of the device
+ for host in self.device.hosts:
+ # Add host-device link
+ with main.mininetLock:
+ result = main.Mininet1.addLink( self.device.name, host.name )
+ if not result:
+ main.log.warn( "%s - failed to re-connect host %s to device" % ( self.typeString, host.name ) )
+ return EventStates().FAIL
+ for link in self.device.outgoingLinks:
+ neighbor = link.deviceB
+ # Skip bringing up any link that connecting this device to a removed neighbor
+ if neighbor.isRemoved():
+ continue
+ with main.mininetLock:
+ result = main.Mininet1.addLink( self.device.name, neighbor.name )
+ if not result:
+ main.log.warn( "%s - failed to re-add link to %s" % ( self.typeString, neighbor.name ) )
+ return EventStates().FAIL
+ with main.variableLock:
+ link.bringUp()
+ link.backwardLink.bringUp()
+ # Re-assign mastership for the device
+ with main.mininetLock:
+ main.Mininet1.assignSwController( sw=self.device.name, ip=main.onosIPs )
+ # Re-discover hosts
+ for host in self.device.hosts:
+ correspondent = None
+ for h in main.hosts:
+ if h.isUp() and h != host:
+ correspondent = h
+ break
+ if correspondent == None:
+ with main.mininetLock:
+ main.Mininet1.pingall()
+ if main.enableIPv6:
+ main.Mininet1.pingall( protocol="IPv6" )
+ else:
+ ipv4Addr = None
+ ipv6Addr = None
+ for ipAddress in correspondent.ipAddresses:
+ if ipAddress.startswith( str( main.params[ 'TEST' ][ 'ipv6Prefix' ] ) ) and ipv6Addr == None:
+ ipv6Addr = ipAddress
+ elif ipAddress.startswith( str( main.params[ 'TEST' ][ 'ipv4Prefix' ] ) ) and ipv4Addr == None:
+ ipv4Addr = ipAddress
+ assert ipv4Addr != None
+ host.handle.pingHostSetAlternative( [ ipv4Addr ], 1 )
+ if main.enableIPv6:
+ assert ipv6Addr != None
+ host.handle.pingHostSetAlternative( [ ipv6Addr ], 1, True )
+ with main.variableLock:
+ host.bringUp()
+ return EventStates().PASS
diff --git a/TestON/tests/CHOTestMonkey/dependencies/events/ONOSEvent.py b/TestON/tests/CHOTestMonkey/dependencies/events/ONOSEvent.py
new file mode 100644
index 0000000..f4e2a89
--- /dev/null
+++ b/TestON/tests/CHOTestMonkey/dependencies/events/ONOSEvent.py
@@ -0,0 +1,194 @@
+"""
+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
+
+class ONOSEvent( Event ):
+ def __init__( self ):
+ Event.__init__( self )
+ self.ONOSIndex = -1
+
+ def startEvent( self, args ):
+ with self.eventLock:
+ 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:
+ main.log.warn( "%s - Not enough arguments: %s" % ( self.typeString, args ) )
+ result = EventStates().ABORT
+ elif len( args ) > 1:
+ main.log.warn( "%s - Too many arguments: %s" % ( self.typeString, args ) )
+ result = EventStates().ABORT
+ else:
+ index = int( args[ 0 ] )
+ if index < 1 or index > int( main.numCtrls ):
+ main.log.warn( "%s - invalid argument: %s" % ( self.typeString, index ) )
+ result = EventStates().ABORT
+ else:
+ self.ONOSIndex = index
+ result = self.startONOSEvent()
+ return result
+
+class ONOSDown( ONOSEvent ):
+ def __init__( self ):
+ ONOSEvent.__init__( self )
+ self.typeString = main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeString' ]
+ self.typeIndex= int( main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeIndex' ] )
+
+ def startONOSEvent( self ):
+ assert self.ONOSIndex != -1
+ with main.variableLock:
+ if not main.controllers[ self.ONOSIndex - 1 ].isUp():
+ main.log.warn( "ONOS Down - ONOS already down" )
+ return EventStates().ABORT
+ with main.ONOSbenchLock:
+ result = main.ONOSbench.onosStop( main.controllers[ self.ONOSIndex - 1 ].ip )
+ if not result:
+ main.log.warn( "%s - failed to bring down ONOS" % ( self.typeString ) )
+ return EventStates().FAIL
+ with main.variableLock:
+ main.controllers[ self.ONOSIndex - 1 ].bringDown()
+ return EventStates().PASS
+
+class ONOSUp( ONOSEvent ):
+ def __init__( self ):
+ ONOSEvent.__init__( self )
+ self.typeString = main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeString' ]
+ self.typeIndex= int( main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeIndex' ] )
+
+ def startONOSEvent( self ):
+ assert self.ONOSIndex != -1
+ with main.variableLock:
+ if main.controllers[ self.ONOSIndex - 1 ].isUp():
+ main.log.warn( "ONOS Up - ONOS already up" )
+ return EventStates().ABORT
+ with main.ONOSbenchLock:
+ startResult = main.ONOSbench.onosStart( main.controllers[ self.ONOSIndex - 1 ].ip )
+ if not startResult:
+ main.log.warn( "%s - failed to bring up ONOS" % ( self.typeString ) )
+ return EventStates().FAIL
+ else:
+ ONOSState = main.ONOSbench.isup( main.controllers[ self.ONOSIndex - 1 ].ip )
+ if not ONOSState:
+ main.log.warn( "%s - ONOS is not up" % ( self.typeString ) )
+ return EventStates().FAIL
+ else:
+ cliResult = main.controllers[ self.ONOSIndex - 1 ].startCLI()
+ if not cliResult:
+ main.log.warn( "%s - failed to start ONOS cli" % ( self.typeString ) )
+ return EventStates().FAIL
+ else:
+ with main.variableLock:
+ main.controllers[ self.ONOSIndex - 1 ].bringUp()
+ return EventStates().PASS
+
+class CfgEvent( Event ):
+ def __init__( self ):
+ Event.__init__( self )
+ self.component = ''
+ self.propName = ''
+ self.value = ''
+
+ def startEvent( self, args ):
+ with self.eventLock:
+ main.log.info( "%s - starting event" % ( self.typeString ) )
+ result = self.startCfgEvent( args )
+ return result
+
+class SetCfg( CfgEvent ):
+ def __init__( self ):
+ CfgEvent.__init__( self )
+ self.typeString = main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeString' ]
+ self.typeIndex= int( main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeIndex' ] )
+
+ def startCfgEvent( self, args ):
+ 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:
+ self.component = str( args[ 0 ] )
+ self.propName = str( args[ 1 ] )
+ self.value = str( args[ 2 ] )
+ assert self.component != '' and self.propName != '' and self.value != ''
+ index = -1
+ for controller in main.controllers:
+ if controller.isUp():
+ index = controller.index
+ if index == -1:
+ main.log.warn( "%s - No available controllers" %s ( self.typeString ) )
+ return EventStates().ABORT
+ controller = main.controllers[ index - 1 ]
+ with controller.CLILock:
+ result = controller.CLI.setCfg( component=self.component,
+ propName=self.propName,
+ value=self.value )
+ if not result:
+ main.log.warn( "%s - failed to set configuration" % ( self.typeString ) )
+ return EventStates().FAIL
+ return EventStates().PASS
+
+class SetFlowObj( CfgEvent ):
+ def __init__( self ):
+ CfgEvent.__init__( self )
+ self.typeString = main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeString' ]
+ self.typeIndex= int( main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeIndex' ] )
+
+ def startCfgEvent( self, args ):
+ if len( args ) < 1:
+ main.log.warn( "%s - Not enough arguments: %s" % ( self.typeString, args ) )
+ return EventStates().ABORT
+ elif len( args ) > 1:
+ main.log.warn( "%s - Too many arguments: %s" % ( self.typeString, args ) )
+ return EventStates().ABORT
+ elif args[ 0 ] != 'true' and args[ 0 ] != 'false':
+ main.log.warn( "%s - Invalid arguments: %s" % ( self.typeString, args ) )
+ return EventStates().ABORT
+ else:
+ self.component = 'org.onosproject.net.intent.impl.compiler.IntentConfigurableRegistrator'
+ self.propName = 'useFlowObjectives'
+ self.value = str( args[ 0 ] )
+ index = -1
+ for controller in main.controllers:
+ if controller.isUp():
+ index = controller.index
+ if index == -1:
+ main.log.warn( "%s - No available controllers" %s ( self.typeString ) )
+ return EventStates().ABORT
+ controller = main.controllers[ index - 1 ]
+ with controller.CLILock:
+ result = controller.CLI.setCfg( component=self.component,
+ propName=self.propName,
+ value=self.value )
+ if not result:
+ main.log.warn( "%s - failed to set configuration" % ( self.typeString ) )
+ return EventStates().FAIL
+ return EventStates().PASS
+
+class BalanceMasters( Event ):
+ def __init__( self ):
+ Event.__init__( self )
+ self.typeString = main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeString' ]
+ self.typeIndex= int( main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeIndex' ] )
+
+ def startEvent( self, args=None ):
+ with self.eventLock:
+ main.log.info( "%s - starting event" % ( self.typeString ) )
+ index = -1
+ for controller in main.controllers:
+ if controller.isUp():
+ index = controller.index
+ if index == -1:
+ main.log.warn( "%s - No available controllers" %s ( self.typeString ) )
+ return EventStates().ABORT
+ controller = main.controllers[ index - 1 ]
+ with controller.CLILock:
+ result = controller.CLI.balanceMasters()
+ if not result:
+ main.log.warn( "%s - failed to balance masters" % ( self.typeString ) )
+ return EventStates().FAIL
+ return EventStates().PASS
+
diff --git a/TestON/tests/CHOTestMonkey/dependencies/events/TestEvent.py b/TestON/tests/CHOTestMonkey/dependencies/events/TestEvent.py
new file mode 100644
index 0000000..605e43f
--- /dev/null
+++ b/TestON/tests/CHOTestMonkey/dependencies/events/TestEvent.py
@@ -0,0 +1,59 @@
+"""
+This file contains classes for CHOTestMonkey that are related to check event
+Author: you@onlab.us
+"""
+from tests.CHOTestMonkey.dependencies.events.Event import EventType, EventStates, Event
+
+class TestEvent( Event ):
+ def __init__( self ):
+ Event.__init__( self )
+
+ def startTestEvent( self ):
+ return EventStates().PASS
+
+ def startEvent( self, args ):
+ with self.eventLock:
+ main.log.info( "%s - starting event" % ( self.typeString ) )
+ result = self.startTestEvent( args )
+ return result
+
+class TestPause( TestEvent ):
+ def __init__( self ):
+ TestEvent.__init__( self )
+ self.typeString = main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeString' ]
+ self.typeIndex = int( main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeIndex' ] )
+
+ def startTestEvent( self, args=None ):
+ result = EventStates().PASS
+ main.eventScheduler.setRunningState( False )
+ return result
+
+class TestResume( TestEvent ):
+ def __init__( self ):
+ TestEvent.__init__( self )
+ self.typeString = main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeString' ]
+ self.typeIndex = int( main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeIndex' ] )
+
+ def startTestEvent( self, args=None ):
+ result = EventStates().PASS
+ main.eventScheduler.setRunningState( True )
+ return result
+
+class TestSleep( TestEvent ):
+ def __init__( self ):
+ TestEvent.__init__( self )
+ self.typeString = main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeString' ]
+ self.typeIndex = int( main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeIndex' ] )
+
+ def startTestEvent( self, args ):
+ import time
+ result = EventStates().PASS
+ if len( args ) < 1:
+ main.log.warn( "%s - Not enough arguments: %s" % ( self.typeString, args ) )
+ result = EventStates().ABORT
+ elif len( args ) > 1:
+ main.log.warn( "%s - Too many arguments: %s" % ( self.typeString, args ) )
+ result = EventStates().ABORT
+ sleepTime = int( args[ 0 ] )
+ time.sleep( sleepTime )
+ return result
diff --git a/TestON/tests/CHOTestMonkey/dependencies/events/__init__.py b/TestON/tests/CHOTestMonkey/dependencies/events/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/TestON/tests/CHOTestMonkey/dependencies/events/__init__.py
diff --git a/TestON/tests/CHOTestMonkey/dependencies/topologies/__init__.py b/TestON/tests/CHOTestMonkey/dependencies/topologies/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/TestON/tests/CHOTestMonkey/dependencies/topologies/__init__.py
diff --git a/TestON/tests/CHOTestMonkey/dependencies/topologies/topoAtt.py b/TestON/tests/CHOTestMonkey/dependencies/topologies/topoAtt.py
new file mode 100755
index 0000000..4291f8b
--- /dev/null
+++ b/TestON/tests/CHOTestMonkey/dependencies/topologies/topoAtt.py
@@ -0,0 +1,182 @@
+#!/usr/bin/python
+
+"""
+Custom topology for Mininet
+"""
+from mininet.topo import Topo
+from mininet.net import Mininet
+from mininet.node import RemoteController
+from mininet.node import Node
+from mininet.node import CPULimitedHost
+from mininet.link import TCLink
+from mininet.cli import CLI
+from mininet.log import setLogLevel
+from mininet.util import dumpNodeConnections
+from mininet.node import ( UserSwitch, OVSSwitch, IVSSwitch )
+
+class attTopo( Topo ):
+
+ def __init__( self, **opts ):
+ "Create a topology."
+
+ # Initialize Topology
+ Topo.__init__( self, **opts )
+
+ # add nodes, switches first...
+ NY54 = self.addSwitch( 's1' )
+ CMBR = self.addSwitch( 's2' )
+ CHCG = self.addSwitch( 's3' )
+ CLEV = self.addSwitch( 's4' )
+ RLGH = self.addSwitch( 's5' )
+ ATLN = self.addSwitch( 's6' )
+ PHLA = self.addSwitch( 's7' )
+ WASH = self.addSwitch( 's8' )
+ NSVL = self.addSwitch( 's9' )
+ STLS = self.addSwitch( 's10' )
+ NWOR = self.addSwitch( 's11' )
+ HSTN = self.addSwitch( 's12' )
+ SNAN = self.addSwitch( 's13' )
+ DLLS = self.addSwitch( 's14' )
+ ORLD = self.addSwitch( 's15' )
+ DNVR = self.addSwitch( 's16' )
+ KSCY = self.addSwitch( 's17' )
+ SNFN = self.addSwitch( 's18' )
+ SCRM = self.addSwitch( 's19' )
+ PTLD = self.addSwitch( 's20' )
+ STTL = self.addSwitch( 's21' )
+ SLKC = self.addSwitch( 's22' )
+ LA03 = self.addSwitch( 's23' )
+ SNDG = self.addSwitch( 's24' )
+ PHNX = self.addSwitch( 's25' )
+
+ # ... and now hosts
+ NY54_host = self.addHost( 'h1' )
+ CMBR_host = self.addHost( 'h2' )
+ CHCG_host = self.addHost( 'h3' )
+ CLEV_host = self.addHost( 'h4' )
+ RLGH_host = self.addHost( 'h5' )
+ ATLN_host = self.addHost( 'h6' )
+ PHLA_host = self.addHost( 'h7' )
+ WASH_host = self.addHost( 'h8' )
+ NSVL_host = self.addHost( 'h9' )
+ STLS_host = self.addHost( 'h10' )
+ NWOR_host = self.addHost( 'h11' )
+ HSTN_host = self.addHost( 'h12' )
+ SNAN_host = self.addHost( 'h13' )
+ DLLS_host = self.addHost( 'h14' )
+ ORLD_host = self.addHost( 'h15' )
+ DNVR_host = self.addHost( 'h16' )
+ KSCY_host = self.addHost( 'h17' )
+ SNFN_host = self.addHost( 'h18' )
+ SCRM_host = self.addHost( 'h19' )
+ PTLD_host = self.addHost( 'h20' )
+ STTL_host = self.addHost( 'h21' )
+ SLKC_host = self.addHost( 'h22' )
+ LA03_host = self.addHost( 'h23' )
+ SNDG_host = self.addHost( 'h24' )
+ PHNX_host = self.addHost( 'h25' )
+
+ # add edges between switch and corresponding host
+ self.addLink( NY54 , NY54_host )
+ self.addLink( CMBR , CMBR_host )
+ self.addLink( CHCG , CHCG_host )
+ self.addLink( CLEV , CLEV_host )
+ self.addLink( RLGH , RLGH_host )
+ self.addLink( ATLN , ATLN_host )
+ self.addLink( PHLA , PHLA_host )
+ self.addLink( WASH , WASH_host )
+ self.addLink( NSVL , NSVL_host )
+ self.addLink( STLS , STLS_host )
+ self.addLink( NWOR , NWOR_host )
+ self.addLink( HSTN , HSTN_host )
+ self.addLink( SNAN , SNAN_host )
+ self.addLink( DLLS , DLLS_host )
+ self.addLink( ORLD , ORLD_host )
+ self.addLink( DNVR , DNVR_host )
+ self.addLink( KSCY , KSCY_host )
+ self.addLink( SNFN , SNFN_host )
+ self.addLink( SCRM , SCRM_host )
+ self.addLink( PTLD , PTLD_host )
+ self.addLink( STTL , STTL_host )
+ self.addLink( SLKC , SLKC_host )
+ self.addLink( LA03 , LA03_host )
+ self.addLink( SNDG , SNDG_host )
+ self.addLink( PHNX , PHNX_host )
+
+ # add edges between switches
+ self.addLink( NY54 , CMBR, bw=10, delay='0.979030824185ms')
+ self.addLink( NY54 , CHCG, bw=10, delay='0.806374975652ms')
+ self.addLink( NY54 , PHLA, bw=10, delay='0.686192970166ms')
+ self.addLink( NY54 , WASH, bw=10, delay='0.605826192092ms')
+ self.addLink( CMBR , PHLA, bw=10, delay='1.4018238197ms')
+ self.addLink( CHCG , CLEV, bw=10, delay='0.232315346482ms')
+ self.addLink( CHCG , PHLA, bw=10, delay='1.07297714274ms')
+ self.addLink( CHCG , STLS, bw=10, delay='1.12827896944ms')
+ self.addLink( CHCG , DNVR, bw=10, delay='1.35964770335ms')
+ self.addLink( CHCG , KSCY, bw=10, delay='1.5199778541ms')
+ self.addLink( CHCG , SNFN, bw=10, delay='0.620743405435ms')
+ self.addLink( CHCG , STTL, bw=10, delay='0.93027212534ms')
+ self.addLink( CHCG , SLKC, bw=10, delay='0.735621751348ms')
+ self.addLink( CLEV , NSVL, bw=10, delay='0.523419372248ms')
+ self.addLink( CLEV , STLS, bw=10, delay='1.00360290845ms')
+ self.addLink( CLEV , PHLA, bw=10, delay='0.882912133249ms')
+ self.addLink( RLGH , ATLN, bw=10, delay='1.1644489729ms')
+ self.addLink( RLGH , WASH, bw=10, delay='1.48176810502ms')
+ self.addLink( ATLN , WASH, bw=10, delay='0.557636936322ms')
+ self.addLink( ATLN , NSVL, bw=10, delay='1.32869749865ms')
+ self.addLink( ATLN , STLS, bw=10, delay='0.767705554748ms')
+ self.addLink( ATLN , DLLS, bw=10, delay='0.544782086448ms')
+ self.addLink( ATLN , ORLD, bw=10, delay='1.46119152532ms')
+ self.addLink( PHLA , WASH, bw=10, delay='0.372209320106ms')
+ self.addLink( NSVL , STLS, bw=10, delay='1.43250491305ms')
+ self.addLink( NSVL , DLLS, bw=10, delay='1.67698215288ms')
+ self.addLink( STLS , DLLS, bw=10, delay='0.256389964194ms')
+ self.addLink( STLS , KSCY, bw=10, delay='0.395511571791ms')
+ self.addLink( STLS , LA03, bw=10, delay='0.257085227363ms')
+ self.addLink( NWOR , HSTN, bw=10, delay='0.0952906633914ms')
+ self.addLink( NWOR , DLLS, bw=10, delay='1.60231329739ms')
+ self.addLink( NWOR , ORLD, bw=10, delay='0.692731063896ms')
+ self.addLink( HSTN , SNAN, bw=10, delay='0.284150653798ms')
+ self.addLink( HSTN , DLLS, bw=10, delay='1.65690128332ms')
+ self.addLink( HSTN , ORLD, bw=10, delay='0.731886304782ms')
+ self.addLink( SNAN , PHNX, bw=10, delay='1.34258627257ms')
+ self.addLink( SNAN , DLLS, bw=10, delay='1.50063532341ms')
+ self.addLink( DLLS , DNVR, bw=10, delay='0.251471593235ms')
+ self.addLink( DLLS , KSCY, bw=10, delay='0.18026026737ms')
+ self.addLink( DLLS , SNFN, bw=10, delay='0.74304274592ms')
+ self.addLink( DLLS , LA03, bw=10, delay='0.506439293357ms')
+ self.addLink( DNVR , KSCY, bw=10, delay='0.223328790403ms')
+ self.addLink( DNVR , SNFN, bw=10, delay='0.889017541903ms')
+ self.addLink( DNVR , SLKC, bw=10, delay='0.631898982721ms')
+ self.addLink( KSCY , SNFN, bw=10, delay='0.922778522233ms')
+ self.addLink( SNFN , SCRM, bw=10, delay='0.630352278097ms')
+ self.addLink( SNFN , PTLD, bw=10, delay='0.828572513655ms')
+ self.addLink( SNFN , STTL, bw=10, delay='1.54076081649ms')
+ self.addLink( SNFN , SLKC, bw=10, delay='0.621507502625ms')
+ self.addLink( SNFN , LA03, bw=10, delay='0.602936230151ms')
+ self.addLink( SCRM , SLKC, bw=10, delay='0.461350343644ms')
+ self.addLink( PTLD , STTL, bw=10, delay='1.17591515181ms')
+ self.addLink( SLKC , LA03, bw=10, delay='0.243225267023ms')
+ self.addLink( LA03 , SNDG, bw=10, delay='0.681264950821ms')
+ self.addLink( LA03 , PHNX, bw=10, delay='0.343709457969ms')
+ self.addLink( SNDG , PHNX, bw=10, delay='0.345064487693ms')
+
+topos = { 'att': ( lambda: attTopo() ) }
+
+# HERE THE CODE DEFINITION OF THE TOPOLOGY ENDS
+
+def setupNetwork():
+ "Create network"
+ topo = attTopo()
+ #if controller_ip == '':
+ #controller_ip = '10.0.2.2';
+ # controller_ip = '127.0.0.1';
+ network = Mininet(topo=topo, link=TCLink, autoSetMacs=True, controller=None)
+ network.start()
+ CLI( network )
+ network.stop()
+
+if __name__ == '__main__':
+ setLogLevel('info')
+ #setLogLevel('debug')
+ setupNetwork()
diff --git a/TestON/tests/CHOTestMonkey/dependencies/topologies/topoAttIpv6.py b/TestON/tests/CHOTestMonkey/dependencies/topologies/topoAttIpv6.py
new file mode 100755
index 0000000..f135c81
--- /dev/null
+++ b/TestON/tests/CHOTestMonkey/dependencies/topologies/topoAttIpv6.py
@@ -0,0 +1,188 @@
+#!/usr/bin/python
+
+"""
+Custom topology for Mininet
+"""
+from mininet.topo import Topo
+from mininet.net import Mininet
+from mininet.node import Host, RemoteController
+from mininet.node import Node
+from mininet.node import CPULimitedHost
+from mininet.link import TCLink
+from mininet.cli import CLI
+from mininet.log import setLogLevel
+from mininet.util import dumpNodeConnections
+from mininet.node import ( UserSwitch, OVSSwitch, IVSSwitch )
+
+class dualStackHost( Host ):
+ def config( self, v6Addr='1000::1/64', **params ):
+ r = super( Host, self ).config( **params )
+ intf = self.defaultIntf()
+ self.cmd( 'ip -6 addr add %s dev %s' % ( v6Addr, intf ) )
+ return r
+
+class attTopo( Topo ):
+
+ def __init__( self, **opts ):
+ "Create a topology."
+
+ # Initialize Topology
+ Topo.__init__( self, **opts )
+
+ NY54 = self.addSwitch( 's1' )
+ CMBR = self.addSwitch( 's2' )
+ CHCG = self.addSwitch( 's3' )
+ CLEV = self.addSwitch( 's4' )
+ RLGH = self.addSwitch( 's5' )
+ ATLN = self.addSwitch( 's6' )
+ PHLA = self.addSwitch( 's7' )
+ WASH = self.addSwitch( 's8' )
+ NSVL = self.addSwitch( 's9' )
+ STLS = self.addSwitch( 's10' )
+ NWOR = self.addSwitch( 's11' )
+ HSTN = self.addSwitch( 's12' )
+ SNAN = self.addSwitch( 's13' )
+ DLLS = self.addSwitch( 's14' )
+ ORLD = self.addSwitch( 's15' )
+ DNVR = self.addSwitch( 's16' )
+ KSCY = self.addSwitch( 's17' )
+ SNFN = self.addSwitch( 's18' )
+ SCRM = self.addSwitch( 's19' )
+ PTLD = self.addSwitch( 's20' )
+ STTL = self.addSwitch( 's21' )
+ SLKC = self.addSwitch( 's22' )
+ LA03 = self.addSwitch( 's23' )
+ SNDG = self.addSwitch( 's24' )
+ PHNX = self.addSwitch( 's25' )
+
+ # ... and now hosts
+ NY54_host = self.addHost( 'h1', ip='10.1.0.1/24', cls=dualStackHost, v6Addr='1000::1/64' )
+ CMBR_host = self.addHost( 'h2', ip='10.1.0.2/24', cls=dualStackHost, v6Addr='1000::2/64' )
+ CHCG_host = self.addHost( 'h3', ip='10.1.0.3/24', cls=dualStackHost, v6Addr='1000::3/64' )
+ CLEV_host = self.addHost( 'h4', ip='10.1.0.4/24', cls=dualStackHost, v6Addr='1000::4/64' )
+ RLGH_host = self.addHost( 'h5', ip='10.1.0.5/24', cls=dualStackHost, v6Addr='1000::5/64' )
+ ATLN_host = self.addHost( 'h6', ip='10.1.0.6/24', cls=dualStackHost, v6Addr='1000::6/64' )
+ PHLA_host = self.addHost( 'h7', ip='10.1.0.7/24', cls=dualStackHost, v6Addr='1000::7/64' )
+ WASH_host = self.addHost( 'h8', ip='10.1.0.8/24', cls=dualStackHost, v6Addr='1000::8/64' )
+ NSVL_host = self.addHost( 'h9', ip='10.1.0.9/24', cls=dualStackHost, v6Addr='1000::9/64' )
+ STLS_host = self.addHost( 'h10', ip='10.1.0.10/24', cls=dualStackHost, v6Addr='1000::10/64' )
+ NWOR_host = self.addHost( 'h11', ip='10.1.0.11/24', cls=dualStackHost, v6Addr='1000::11/64' )
+ HSTN_host = self.addHost( 'h12', ip='10.1.0.12/24', cls=dualStackHost, v6Addr='1000::12/64' )
+ SNAN_host = self.addHost( 'h13', ip='10.1.0.13/24', cls=dualStackHost, v6Addr='1000::13/64' )
+ DLLS_host = self.addHost( 'h14', ip='10.1.0.14/24', cls=dualStackHost, v6Addr='1000::14/64' )
+ ORLD_host = self.addHost( 'h15', ip='10.1.0.15/24', cls=dualStackHost, v6Addr='1000::15/64' )
+ DNVR_host = self.addHost( 'h16', ip='10.1.0.16/24', cls=dualStackHost, v6Addr='1000::16/64' )
+ KSCY_host = self.addHost( 'h17', ip='10.1.0.17/24', cls=dualStackHost, v6Addr='1000::17/64' )
+ SNFN_host = self.addHost( 'h18', ip='10.1.0.18/24', cls=dualStackHost, v6Addr='1000::18/64' )
+ SCRM_host = self.addHost( 'h19', ip='10.1.0.19/24', cls=dualStackHost, v6Addr='1000::19/64' )
+ PTLD_host = self.addHost( 'h20', ip='10.1.0.20/24', cls=dualStackHost, v6Addr='1000::20/64' )
+ STTL_host = self.addHost( 'h21', ip='10.1.0.21/24', cls=dualStackHost, v6Addr='1000::21/64' )
+ SLKC_host = self.addHost( 'h22', ip='10.1.0.22/24', cls=dualStackHost, v6Addr='1000::22/64' )
+ LA03_host = self.addHost( 'h23', ip='10.1.0.23/24', cls=dualStackHost, v6Addr='1000::23/64' )
+ SNDG_host = self.addHost( 'h24', ip='10.1.0.24/24', cls=dualStackHost, v6Addr='1000::24/64' )
+ PHNX_host = self.addHost( 'h25', ip='10.1.0.25/24', cls=dualStackHost, v6Addr='1000::25/64' )
+
+ # add edges between switch and corresponding host
+ self.addLink( NY54 , NY54_host )
+ self.addLink( CMBR , CMBR_host )
+ self.addLink( CHCG , CHCG_host )
+ self.addLink( CLEV , CLEV_host )
+ self.addLink( RLGH , RLGH_host )
+ self.addLink( ATLN , ATLN_host )
+ self.addLink( PHLA , PHLA_host )
+ self.addLink( WASH , WASH_host )
+ self.addLink( NSVL , NSVL_host )
+ self.addLink( STLS , STLS_host )
+ self.addLink( NWOR , NWOR_host )
+ self.addLink( HSTN , HSTN_host )
+ self.addLink( SNAN , SNAN_host )
+ self.addLink( DLLS , DLLS_host )
+ self.addLink( ORLD , ORLD_host )
+ self.addLink( DNVR , DNVR_host )
+ self.addLink( KSCY , KSCY_host )
+ self.addLink( SNFN , SNFN_host )
+ self.addLink( SCRM , SCRM_host )
+ self.addLink( PTLD , PTLD_host )
+ self.addLink( STTL , STTL_host )
+ self.addLink( SLKC , SLKC_host )
+ self.addLink( LA03 , LA03_host )
+ self.addLink( SNDG , SNDG_host )
+ self.addLink( PHNX , PHNX_host )
+
+ # add edges between switches
+ self.addLink( NY54 , CMBR, bw=10, delay='0.979030824185ms')
+ self.addLink( NY54 , CHCG, bw=10, delay='0.806374975652ms')
+ self.addLink( NY54 , PHLA, bw=10, delay='0.686192970166ms')
+ self.addLink( NY54 , WASH, bw=10, delay='0.605826192092ms')
+ self.addLink( CMBR , PHLA, bw=10, delay='1.4018238197ms')
+ self.addLink( CHCG , CLEV, bw=10, delay='0.232315346482ms')
+ self.addLink( CHCG , PHLA, bw=10, delay='1.07297714274ms')
+ self.addLink( CHCG , STLS, bw=10, delay='1.12827896944ms')
+ self.addLink( CHCG , DNVR, bw=10, delay='1.35964770335ms')
+ self.addLink( CHCG , KSCY, bw=10, delay='1.5199778541ms')
+ self.addLink( CHCG , SNFN, bw=10, delay='0.620743405435ms')
+ self.addLink( CHCG , STTL, bw=10, delay='0.93027212534ms')
+ self.addLink( CHCG , SLKC, bw=10, delay='0.735621751348ms')
+ self.addLink( CLEV , NSVL, bw=10, delay='0.523419372248ms')
+ self.addLink( CLEV , STLS, bw=10, delay='1.00360290845ms')
+ self.addLink( CLEV , PHLA, bw=10, delay='0.882912133249ms')
+ self.addLink( RLGH , ATLN, bw=10, delay='1.1644489729ms')
+ self.addLink( RLGH , WASH, bw=10, delay='1.48176810502ms')
+ self.addLink( ATLN , WASH, bw=10, delay='0.557636936322ms')
+ self.addLink( ATLN , NSVL, bw=10, delay='1.32869749865ms')
+ self.addLink( ATLN , STLS, bw=10, delay='0.767705554748ms')
+ self.addLink( ATLN , DLLS, bw=10, delay='0.544782086448ms')
+ self.addLink( ATLN , ORLD, bw=10, delay='1.46119152532ms')
+ self.addLink( PHLA , WASH, bw=10, delay='0.372209320106ms')
+ self.addLink( NSVL , STLS, bw=10, delay='1.43250491305ms')
+ self.addLink( NSVL , DLLS, bw=10, delay='1.67698215288ms')
+ self.addLink( STLS , DLLS, bw=10, delay='0.256389964194ms')
+ self.addLink( STLS , KSCY, bw=10, delay='0.395511571791ms')
+ self.addLink( STLS , LA03, bw=10, delay='0.257085227363ms')
+ self.addLink( NWOR , HSTN, bw=10, delay='0.0952906633914ms')
+ self.addLink( NWOR , DLLS, bw=10, delay='1.60231329739ms')
+ self.addLink( NWOR , ORLD, bw=10, delay='0.692731063896ms')
+ self.addLink( HSTN , SNAN, bw=10, delay='0.284150653798ms')
+ self.addLink( HSTN , DLLS, bw=10, delay='1.65690128332ms')
+ self.addLink( HSTN , ORLD, bw=10, delay='0.731886304782ms')
+ self.addLink( SNAN , PHNX, bw=10, delay='1.34258627257ms')
+ self.addLink( SNAN , DLLS, bw=10, delay='1.50063532341ms')
+ self.addLink( DLLS , DNVR, bw=10, delay='0.251471593235ms')
+ self.addLink( DLLS , KSCY, bw=10, delay='0.18026026737ms')
+ self.addLink( DLLS , SNFN, bw=10, delay='0.74304274592ms')
+ self.addLink( DLLS , LA03, bw=10, delay='0.506439293357ms')
+ self.addLink( DNVR , KSCY, bw=10, delay='0.223328790403ms')
+ self.addLink( DNVR , SNFN, bw=10, delay='0.889017541903ms')
+ self.addLink( DNVR , SLKC, bw=10, delay='0.631898982721ms')
+ self.addLink( KSCY , SNFN, bw=10, delay='0.922778522233ms')
+ self.addLink( SNFN , SCRM, bw=10, delay='0.630352278097ms')
+ self.addLink( SNFN , PTLD, bw=10, delay='0.828572513655ms')
+ self.addLink( SNFN , STTL, bw=10, delay='1.54076081649ms')
+ self.addLink( SNFN , SLKC, bw=10, delay='0.621507502625ms')
+ self.addLink( SNFN , LA03, bw=10, delay='0.602936230151ms')
+ self.addLink( SCRM , SLKC, bw=10, delay='0.461350343644ms')
+ self.addLink( PTLD , STTL, bw=10, delay='1.17591515181ms')
+ self.addLink( SLKC , LA03, bw=10, delay='0.243225267023ms')
+ self.addLink( LA03 , SNDG, bw=10, delay='0.681264950821ms')
+ self.addLink( LA03 , PHNX, bw=10, delay='0.343709457969ms')
+ self.addLink( SNDG , PHNX, bw=10, delay='0.345064487693ms')
+
+topos = { 'att': ( lambda: attTopo() ) }
+
+# HERE THE CODE DEFINITION OF THE TOPOLOGY ENDS
+
+def setupNetwork():
+ "Create network"
+ topo = attTopo()
+ #if controller_ip == '':
+ #controller_ip = '10.0.2.2';
+ # controller_ip = '127.0.0.1';
+ network = Mininet(topo=topo, link=TCLink, autoSetMacs=True, controller=None)
+ network.start()
+ CLI( network )
+ network.stop()
+
+if __name__ == '__main__':
+ setLogLevel('info')
+ #setLogLevel('debug')
+ setupNetwork()
diff --git a/TestON/tests/CHOTestMonkey/dependencies/topologies/topoChordal.py b/TestON/tests/CHOTestMonkey/dependencies/topologies/topoChordal.py
new file mode 100755
index 0000000..542c3ed
--- /dev/null
+++ b/TestON/tests/CHOTestMonkey/dependencies/topologies/topoChordal.py
@@ -0,0 +1,422 @@
+#!/usr/bin/python
+"""
+"""
+from mininet.topo import Topo
+from mininet.net import Mininet
+from mininet.node import RemoteController
+from mininet.node import Node
+from mininet.node import CPULimitedHost
+from mininet.link import TCLink
+from mininet.cli import CLI
+from mininet.log import setLogLevel
+from mininet.util import dumpNodeConnections
+from mininet.node import ( UserSwitch, OVSSwitch, IVSSwitch )
+
+class chordalTopo( Topo ):
+
+ def __init__( self, **opts ):
+ "Create a topology."
+
+ # Initialize Topology
+ Topo.__init__( self, **opts )
+
+ # add nodes, switches first...
+ s1 = self.addSwitch( 's1' )
+ s2 = self.addSwitch( 's2' )
+ s3 = self.addSwitch( 's3' )
+ s4 = self.addSwitch( 's4' )
+ s5 = self.addSwitch( 's5' )
+ s6 = self.addSwitch( 's6' )
+ s7 = self.addSwitch( 's7' )
+ s8 = self.addSwitch( 's8' )
+ s9 = self.addSwitch( 's9' )
+ s10 = self.addSwitch( 's10' )
+ s11 = self.addSwitch( 's11' )
+ s12 = self.addSwitch( 's12' )
+ s13 = self.addSwitch( 's13' )
+ s14 = self.addSwitch( 's14' )
+ s15 = self.addSwitch( 's15' )
+ s16 = self.addSwitch( 's16' )
+ s17 = self.addSwitch( 's17' )
+ s18 = self.addSwitch( 's18' )
+ s19 = self.addSwitch( 's19' )
+ s20 = self.addSwitch( 's20' )
+ s21 = self.addSwitch( 's21' )
+ s22 = self.addSwitch( 's22' )
+ s23 = self.addSwitch( 's23' )
+ s24 = self.addSwitch( 's24' )
+ s25 = self.addSwitch( 's25' )
+
+ # ... and now hosts
+ s1_host = self.addHost( 'h1' )
+ s2_host = self.addHost( 'h2' )
+ s3_host = self.addHost( 'h3' )
+ s4_host = self.addHost( 'h4' )
+ s5_host = self.addHost( 'h5' )
+ s6_host = self.addHost( 'h6' )
+ s7_host = self.addHost( 'h7' )
+ s8_host = self.addHost( 'h8' )
+ s9_host = self.addHost( 'h9' )
+ s10_host = self.addHost( 'h10' )
+ s11_host = self.addHost( 'h11' )
+ s12_host = self.addHost( 'h12' )
+ s13_host = self.addHost( 'h13' )
+ s14_host = self.addHost( 'h14' )
+ s15_host = self.addHost( 'h15' )
+ s16_host = self.addHost( 'h16' )
+ s17_host = self.addHost( 'h17' )
+ s18_host = self.addHost( 'h18' )
+ s19_host = self.addHost( 'h19' )
+ s20_host = self.addHost( 'h20' )
+ s21_host = self.addHost( 'h21' )
+ s22_host = self.addHost( 'h22' )
+ s23_host = self.addHost( 'h23' )
+ s24_host = self.addHost( 'h24' )
+ s25_host = self.addHost( 'h25' )
+
+ # add edges between switch and corresponding host
+ self.addLink( s1 , s1_host )
+ self.addLink( s2 , s2_host )
+ self.addLink( s3 , s3_host )
+ self.addLink( s4 , s4_host )
+ self.addLink( s5 , s5_host )
+ self.addLink( s6 , s6_host )
+ self.addLink( s7 , s7_host )
+ self.addLink( s8 , s8_host )
+ self.addLink( s9 , s9_host )
+ self.addLink( s10 , s10_host )
+ self.addLink( s11 , s11_host )
+ self.addLink( s12 , s12_host )
+ self.addLink( s13 , s13_host )
+ self.addLink( s14 , s14_host )
+ self.addLink( s15 , s15_host )
+ self.addLink( s16 , s16_host )
+ self.addLink( s17 , s17_host )
+ self.addLink( s18 , s18_host )
+ self.addLink( s19 , s19_host )
+ self.addLink( s20 , s20_host )
+ self.addLink( s21 , s21_host )
+ self.addLink( s22 , s22_host )
+ self.addLink( s23 , s23_host )
+ self.addLink( s24 , s24_host )
+ self.addLink( s25 , s25_host )
+ self.addLink(s1, s2)
+ self.addLink(s1, s3)
+ self.addLink(s1, s4)
+ self.addLink(s1, s5)
+ self.addLink(s1, s6)
+ self.addLink(s1, s7)
+ self.addLink(s1, s8)
+ self.addLink(s1, s9)
+ self.addLink(s1, s10)
+ self.addLink(s1, s11)
+ self.addLink(s1, s12)
+ self.addLink(s1, s13)
+ self.addLink(s1, s14)
+ self.addLink(s1, s15)
+ self.addLink(s1, s16)
+ self.addLink(s1, s17)
+ self.addLink(s1, s18)
+ self.addLink(s1, s19)
+ self.addLink(s1, s20)
+ self.addLink(s1, s21)
+ self.addLink(s1, s22)
+ self.addLink(s1, s23)
+ self.addLink(s1, s24)
+ self.addLink(s1, s25)
+ self.addLink(s2, s3)
+ self.addLink(s2, s4)
+ self.addLink(s2, s5)
+ self.addLink(s2, s6)
+ self.addLink(s2, s7)
+ self.addLink(s2, s8)
+ self.addLink(s2, s9)
+ self.addLink(s2, s10)
+ self.addLink(s2, s11)
+ self.addLink(s2, s12)
+ self.addLink(s2, s13)
+ self.addLink(s2, s14)
+ self.addLink(s2, s15)
+ self.addLink(s2, s16)
+ self.addLink(s2, s17)
+ self.addLink(s2, s18)
+ self.addLink(s2, s19)
+ self.addLink(s2, s20)
+ self.addLink(s2, s21)
+ self.addLink(s2, s22)
+ self.addLink(s2, s23)
+ self.addLink(s2, s24)
+ self.addLink(s2, s25)
+ self.addLink(s3, s4)
+ self.addLink(s3, s5)
+ self.addLink(s3, s6)
+ self.addLink(s3, s7)
+ self.addLink(s3, s8)
+ self.addLink(s3, s9)
+ self.addLink(s3, s10)
+ self.addLink(s3, s11)
+ self.addLink(s3, s12)
+ self.addLink(s3, s13)
+ self.addLink(s3, s14)
+ self.addLink(s3, s15)
+ self.addLink(s3, s16)
+ self.addLink(s3, s17)
+ self.addLink(s3, s18)
+ self.addLink(s3, s19)
+ self.addLink(s3, s20)
+ self.addLink(s3, s21)
+ self.addLink(s3, s22)
+ self.addLink(s3, s23)
+ self.addLink(s3, s24)
+ self.addLink(s3, s25)
+ self.addLink(s4, s5)
+ self.addLink(s4, s6)
+ self.addLink(s4, s7)
+ self.addLink(s4, s8)
+ self.addLink(s4, s9)
+ self.addLink(s4, s10)
+ self.addLink(s4, s11)
+ self.addLink(s4, s12)
+ self.addLink(s4, s13)
+ self.addLink(s4, s14)
+ self.addLink(s4, s15)
+ self.addLink(s4, s16)
+ self.addLink(s4, s17)
+ self.addLink(s4, s18)
+ self.addLink(s4, s19)
+ self.addLink(s4, s20)
+ self.addLink(s4, s21)
+ self.addLink(s4, s22)
+ self.addLink(s4, s23)
+ self.addLink(s4, s24)
+ self.addLink(s4, s25)
+ self.addLink(s5, s6)
+ self.addLink(s5, s7)
+ self.addLink(s5, s8)
+ self.addLink(s5, s9)
+ self.addLink(s5, s10)
+ self.addLink(s5, s11)
+ self.addLink(s5, s12)
+ self.addLink(s5, s13)
+ self.addLink(s5, s14)
+ self.addLink(s5, s15)
+ self.addLink(s5, s16)
+ self.addLink(s5, s17)
+ self.addLink(s5, s18)
+ self.addLink(s5, s19)
+ self.addLink(s5, s20)
+ self.addLink(s5, s21)
+ self.addLink(s5, s22)
+ self.addLink(s5, s23)
+ self.addLink(s5, s24)
+ self.addLink(s5, s25)
+ self.addLink(s6, s7)
+ self.addLink(s6, s8)
+ self.addLink(s6, s9)
+ self.addLink(s6, s10)
+ self.addLink(s6, s11)
+ self.addLink(s6, s12)
+ self.addLink(s6, s13)
+ self.addLink(s6, s14)
+ self.addLink(s6, s15)
+ self.addLink(s6, s16)
+ self.addLink(s6, s17)
+ self.addLink(s6, s18)
+ self.addLink(s6, s19)
+ self.addLink(s6, s20)
+ self.addLink(s6, s21)
+ self.addLink(s6, s22)
+ self.addLink(s6, s23)
+ self.addLink(s6, s24)
+ self.addLink(s6, s25)
+ self.addLink(s7, s8)
+ self.addLink(s7, s9)
+ self.addLink(s7, s10)
+ self.addLink(s7, s11)
+ self.addLink(s7, s12)
+ self.addLink(s7, s13)
+ self.addLink(s7, s14)
+ self.addLink(s7, s15)
+ self.addLink(s7, s16)
+ self.addLink(s7, s17)
+ self.addLink(s7, s18)
+ self.addLink(s7, s19)
+ self.addLink(s7, s20)
+ self.addLink(s7, s21)
+ self.addLink(s7, s22)
+ self.addLink(s7, s23)
+ self.addLink(s7, s24)
+ self.addLink(s7, s25)
+ self.addLink(s8, s9)
+ self.addLink(s8, s10)
+ self.addLink(s8, s11)
+ self.addLink(s8, s12)
+ self.addLink(s8, s13)
+ self.addLink(s8, s14)
+ self.addLink(s8, s15)
+ self.addLink(s8, s16)
+ self.addLink(s8, s17)
+ self.addLink(s8, s18)
+ self.addLink(s8, s19)
+ self.addLink(s8, s20)
+ self.addLink(s8, s21)
+ self.addLink(s8, s22)
+ self.addLink(s8, s23)
+ self.addLink(s8, s24)
+ self.addLink(s8, s25)
+ self.addLink(s9, s10)
+ self.addLink(s9, s11)
+ self.addLink(s9, s12)
+ self.addLink(s9, s13)
+ self.addLink(s9, s14)
+ self.addLink(s9, s15)
+ self.addLink(s9, s16)
+ self.addLink(s9, s17)
+ self.addLink(s9, s18)
+ self.addLink(s9, s19)
+ self.addLink(s9, s20)
+ self.addLink(s9, s21)
+ self.addLink(s9, s22)
+ self.addLink(s9, s23)
+ self.addLink(s9, s24)
+ self.addLink(s9, s25)
+ self.addLink(s10, s11)
+ self.addLink(s10, s12)
+ self.addLink(s10, s13)
+ self.addLink(s10, s14)
+ self.addLink(s10, s15)
+ self.addLink(s10, s16)
+ self.addLink(s10, s17)
+ self.addLink(s10, s18)
+ self.addLink(s10, s19)
+ self.addLink(s10, s20)
+ self.addLink(s10, s21)
+ self.addLink(s10, s22)
+ self.addLink(s10, s23)
+ self.addLink(s10, s24)
+ self.addLink(s10, s25)
+ self.addLink(s11, s12)
+ self.addLink(s11, s13)
+ self.addLink(s11, s14)
+ self.addLink(s11, s15)
+ self.addLink(s11, s16)
+ self.addLink(s11, s17)
+ self.addLink(s11, s18)
+ self.addLink(s11, s19)
+ self.addLink(s11, s20)
+ self.addLink(s11, s21)
+ self.addLink(s11, s22)
+ self.addLink(s11, s23)
+ self.addLink(s11, s24)
+ self.addLink(s11, s25)
+ self.addLink(s12, s13)
+ self.addLink(s12, s14)
+ self.addLink(s12, s15)
+ self.addLink(s12, s16)
+ self.addLink(s12, s17)
+ self.addLink(s12, s18)
+ self.addLink(s12, s19)
+ self.addLink(s12, s20)
+ self.addLink(s12, s21)
+ self.addLink(s12, s22)
+ self.addLink(s12, s23)
+ self.addLink(s12, s24)
+ self.addLink(s12, s25)
+ self.addLink(s13, s14)
+ self.addLink(s13, s15)
+ self.addLink(s13, s16)
+ self.addLink(s13, s17)
+ self.addLink(s13, s18)
+ self.addLink(s13, s19)
+ self.addLink(s13, s20)
+ self.addLink(s13, s21)
+ self.addLink(s13, s22)
+ self.addLink(s13, s23)
+ self.addLink(s13, s24)
+ self.addLink(s13, s25)
+ self.addLink(s14, s15)
+ self.addLink(s14, s16)
+ self.addLink(s14, s17)
+ self.addLink(s14, s18)
+ self.addLink(s14, s19)
+ self.addLink(s14, s20)
+ self.addLink(s14, s21)
+ self.addLink(s14, s22)
+ self.addLink(s14, s23)
+ self.addLink(s14, s24)
+ self.addLink(s14, s25)
+ self.addLink(s15, s16)
+ self.addLink(s15, s17)
+ self.addLink(s15, s18)
+ self.addLink(s15, s19)
+ self.addLink(s15, s20)
+ self.addLink(s15, s21)
+ self.addLink(s15, s22)
+ self.addLink(s15, s23)
+ self.addLink(s15, s24)
+ self.addLink(s15, s25)
+ self.addLink(s16, s17)
+ self.addLink(s16, s18)
+ self.addLink(s16, s19)
+ self.addLink(s16, s20)
+ self.addLink(s16, s21)
+ self.addLink(s16, s22)
+ self.addLink(s16, s23)
+ self.addLink(s16, s24)
+ self.addLink(s16, s25)
+ self.addLink(s17, s18)
+ self.addLink(s17, s19)
+ self.addLink(s17, s20)
+ self.addLink(s17, s21)
+ self.addLink(s17, s22)
+ self.addLink(s17, s23)
+ self.addLink(s17, s24)
+ self.addLink(s17, s25)
+ self.addLink(s18, s19)
+ self.addLink(s18, s20)
+ self.addLink(s18, s21)
+ self.addLink(s18, s22)
+ self.addLink(s18, s23)
+ self.addLink(s18, s24)
+ self.addLink(s18, s25)
+ self.addLink(s19, s20)
+ self.addLink(s19, s21)
+ self.addLink(s19, s22)
+ self.addLink(s19, s23)
+ self.addLink(s19, s24)
+ self.addLink(s19, s25)
+ self.addLink(s20, s21)
+ self.addLink(s20, s22)
+ self.addLink(s20, s23)
+ self.addLink(s20, s24)
+ self.addLink(s20, s25)
+ self.addLink(s21, s22)
+ self.addLink(s21, s23)
+ self.addLink(s21, s24)
+ self.addLink(s21, s25)
+ self.addLink(s22, s23)
+ self.addLink(s22, s24)
+ self.addLink(s22, s25)
+ self.addLink(s23, s24)
+ self.addLink(s23, s25)
+ self.addLink(s24, s25)
+
+topos = { 'chordal': ( lambda: chordalTopo() ) }
+
+# HERE THE CODE DEFINITION OF THE TOPOLOGY ENDS
+
+def setupNetwork():
+ "Create network"
+ topo = chordalTopo()
+ #if controller_ip == '':
+ #controller_ip = '10.0.2.2';
+ # controller_ip = '127.0.0.1';
+ network = Mininet(topo=topo, switch=OVSSwitch,autoSetMacs=True, controller=None)
+ network.start()
+ CLI( network )
+ network.stop()
+
+if __name__ == '__main__':
+ setLogLevel('info')
+ #setLogLevel('debug')
+ setupNetwork()
diff --git a/TestON/tests/CHOTestMonkey/dependencies/topologies/topoChordalIpv6.py b/TestON/tests/CHOTestMonkey/dependencies/topologies/topoChordalIpv6.py
new file mode 100755
index 0000000..87d5946
--- /dev/null
+++ b/TestON/tests/CHOTestMonkey/dependencies/topologies/topoChordalIpv6.py
@@ -0,0 +1,428 @@
+#!/usr/bin/python
+"""
+"""
+from mininet.topo import Topo
+from mininet.net import Mininet
+from mininet.node import Host, RemoteController
+from mininet.node import Node
+from mininet.node import CPULimitedHost
+from mininet.link import TCLink
+from mininet.cli import CLI
+from mininet.log import setLogLevel
+from mininet.util import dumpNodeConnections
+from mininet.node import ( UserSwitch, OVSSwitch, IVSSwitch )
+
+class dualStackHost( Host ):
+ def config( self, v6Addr='1000::1/64', **params ):
+ r = super( Host, self ).config( **params )
+ intf = self.defaultIntf()
+ self.cmd( 'ip -6 addr add %s dev %s' % ( v6Addr, intf ) )
+ return r
+
+class chordalTopo( Topo ):
+
+ def __init__( self, **opts ):
+ "Create a topology."
+
+ # Initialize Topology
+ Topo.__init__( self, **opts )
+
+ s1 = self.addSwitch( 's1' )
+ s2 = self.addSwitch( 's2' )
+ s3 = self.addSwitch( 's3' )
+ s4 = self.addSwitch( 's4' )
+ s5 = self.addSwitch( 's5' )
+ s6 = self.addSwitch( 's6' )
+ s7 = self.addSwitch( 's7' )
+ s8 = self.addSwitch( 's8' )
+ s9 = self.addSwitch( 's9' )
+ s10 = self.addSwitch( 's10' )
+ s11 = self.addSwitch( 's11' )
+ s12 = self.addSwitch( 's12' )
+ s13 = self.addSwitch( 's13' )
+ s14 = self.addSwitch( 's14' )
+ s15 = self.addSwitch( 's15' )
+ s16 = self.addSwitch( 's16' )
+ s17 = self.addSwitch( 's17' )
+ s18 = self.addSwitch( 's18' )
+ s19 = self.addSwitch( 's19' )
+ s20 = self.addSwitch( 's20' )
+ s21 = self.addSwitch( 's21' )
+ s22 = self.addSwitch( 's22' )
+ s23 = self.addSwitch( 's23' )
+ s24 = self.addSwitch( 's24' )
+ s25 = self.addSwitch( 's25' )
+
+ # ... and now hosts
+ s1_host = self.addHost( 'h1', ip='10.1.0.1/24', cls=dualStackHost, v6Addr='1000::1/64' )
+ s2_host = self.addHost( 'h2', ip='10.1.0.2/24', cls=dualStackHost, v6Addr='1000::2/64' )
+ s3_host = self.addHost( 'h3', ip='10.1.0.3/24', cls=dualStackHost, v6Addr='1000::3/64' )
+ s4_host = self.addHost( 'h4', ip='10.1.0.4/24', cls=dualStackHost, v6Addr='1000::4/64' )
+ s5_host = self.addHost( 'h5', ip='10.1.0.5/24', cls=dualStackHost, v6Addr='1000::5/64' )
+ s6_host = self.addHost( 'h6', ip='10.1.0.6/24', cls=dualStackHost, v6Addr='1000::6/64' )
+ s7_host = self.addHost( 'h7', ip='10.1.0.7/24', cls=dualStackHost, v6Addr='1000::7/64' )
+ s8_host = self.addHost( 'h8', ip='10.1.0.8/24', cls=dualStackHost, v6Addr='1000::8/64' )
+ s9_host = self.addHost( 'h9', ip='10.1.0.9/24', cls=dualStackHost, v6Addr='1000::9/64' )
+ s10_host = self.addHost( 'h10', ip='10.1.0.10/24', cls=dualStackHost, v6Addr='1000::10/64' )
+ s11_host = self.addHost( 'h11', ip='10.1.0.11/24', cls=dualStackHost, v6Addr='1000::11/64' )
+ s12_host = self.addHost( 'h12', ip='10.1.0.12/24', cls=dualStackHost, v6Addr='1000::12/64' )
+ s13_host = self.addHost( 'h13', ip='10.1.0.13/24', cls=dualStackHost, v6Addr='1000::13/64' )
+ s14_host = self.addHost( 'h14', ip='10.1.0.14/24', cls=dualStackHost, v6Addr='1000::14/64' )
+ s15_host = self.addHost( 'h15', ip='10.1.0.15/24', cls=dualStackHost, v6Addr='1000::15/64' )
+ s16_host = self.addHost( 'h16', ip='10.1.0.16/24', cls=dualStackHost, v6Addr='1000::16/64' )
+ s17_host = self.addHost( 'h17', ip='10.1.0.17/24', cls=dualStackHost, v6Addr='1000::17/64' )
+ s18_host = self.addHost( 'h18', ip='10.1.0.18/24', cls=dualStackHost, v6Addr='1000::18/64' )
+ s19_host = self.addHost( 'h19', ip='10.1.0.19/24', cls=dualStackHost, v6Addr='1000::19/64' )
+ s20_host = self.addHost( 'h20', ip='10.1.0.20/24', cls=dualStackHost, v6Addr='1000::20/64' )
+ s21_host = self.addHost( 'h21', ip='10.1.0.21/24', cls=dualStackHost, v6Addr='1000::21/64' )
+ s22_host = self.addHost( 'h22', ip='10.1.0.22/24', cls=dualStackHost, v6Addr='1000::22/64' )
+ s23_host = self.addHost( 'h23', ip='10.1.0.23/24', cls=dualStackHost, v6Addr='1000::23/64' )
+ s24_host = self.addHost( 'h24', ip='10.1.0.24/24', cls=dualStackHost, v6Addr='1000::24/64' )
+ s25_host = self.addHost( 'h25', ip='10.1.0.25/24', cls=dualStackHost, v6Addr='1000::25/64' )
+
+ # add edges between switch and corresponding host
+ self.addLink( s1 , s1_host )
+ self.addLink( s2 , s2_host )
+ self.addLink( s3 , s3_host )
+ self.addLink( s4 , s4_host )
+ self.addLink( s5 , s5_host )
+ self.addLink( s6 , s6_host )
+ self.addLink( s7 , s7_host )
+ self.addLink( s8 , s8_host )
+ self.addLink( s9 , s9_host )
+ self.addLink( s10 , s10_host )
+ self.addLink( s11 , s11_host )
+ self.addLink( s12 , s12_host )
+ self.addLink( s13 , s13_host )
+ self.addLink( s14 , s14_host )
+ self.addLink( s15 , s15_host )
+ self.addLink( s16 , s16_host )
+ self.addLink( s17 , s17_host )
+ self.addLink( s18 , s18_host )
+ self.addLink( s19 , s19_host )
+ self.addLink( s20 , s20_host )
+ self.addLink( s21 , s21_host )
+ self.addLink( s22 , s22_host )
+ self.addLink( s23 , s23_host )
+ self.addLink( s24 , s24_host )
+ self.addLink( s25 , s25_host )
+ self.addLink(s1, s2)
+ self.addLink(s1, s3)
+ self.addLink(s1, s4)
+ self.addLink(s1, s5)
+ self.addLink(s1, s6)
+ self.addLink(s1, s7)
+ self.addLink(s1, s8)
+ self.addLink(s1, s9)
+ self.addLink(s1, s10)
+ self.addLink(s1, s11)
+ self.addLink(s1, s12)
+ self.addLink(s1, s13)
+ self.addLink(s1, s14)
+ self.addLink(s1, s15)
+ self.addLink(s1, s16)
+ self.addLink(s1, s17)
+ self.addLink(s1, s18)
+ self.addLink(s1, s19)
+ self.addLink(s1, s20)
+ self.addLink(s1, s21)
+ self.addLink(s1, s22)
+ self.addLink(s1, s23)
+ self.addLink(s1, s24)
+ self.addLink(s1, s25)
+ self.addLink(s2, s3)
+ self.addLink(s2, s4)
+ self.addLink(s2, s5)
+ self.addLink(s2, s6)
+ self.addLink(s2, s7)
+ self.addLink(s2, s8)
+ self.addLink(s2, s9)
+ self.addLink(s2, s10)
+ self.addLink(s2, s11)
+ self.addLink(s2, s12)
+ self.addLink(s2, s13)
+ self.addLink(s2, s14)
+ self.addLink(s2, s15)
+ self.addLink(s2, s16)
+ self.addLink(s2, s17)
+ self.addLink(s2, s18)
+ self.addLink(s2, s19)
+ self.addLink(s2, s20)
+ self.addLink(s2, s21)
+ self.addLink(s2, s22)
+ self.addLink(s2, s23)
+ self.addLink(s2, s24)
+ self.addLink(s2, s25)
+ self.addLink(s3, s4)
+ self.addLink(s3, s5)
+ self.addLink(s3, s6)
+ self.addLink(s3, s7)
+ self.addLink(s3, s8)
+ self.addLink(s3, s9)
+ self.addLink(s3, s10)
+ self.addLink(s3, s11)
+ self.addLink(s3, s12)
+ self.addLink(s3, s13)
+ self.addLink(s3, s14)
+ self.addLink(s3, s15)
+ self.addLink(s3, s16)
+ self.addLink(s3, s17)
+ self.addLink(s3, s18)
+ self.addLink(s3, s19)
+ self.addLink(s3, s20)
+ self.addLink(s3, s21)
+ self.addLink(s3, s22)
+ self.addLink(s3, s23)
+ self.addLink(s3, s24)
+ self.addLink(s3, s25)
+ self.addLink(s4, s5)
+ self.addLink(s4, s6)
+ self.addLink(s4, s7)
+ self.addLink(s4, s8)
+ self.addLink(s4, s9)
+ self.addLink(s4, s10)
+ self.addLink(s4, s11)
+ self.addLink(s4, s12)
+ self.addLink(s4, s13)
+ self.addLink(s4, s14)
+ self.addLink(s4, s15)
+ self.addLink(s4, s16)
+ self.addLink(s4, s17)
+ self.addLink(s4, s18)
+ self.addLink(s4, s19)
+ self.addLink(s4, s20)
+ self.addLink(s4, s21)
+ self.addLink(s4, s22)
+ self.addLink(s4, s23)
+ self.addLink(s4, s24)
+ self.addLink(s4, s25)
+ self.addLink(s5, s6)
+ self.addLink(s5, s7)
+ self.addLink(s5, s8)
+ self.addLink(s5, s9)
+ self.addLink(s5, s10)
+ self.addLink(s5, s11)
+ self.addLink(s5, s12)
+ self.addLink(s5, s13)
+ self.addLink(s5, s14)
+ self.addLink(s5, s15)
+ self.addLink(s5, s16)
+ self.addLink(s5, s17)
+ self.addLink(s5, s18)
+ self.addLink(s5, s19)
+ self.addLink(s5, s20)
+ self.addLink(s5, s21)
+ self.addLink(s5, s22)
+ self.addLink(s5, s23)
+ self.addLink(s5, s24)
+ self.addLink(s5, s25)
+ self.addLink(s6, s7)
+ self.addLink(s6, s8)
+ self.addLink(s6, s9)
+ self.addLink(s6, s10)
+ self.addLink(s6, s11)
+ self.addLink(s6, s12)
+ self.addLink(s6, s13)
+ self.addLink(s6, s14)
+ self.addLink(s6, s15)
+ self.addLink(s6, s16)
+ self.addLink(s6, s17)
+ self.addLink(s6, s18)
+ self.addLink(s6, s19)
+ self.addLink(s6, s20)
+ self.addLink(s6, s21)
+ self.addLink(s6, s22)
+ self.addLink(s6, s23)
+ self.addLink(s6, s24)
+ self.addLink(s6, s25)
+ self.addLink(s7, s8)
+ self.addLink(s7, s9)
+ self.addLink(s7, s10)
+ self.addLink(s7, s11)
+ self.addLink(s7, s12)
+ self.addLink(s7, s13)
+ self.addLink(s7, s14)
+ self.addLink(s7, s15)
+ self.addLink(s7, s16)
+ self.addLink(s7, s17)
+ self.addLink(s7, s18)
+ self.addLink(s7, s19)
+ self.addLink(s7, s20)
+ self.addLink(s7, s21)
+ self.addLink(s7, s22)
+ self.addLink(s7, s23)
+ self.addLink(s7, s24)
+ self.addLink(s7, s25)
+ self.addLink(s8, s9)
+ self.addLink(s8, s10)
+ self.addLink(s8, s11)
+ self.addLink(s8, s12)
+ self.addLink(s8, s13)
+ self.addLink(s8, s14)
+ self.addLink(s8, s15)
+ self.addLink(s8, s16)
+ self.addLink(s8, s17)
+ self.addLink(s8, s18)
+ self.addLink(s8, s19)
+ self.addLink(s8, s20)
+ self.addLink(s8, s21)
+ self.addLink(s8, s22)
+ self.addLink(s8, s23)
+ self.addLink(s8, s24)
+ self.addLink(s8, s25)
+ self.addLink(s9, s10)
+ self.addLink(s9, s11)
+ self.addLink(s9, s12)
+ self.addLink(s9, s13)
+ self.addLink(s9, s14)
+ self.addLink(s9, s15)
+ self.addLink(s9, s16)
+ self.addLink(s9, s17)
+ self.addLink(s9, s18)
+ self.addLink(s9, s19)
+ self.addLink(s9, s20)
+ self.addLink(s9, s21)
+ self.addLink(s9, s22)
+ self.addLink(s9, s23)
+ self.addLink(s9, s24)
+ self.addLink(s9, s25)
+ self.addLink(s10, s11)
+ self.addLink(s10, s12)
+ self.addLink(s10, s13)
+ self.addLink(s10, s14)
+ self.addLink(s10, s15)
+ self.addLink(s10, s16)
+ self.addLink(s10, s17)
+ self.addLink(s10, s18)
+ self.addLink(s10, s19)
+ self.addLink(s10, s20)
+ self.addLink(s10, s21)
+ self.addLink(s10, s22)
+ self.addLink(s10, s23)
+ self.addLink(s10, s24)
+ self.addLink(s10, s25)
+ self.addLink(s11, s12)
+ self.addLink(s11, s13)
+ self.addLink(s11, s14)
+ self.addLink(s11, s15)
+ self.addLink(s11, s16)
+ self.addLink(s11, s17)
+ self.addLink(s11, s18)
+ self.addLink(s11, s19)
+ self.addLink(s11, s20)
+ self.addLink(s11, s21)
+ self.addLink(s11, s22)
+ self.addLink(s11, s23)
+ self.addLink(s11, s24)
+ self.addLink(s11, s25)
+ self.addLink(s12, s13)
+ self.addLink(s12, s14)
+ self.addLink(s12, s15)
+ self.addLink(s12, s16)
+ self.addLink(s12, s17)
+ self.addLink(s12, s18)
+ self.addLink(s12, s19)
+ self.addLink(s12, s20)
+ self.addLink(s12, s21)
+ self.addLink(s12, s22)
+ self.addLink(s12, s23)
+ self.addLink(s12, s24)
+ self.addLink(s12, s25)
+ self.addLink(s13, s14)
+ self.addLink(s13, s15)
+ self.addLink(s13, s16)
+ self.addLink(s13, s17)
+ self.addLink(s13, s18)
+ self.addLink(s13, s19)
+ self.addLink(s13, s20)
+ self.addLink(s13, s21)
+ self.addLink(s13, s22)
+ self.addLink(s13, s23)
+ self.addLink(s13, s24)
+ self.addLink(s13, s25)
+ self.addLink(s14, s15)
+ self.addLink(s14, s16)
+ self.addLink(s14, s17)
+ self.addLink(s14, s18)
+ self.addLink(s14, s19)
+ self.addLink(s14, s20)
+ self.addLink(s14, s21)
+ self.addLink(s14, s22)
+ self.addLink(s14, s23)
+ self.addLink(s14, s24)
+ self.addLink(s14, s25)
+ self.addLink(s15, s16)
+ self.addLink(s15, s17)
+ self.addLink(s15, s18)
+ self.addLink(s15, s19)
+ self.addLink(s15, s20)
+ self.addLink(s15, s21)
+ self.addLink(s15, s22)
+ self.addLink(s15, s23)
+ self.addLink(s15, s24)
+ self.addLink(s15, s25)
+ self.addLink(s16, s17)
+ self.addLink(s16, s18)
+ self.addLink(s16, s19)
+ self.addLink(s16, s20)
+ self.addLink(s16, s21)
+ self.addLink(s16, s22)
+ self.addLink(s16, s23)
+ self.addLink(s16, s24)
+ self.addLink(s16, s25)
+ self.addLink(s17, s18)
+ self.addLink(s17, s19)
+ self.addLink(s17, s20)
+ self.addLink(s17, s21)
+ self.addLink(s17, s22)
+ self.addLink(s17, s23)
+ self.addLink(s17, s24)
+ self.addLink(s17, s25)
+ self.addLink(s18, s19)
+ self.addLink(s18, s20)
+ self.addLink(s18, s21)
+ self.addLink(s18, s22)
+ self.addLink(s18, s23)
+ self.addLink(s18, s24)
+ self.addLink(s18, s25)
+ self.addLink(s19, s20)
+ self.addLink(s19, s21)
+ self.addLink(s19, s22)
+ self.addLink(s19, s23)
+ self.addLink(s19, s24)
+ self.addLink(s19, s25)
+ self.addLink(s20, s21)
+ self.addLink(s20, s22)
+ self.addLink(s20, s23)
+ self.addLink(s20, s24)
+ self.addLink(s20, s25)
+ self.addLink(s21, s22)
+ self.addLink(s21, s23)
+ self.addLink(s21, s24)
+ self.addLink(s21, s25)
+ self.addLink(s22, s23)
+ self.addLink(s22, s24)
+ self.addLink(s22, s25)
+ self.addLink(s23, s24)
+ self.addLink(s23, s25)
+ self.addLink(s24, s25)
+
+topos = { 'chordal': ( lambda: chordalTopo() ) }
+
+# HERE THE CODE DEFINITION OF THE TOPOLOGY ENDS
+
+def setupNetwork():
+ "Create network"
+ topo = chordalTopo()
+ #if controller_ip == '':
+ #controller_ip = '10.0.2.2';
+ # controller_ip = '127.0.0.1';
+ network = Mininet(topo=topo, switch=OVSSwitch,autoSetMacs=True, controller=None)
+ network.start()
+ CLI( network )
+ network.stop()
+
+if __name__ == '__main__':
+ setLogLevel('info')
+ #setLogLevel('debug')
+ setupNetwork()
diff --git a/TestON/tests/CHOTestMonkey/dependencies/topologies/topoRingIpv6.py b/TestON/tests/CHOTestMonkey/dependencies/topologies/topoRingIpv6.py
new file mode 100755
index 0000000..4b81223
--- /dev/null
+++ b/TestON/tests/CHOTestMonkey/dependencies/topologies/topoRingIpv6.py
@@ -0,0 +1,93 @@
+#!/usr/bin/python
+"""
+"""
+from mininet.topo import Topo
+from mininet.net import Mininet
+from mininet.node import Host, RemoteController
+from mininet.node import Node
+from mininet.node import CPULimitedHost
+from mininet.link import TCLink
+from mininet.cli import CLI
+from mininet.log import setLogLevel
+from mininet.util import dumpNodeConnections
+from mininet.node import ( UserSwitch, OVSSwitch, IVSSwitch )
+
+class dualStackHost( Host ):
+ def config( self, v6Addr='1000::1/64', **params ):
+ r = super( Host, self ).config( **params )
+ intf = self.defaultIntf()
+ self.cmd( 'ip -6 addr add %s dev %s' % ( v6Addr, intf ) )
+ return r
+
+class ringTopo( Topo ):
+
+ def __init__( self, **opts ):
+ "Create a topology."
+
+ # Initialize Topology
+ Topo.__init__( self, **opts )
+
+ s1 = self.addSwitch( 's1' )
+ s2 = self.addSwitch( 's2' )
+ s3 = self.addSwitch( 's3' )
+ s4 = self.addSwitch( 's4' )
+ s5 = self.addSwitch( 's5' )
+ s6 = self.addSwitch( 's6' )
+ s7 = self.addSwitch( 's7' )
+ s8 = self.addSwitch( 's8' )
+ s9 = self.addSwitch( 's9' )
+ s10 = self.addSwitch( 's10' )
+
+ # ... and now hosts
+ s1_host = self.addHost( 'h1', ip='10.1.0.1/24', cls=dualStackHost, v6Addr='1000::1/64' )
+ s2_host = self.addHost( 'h2', ip='10.1.0.2/24', cls=dualStackHost, v6Addr='1000::2/64' )
+ s3_host = self.addHost( 'h3', ip='10.1.0.3/24', cls=dualStackHost, v6Addr='1000::3/64' )
+ s4_host = self.addHost( 'h4', ip='10.1.0.4/24', cls=dualStackHost, v6Addr='1000::4/64' )
+ s5_host = self.addHost( 'h5', ip='10.1.0.5/24', cls=dualStackHost, v6Addr='1000::5/64' )
+ s6_host = self.addHost( 'h6', ip='10.1.0.6/24', cls=dualStackHost, v6Addr='1000::6/64' )
+ s7_host = self.addHost( 'h7', ip='10.1.0.7/24', cls=dualStackHost, v6Addr='1000::7/64' )
+ s8_host = self.addHost( 'h8', ip='10.1.0.8/24', cls=dualStackHost, v6Addr='1000::8/64' )
+ s9_host = self.addHost( 'h9', ip='10.1.0.9/24', cls=dualStackHost, v6Addr='1000::9/64' )
+ s10_host = self.addHost( 'h10', ip='10.1.0.10/24', cls=dualStackHost, v6Addr='1000::10/64' )
+
+ # add edges between switch and corresponding host
+ self.addLink( s1 , s1_host )
+ self.addLink( s2 , s2_host )
+ self.addLink( s3 , s3_host )
+ self.addLink( s4 , s4_host )
+ self.addLink( s5 , s5_host )
+ self.addLink( s6 , s6_host )
+ self.addLink( s7 , s7_host )
+ self.addLink( s8 , s8_host )
+ self.addLink( s9 , s9_host )
+ self.addLink( s10 , s10_host )
+ self.addLink(s1, s2)
+ self.addLink(s2, s3)
+ self.addLink(s3, s4)
+ self.addLink(s4, s5)
+ self.addLink(s5, s6)
+ self.addLink(s6, s7)
+ self.addLink(s7, s8)
+ self.addLink(s8, s9)
+ self.addLink(s9, s10)
+ self.addLink(s10, s1)
+
+topos = { 'ring': ( lambda: ringTopo() ) }
+
+# HERE THE CODE DEFINITION OF THE TOPOLOGY ENDS
+
+def setupNetwork():
+ "Create network"
+ topo = ringTopo()
+ #if controller_ip == '':
+ #controller_ip = '10.0.2.2';
+ # controller_ip = '127.0.0.1';
+ network = Mininet(topo=topo, switch=OVSSwitch, autoSetMacs=True, controller=None)
+ network.start()
+ CLI( network )
+ network.stop()
+
+if __name__ == '__main__':
+ setLogLevel('info')
+ #setLogLevel('debug')
+ setupNetwork()
diff --git a/TestON/tests/CHOTestMonkey/dependencies/topologies/topoSpine.py b/TestON/tests/CHOTestMonkey/dependencies/topologies/topoSpine.py
new file mode 100755
index 0000000..5787d93
--- /dev/null
+++ b/TestON/tests/CHOTestMonkey/dependencies/topologies/topoSpine.py
@@ -0,0 +1,434 @@
+#!/usr/bin/python
+
+from mininet.topo import Topo
+from mininet.net import Mininet
+from mininet.node import Controller, RemoteController, OVSController
+from mininet.node import CPULimitedHost, Host, Node
+from mininet.cli import CLI
+from mininet.log import setLogLevel, info
+from mininet.link import TCLink, Intf
+from subprocess import call
+from mininet.util import dumpNodeConnections
+from mininet.node import ( UserSwitch, OVSSwitch, IVSSwitch )
+
+class spineTopo( Topo ):
+
+ def __init__( self, **opts ):
+ "Create a topology."
+
+ # Initialize Topology
+ Topo.__init__( self, **opts )
+
+ # add nodes, Leaf switches
+ s1 = self.addSwitch( 's1' )
+ s2 = self.addSwitch( 's2' )
+ s3 = self.addSwitch( 's3' )
+ s4 = self.addSwitch( 's4' )
+ s5 = self.addSwitch( 's5' )
+ s6 = self.addSwitch( 's6' )
+ s7 = self.addSwitch( 's7' )
+ s8 = self.addSwitch( 's8' )
+ s9 = self.addSwitch( 's9' )
+ s10 = self.addSwitch( 's10' )
+ s11 = self.addSwitch( 's11' )
+ s12 = self.addSwitch( 's12' )
+ s13 = self.addSwitch( 's13' )
+ s14 = self.addSwitch( 's14' )
+
+ # add nodes, Spine switches first...
+ s15 = self.addSwitch( 's15' )
+ s16 = self.addSwitch( 's16' )
+ s17 = self.addSwitch( 's17' )
+ s18 = self.addSwitch( 's18' )
+ s19 = self.addSwitch( 's19' )
+ s20 = self.addSwitch( 's20' )
+ s21 = self.addSwitch( 's21' )
+ s22 = self.addSwitch( 's22' )
+ s23 = self.addSwitch( 's23' )
+ s24 = self.addSwitch( 's24' )
+ s25 = self.addSwitch( 's25' )
+ s26 = self.addSwitch( 's26' )
+ s27 = self.addSwitch( 's27' )
+ s28 = self.addSwitch( 's28' )
+ s29 = self.addSwitch( 's29' )
+ s30 = self.addSwitch( 's30' )
+ s31 = self.addSwitch( 's31' )
+ s32 = self.addSwitch( 's32' )
+ s33 = self.addSwitch( 's33' )
+ s34 = self.addSwitch( 's34' )
+ s35 = self.addSwitch( 's35' )
+ s36 = self.addSwitch( 's36' )
+ s37 = self.addSwitch( 's37' )
+ s38 = self.addSwitch( 's38' )
+ s39 = self.addSwitch( 's39' )
+ s40 = self.addSwitch( 's40' )
+ s41 = self.addSwitch( 's41' )
+ s42 = self.addSwitch( 's42' )
+ s43 = self.addSwitch( 's43' )
+ s44 = self.addSwitch( 's44' )
+ s45 = self.addSwitch( 's45' )
+ s46 = self.addSwitch( 's46' )
+ s47 = self.addSwitch( 's47' )
+ s48 = self.addSwitch( 's48' )
+ s49 = self.addSwitch( 's49' )
+ s50 = self.addSwitch( 's50' )
+ s51 = self.addSwitch( 's51' )
+ s52 = self.addSwitch( 's52' )
+ s53 = self.addSwitch( 's53' )
+ s54 = self.addSwitch( 's54' )
+ s55 = self.addSwitch( 's55' )
+ s56 = self.addSwitch( 's56' )
+ s57 = self.addSwitch( 's57' )
+ s58 = self.addSwitch( 's58' )
+ s59 = self.addSwitch( 's59' )
+ s60 = self.addSwitch( 's60' )
+ s61 = self.addSwitch( 's61' )
+ s62 = self.addSwitch( 's62' )
+ s63 = self.addSwitch( 's63' )
+ s64 = self.addSwitch( 's64' )
+ s65 = self.addSwitch( 's65' )
+ s66 = self.addSwitch( 's66' )
+ s67 = self.addSwitch( 's67' )
+ s68 = self.addSwitch( 's68' )
+ s69 = self.addSwitch( 's69' )
+ s70 = self.addSwitch( 's70' )
+ s71 = self.addSwitch( 's71' )
+ s72 = self.addSwitch( 's72' )
+ s73 = self.addSwitch( 's73' )
+ s74 = self.addSwitch( 's74' )
+ s75 = self.addSwitch( 's75' )
+ s76 = self.addSwitch( 's76' )
+ s77 = self.addSwitch( 's77' )
+ s78 = self.addSwitch( 's78' )
+
+ # ... and now hosts
+ #s1_host = self.addHost( 'h1' )
+ #s2_host = self.addHost( 'h2' )
+ #s3_host = self.addHost( 'h3' )
+ #s4_host = self.addHost( 'h4' )
+ #s5_host = self.addHost( 'h5' )
+ #s6_host = self.addHost( 'h6' )
+ #s7_host = self.addHost( 'h7' )
+ #s8_host = self.addHost( 'h8' )
+ #s9_host = self.addHost( 'h9' )
+ #s10_host = self.addHost( 'h10' )
+ s11_host = self.addHost( 'h11' )
+ s12_host = self.addHost( 'h12' )
+ s13_host = self.addHost( 'h13' )
+ s14_host = self.addHost( 'h14' )
+ s15_host = self.addHost( 'h15' )
+ s16_host = self.addHost( 'h16' )
+ s17_host = self.addHost( 'h17' )
+ s18_host = self.addHost( 'h18' )
+ s19_host = self.addHost( 'h19' )
+ s20_host = self.addHost( 'h20' )
+ s21_host = self.addHost( 'h21' )
+ s22_host = self.addHost( 'h22' )
+ s23_host = self.addHost( 'h23' )
+ s24_host = self.addHost( 'h24' )
+ s25_host = self.addHost( 'h25' )
+ s26_host = self.addHost( 'h26' )
+ s27_host = self.addHost( 'h27' )
+ s28_host = self.addHost( 'h28' )
+ s29_host = self.addHost( 'h29' )
+ s30_host = self.addHost( 'h30' )
+ s31_host = self.addHost( 'h31' )
+ s32_host = self.addHost( 'h32' )
+ s33_host = self.addHost( 'h33' )
+ s34_host = self.addHost( 'h34' )
+ s35_host = self.addHost( 'h35' )
+ s36_host = self.addHost( 'h36' )
+ s37_host = self.addHost( 'h37' )
+ s38_host = self.addHost( 'h38' )
+ s39_host = self.addHost( 'h39' )
+ s40_host = self.addHost( 'h40' )
+ s41_host = self.addHost( 'h41' )
+ s42_host = self.addHost( 'h42' )
+ s43_host = self.addHost( 'h43' )
+ s44_host = self.addHost( 'h44' )
+ s45_host = self.addHost( 'h45' )
+ s46_host = self.addHost( 'h46' )
+ s47_host = self.addHost( 'h47' )
+ s48_host = self.addHost( 'h48' )
+ s49_host = self.addHost( 'h49' )
+ s50_host = self.addHost( 'h50' )
+ s51_host = self.addHost( 'h51' )
+ s52_host = self.addHost( 'h52' )
+ s53_host = self.addHost( 'h53' )
+ s54_host = self.addHost( 'h54' )
+ s55_host = self.addHost( 'h55' )
+ s56_host = self.addHost( 'h56' )
+ s57_host = self.addHost( 'h57' )
+ s58_host = self.addHost( 'h58' )
+ s59_host = self.addHost( 'h59' )
+ s60_host = self.addHost( 'h60' )
+ s61_host = self.addHost( 'h61' )
+ s62_host = self.addHost( 'h62' )
+ s63_host = self.addHost( 'h63' )
+ s64_host = self.addHost( 'h64' )
+ s65_host = self.addHost( 'h65' )
+ s66_host = self.addHost( 'h66' )
+ s67_host = self.addHost( 'h67' )
+ s68_host = self.addHost( 'h68' )
+ s69_host = self.addHost( 'h69' )
+ s70_host = self.addHost( 'h70' )
+ s71_host = self.addHost( 'h71' )
+ s72_host = self.addHost( 'h72' )
+ s73_host = self.addHost( 'h73' )
+ s74_host = self.addHost( 'h74' )
+ s75_host = self.addHost( 'h75' )
+ s76_host = self.addHost( 'h76' )
+ s77_host = self.addHost( 'h77' )
+ s78_host = self.addHost( 'h78' )
+
+ # add edges between switch and corresponding host
+ #self.addLink( s1 , s1_host )
+ #self.addLink( s2 , s2_host )
+ #self.addLink( s3 , s3_host )
+ #self.addLink( s4 , s4_host )
+ #self.addLink( s5 , s5_host )
+ #self.addLink( s6 , s6_host )
+ #self.addLink( s7 , s7_host )
+ #self.addLink( s8 , s8_host )
+ #self.addLink( s9 , s9_host )
+ #self.addLink( s10 , s10_host )
+ self.addLink( s11 , s11_host )
+ self.addLink( s12 , s12_host )
+ self.addLink( s13 , s13_host )
+ self.addLink( s14 , s14_host )
+ self.addLink( s15 , s15_host )
+ self.addLink( s16 , s16_host )
+ self.addLink( s17 , s17_host )
+ self.addLink( s18 , s18_host )
+ self.addLink( s19 , s19_host )
+ self.addLink( s20 , s20_host )
+ self.addLink( s21 , s21_host )
+ self.addLink( s22 , s22_host )
+ self.addLink( s23 , s23_host )
+ self.addLink( s24 , s24_host )
+ self.addLink( s25 , s25_host )
+ self.addLink( s26 , s26_host )
+ self.addLink( s27 , s27_host )
+ self.addLink( s28 , s28_host )
+ self.addLink( s29 , s29_host )
+ self.addLink( s30 , s30_host )
+ self.addLink( s31 , s31_host )
+ self.addLink( s32 , s32_host )
+ self.addLink( s33 , s33_host )
+ self.addLink( s34 , s34_host )
+ self.addLink( s35 , s35_host )
+ self.addLink( s36 , s36_host )
+ self.addLink( s37 , s37_host )
+ self.addLink( s38 , s38_host )
+ self.addLink( s39 , s39_host )
+ self.addLink( s40 , s40_host )
+ self.addLink( s41 , s41_host )
+ self.addLink( s42 , s42_host )
+ self.addLink( s43 , s43_host )
+ self.addLink( s44 , s44_host )
+ self.addLink( s45 , s45_host )
+ self.addLink( s46 , s46_host )
+ self.addLink( s47 , s47_host )
+ self.addLink( s48 , s48_host )
+ self.addLink( s49 , s49_host )
+ self.addLink( s50 , s50_host )
+ self.addLink( s51 , s51_host )
+ self.addLink( s52 , s52_host )
+ self.addLink( s53 , s53_host )
+ self.addLink( s54 , s54_host )
+ self.addLink( s55 , s55_host )
+ self.addLink( s56 , s56_host )
+ self.addLink( s57 , s57_host )
+ self.addLink( s58 , s58_host )
+ self.addLink( s59 , s59_host )
+ self.addLink( s60 , s60_host )
+ self.addLink( s61 , s61_host )
+ self.addLink( s62 , s62_host )
+ self.addLink( s63 , s63_host )
+ self.addLink( s64 , s64_host )
+ self.addLink( s65 , s65_host )
+ self.addLink( s66 , s66_host )
+ self.addLink( s67 , s67_host )
+ self.addLink( s68 , s68_host )
+ self.addLink( s69 , s69_host )
+ self.addLink( s70 , s70_host )
+ self.addLink( s71 , s71_host )
+ self.addLink( s72 , s72_host )
+ self.addLink( s73 , s73_host )
+ self.addLink( s74 , s74_host )
+ self.addLink( s75 , s75_host )
+ self.addLink( s76 , s76_host )
+ self.addLink( s77 , s77_host )
+ self.addLink( s78 , s78_host )
+
+ #info( '*** Add Leaf links\n')
+ self.addLink(s1, s9)
+ self.addLink(s2, s10)
+ self.addLink(s3, s9)
+ self.addLink(s4, s10)
+ self.addLink(s5, s9)
+ self.addLink(s6, s10)
+ self.addLink(s7, s9)
+ self.addLink(s8, s10)
+ self.addLink(s9, s11)
+ self.addLink(s9, s12)
+ self.addLink(s10, s13)
+ self.addLink(s10, s14)
+ self.addLink(s11, s12)
+ self.addLink(s13, s14)
+
+ #info( '*** Add Spine-1 links\n')
+ self.addLink(s15, s1)
+ self.addLink(s15, s2)
+ self.addLink(s16, s1)
+ self.addLink(s16, s2)
+ self.addLink(s17, s1)
+ self.addLink(s17, s2)
+ self.addLink(s18, s1)
+ self.addLink(s18, s2)
+ self.addLink(s19, s1)
+ self.addLink(s19, s2)
+ self.addLink(s20, s1)
+ self.addLink(s20, s2)
+ self.addLink(s21, s1)
+ self.addLink(s21, s2)
+ self.addLink(s22, s1)
+ self.addLink(s22, s2)
+ self.addLink(s23, s1)
+ self.addLink(s23, s2)
+ self.addLink(s24, s1)
+ self.addLink(s24, s2)
+ self.addLink(s25, s1)
+ self.addLink(s25, s2)
+ self.addLink(s26, s1)
+ self.addLink(s26, s2)
+ self.addLink(s27, s1)
+ self.addLink(s27, s2)
+ self.addLink(s28, s1)
+ self.addLink(s28, s2)
+ self.addLink(s29, s1)
+ self.addLink(s29, s2)
+ self.addLink(s30, s1)
+ self.addLink(s30, s2)
+
+ #info( '*** Add Spine-2 links\n')
+ self.addLink(s31, s3)
+ self.addLink(s31, s4)
+ self.addLink(s32, s3)
+ self.addLink(s32, s4)
+ self.addLink(s33, s3)
+ self.addLink(s33, s4)
+ self.addLink(s34, s3)
+ self.addLink(s34, s4)
+ self.addLink(s35, s3)
+ self.addLink(s35, s4)
+ self.addLink(s36, s3)
+ self.addLink(s36, s4)
+ self.addLink(s37, s3)
+ self.addLink(s37, s4)
+ self.addLink(s38, s3)
+ self.addLink(s38, s4)
+ self.addLink(s39, s3)
+ self.addLink(s39, s4)
+ self.addLink(s40, s3)
+ self.addLink(s40, s4)
+ self.addLink(s41, s3)
+ self.addLink(s41, s4)
+ self.addLink(s42, s3)
+ self.addLink(s42, s4)
+ self.addLink(s43, s3)
+ self.addLink(s43, s4)
+ self.addLink(s44, s3)
+ self.addLink(s44, s4)
+ self.addLink(s45, s3)
+ self.addLink(s45, s4)
+ self.addLink(s46, s3)
+ self.addLink(s46, s4)
+
+ #info( '*** Add Spine-3 links\n')
+ self.addLink(s47, s5)
+ self.addLink(s47, s6)
+ self.addLink(s48, s5)
+ self.addLink(s48, s6)
+ self.addLink(s49, s5)
+ self.addLink(s49, s6)
+ self.addLink(s50, s5)
+ self.addLink(s50, s6)
+ self.addLink(s51, s5)
+ self.addLink(s51, s6)
+ self.addLink(s52, s5)
+ self.addLink(s52, s6)
+ self.addLink(s53, s5)
+ self.addLink(s53, s6)
+ self.addLink(s54, s5)
+ self.addLink(s54, s6)
+ self.addLink(s55, s5)
+ self.addLink(s55, s6)
+ self.addLink(s56, s5)
+ self.addLink(s56, s6)
+ self.addLink(s57, s5)
+ self.addLink(s57, s6)
+ self.addLink(s58, s5)
+ self.addLink(s58, s6)
+ self.addLink(s59, s5)
+ self.addLink(s59, s6)
+ self.addLink(s60, s5)
+ self.addLink(s60, s6)
+ self.addLink(s61, s5)
+ self.addLink(s61, s6)
+ self.addLink(s62, s5)
+ self.addLink(s62, s6)
+
+ #info( '*** Add Spine-4 links\n')
+ self.addLink(s63, s7)
+ self.addLink(s63, s8)
+ self.addLink(s64, s7)
+ self.addLink(s64, s8)
+ self.addLink(s65, s7)
+ self.addLink(s65, s8)
+ self.addLink(s66, s7)
+ self.addLink(s66, s8)
+ self.addLink(s67, s7)
+ self.addLink(s67, s8)
+ self.addLink(s68, s7)
+ self.addLink(s68, s8)
+ self.addLink(s69, s7)
+ self.addLink(s69, s8)
+ self.addLink(s70, s7)
+ self.addLink(s70, s8)
+ self.addLink(s71, s7)
+ self.addLink(s71, s8)
+ self.addLink(s72, s7)
+ self.addLink(s72, s8)
+ self.addLink(s73, s7)
+ self.addLink(s73, s8)
+ self.addLink(s74, s7)
+ self.addLink(s74, s8)
+ self.addLink(s75, s7)
+ self.addLink(s75, s8)
+ self.addLink(s76, s7)
+ self.addLink(s76, s8)
+ self.addLink(s77, s7)
+ self.addLink(s77, s8)
+ self.addLink(s78, s7)
+ self.addLink(s78, s8)
+
+topos = { 'spine': ( lambda: spineTopo() ) }
+
+# HERE THE CODE DEFINITION OF THE TOPOLOGY ENDS
+
+def setupNetwork():
+ "Create network"
+ topo = spineTopo()
+ #if controller_ip == '':
+ #controller_ip = '10.0.2.2';
+ # controller_ip = '127.0.0.1';
+ network = Mininet(topo=topo, switch=OVSSwitch, link=TCLink, autoSetMacs = True, controller=None)
+ network.start()
+ CLI( network )
+ network.stop()
+
+if __name__ == '__main__':
+ setLogLevel('info')
+ #setLogLevel('debug')
+ setupNetwork()
diff --git a/TestON/tests/CHOTestMonkey/dependencies/topologies/topoSpineIpv6.py b/TestON/tests/CHOTestMonkey/dependencies/topologies/topoSpineIpv6.py
new file mode 100755
index 0000000..3f35494
--- /dev/null
+++ b/TestON/tests/CHOTestMonkey/dependencies/topologies/topoSpineIpv6.py
@@ -0,0 +1,441 @@
+#!/usr/bin/python
+from mininet.topo import Topo
+from mininet.net import Mininet
+from mininet.node import Host, RemoteController
+from mininet.node import Node
+from mininet.node import CPULimitedHost
+from mininet.link import TCLink
+from mininet.cli import CLI
+from mininet.log import setLogLevel
+from mininet.util import dumpNodeConnections
+from mininet.node import ( UserSwitch, OVSSwitch, IVSSwitch )
+
+class dualStackHost( Host ):
+ def config( self, v6Addr='1000::1/64', **params ):
+ r = super( Host, self ).config( **params )
+ intf = self.defaultIntf()
+ self.cmd( 'ip -6 addr add %s dev %s' % ( v6Addr, intf ) )
+ return r
+
+class spineTopo( Topo ):
+
+ def __init__( self, **opts ):
+ "Create a topology."
+
+ # Initialize Topology
+ Topo.__init__( self, **opts )
+
+ # add nodes, Leaf switches
+ s1 = self.addSwitch( 's1' )
+ s2 = self.addSwitch( 's2' )
+ s3 = self.addSwitch( 's3' )
+ s4 = self.addSwitch( 's4' )
+ s5 = self.addSwitch( 's5' )
+ s6 = self.addSwitch( 's6' )
+ s7 = self.addSwitch( 's7' )
+ s8 = self.addSwitch( 's8' )
+ s9 = self.addSwitch( 's9' )
+ s10 = self.addSwitch( 's10' )
+ s11 = self.addSwitch( 's11' )
+ s12 = self.addSwitch( 's12' )
+ s13 = self.addSwitch( 's13' )
+ s14 = self.addSwitch( 's14' )
+
+ # add nodes, Spine switches first...
+ s15 = self.addSwitch( 's15' )
+ s16 = self.addSwitch( 's16' )
+ s17 = self.addSwitch( 's17' )
+ s18 = self.addSwitch( 's18' )
+ s19 = self.addSwitch( 's19' )
+ s20 = self.addSwitch( 's20' )
+ s21 = self.addSwitch( 's21' )
+ s22 = self.addSwitch( 's22' )
+ s23 = self.addSwitch( 's23' )
+ s24 = self.addSwitch( 's24' )
+ s25 = self.addSwitch( 's25' )
+ s26 = self.addSwitch( 's26' )
+ s27 = self.addSwitch( 's27' )
+ s28 = self.addSwitch( 's28' )
+ s29 = self.addSwitch( 's29' )
+ s30 = self.addSwitch( 's30' )
+ s31 = self.addSwitch( 's31' )
+ s32 = self.addSwitch( 's32' )
+ s33 = self.addSwitch( 's33' )
+ s34 = self.addSwitch( 's34' )
+ s35 = self.addSwitch( 's35' )
+ s36 = self.addSwitch( 's36' )
+ s37 = self.addSwitch( 's37' )
+ s38 = self.addSwitch( 's38' )
+ s39 = self.addSwitch( 's39' )
+ s40 = self.addSwitch( 's40' )
+ s41 = self.addSwitch( 's41' )
+ s42 = self.addSwitch( 's42' )
+ s43 = self.addSwitch( 's43' )
+ s44 = self.addSwitch( 's44' )
+ s45 = self.addSwitch( 's45' )
+ s46 = self.addSwitch( 's46' )
+ s47 = self.addSwitch( 's47' )
+ s48 = self.addSwitch( 's48' )
+ s49 = self.addSwitch( 's49' )
+ s50 = self.addSwitch( 's50' )
+ s51 = self.addSwitch( 's51' )
+ s52 = self.addSwitch( 's52' )
+ s53 = self.addSwitch( 's53' )
+ s54 = self.addSwitch( 's54' )
+ s55 = self.addSwitch( 's55' )
+ s56 = self.addSwitch( 's56' )
+ s57 = self.addSwitch( 's57' )
+ s58 = self.addSwitch( 's58' )
+ s59 = self.addSwitch( 's59' )
+ s60 = self.addSwitch( 's60' )
+ s61 = self.addSwitch( 's61' )
+ s62 = self.addSwitch( 's62' )
+ s63 = self.addSwitch( 's63' )
+ s64 = self.addSwitch( 's64' )
+ s65 = self.addSwitch( 's65' )
+ s66 = self.addSwitch( 's66' )
+ s67 = self.addSwitch( 's67' )
+ s68 = self.addSwitch( 's68' )
+ s69 = self.addSwitch( 's69' )
+ s70 = self.addSwitch( 's70' )
+ s71 = self.addSwitch( 's71' )
+ s72 = self.addSwitch( 's72' )
+ s73 = self.addSwitch( 's73' )
+ s74 = self.addSwitch( 's74' )
+ s75 = self.addSwitch( 's75' )
+ s76 = self.addSwitch( 's76' )
+ s77 = self.addSwitch( 's77' )
+ s78 = self.addSwitch( 's78' )
+
+
+ # ... and now hosts
+ # s1_host = self.addHost( 'h1', ip='10.1.0.1/24', cls=dualStackHost, v6Addr='1000::1/64' )
+ # s2_host = self.addHost( 'h2', ip='10.1.0.2/24', cls=dualStackHost, v6Addr='1000::2/64' )
+ # s3_host = self.addHost( 'h3', ip='10.1.0.3/24', cls=dualStackHost, v6Addr='1000::3/64' )
+ # s4_host = self.addHost( 'h4', ip='10.1.0.4/24', cls=dualStackHost, v6Addr='1000::4/64' )
+ # s5_host = self.addHost( 'h5', ip='10.1.0.5/24', cls=dualStackHost, v6Addr='1000::5/64' )
+ # s6_host = self.addHost( 'h6', ip='10.1.0.6/24', cls=dualStackHost, v6Addr='1000::6/64' )
+ # s7_host = self.addHost( 'h7', ip='10.1.0.7/24', cls=dualStackHost, v6Addr='1000::7/64' )
+ # s8_host = self.addHost( 'h8', ip='10.1.0.8/24', cls=dualStackHost, v6Addr='1000::8/64' )
+ # s9_host = self.addHost( 'h9', ip='10.1.0.9/24', cls=dualStackHost, v6Addr='1000::9/64' )
+ # s10_host = self.addHost( 'h10', ip='10.1.0.10/24', cls=dualStackHost, v6Addr='1000::10/64' )
+ s11_host = self.addHost( 'h11', ip='10.1.0.11/24', cls=dualStackHost, v6Addr='1000::11/64' )
+ s12_host = self.addHost( 'h12', ip='10.1.0.12/24', cls=dualStackHost, v6Addr='1000::12/64' )
+ s13_host = self.addHost( 'h13', ip='10.1.0.13/24', cls=dualStackHost, v6Addr='1000::13/64' )
+ s14_host = self.addHost( 'h14', ip='10.1.0.14/24', cls=dualStackHost, v6Addr='1000::14/64' )
+ s15_host = self.addHost( 'h15', ip='10.1.0.15/24', cls=dualStackHost, v6Addr='1000::15/64' )
+ s16_host = self.addHost( 'h16', ip='10.1.0.16/24', cls=dualStackHost, v6Addr='1000::16/64' )
+ s17_host = self.addHost( 'h17', ip='10.1.0.17/24', cls=dualStackHost, v6Addr='1000::17/64' )
+ s18_host = self.addHost( 'h18', ip='10.1.0.18/24', cls=dualStackHost, v6Addr='1000::18/64' )
+ s19_host = self.addHost( 'h19', ip='10.1.0.19/24', cls=dualStackHost, v6Addr='1000::19/64' )
+ s20_host = self.addHost( 'h20', ip='10.1.0.20/24', cls=dualStackHost, v6Addr='1000::20/64' )
+ s21_host = self.addHost( 'h21', ip='10.1.0.21/24', cls=dualStackHost, v6Addr='1000::21/64' )
+ s22_host = self.addHost( 'h22', ip='10.1.0.22/24', cls=dualStackHost, v6Addr='1000::22/64' )
+ s23_host = self.addHost( 'h23', ip='10.1.0.23/24', cls=dualStackHost, v6Addr='1000::23/64' )
+ s24_host = self.addHost( 'h24', ip='10.1.0.24/24', cls=dualStackHost, v6Addr='1000::24/64' )
+ s25_host = self.addHost( 'h25', ip='10.1.0.25/24', cls=dualStackHost, v6Addr='1000::25/64' )
+ s26_host = self.addHost( 'h26', ip='10.1.0.26/24', cls=dualStackHost, v6Addr='1000::26/64' )
+ s27_host = self.addHost( 'h27', ip='10.1.0.27/24', cls=dualStackHost, v6Addr='1000::27/64' )
+ s28_host = self.addHost( 'h28', ip='10.1.0.28/24', cls=dualStackHost, v6Addr='1000::28/64' )
+ s29_host = self.addHost( 'h29', ip='10.1.0.29/24', cls=dualStackHost, v6Addr='1000::29/64' )
+ s30_host = self.addHost( 'h30', ip='10.1.0.30/24', cls=dualStackHost, v6Addr='1000::30/64' )
+ s31_host = self.addHost( 'h31', ip='10.1.0.31/24', cls=dualStackHost, v6Addr='1000::31/64' )
+ s32_host = self.addHost( 'h32', ip='10.1.0.32/24', cls=dualStackHost, v6Addr='1000::32/64' )
+ s33_host = self.addHost( 'h33', ip='10.1.0.33/24', cls=dualStackHost, v6Addr='1000::33/64' )
+ s34_host = self.addHost( 'h34', ip='10.1.0.34/24', cls=dualStackHost, v6Addr='1000::34/64' )
+ s35_host = self.addHost( 'h35', ip='10.1.0.35/24', cls=dualStackHost, v6Addr='1000::35/64' )
+ s36_host = self.addHost( 'h36', ip='10.1.0.36/24', cls=dualStackHost, v6Addr='1000::36/64' )
+ s37_host = self.addHost( 'h37', ip='10.1.0.37/24', cls=dualStackHost, v6Addr='1000::37/64' )
+ s38_host = self.addHost( 'h38', ip='10.1.0.38/24', cls=dualStackHost, v6Addr='1000::38/64' )
+ s39_host = self.addHost( 'h39', ip='10.1.0.39/24', cls=dualStackHost, v6Addr='1000::39/64' )
+ s40_host = self.addHost( 'h40', ip='10.1.0.40/24', cls=dualStackHost, v6Addr='1000::40/64' )
+ s41_host = self.addHost( 'h41', ip='10.1.0.41/24', cls=dualStackHost, v6Addr='1000::41/64' )
+ s42_host = self.addHost( 'h42', ip='10.1.0.42/24', cls=dualStackHost, v6Addr='1000::42/64' )
+ s43_host = self.addHost( 'h43', ip='10.1.0.43/24', cls=dualStackHost, v6Addr='1000::43/64' )
+ s44_host = self.addHost( 'h44', ip='10.1.0.44/24', cls=dualStackHost, v6Addr='1000::44/64' )
+ s45_host = self.addHost( 'h45', ip='10.1.0.45/24', cls=dualStackHost, v6Addr='1000::45/64' )
+ s46_host = self.addHost( 'h46', ip='10.1.0.46/24', cls=dualStackHost, v6Addr='1000::46/64' )
+ s47_host = self.addHost( 'h47', ip='10.1.0.47/24', cls=dualStackHost, v6Addr='1000::47/64' )
+ s48_host = self.addHost( 'h48', ip='10.1.0.48/24', cls=dualStackHost, v6Addr='1000::48/64' )
+ s49_host = self.addHost( 'h49', ip='10.1.0.49/24', cls=dualStackHost, v6Addr='1000::49/64' )
+ s50_host = self.addHost( 'h50', ip='10.1.0.50/24', cls=dualStackHost, v6Addr='1000::50/64' )
+ s51_host = self.addHost( 'h51', ip='10.1.0.51/24', cls=dualStackHost, v6Addr='1000::51/64' )
+ s52_host = self.addHost( 'h52', ip='10.1.0.52/24', cls=dualStackHost, v6Addr='1000::52/64' )
+ s53_host = self.addHost( 'h53', ip='10.1.0.53/24', cls=dualStackHost, v6Addr='1000::53/64' )
+ s54_host = self.addHost( 'h54', ip='10.1.0.54/24', cls=dualStackHost, v6Addr='1000::54/64' )
+ s55_host = self.addHost( 'h55', ip='10.1.0.55/24', cls=dualStackHost, v6Addr='1000::55/64' )
+ s56_host = self.addHost( 'h56', ip='10.1.0.56/24', cls=dualStackHost, v6Addr='1000::56/64' )
+ s57_host = self.addHost( 'h57', ip='10.1.0.57/24', cls=dualStackHost, v6Addr='1000::57/64' )
+ s58_host = self.addHost( 'h58', ip='10.1.0.58/24', cls=dualStackHost, v6Addr='1000::58/64' )
+ s59_host = self.addHost( 'h59', ip='10.1.0.59/24', cls=dualStackHost, v6Addr='1000::59/64' )
+ s60_host = self.addHost( 'h60', ip='10.1.0.60/24', cls=dualStackHost, v6Addr='1000::60/64' )
+ s61_host = self.addHost( 'h61', ip='10.1.0.61/24', cls=dualStackHost, v6Addr='1000::61/64' )
+ s62_host = self.addHost( 'h62', ip='10.1.0.62/24', cls=dualStackHost, v6Addr='1000::62/64' )
+ s63_host = self.addHost( 'h63', ip='10.1.0.63/24', cls=dualStackHost, v6Addr='1000::63/64' )
+ s64_host = self.addHost( 'h64', ip='10.1.0.64/24', cls=dualStackHost, v6Addr='1000::64/64' )
+ s65_host = self.addHost( 'h65', ip='10.1.0.65/24', cls=dualStackHost, v6Addr='1000::65/64' )
+ s66_host = self.addHost( 'h66', ip='10.1.0.66/24', cls=dualStackHost, v6Addr='1000::66/64' )
+ s67_host = self.addHost( 'h67', ip='10.1.0.67/24', cls=dualStackHost, v6Addr='1000::67/64' )
+ s68_host = self.addHost( 'h68', ip='10.1.0.68/24', cls=dualStackHost, v6Addr='1000::68/64' )
+ s69_host = self.addHost( 'h69', ip='10.1.0.69/24', cls=dualStackHost, v6Addr='1000::69/64' )
+ s70_host = self.addHost( 'h70', ip='10.1.0.70/24', cls=dualStackHost, v6Addr='1000::70/64' )
+ s71_host = self.addHost( 'h71', ip='10.1.0.71/24', cls=dualStackHost, v6Addr='1000::71/64' )
+ s72_host = self.addHost( 'h72', ip='10.1.0.72/24', cls=dualStackHost, v6Addr='1000::72/64' )
+ s73_host = self.addHost( 'h73', ip='10.1.0.73/24', cls=dualStackHost, v6Addr='1000::73/64' )
+ s74_host = self.addHost( 'h74', ip='10.1.0.74/24', cls=dualStackHost, v6Addr='1000::74/64' )
+ s75_host = self.addHost( 'h75', ip='10.1.0.75/24', cls=dualStackHost, v6Addr='1000::75/64' )
+ s76_host = self.addHost( 'h76', ip='10.1.0.76/24', cls=dualStackHost, v6Addr='1000::76/64' )
+ s77_host = self.addHost( 'h77', ip='10.1.0.77/24', cls=dualStackHost, v6Addr='1000::77/64' )
+ s78_host = self.addHost( 'h78', ip='10.1.0.78/24', cls=dualStackHost, v6Addr='1000::78/64' )
+
+ # add edges between switch and corresponding host
+ #self.addLink( s1 , s1_host )
+ #self.addLink( s2 , s2_host )
+ #self.addLink( s3 , s3_host )
+ #self.addLink( s4 , s4_host )
+ #self.addLink( s5 , s5_host )
+ #self.addLink( s6 , s6_host )
+ #self.addLink( s7 , s7_host )
+ #self.addLink( s8 , s8_host )
+ #self.addLink( s9 , s9_host )
+ #self.addLink( s10 , s10_host )
+ self.addLink( s11 , s11_host )
+ self.addLink( s12 , s12_host )
+ self.addLink( s13 , s13_host )
+ self.addLink( s14 , s14_host )
+ self.addLink( s15 , s15_host )
+ self.addLink( s16 , s16_host )
+ self.addLink( s17 , s17_host )
+ self.addLink( s18 , s18_host )
+ self.addLink( s19 , s19_host )
+ self.addLink( s20 , s20_host )
+ self.addLink( s21 , s21_host )
+ self.addLink( s22 , s22_host )
+ self.addLink( s23 , s23_host )
+ self.addLink( s24 , s24_host )
+ self.addLink( s25 , s25_host )
+ self.addLink( s26 , s26_host )
+ self.addLink( s27 , s27_host )
+ self.addLink( s28 , s28_host )
+ self.addLink( s29 , s29_host )
+ self.addLink( s30 , s30_host )
+ self.addLink( s31 , s31_host )
+ self.addLink( s32 , s32_host )
+ self.addLink( s33 , s33_host )
+ self.addLink( s34 , s34_host )
+ self.addLink( s35 , s35_host )
+ self.addLink( s36 , s36_host )
+ self.addLink( s37 , s37_host )
+ self.addLink( s38 , s38_host )
+ self.addLink( s39 , s39_host )
+ self.addLink( s40 , s40_host )
+ self.addLink( s41 , s41_host )
+ self.addLink( s42 , s42_host )
+ self.addLink( s43 , s43_host )
+ self.addLink( s44 , s44_host )
+ self.addLink( s45 , s45_host )
+ self.addLink( s46 , s46_host )
+ self.addLink( s47 , s47_host )
+ self.addLink( s48 , s48_host )
+ self.addLink( s49 , s49_host )
+ self.addLink( s50 , s50_host )
+ self.addLink( s51 , s51_host )
+ self.addLink( s52 , s52_host )
+ self.addLink( s53 , s53_host )
+ self.addLink( s54 , s54_host )
+ self.addLink( s55 , s55_host )
+ self.addLink( s56 , s56_host )
+ self.addLink( s57 , s57_host )
+ self.addLink( s58 , s58_host )
+ self.addLink( s59 , s59_host )
+ self.addLink( s60 , s60_host )
+ self.addLink( s61 , s61_host )
+ self.addLink( s62 , s62_host )
+ self.addLink( s63 , s63_host )
+ self.addLink( s64 , s64_host )
+ self.addLink( s65 , s65_host )
+ self.addLink( s66 , s66_host )
+ self.addLink( s67 , s67_host )
+ self.addLink( s68 , s68_host )
+ self.addLink( s69 , s69_host )
+ self.addLink( s70 , s70_host )
+ self.addLink( s71 , s71_host )
+ self.addLink( s72 , s72_host )
+ self.addLink( s73 , s73_host )
+ self.addLink( s74 , s74_host )
+ self.addLink( s75 , s75_host )
+ self.addLink( s76 , s76_host )
+ self.addLink( s77 , s77_host )
+ self.addLink( s78 , s78_host )
+
+ #info( '*** Add Leaf links\n')
+ self.addLink(s1, s9)
+ self.addLink(s2, s10)
+ self.addLink(s3, s9)
+ self.addLink(s4, s10)
+ self.addLink(s5, s9)
+ self.addLink(s6, s10)
+ self.addLink(s7, s9)
+ self.addLink(s8, s10)
+ self.addLink(s9, s11)
+ self.addLink(s9, s12)
+ self.addLink(s10, s13)
+ self.addLink(s10, s14)
+ self.addLink(s11, s12)
+ self.addLink(s13, s14)
+
+ #info( '*** Add Spine-1 links\n')
+ self.addLink(s15, s1)
+ self.addLink(s15, s2)
+ self.addLink(s16, s1)
+ self.addLink(s16, s2)
+ self.addLink(s17, s1)
+ self.addLink(s17, s2)
+ self.addLink(s18, s1)
+ self.addLink(s18, s2)
+ self.addLink(s19, s1)
+ self.addLink(s19, s2)
+ self.addLink(s20, s1)
+ self.addLink(s20, s2)
+ self.addLink(s21, s1)
+ self.addLink(s21, s2)
+ self.addLink(s22, s1)
+ self.addLink(s22, s2)
+ self.addLink(s23, s1)
+ self.addLink(s23, s2)
+ self.addLink(s24, s1)
+ self.addLink(s24, s2)
+ self.addLink(s25, s1)
+ self.addLink(s25, s2)
+ self.addLink(s26, s1)
+ self.addLink(s26, s2)
+ self.addLink(s27, s1)
+ self.addLink(s27, s2)
+ self.addLink(s28, s1)
+ self.addLink(s28, s2)
+ self.addLink(s29, s1)
+ self.addLink(s29, s2)
+ self.addLink(s30, s1)
+ self.addLink(s30, s2)
+
+ #info( '*** Add Spine-2 links\n')
+ self.addLink(s31, s3)
+ self.addLink(s31, s4)
+ self.addLink(s32, s3)
+ self.addLink(s32, s4)
+ self.addLink(s33, s3)
+ self.addLink(s33, s4)
+ self.addLink(s34, s3)
+ self.addLink(s34, s4)
+ self.addLink(s35, s3)
+ self.addLink(s35, s4)
+ self.addLink(s36, s3)
+ self.addLink(s36, s4)
+ self.addLink(s37, s3)
+ self.addLink(s37, s4)
+ self.addLink(s38, s3)
+ self.addLink(s38, s4)
+ self.addLink(s39, s3)
+ self.addLink(s39, s4)
+ self.addLink(s40, s3)
+ self.addLink(s40, s4)
+ self.addLink(s41, s3)
+ self.addLink(s41, s4)
+ self.addLink(s42, s3)
+ self.addLink(s42, s4)
+ self.addLink(s43, s3)
+ self.addLink(s43, s4)
+ self.addLink(s44, s3)
+ self.addLink(s44, s4)
+ self.addLink(s45, s3)
+ self.addLink(s45, s4)
+ self.addLink(s46, s3)
+ self.addLink(s46, s4)
+
+ #info( '*** Add Spine-3 links\n')
+ self.addLink(s47, s5)
+ self.addLink(s47, s6)
+ self.addLink(s48, s5)
+ self.addLink(s48, s6)
+ self.addLink(s49, s5)
+ self.addLink(s49, s6)
+ self.addLink(s50, s5)
+ self.addLink(s50, s6)
+ self.addLink(s51, s5)
+ self.addLink(s51, s6)
+ self.addLink(s52, s5)
+ self.addLink(s52, s6)
+ self.addLink(s53, s5)
+ self.addLink(s53, s6)
+ self.addLink(s54, s5)
+ self.addLink(s54, s6)
+ self.addLink(s55, s5)
+ self.addLink(s55, s6)
+ self.addLink(s56, s5)
+ self.addLink(s56, s6)
+ self.addLink(s57, s5)
+ self.addLink(s57, s6)
+ self.addLink(s58, s5)
+ self.addLink(s58, s6)
+ self.addLink(s59, s5)
+ self.addLink(s59, s6)
+ self.addLink(s60, s5)
+ self.addLink(s60, s6)
+ self.addLink(s61, s5)
+ self.addLink(s61, s6)
+ self.addLink(s62, s5)
+ self.addLink(s62, s6)
+
+ #info( '*** Add Spine-4 links\n')
+ self.addLink(s63, s7)
+ self.addLink(s63, s8)
+ self.addLink(s64, s7)
+ self.addLink(s64, s8)
+ self.addLink(s65, s7)
+ self.addLink(s65, s8)
+ self.addLink(s66, s7)
+ self.addLink(s66, s8)
+ self.addLink(s67, s7)
+ self.addLink(s67, s8)
+ self.addLink(s68, s7)
+ self.addLink(s68, s8)
+ self.addLink(s69, s7)
+ self.addLink(s69, s8)
+ self.addLink(s70, s7)
+ self.addLink(s70, s8)
+ self.addLink(s71, s7)
+ self.addLink(s71, s8)
+ self.addLink(s72, s7)
+ self.addLink(s72, s8)
+ self.addLink(s73, s7)
+ self.addLink(s73, s8)
+ self.addLink(s74, s7)
+ self.addLink(s74, s8)
+ self.addLink(s75, s7)
+ self.addLink(s75, s8)
+ self.addLink(s76, s7)
+ self.addLink(s76, s8)
+ self.addLink(s77, s7)
+ self.addLink(s77, s8)
+ self.addLink(s78, s7)
+ self.addLink(s78, s8)
+
+topos = { 'spine': ( lambda: spineTopo() ) }
+
+# HERE THE CODE DEFINITION OF THE TOPOLOGY ENDS
+
+def setupNetwork():
+ "Create network"
+ topo = spineTopo()
+ #if controller_ip == '':
+ #controller_ip = '10.0.2.2';
+ # controller_ip = '127.0.0.1';
+ network = Mininet(topo=topo, switch=OVSSwitch, link=TCLink, autoSetMacs = True, controller=None)
+ network.start()
+ CLI( network )
+ network.stop()
+
+if __name__ == '__main__':
+ setLogLevel('info')
+ #setLogLevel('debug')
+ setupNetwork()
diff --git a/TestON/tests/CHOTestMonkey/dependencies/topologies/topoTripleIpv6.py b/TestON/tests/CHOTestMonkey/dependencies/topologies/topoTripleIpv6.py
new file mode 100755
index 0000000..2a53b3d
--- /dev/null
+++ b/TestON/tests/CHOTestMonkey/dependencies/topologies/topoTripleIpv6.py
@@ -0,0 +1,65 @@
+#!/usr/bin/python
+"""
+"""
+from mininet.topo import Topo
+from mininet.net import Mininet
+from mininet.node import Host, RemoteController
+from mininet.node import Node
+from mininet.node import CPULimitedHost
+from mininet.link import TCLink
+from mininet.cli import CLI
+from mininet.log import setLogLevel
+from mininet.util import dumpNodeConnections
+from mininet.node import ( UserSwitch, OVSSwitch, IVSSwitch )
+
+class dualStackHost( Host ):
+ def config( self, v6Addr='1000::1/64', **params ):
+ r = super( Host, self ).config( **params )
+ intf = self.defaultIntf()
+ self.cmd( 'ip -6 addr add %s dev %s' % ( v6Addr, intf ) )
+ return r
+
+class tripleTopo( Topo ):
+
+ def __init__( self, **opts ):
+ "Create a topology."
+
+ # Initialize Topology
+ Topo.__init__( self, **opts )
+
+ s1 = self.addSwitch( 's1' )
+ s2 = self.addSwitch( 's2' )
+ s3 = self.addSwitch( 's3' )
+
+ # ... and now hosts
+ s1_host = self.addHost( 'h1', ip='10.1.0.1/24', cls=dualStackHost, v6Addr='1000::1/64' )
+ s2_host = self.addHost( 'h2', ip='10.1.0.2/24', cls=dualStackHost, v6Addr='1000::2/64' )
+ s3_host = self.addHost( 'h3', ip='10.1.0.3/24', cls=dualStackHost, v6Addr='1000::3/64' )
+
+ # add edges between switch and corresponding host
+ self.addLink( s1 , s1_host )
+ self.addLink( s2 , s2_host )
+ self.addLink( s3 , s3_host )
+ self.addLink(s1, s2)
+ self.addLink(s1, s3)
+ self.addLink(s2, s3)
+
+topos = { 'triple': ( lambda: tripleTopo() ) }
+
+# HERE THE CODE DEFINITION OF THE TOPOLOGY ENDS
+
+def setupNetwork():
+ "Create network"
+ topo = tripleTopo()
+ #if controller_ip == '':
+ #controller_ip = '10.0.2.2';
+ # controller_ip = '127.0.0.1';
+ network = Mininet(topo=topo, switch=OVSSwitch, autoSetMacs=True, controller=None)
+ network.start()
+ CLI( network )
+ network.stop()
+
+if __name__ == '__main__':
+ setLogLevel('info')
+ #setLogLevel('debug')
+ setupNetwork()