blob: 4dfcd533491b21e734a552c80dce2888bb33d5d1 [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
Jon Hall06fd0df2021-01-25 15:50:06 -080047 switchPrefix = main.params[ 'DEPENDENCY' ].get( 'switchPrefix', '' )
48 if switchPrefix is None:
49 switchPrefix = ''
Jon Hall9b0de1f2020-08-24 15:38:04 -070050 translator.ofdpaToBmv2( main, switchPrefix=switchPrefix )
51 else:
52 translator.bmv2ToOfdpa( main )
Jon Hall06fd0df2021-01-25 15:50:06 -080053 if not main.persistentSetup:
54 lib.loadJson( main )
Jon Hall9b0de1f2020-08-24 15:38:04 -070055 time.sleep( float( main.params[ "timers" ][ "loadNetcfgSleep" ] ) )
56 main.cfgName = "common" if hasattr( main, "Mininet1" ) else main.params[ "DEPENDENCY" ][ "confName" ]
57 lib.loadMulticastConfig( main )
58 lib.loadHost( main )
Pier6a0c4de2018-03-18 16:01:30 -070059
Jon Hall9b0de1f2020-08-24 15:38:04 -070060 if hasattr( main, "Mininet1" ):
61 # Run the test with Mininet
62 mininet_args = " --dhcp=1 --routers=1 --ipv6=1 --ipv4=1"
63 if main.useBmv2:
Jon Hallf69e3162020-09-01 09:08:44 -070064 mininet_args += ' --switch %s' % main.switchType
65 main.log.info( "Using %s switch" % main.switchType )
Jon Hall9b0de1f2020-08-24 15:38:04 -070066 lib.startMininet( main, main.params[ "DEPENDENCY" ][ "topology" ], args=mininet_args )
67 time.sleep( float( main.params[ "timers" ][ "startMininetSleep" ] ) )
68 else:
69 # Run the test with physical devices
70 lib.connectToPhysicalNetwork( main )
71
72 # Create scapy components
73 lib.startScapyHosts( main )
74 # Verify host IP assignment
75 lib.verifyOnosHostIp( main )
76 lib.verifyNetworkHostIp( main )
77 except Exception as e:
78 main.log.exception( "Error in setupTest" )
79 main.skipCase( result="FAIL", msg=e )
You Wangece951a2018-04-16 13:34:43 -070080
You Wangc02d8352018-04-17 16:42:10 -070081def verifyMcastRoutes( main ):
82 """
83 Install multicast routes and check traffic
84 """
85 from tests.USECASE.SegmentRouting.dependencies.Testcaselib import Testcaselib as lib
86 for routeName in main.mcastRoutes.keys():
You Wangc02d8352018-04-17 16:42:10 -070087 installMcastRoute( main, routeName )
88 lib.verifyMulticastTraffic( main, routeName, True )
You Wange24d6272018-03-27 21:18:50 -070089
You Wangc02d8352018-04-17 16:42:10 -070090def installMcastRoute( main, routeName ):
91 """
92 Install a multicast route
93 """
You Wang85747762018-05-11 15:51:50 -070094 main.step( "Install {} multicast route".format( routeName ) )
You Wangc02d8352018-04-17 16:42:10 -070095 routeData = main.multicastConfig[ routeName ]
96 src = main.mcastRoutes[ routeName ][ "src" ]
97 dst = main.mcastRoutes[ routeName ][ "dst" ]
98 main.Cluster.active( 0 ).CLI.mcastHostJoin( routeData[ "src" ][ src[ 0 ] ][ "ip" ], routeData[ "group" ],
You Wang547893e2018-05-08 13:34:59 -070099 [ routeData[ "src" ][ i ][ "id" ] for i in src ],
You Wangc02d8352018-04-17 16:42:10 -0700100 [ routeData[ "dst" ][ i ][ "id" ] for i in dst ] )
101 time.sleep( float( main.params[ "timers" ][ "mcastSleep" ] ) )
You Wange24d6272018-03-27 21:18:50 -0700102
You Wangc02d8352018-04-17 16:42:10 -0700103def verifyMcastRouteRemoval( main, routeName ):
104 """
105 Verify removal of a multicast route
106 """
107 routeData = main.multicastConfig[ routeName ]
You Wang85747762018-05-11 15:51:50 -0700108 main.step( "Remove {} route".format( routeName ) )
You Wang547893e2018-05-08 13:34:59 -0700109 main.Cluster.active( 0 ).CLI.mcastSinkDelete( routeData[ "src" ][ 0 ][ "ip" ], routeData[ "group" ] )
You Wangc02d8352018-04-17 16:42:10 -0700110 # TODO: verify the deletion
You Wange24d6272018-03-27 21:18:50 -0700111
You Wangc02d8352018-04-17 16:42:10 -0700112def verifyMcastSinkRemoval( main, routeName, sinkIndex, expect ):
113 """
114 Verify removal of a multicast sink
115 """
116 from tests.USECASE.SegmentRouting.dependencies.Testcaselib import Testcaselib as lib
117 routeData = main.multicastConfig[ routeName ]
118 sinkId = routeData[ "dst" ][ sinkIndex ][ "id" ]
You Wang85747762018-05-11 15:51:50 -0700119 main.step( "Remove sink {} of route {}".format( sinkId, routeName ) )
You Wang547893e2018-05-08 13:34:59 -0700120 main.Cluster.active( 0 ).CLI.mcastSinkDelete( routeData[ "src" ][ 0 ][ "ip" ], routeData[ "group" ], sinkId )
You Wangc02d8352018-04-17 16:42:10 -0700121 time.sleep( float( main.params[ "timers" ][ "mcastSleep" ] ) )
122 lib.verifyMulticastTraffic( main, routeName, expect )
You Wange24d6272018-03-27 21:18:50 -0700123
You Wangc02d8352018-04-17 16:42:10 -0700124def verifyMcastSourceRemoval( main, routeName, sourceIndex, expect ):
125 """
126 Verify removal of a multicast source
127 """
128 from tests.USECASE.SegmentRouting.dependencies.Testcaselib import Testcaselib as lib
129 routeData = main.multicastConfig[ routeName ]
You Wang547893e2018-05-08 13:34:59 -0700130 sourceId = [ routeData[ "src" ][ sourceIndex ][ "id" ] ]
You Wang85747762018-05-11 15:51:50 -0700131 main.step( "Remove source {} of route {}".format( sourceId, routeName ) )
You Wang547893e2018-05-08 13:34:59 -0700132 main.Cluster.active( 0 ).CLI.mcastSourceDelete( routeData[ "src" ][ 0 ][ "ip" ], routeData[ "group" ], sourceId )
You Wangc02d8352018-04-17 16:42:10 -0700133 time.sleep( float( main.params[ "timers" ][ "mcastSleep" ] ) )
134 lib.verifyMulticastTraffic( main, routeName, expect )
You Wange24d6272018-03-27 21:18:50 -0700135
You Wangc02d8352018-04-17 16:42:10 -0700136def verifyMcastRemoval( main, removeDHT1=True ):
137 """
138 Verify removal of IPv6 route, IPv4 sinks and IPv4 source
139 """
140 from tests.USECASE.SegmentRouting.dependencies.Testcaselib import Testcaselib as lib
141 verifyMcastRouteRemoval( main, "ipv6" )
142 if removeDHT1:
143 verifyMcastSinkRemoval( main, "ipv4", 0, [ False, True, True ] )
144 verifyMcastSinkRemoval( main, "ipv4", 1, [ False, False, True ] )
145 else:
146 verifyMcastSinkRemoval( main, "ipv4", 2, [ True, True, False ] )
147 verifyMcastSinkRemoval( main, "ipv4", 1, [ True, False, False ] )
148 verifyMcastSourceRemoval( main, "ipv4", 0, False )
You Wange24d6272018-03-27 21:18:50 -0700149
You Wang547893e2018-05-08 13:34:59 -0700150def verifyLinkDown( main, link, affectedLinkNum, expectList={ "ipv4": True, "ipv6": True }, hostsToDiscover=[], hostLocations={} ):
You Wangc02d8352018-04-17 16:42:10 -0700151 """
152 Kill a batch of links and verify traffic
153 Restore the links and verify traffic
154 """
155 from tests.USECASE.SegmentRouting.dependencies.Testcaselib import Testcaselib as lib
156 link = link if ( isinstance( link, list ) and isinstance( link[ 0 ], list ) ) else [ link ]
157 # Kill the link(s)
158 lib.killLinkBatch( main, link, int( main.params[ "TOPO" ][ "linkNum" ] ) - affectedLinkNum, int( main.params[ "TOPO" ][ "switchNum" ] ) )
159 for routeName in expectList.keys():
160 lib.verifyMulticastTraffic( main, routeName, expectList[ routeName ] )
161 # Restore the link(s)
162 lib.restoreLinkBatch( main, link, int( main.params[ "TOPO" ][ "linkNum" ] ), int( main.params[ "TOPO" ][ "switchNum" ] ) )
You Wang547893e2018-05-08 13:34:59 -0700163 if hostsToDiscover:
164 main.Network.discoverHosts( hostList=hostsToDiscover )
You Wang85747762018-05-11 15:51:50 -0700165 if hostLocations:
You Wang5c4a6382018-05-16 15:36:41 -0700166 lib.verifyHostLocations( main, hostLocations, retry=int( main.params[ "RETRY" ][ "hostDiscovery" ] ) )
You Wangc02d8352018-04-17 16:42:10 -0700167 for routeName in expectList.keys():
168 lib.verifyMulticastTraffic( main, routeName, True )
You Wange24d6272018-03-27 21:18:50 -0700169
You Wang547893e2018-05-08 13:34:59 -0700170def verifyPortDown( main, dpid, port, expectList={ "ipv4": True, "ipv6": True }, hostsToDiscover=[], hostLocations={} ):
171 """
172 Disable a port and verify traffic
173 Reenable the port and verify traffic
174 """
175 from tests.USECASE.SegmentRouting.dependencies.Testcaselib import Testcaselib as lib
You Wang5c4a6382018-05-16 15:36:41 -0700176 # Disable the port(s)
You Wang547893e2018-05-08 13:34:59 -0700177 main.step( "Disable port {}/{}".format( dpid, port ) )
178 main.Cluster.active( 0 ).CLI.portstate( dpid=dpid, port=port, state="disable" )
179 time.sleep( 10 )
180 for routeName in expectList.keys():
181 lib.verifyMulticastTraffic( main, routeName, expectList[ routeName ] )
You Wang5c4a6382018-05-16 15:36:41 -0700182 # Reenable the port(s)
183 main.step( "Enable port {}/{}".format( dpid, port ) )
You Wang547893e2018-05-08 13:34:59 -0700184 main.Cluster.active( 0 ).CLI.portstate( dpid=dpid, port=port, state="enable" )
185 if hostsToDiscover:
186 main.Network.discoverHosts( hostList=hostsToDiscover )
You Wang85747762018-05-11 15:51:50 -0700187 if hostLocations:
You Wang5c4a6382018-05-16 15:36:41 -0700188 lib.verifyHostLocations( main, hostLocations, retry=int( main.params[ "RETRY" ][ "hostDiscovery" ] ) )
You Wang547893e2018-05-08 13:34:59 -0700189 for routeName in expectList.keys():
190 lib.verifyMulticastTraffic( main, routeName, True )
191
192def verifySwitchDown( main, switchName, affectedLinkNum, expectList={ "ipv4": True, "ipv6": True }, hostsToDiscover=[], hostLocations={} ):
You Wangc02d8352018-04-17 16:42:10 -0700193 """
194 Kill a batch of switches and verify traffic
195 Recover the swithces and verify traffic
196 """
197 from tests.USECASE.SegmentRouting.dependencies.Testcaselib import Testcaselib as lib
198 switchName = switchName if isinstance( switchName, list ) else [ switchName ]
199 # Kill the switch(es)
200 lib.killSwitch( main, switchName, int( main.params[ "TOPO" ][ "switchNum" ] ) - len( switchName ), int( main.params[ "TOPO" ][ "linkNum" ] ) - affectedLinkNum )
201 for routeName in expectList.keys():
202 lib.verifyMulticastTraffic( main, routeName, expectList[ routeName ] )
203 # Recover the switch(es)
You Wang547893e2018-05-08 13:34:59 -0700204 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 -0700205 if hostLocations:
You Wang5c4a6382018-05-16 15:36:41 -0700206 lib.verifyHostLocations( main, hostLocations, retry=int( main.params[ "RETRY" ][ "hostDiscovery" ] ) )
You Wangc02d8352018-04-17 16:42:10 -0700207 for routeName in expectList.keys():
208 lib.verifyMulticastTraffic( main, routeName, True )
You Wange24d6272018-03-27 21:18:50 -0700209
You Wangc02d8352018-04-17 16:42:10 -0700210def verifyOnosDown( main, expectList={ "ipv4": True, "ipv6": True } ):
211 """
212 Kill and recover ONOS instances Sequencially and check traffic
213 """
214 from tests.USECASE.SegmentRouting.dependencies.Testcaselib import Testcaselib as lib
215 import json
216 numCtrls = len( main.Cluster.runningNodes )
217 links = len( json.loads( main.Cluster.next().links() ) )
218 switches = len( json.loads( main.Cluster.next().devices() ) )
219 for ctrl in xrange( numCtrls ):
220 # Kill node
221 lib.killOnos( main, [ ctrl ], switches, links, ( numCtrls - 1 ) )
222 main.Cluster.active(0).CLI.balanceMasters()
223 time.sleep( float( main.params[ 'timers' ][ 'balanceMasterSleep' ] ) )
224 for routeName in expectList.keys():
225 lib.verifyMulticastTraffic( main, routeName, True )
226 # Recover node
227 lib.recoverOnos( main, [ ctrl ], switches, links, numCtrls )
228 main.Cluster.active(0).CLI.balanceMasters()
229 time.sleep( float( main.params[ 'timers' ][ 'balanceMasterSleep' ] ) )
230 for routeName in expectList.keys():
231 lib.verifyMulticastTraffic( main, routeName, True )