blob: 50d3329079e7243d299441196b195890466775d5 [file] [log] [blame]
Andreas Pantelopoulos90f0b102018-02-01 13:21:45 -08001"""
2Copyright 2017 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
Jon Halla604fd42018-05-04 14:27:27 -070022def setupTest( main, test_idx, onosNodes=-1, ipv4=True, ipv6=True,
23 external=True, static=False, countFlowsGroups=False ):
You Wang5da39c82018-04-26 22:55:08 -070024 """
25 SRRouting test setup
26 """
27 from tests.USECASE.SegmentRouting.dependencies.Testcaselib import Testcaselib as lib
You Wang68568b12019-03-04 11:49:57 -080028 import tests.USECASE.SegmentRouting.dependencies.cfgtranslator as translator
You Wangd66de192018-04-30 17:30:12 -070029 import time
30
Jon Hall9b0de1f2020-08-24 15:38:04 -070031 try:
32 skipPackage = False
33 init = False
34 if not hasattr( main, 'apps' ):
35 init = True
36 lib.initTest( main )
37 if onosNodes < 0:
38 onosNodes = main.Cluster.numCtrls
39 # Skip onos packaging if the cluster size stays the same
40 if not init and onosNodes == main.Cluster.numCtrls:
41 skipPackage = True
You Wang5da39c82018-04-26 22:55:08 -070042
Jon Hall9b0de1f2020-08-24 15:38:04 -070043 main.internalIpv4Hosts = main.params[ 'TOPO' ][ 'internalIpv4Hosts' ].split( ',' )
Siddesha2938fe2021-04-06 02:46:06 +000044 main.internalIpv6Hosts = main.params[ 'TOPO' ][ 'internalIpv6Hosts' ].split( ',' ) if main.params[ 'TOPO' ].get( 'internalIpv6Hosts' ) else []
Jon Hall9b0de1f2020-08-24 15:38:04 -070045 main.externalIpv4Hosts = main.params[ 'TOPO' ][ 'externalIpv4Hosts' ].split( ',' ) if main.params[ 'TOPO' ].get('externalIpv4Hosts') else []
46 main.externalIpv6Hosts = main.params[ 'TOPO' ][ 'externalIpv6Hosts' ].split( ',' ) if main.params[ 'TOPO' ].get('externalIpv6Hosts') else []
47 main.staticIpv4Hosts = main.params[ 'TOPO' ][ 'staticIpv4Hosts' ].split( ',' ) if main.params[ 'TOPO' ].get('staticIpv4Hosts') else []
48 main.staticIpv6Hosts = main.params[ 'TOPO' ][ 'staticIpv6Hosts' ].split( ',' ) if main.params[ 'TOPO' ].get('staticIpv6Hosts') else []
49 main.disconnectedIpv4Hosts = []
50 main.disconnectedIpv6Hosts = []
51 main.disconnectedExternalIpv4Hosts = []
52 main.disconnectedExternalIpv6Hosts = []
53 main.disconnectedStaticIpv4Hosts = []
54 main.disconnectedStaticIpv6Hosts = []
55 main.resultFileName = 'CASE%03d' % test_idx
56 main.Cluster.setRunningNode( onosNodes )
You Wang5da39c82018-04-26 22:55:08 -070057
Jon Hall9b0de1f2020-08-24 15:38:04 -070058 lib.installOnos( main, skipPackage=skipPackage, cliSleep=5 )
You Wangd66de192018-04-30 17:30:12 -070059
Jon Hall9b0de1f2020-08-24 15:38:04 -070060 # Load configuration files
61 if hasattr( main, "Mininet1" ):
62 main.cfgName = 'TEST_CONFIG_ipv4={}_ipv6={}'.format( 1 if ipv4 else 0,
63 1 if ipv6 else 0)
64 else:
65 main.cfgName = main.params[ "DEPENDENCY" ][ "confName" ]
Jon Hall06fd0df2021-01-25 15:50:06 -080066 if not main.persistentSetup:
Siddesha2938fe2021-04-06 02:46:06 +000067 if main.useBmv2:
68 # Translate configuration file from OVS-OFDPA to BMv2 driver
69 translator.bmv2ToOfdpa( main ) # Try to cleanup if switching between switch types
70 switchPrefix = main.params[ 'DEPENDENCY' ].get( 'switchPrefix', '' )
71 if switchPrefix is None:
72 switchPrefix = ''
73 translator.ofdpaToBmv2( main, switchPrefix=switchPrefix )
74 else:
75 translator.bmv2ToOfdpa( main )
Jon Hall06fd0df2021-01-25 15:50:06 -080076 lib.loadJson( main )
Jon Hall9b0de1f2020-08-24 15:38:04 -070077 main.log.debug( "sleeping %i seconds" % float( main.params[ 'timers' ][ 'loadNetcfgSleep' ] ) )
78 time.sleep( float( main.params[ 'timers' ][ 'loadNetcfgSleep' ] ) )
79 lib.loadHost( main )
You Wang0fc21702018-11-02 17:49:18 -070080
Jon Hall9b0de1f2020-08-24 15:38:04 -070081 # if static route flag add routes
82 # these routes are topology specific
Siddesh715a9192021-11-03 19:51:20 +000083 # these should be in the params file
Jon Hall9b0de1f2020-08-24 15:38:04 -070084 if static:
85 if ipv4:
86 lib.addStaticOnosRoute( main, "10.0.88.0/24", "10.0.1.1")
87 lib.addStaticOnosRoute( main, "10.0.88.0/24", "10.0.5.1")
88 if ipv6:
89 lib.addStaticOnosRoute( main, "2000::8700/120", "2000::101")
90 lib.addStaticOnosRoute( main, "2000::8700/120", "2000::501")
91 if countFlowsGroups:
92 lib.loadCount( main )
93
94 if hasattr( main, 'Mininet1' ):
95 lib.mnDockerSetup( main )
96 # Run the test with Mininet
97 mininet_args = ' --dhcp=1 --routers=1 --ipv6={} --ipv4={}'.format( 1 if ipv6 else 0,
98 1 if ipv4 else 0 )
99 if main.useBmv2:
100 mininet_args += ' --switch %s' % main.switchType
101 main.log.info( "Using %s switch" % main.switchType )
102 lib.startMininet( main, main.params[ 'DEPENDENCY' ][ 'topology' ], args=mininet_args )
103 main.log.debug( "Waiting %i seconds for ONOS to discover dataplane" % float( main.params[ "timers" ][ "startMininetSleep" ] ))
104 time.sleep( float( main.params[ "timers" ][ "startMininetSleep" ] ) )
105 else:
106 # Run the test with physical devices
107 lib.connectToPhysicalNetwork( main )
108
Jon Hall9b0de1f2020-08-24 15:38:04 -0700109 # wait some time for onos to install the rules!
110 main.log.info( "Waiting %i seconds for ONOS to program the dataplane" % float( main.params[ "timers" ][ "dhcpSleep" ] ))
111 time.sleep( float( main.params[ 'timers' ][ 'dhcpSleep' ] ) )
112 except Exception as e:
113 main.log.exception( "Error in setupTest" )
114 main.skipCase( result="FAIL", msg=e )
You Wang5da39c82018-04-26 22:55:08 -0700115
Siddeshec3efb32021-11-19 17:57:43 +0000116def verifyPingInternal( main, ipv4=True, ipv6=True, disconnected=True, skipOnFail=True, expect=True ):
You Wang5da39c82018-04-26 22:55:08 -0700117 """
118 Verify all connected internal hosts are able to reach each other,
119 and disconnected internal hosts cannot reach any other internal host
120 """
121 from tests.USECASE.SegmentRouting.dependencies.Testcaselib import Testcaselib as lib
122 # Verify connected hosts
You Wangd66de192018-04-30 17:30:12 -0700123 if ipv4:
124 lib.verifyPing( main,
125 [ h for h in main.internalIpv4Hosts if h not in main.disconnectedIpv4Hosts ],
You Wang85747762018-05-11 15:51:50 -0700126 [ h for h in main.internalIpv4Hosts if h not in main.disconnectedIpv4Hosts ],
Siddeshec3efb32021-11-19 17:57:43 +0000127 stepMsg="Verify reachability of connected internal IPv4 hosts", skipOnFail=skipOnFail, expect=expect )
You Wangd66de192018-04-30 17:30:12 -0700128 if ipv6:
129 lib.verifyPing( main,
130 [ h for h in main.internalIpv6Hosts if h not in main.disconnectedIpv6Hosts ],
131 [ h for h in main.internalIpv6Hosts if h not in main.disconnectedIpv6Hosts ],
You Wang42f9e8a2018-07-11 13:25:11 -0700132 ipv6=True,
Siddeshec3efb32021-11-19 17:57:43 +0000133 stepMsg="Verify reachability of connected internal IPv6 hosts", skipOnFail=skipOnFail, expect=expect )
You Wang5da39c82018-04-26 22:55:08 -0700134 # Verify disconnected hosts
You Wangd66de192018-04-30 17:30:12 -0700135 if disconnected:
You Wangd66de192018-04-30 17:30:12 -0700136 if main.disconnectedIpv4Hosts:
You Wang85747762018-05-11 15:51:50 -0700137 lib.verifyPing( main, main.internalIpv4Hosts, main.disconnectedIpv4Hosts, expect=False,
138 stepMsg="Verify unreachability of disconnected internal IPv4 hosts" )
You Wangd66de192018-04-30 17:30:12 -0700139 if main.disconnectedIpv6Hosts:
You Wang85747762018-05-11 15:51:50 -0700140 lib.verifyPing( main, main.internalIpv6Hosts, main.disconnectedIpv6Hosts, ipv6=True, expect=False,
141 stepMsg="Verify unreachability of disconnected internal IPv6 hosts" )
You Wang5da39c82018-04-26 22:55:08 -0700142
Siddeshec3efb32021-11-19 17:57:43 +0000143def verifyPingExternal( main, ipv4=True, ipv6=True, disconnected=True, skipOnFail=True, expect=True ):
You Wang5da39c82018-04-26 22:55:08 -0700144 """
145 Verify all connected internal hosts are able to reach external hosts,
146 and disconnected internal hosts cannot reach any external host
147 """
148 from tests.USECASE.SegmentRouting.dependencies.Testcaselib import Testcaselib as lib
149 # Verify connected hosts
You Wangd66de192018-04-30 17:30:12 -0700150 if ipv4:
151 lib.verifyPing( main,
152 [ h for h in main.internalIpv4Hosts if h not in main.disconnectedIpv4Hosts ],
You Wang85747762018-05-11 15:51:50 -0700153 [ h for h in main.externalIpv4Hosts if h not in main.disconnectedExternalIpv4Hosts ],
You Wang54b1d672018-06-11 16:44:13 -0700154 stepMsg="Verify reachability from connected internal IPv4 hosts to external IPv4 hosts",
Siddeshec3efb32021-11-19 17:57:43 +0000155 t3Simple=False, skipOnFail=skipOnFail, expect=expect )
You Wangd66de192018-04-30 17:30:12 -0700156 if ipv6:
157 lib.verifyPing( main,
158 [ h for h in main.internalIpv6Hosts if h not in main.disconnectedIpv6Hosts ],
Jonghwan Hyun3759e472018-05-01 15:40:08 -0700159 [ h for h in main.externalIpv6Hosts if h not in main.disconnectedExternalIpv6Hosts ],
You Wang42f9e8a2018-07-11 13:25:11 -0700160 ipv6=True,
You Wang54b1d672018-06-11 16:44:13 -0700161 stepMsg="Verify reachability from connected internal IPv6 hosts to external IPv6 hosts",
Siddeshec3efb32021-11-19 17:57:43 +0000162 t3Simple=False, skipOnFail=skipOnFail, expect=expect )
You Wang5da39c82018-04-26 22:55:08 -0700163 # Verify disconnected hosts
You Wangd66de192018-04-30 17:30:12 -0700164 if disconnected:
Jonghwan Hyun3759e472018-05-01 15:40:08 -0700165 # Disconnected internal to connected external
You Wangd66de192018-04-30 17:30:12 -0700166 if main.disconnectedIpv4Hosts:
Jonghwan Hyun3759e472018-05-01 15:40:08 -0700167 lib.verifyPing( main, main.disconnectedIpv4Hosts,
168 [ h for h in main.externalIpv4Hosts if h not in main.disconnectedExternalIpv4Hosts ],
You Wang85747762018-05-11 15:51:50 -0700169 expect=False,
You Wang54b1d672018-06-11 16:44:13 -0700170 stepMsg="Verify unreachability of disconnected internal IPv4 hosts to connected external IPv4 hosts",
171 t3Simple=False )
You Wangd66de192018-04-30 17:30:12 -0700172 if main.disconnectedIpv6Hosts:
Jonghwan Hyun3759e472018-05-01 15:40:08 -0700173 lib.verifyPing( main, main.disconnectedIpv6Hosts,
174 [ h for h in main.externalIpv6Hosts if h not in main.disconnectedExternalIpv6Hosts ],
You Wang85747762018-05-11 15:51:50 -0700175 ipv6=True, expect=False,
You Wang54b1d672018-06-11 16:44:13 -0700176 stepMsg="Verify unreachability of disconnected internal IPv6 hosts to connected external IPv6 hosts",
177 t3Simple=False )
Jonghwan Hyun3759e472018-05-01 15:40:08 -0700178 # Connected internal to disconnected external
179 if main.disconnectedExternalIpv4Hosts:
180 lib.verifyPing( main,
181 [ h for h in main.internalIpv4Hosts if h not in main.disconnectedIpv4Hosts ],
182 main.disconnectedExternalIpv4Hosts,
You Wang85747762018-05-11 15:51:50 -0700183 expect=False,
You Wang54b1d672018-06-11 16:44:13 -0700184 stepMsg="Verify unreachability of connected internal IPv4 hosts to disconnected external IPv4 hosts",
185 t3Simple=False )
Jonghwan Hyun3759e472018-05-01 15:40:08 -0700186 if main.disconnectedExternalIpv6Hosts:
187 lib.verifyPing( main,
188 [ h for h in main.internalIpv6Hosts if h not in main.disconnectedIpv6Hosts ],
189 main.disconnectedExternalIpv6Hosts,
You Wang85747762018-05-11 15:51:50 -0700190 ipv6=True, expect=False,
You Wang54b1d672018-06-11 16:44:13 -0700191 stepMsg="Verify unreachability of connected internal IPv6 hosts to disconnected external IPv6 hosts",
192 t3Simple=False )
You Wang5da39c82018-04-26 22:55:08 -0700193
Siddeshec3efb32021-11-19 17:57:43 +0000194def verifyPing( main, ipv4=True, ipv6=True, disconnected=False, internal=True, external=True, skipOnFail=True, expect=True ):
You Wang5da39c82018-04-26 22:55:08 -0700195 """
196 Verify reachability and unreachability of connected/disconnected hosts
197 """
You Wangd66de192018-04-30 17:30:12 -0700198 if internal:
Siddeshec3efb32021-11-19 17:57:43 +0000199 verifyPingInternal( main, ipv4, ipv6, disconnected, skipOnFail, expect=expect )
You Wangd66de192018-04-30 17:30:12 -0700200 if external:
Siddeshec3efb32021-11-19 17:57:43 +0000201 verifyPingExternal( main, ipv4, ipv6, disconnected, skipOnFail, expect=expect )
You Wangd66de192018-04-30 17:30:12 -0700202
Siddeshec3efb32021-11-19 17:57:43 +0000203def verifyLinkFailure( main, linksToRemove, expectedLinks, expectedSwitches, ipv4=True, ipv6=True, disconnected=False,
204 internal=True, external=True, countFlowsGroups=False, skipOnFail=True, expectedConnectivity=True ):
You Wangd66de192018-04-30 17:30:12 -0700205 """
Siddeshec3efb32021-11-19 17:57:43 +0000206 Kill all links sequencially and run verifications
You Wangd66de192018-04-30 17:30:12 -0700207 """
208 from tests.USECASE.SegmentRouting.dependencies.Testcaselib import Testcaselib as lib
Siddeshec3efb32021-11-19 17:57:43 +0000209 #linksToRemove = [ ["leaf1", 260] ]
210 if hasattr( main, "Mininet1" ):
211 skipOnFail=True
212 lib.killLinkBatch( main, linksToRemove, expectedLinks, expectedSwitches )
213 else:
214 skipOnFail=False
215 for link in linksToRemove:
216 main.Cluster.next().portstate( dpid="device:"+link[0], port=link[1], state="disable" )
217 verifyPing( main, ipv4, ipv6, disconnected, internal, external, skipOnFail=skipOnFail, expect=expectedConnectivity )
218
219def verifyLinksRestored( main, linksToRemove, expectedLinks, expectedSwitches, ipv4=True, ipv6=True, disconnected=False,
220 internal=True, external=True, countFlowsGroups=False, skipOnFail=True, topoSleep=30 ):
221 """
222 Recover all links sequencially and run verifications
223 """
224 from tests.USECASE.SegmentRouting.dependencies.Testcaselib import Testcaselib as lib
225 import time
226 if hasattr( main, "Mininet1"):
227 lib.restoreLinkBatch( main, linksToRemove, expectedLinks, expectedSwitches )
228 else:
229 for link in linksToRemove:
230 main.Cluster.next().portstate( dpid="device:"+link[0], port=link[1], state="enable" )
231 time.sleep(topoSleep)
232 lib.discoverHosts(main)
233 verifyPing( main, ipv4, ipv6, disconnected, internal, external )
You Wangd66de192018-04-30 17:30:12 -0700234
Jon Halla604fd42018-05-04 14:27:27 -0700235def verifySwitchFailure( main, ipv4=True, ipv6=True, disconnected=False,
236 internal=True, external=True, countFlowsGroups=False ):
You Wangd66de192018-04-30 17:30:12 -0700237 """
238 Kill and recover spine101 and 102 sequencially and run verifications
239 """
240 from tests.USECASE.SegmentRouting.dependencies.Testcaselib import Testcaselib as lib
241 for switchToKill in [ "spine101", "spine102" ]:
Siddeshec3efb32021-11-19 17:57:43 +0000242 lib.killSwitch( main, switchToKill, expectedLinks, expectedSwitches )
You Wangd66de192018-04-30 17:30:12 -0700243 verify( main, ipv4, ipv6, disconnected, internal, external, countFlowsGroups )
Siddeshec3efb32021-11-19 17:57:43 +0000244 lib.recoverSwitch( main, switchToKill, expectedLinks, expectedSwitches )
You Wangd66de192018-04-30 17:30:12 -0700245 verify( main, ipv4, ipv6, disconnected, internal, external, countFlowsGroups )
246
Jon Halla604fd42018-05-04 14:27:27 -0700247def verifyOnosFailure( main, ipv4=True, ipv6=True, disconnected=False,
248 internal=True, external=True, countFlowsGroups=False ):
You Wangd66de192018-04-30 17:30:12 -0700249 """
250 Kill and recover onos nodes sequencially and run verifications
251 """
252 from tests.USECASE.SegmentRouting.dependencies.Testcaselib import Testcaselib as lib
253 import json
254 import time
255
256 numCtrls = len( main.Cluster.runningNodes )
257 links = len( json.loads( main.Cluster.next().links() ) )
258 switches = len( json.loads( main.Cluster.next().devices() ) )
Jon Halla604fd42018-05-04 14:27:27 -0700259 mastershipSleep = float( main.params[ 'timers' ][ 'balanceMasterSleep' ] )
You Wangd66de192018-04-30 17:30:12 -0700260 for ctrl in xrange( numCtrls ):
261 # Kill node
262 lib.killOnos( main, [ ctrl ], switches, links, ( numCtrls - 1 ) )
263 main.Cluster.active(0).CLI.balanceMasters()
Jon Hall43060f62020-06-23 13:13:33 -0700264 main.log.debug( "sleeping %i seconds" % mastershipSleep )
Jon Halla604fd42018-05-04 14:27:27 -0700265 time.sleep( mastershipSleep )
You Wangd66de192018-04-30 17:30:12 -0700266 verify( main, ipv4, ipv6, disconnected, internal, external, countFlowsGroups )
267 # Recover node
268 lib.recoverOnos( main, [ ctrl ], switches, links, numCtrls )
269 main.Cluster.active(0).CLI.balanceMasters()
Jon Hall43060f62020-06-23 13:13:33 -0700270 main.log.debug( "sleeping %i seconds" % mastershipSleep )
Jon Halla604fd42018-05-04 14:27:27 -0700271 time.sleep( mastershipSleep )
You Wangd66de192018-04-30 17:30:12 -0700272 verify( main, ipv4, ipv6, disconnected, internal, external, countFlowsGroups )
273
274def verify( main, ipv4=True, ipv6=True, disconnected=True, internal=True, external=True, countFlowsGroups=False ):
275 """
276 Verify host IP assignment, flow/group number and pings
277 """
278 from tests.USECASE.SegmentRouting.dependencies.Testcaselib import Testcaselib as lib
Jon Hall39570262020-11-17 12:18:19 -0800279
Siddesha2938fe2021-04-06 02:46:06 +0000280 switches = int(main.params["TOPO"][ "switchNum" ])
281 links = int( main.params["TOPO"][ "linkNum" ])
Jon Hall39570262020-11-17 12:18:19 -0800282 lib.verifyTopology( main, switches, links, len( main.Cluster.runningNodes ) )
You Wangd66de192018-04-30 17:30:12 -0700283 # check flows / groups numbers
284 if countFlowsGroups:
Jon Halla604fd42018-05-04 14:27:27 -0700285 lib.checkFlowsGroupsFromFile( main )
You Wangd66de192018-04-30 17:30:12 -0700286 # ping hosts
287 verifyPing( main, ipv4, ipv6, disconnected, internal, external )
Jon Hall39570262020-11-17 12:18:19 -0800288 # Verify host IP assignment
289 lib.verifyOnosHostIp( main )
290 lib.verifyNetworkHostIp( main )
291 # ping hosts
292 verifyPing( main, ipv4, ipv6, disconnected, internal, external )
You Wang0f745de2018-07-27 15:49:22 -0700293
294def verifyRouterFailure( main, routerToKill, affectedIpv4Hosts=[], affectedIpv6Hosts=[],
295 ipv4=True, ipv6=True, countFlowsGroups=False ):
296 """
297 Kill and recover a quagga router and verify connectivities to external hosts
298 """
299 from tests.USECASE.SegmentRouting.dependencies.Testcaselib import Testcaselib as lib
300 lib.killRouter( main, routerToKill, 5 )
301 main.disconnectedExternalIpv4Hosts = affectedIpv4Hosts
302 main.disconnectedExternalIpv6Hosts = affectedIpv6Hosts
303 verify( main, ipv4, ipv6, True if (affectedIpv4Hosts or affectedIpv6Hosts) else False, False, True, countFlowsGroups )
304 lib.recoverRouter( main, routerToKill, 5 )
305 main.disconnectedExternalIpv4Hosts = []
306 main.disconnectedExternalIpv6Hosts = []
307 verify( main, ipv4, ipv6, False, False, True, countFlowsGroups )