blob: af9250c0c9b54e207bad5ad4297a7fbc5755be2d [file] [log] [blame]
Pier6a0c4de2018-03-18 16:01:30 -07001"""
2Copyright 2018 Open Networking Foundation ( ONF )
3
4Please refer questions to either the onos test mailing list at <onos-test@onosproject.org>,
5the System Testing Plans and Results wiki page at <https://wiki.onosproject.org/x/voMg>,
6or the System Testing Guide page at <https://wiki.onosproject.org/x/WYQg>
7
8 TestON is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 2 of the License, or
11 ( at your option ) any later version.
12
13 TestON is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with TestON. If not, see <http://www.gnu.org/licenses/>.
20"""
21
You Wange24d6272018-03-27 21:18:50 -070022import time
Pier6a0c4de2018-03-18 16:01:30 -070023
You Wangc02d8352018-04-17 16:42:10 -070024def setupTest( main, test_idx, onosNodes ):
25 from tests.USECASE.SegmentRouting.dependencies.Testcaselib import Testcaselib as lib
You Wang68568b12019-03-04 11:49:57 -080026 import tests.USECASE.SegmentRouting.dependencies.cfgtranslator as translator
27
Jon Hall9b0de1f2020-08-24 15:38:04 -070028 try:
29 skipPackage = False
30 init = False
31 if not hasattr( main, "apps" ):
32 init = True
33 lib.initTest( main )
34 # Skip onos packaging if the cluster size stays the same
35 if not init and onosNodes == main.Cluster.numCtrls:
36 skipPackage = True
Pier6a0c4de2018-03-18 16:01:30 -070037
Jon Hall9b0de1f2020-08-24 15:38:04 -070038 main.resultFileName = "CASE%03d" % test_idx
39 main.Cluster.setRunningNode( onosNodes )
40 lib.installOnos( main, skipPackage=skipPackage, cliSleep=5 )
41 # Load configuration files
42 main.step( "Load configurations" )
43 main.cfgName = "TEST_CONFIG_ipv4=1_ipv6=1" if hasattr( main, "Mininet1" ) else main.params[ "DEPENDENCY" ][ "confName" ]
You Wang68568b12019-03-04 11:49:57 -080044 if main.useBmv2:
Jon Hall9b0de1f2020-08-24 15:38:04 -070045 # Translate configuration file from OVS-OFDPA to BMv2 driver
46 translator.bmv2ToOfdpa( main ) # Try to cleanup if switching between switch types
47 switchPrefix = main.params[ 'DEPENDENCY' ].get( 'switchPrefix', "bmv2" )
48 translator.ofdpaToBmv2( main, switchPrefix=switchPrefix )
49 else:
50 translator.bmv2ToOfdpa( main )
51 lib.loadJson( main )
52 time.sleep( float( main.params[ "timers" ][ "loadNetcfgSleep" ] ) )
53 main.cfgName = "common" if hasattr( main, "Mininet1" ) else main.params[ "DEPENDENCY" ][ "confName" ]
54 lib.loadMulticastConfig( main )
55 lib.loadHost( main )
Pier6a0c4de2018-03-18 16:01:30 -070056
Jon Hall9b0de1f2020-08-24 15:38:04 -070057 if hasattr( main, "Mininet1" ):
58 # Run the test with Mininet
59 mininet_args = " --dhcp=1 --routers=1 --ipv6=1 --ipv4=1"
60 if main.useBmv2:
Jon Hallf69e3162020-09-01 09:08:44 -070061 mininet_args += ' --switch %s' % main.switchType
62 main.log.info( "Using %s switch" % main.switchType )
Jon Hall9b0de1f2020-08-24 15:38:04 -070063 lib.startMininet( main, main.params[ "DEPENDENCY" ][ "topology" ], args=mininet_args )
64 time.sleep( float( main.params[ "timers" ][ "startMininetSleep" ] ) )
65 else:
66 # Run the test with physical devices
67 lib.connectToPhysicalNetwork( main )
68
69 # Create scapy components
70 lib.startScapyHosts( main )
71 # Verify host IP assignment
72 lib.verifyOnosHostIp( main )
73 lib.verifyNetworkHostIp( main )
74 except Exception as e:
75 main.log.exception( "Error in setupTest" )
76 main.skipCase( result="FAIL", msg=e )
You Wangece951a2018-04-16 13:34:43 -070077
You Wangc02d8352018-04-17 16:42:10 -070078def verifyMcastRoutes( main ):
79 """
80 Install multicast routes and check traffic
81 """
82 from tests.USECASE.SegmentRouting.dependencies.Testcaselib import Testcaselib as lib
83 for routeName in main.mcastRoutes.keys():
You Wangc02d8352018-04-17 16:42:10 -070084 installMcastRoute( main, routeName )
85 lib.verifyMulticastTraffic( main, routeName, True )
You Wange24d6272018-03-27 21:18:50 -070086
You Wangc02d8352018-04-17 16:42:10 -070087def installMcastRoute( main, routeName ):
88 """
89 Install a multicast route
90 """
You Wang85747762018-05-11 15:51:50 -070091 main.step( "Install {} multicast route".format( routeName ) )
You Wangc02d8352018-04-17 16:42:10 -070092 routeData = main.multicastConfig[ routeName ]
93 src = main.mcastRoutes[ routeName ][ "src" ]
94 dst = main.mcastRoutes[ routeName ][ "dst" ]
95 main.Cluster.active( 0 ).CLI.mcastHostJoin( routeData[ "src" ][ src[ 0 ] ][ "ip" ], routeData[ "group" ],
You Wang547893e2018-05-08 13:34:59 -070096 [ routeData[ "src" ][ i ][ "id" ] for i in src ],
You Wangc02d8352018-04-17 16:42:10 -070097 [ routeData[ "dst" ][ i ][ "id" ] for i in dst ] )
98 time.sleep( float( main.params[ "timers" ][ "mcastSleep" ] ) )
You Wange24d6272018-03-27 21:18:50 -070099
You Wangc02d8352018-04-17 16:42:10 -0700100def verifyMcastRouteRemoval( main, routeName ):
101 """
102 Verify removal of a multicast route
103 """
104 routeData = main.multicastConfig[ routeName ]
You Wang85747762018-05-11 15:51:50 -0700105 main.step( "Remove {} route".format( routeName ) )
You Wang547893e2018-05-08 13:34:59 -0700106 main.Cluster.active( 0 ).CLI.mcastSinkDelete( routeData[ "src" ][ 0 ][ "ip" ], routeData[ "group" ] )
You Wangc02d8352018-04-17 16:42:10 -0700107 # TODO: verify the deletion
You Wange24d6272018-03-27 21:18:50 -0700108
You Wangc02d8352018-04-17 16:42:10 -0700109def verifyMcastSinkRemoval( main, routeName, sinkIndex, expect ):
110 """
111 Verify removal of a multicast sink
112 """
113 from tests.USECASE.SegmentRouting.dependencies.Testcaselib import Testcaselib as lib
114 routeData = main.multicastConfig[ routeName ]
115 sinkId = routeData[ "dst" ][ sinkIndex ][ "id" ]
You Wang85747762018-05-11 15:51:50 -0700116 main.step( "Remove sink {} of route {}".format( sinkId, routeName ) )
You Wang547893e2018-05-08 13:34:59 -0700117 main.Cluster.active( 0 ).CLI.mcastSinkDelete( routeData[ "src" ][ 0 ][ "ip" ], routeData[ "group" ], sinkId )
You Wangc02d8352018-04-17 16:42:10 -0700118 time.sleep( float( main.params[ "timers" ][ "mcastSleep" ] ) )
119 lib.verifyMulticastTraffic( main, routeName, expect )
You Wange24d6272018-03-27 21:18:50 -0700120
You Wangc02d8352018-04-17 16:42:10 -0700121def verifyMcastSourceRemoval( main, routeName, sourceIndex, expect ):
122 """
123 Verify removal of a multicast source
124 """
125 from tests.USECASE.SegmentRouting.dependencies.Testcaselib import Testcaselib as lib
126 routeData = main.multicastConfig[ routeName ]
You Wang547893e2018-05-08 13:34:59 -0700127 sourceId = [ routeData[ "src" ][ sourceIndex ][ "id" ] ]
You Wang85747762018-05-11 15:51:50 -0700128 main.step( "Remove source {} of route {}".format( sourceId, routeName ) )
You Wang547893e2018-05-08 13:34:59 -0700129 main.Cluster.active( 0 ).CLI.mcastSourceDelete( routeData[ "src" ][ 0 ][ "ip" ], routeData[ "group" ], sourceId )
You Wangc02d8352018-04-17 16:42:10 -0700130 time.sleep( float( main.params[ "timers" ][ "mcastSleep" ] ) )
131 lib.verifyMulticastTraffic( main, routeName, expect )
You Wange24d6272018-03-27 21:18:50 -0700132
You Wangc02d8352018-04-17 16:42:10 -0700133def verifyMcastRemoval( main, removeDHT1=True ):
134 """
135 Verify removal of IPv6 route, IPv4 sinks and IPv4 source
136 """
137 from tests.USECASE.SegmentRouting.dependencies.Testcaselib import Testcaselib as lib
138 verifyMcastRouteRemoval( main, "ipv6" )
139 if removeDHT1:
140 verifyMcastSinkRemoval( main, "ipv4", 0, [ False, True, True ] )
141 verifyMcastSinkRemoval( main, "ipv4", 1, [ False, False, True ] )
142 else:
143 verifyMcastSinkRemoval( main, "ipv4", 2, [ True, True, False ] )
144 verifyMcastSinkRemoval( main, "ipv4", 1, [ True, False, False ] )
145 verifyMcastSourceRemoval( main, "ipv4", 0, False )
You Wange24d6272018-03-27 21:18:50 -0700146
You Wang547893e2018-05-08 13:34:59 -0700147def verifyLinkDown( main, link, affectedLinkNum, expectList={ "ipv4": True, "ipv6": True }, hostsToDiscover=[], hostLocations={} ):
You Wangc02d8352018-04-17 16:42:10 -0700148 """
149 Kill a batch of links and verify traffic
150 Restore the links and verify traffic
151 """
152 from tests.USECASE.SegmentRouting.dependencies.Testcaselib import Testcaselib as lib
153 link = link if ( isinstance( link, list ) and isinstance( link[ 0 ], list ) ) else [ link ]
154 # Kill the link(s)
155 lib.killLinkBatch( main, link, int( main.params[ "TOPO" ][ "linkNum" ] ) - affectedLinkNum, int( main.params[ "TOPO" ][ "switchNum" ] ) )
156 for routeName in expectList.keys():
157 lib.verifyMulticastTraffic( main, routeName, expectList[ routeName ] )
158 # Restore the link(s)
159 lib.restoreLinkBatch( main, link, int( main.params[ "TOPO" ][ "linkNum" ] ), int( main.params[ "TOPO" ][ "switchNum" ] ) )
You Wang547893e2018-05-08 13:34:59 -0700160 if hostsToDiscover:
161 main.Network.discoverHosts( hostList=hostsToDiscover )
You Wang85747762018-05-11 15:51:50 -0700162 if hostLocations:
You Wang5c4a6382018-05-16 15:36:41 -0700163 lib.verifyHostLocations( main, hostLocations, retry=int( main.params[ "RETRY" ][ "hostDiscovery" ] ) )
You Wangc02d8352018-04-17 16:42:10 -0700164 for routeName in expectList.keys():
165 lib.verifyMulticastTraffic( main, routeName, True )
You Wange24d6272018-03-27 21:18:50 -0700166
You Wang547893e2018-05-08 13:34:59 -0700167def verifyPortDown( main, dpid, port, expectList={ "ipv4": True, "ipv6": True }, hostsToDiscover=[], hostLocations={} ):
168 """
169 Disable a port and verify traffic
170 Reenable the port and verify traffic
171 """
172 from tests.USECASE.SegmentRouting.dependencies.Testcaselib import Testcaselib as lib
You Wang5c4a6382018-05-16 15:36:41 -0700173 # Disable the port(s)
You Wang547893e2018-05-08 13:34:59 -0700174 main.step( "Disable port {}/{}".format( dpid, port ) )
175 main.Cluster.active( 0 ).CLI.portstate( dpid=dpid, port=port, state="disable" )
176 time.sleep( 10 )
177 for routeName in expectList.keys():
178 lib.verifyMulticastTraffic( main, routeName, expectList[ routeName ] )
You Wang5c4a6382018-05-16 15:36:41 -0700179 # Reenable the port(s)
180 main.step( "Enable port {}/{}".format( dpid, port ) )
You Wang547893e2018-05-08 13:34:59 -0700181 main.Cluster.active( 0 ).CLI.portstate( dpid=dpid, port=port, state="enable" )
182 if hostsToDiscover:
183 main.Network.discoverHosts( hostList=hostsToDiscover )
You Wang85747762018-05-11 15:51:50 -0700184 if hostLocations:
You Wang5c4a6382018-05-16 15:36:41 -0700185 lib.verifyHostLocations( main, hostLocations, retry=int( main.params[ "RETRY" ][ "hostDiscovery" ] ) )
You Wang547893e2018-05-08 13:34:59 -0700186 for routeName in expectList.keys():
187 lib.verifyMulticastTraffic( main, routeName, True )
188
189def verifySwitchDown( main, switchName, affectedLinkNum, expectList={ "ipv4": True, "ipv6": True }, hostsToDiscover=[], hostLocations={} ):
You Wangc02d8352018-04-17 16:42:10 -0700190 """
191 Kill a batch of switches and verify traffic
192 Recover the swithces and verify traffic
193 """
194 from tests.USECASE.SegmentRouting.dependencies.Testcaselib import Testcaselib as lib
195 switchName = switchName if isinstance( switchName, list ) else [ switchName ]
196 # Kill the switch(es)
197 lib.killSwitch( main, switchName, int( main.params[ "TOPO" ][ "switchNum" ] ) - len( switchName ), int( main.params[ "TOPO" ][ "linkNum" ] ) - affectedLinkNum )
198 for routeName in expectList.keys():
199 lib.verifyMulticastTraffic( main, routeName, expectList[ routeName ] )
200 # Recover the switch(es)
You Wang547893e2018-05-08 13:34:59 -0700201 lib.recoverSwitch( main, switchName, int( main.params[ "TOPO" ][ "switchNum" ] ), int( main.params[ "TOPO" ][ "linkNum" ] ), True if hostsToDiscover else False, hostsToDiscover )
You Wang85747762018-05-11 15:51:50 -0700202 if hostLocations:
You Wang5c4a6382018-05-16 15:36:41 -0700203 lib.verifyHostLocations( main, hostLocations, retry=int( main.params[ "RETRY" ][ "hostDiscovery" ] ) )
You Wangc02d8352018-04-17 16:42:10 -0700204 for routeName in expectList.keys():
205 lib.verifyMulticastTraffic( main, routeName, True )
You Wange24d6272018-03-27 21:18:50 -0700206
You Wangc02d8352018-04-17 16:42:10 -0700207def verifyOnosDown( main, expectList={ "ipv4": True, "ipv6": True } ):
208 """
209 Kill and recover ONOS instances Sequencially and check traffic
210 """
211 from tests.USECASE.SegmentRouting.dependencies.Testcaselib import Testcaselib as lib
212 import json
213 numCtrls = len( main.Cluster.runningNodes )
214 links = len( json.loads( main.Cluster.next().links() ) )
215 switches = len( json.loads( main.Cluster.next().devices() ) )
216 for ctrl in xrange( numCtrls ):
217 # Kill node
218 lib.killOnos( main, [ ctrl ], switches, links, ( numCtrls - 1 ) )
219 main.Cluster.active(0).CLI.balanceMasters()
220 time.sleep( float( main.params[ 'timers' ][ 'balanceMasterSleep' ] ) )
221 for routeName in expectList.keys():
222 lib.verifyMulticastTraffic( main, routeName, True )
223 # Recover node
224 lib.recoverOnos( main, [ ctrl ], switches, links, numCtrls )
225 main.Cluster.active(0).CLI.balanceMasters()
226 time.sleep( float( main.params[ 'timers' ][ 'balanceMasterSleep' ] ) )
227 for routeName in expectList.keys():
228 lib.verifyMulticastTraffic( main, routeName, True )