blob: 7fc716459b0579f4829eab23086e5a26795ef1e7 [file] [log] [blame]
Jeremy Ronquillob27ce4c2017-07-17 12:41:28 -07001"""
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002Copyright 2016 Open Networking Foundation ( ONF )
Jeremy Ronquillob27ce4c2017-07-17 12:41:28 -07003
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
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -070011 ( at your option ) any later version.
Jeremy Ronquillob27ce4c2017-07-17 12:41:28 -070012
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"""
Jon Hall1efcb3f2016-08-23 13:42:15 -070021import os
Jon Hall1efcb3f2016-08-23 13:42:15 -070022import time
23import json
24import urllib
25from core import utilities
26
27
28class Testcaselib:
Pierfb719b12016-09-19 14:51:44 -070029
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -070030 useSSH = True
Pierfb719b12016-09-19 14:51:44 -070031
Jon Hall1efcb3f2016-08-23 13:42:15 -070032 @staticmethod
33 def initTest( main ):
34 """
35 - Construct tests variables
36 - GIT ( optional )
37 - Checkout ONOS master branch
38 - Pull latest ONOS code
39 - Building ONOS ( optional )
40 - Install ONOS package
41 - Build ONOS package
42 """
Devin Lim58046fa2017-07-05 16:55:00 -070043 try:
44 from tests.dependencies.ONOSSetup import ONOSSetup
45 main.testSetUp = ONOSSetup()
46 except ImportError:
47 main.log.error( "ONOSSetup not found. exiting the test" )
Devin Lim44075962017-08-11 10:56:37 -070048 main.cleanAndExit()
You Wangd5873482018-01-24 12:30:00 -080049 from tests.dependencies.Network import Network
50 main.Network = Network()
Devin Lim0c972b72018-02-08 14:53:59 -080051 main.testSetUp.envSetupDescription( False )
Devin Lim58046fa2017-07-05 16:55:00 -070052 stepResult = main.FALSE
53 try:
Devin Lim58046fa2017-07-05 16:55:00 -070054 # Test variables
55 main.cellName = main.params[ 'ENV' ][ 'cellName' ]
56 main.apps = main.params[ 'ENV' ][ 'cellApps' ]
Devin Lim58046fa2017-07-05 16:55:00 -070057 main.path = os.path.dirname( main.testFile )
Devin Lim57221b02018-02-14 15:45:36 -080058 main.useCommonTopo = main.params[ 'DEPENDENCY' ][ 'useCommonTopo' ] == 'True'
59 main.topoPath = main.path + ( "/.." if main.useCommonTopo else "" ) + "/dependencies/"
60 main.useCommonConf = main.params[ 'DEPENDENCY' ][ 'useCommonConf' ] == 'True'
61 main.configPath = main.path + ( "/.." if main.useCommonConf else "" ) + "/dependencies/"
62 main.forJson = "json/"
63 main.forChart = "chart/"
64 main.forConfig = "conf/"
65 main.forHost = "host/"
You Wang27317572018-03-06 12:13:11 -080066 main.forSwitchFailure = "switchFailure/"
Andreas Pantelopoulosfab6bf32018-03-06 18:56:35 -080067 main.forLinkFailure = "linkFailure/"
You Wange24d6272018-03-27 21:18:50 -070068 main.forMulticast = "multicast/"
Devin Lim58046fa2017-07-05 16:55:00 -070069 main.topology = main.params[ 'DEPENDENCY' ][ 'topology' ]
You Wangd87b2312018-01-30 12:47:17 -080070 main.topologyLib = main.params[ 'DEPENDENCY' ][ 'lib' ] if 'lib' in main.params[ 'DEPENDENCY' ] else None
71 main.topologyConf = main.params[ 'DEPENDENCY' ][ 'conf' ] if 'conf' in main.params[ 'DEPENDENCY' ] else None
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -070072 main.scale = ( main.params[ 'SCALE' ][ 'size' ] ).split( "," )
Devin Lim58046fa2017-07-05 16:55:00 -070073 main.maxNodes = int( main.params[ 'SCALE' ][ 'max' ] )
Jon Hall1efcb3f2016-08-23 13:42:15 -070074
Devin Lim0c972b72018-02-08 14:53:59 -080075 stepResult = main.testSetUp.envSetup( False )
Devin Lim58046fa2017-07-05 16:55:00 -070076 except Exception as e:
77 main.testSetUp.envSetupException( e )
Jonghwan Hyun3731d6a2017-10-19 11:59:31 -070078
Devin Lim58046fa2017-07-05 16:55:00 -070079 main.testSetUp.evnSetupConclusion( stepResult )
Jon Hall1efcb3f2016-08-23 13:42:15 -070080
Jon Hall1efcb3f2016-08-23 13:42:15 -070081 @staticmethod
Andreas Pantelopoulos90f0b102018-02-01 13:21:45 -080082 def installOnos( main, vlanCfg=True, skipPackage=False, cliSleep=10,
83 parallel=True ):
Jon Hall1efcb3f2016-08-23 13:42:15 -070084 """
85 - Set up cell
86 - Create cell file
87 - Set cell file
88 - Verify cell file
89 - Kill ONOS process
90 - Uninstall ONOS cluster
91 - Verify ONOS start up
92 - Install ONOS cluster
93 - Connect to cli
94 """
95 # main.scale[ 0 ] determines the current number of ONOS controller
You Wangd87b2312018-01-30 12:47:17 -080096 if not main.apps:
Jon Hall1efcb3f2016-08-23 13:42:15 -070097 main.log.error( "App list is empty" )
Jon Hall3c910162018-03-07 14:42:16 -080098 main.log.info( "Cluster size: " + str( main.Cluster.numCtrls ) )
99 main.log.info( "Cluster ips: " + ', '.join( main.Cluster.getIps() ) )
Jon Hall1efcb3f2016-08-23 13:42:15 -0700100 main.dynamicHosts = [ 'in1', 'out1' ]
You Wanga0f6ff62018-01-11 15:46:30 -0800101 main.testSetUp.ONOSSetUp( main.Cluster, newCell=True, cellName=main.cellName,
Andreas Pantelopoulos90f0b102018-02-01 13:21:45 -0800102 skipPack=skipPackage,
103 useSSH=Testcaselib.useSSH,
Devin Lim0c972b72018-02-08 14:53:59 -0800104 installParallel=parallel, includeCaseDesc=False )
Devin Lim142b5342017-07-20 15:22:39 -0700105 ready = utilities.retry( main.Cluster.active( 0 ).CLI.summary,
106 main.FALSE,
You Wang1cdc5f52017-12-19 16:47:51 -0800107 sleep=cliSleep,
Devin Lim142b5342017-07-20 15:22:39 -0700108 attempts=10 )
109 if ready:
110 ready = main.TRUE
111 utilities.assert_equals( expect=main.TRUE, actual=ready,
Jon Hall1efcb3f2016-08-23 13:42:15 -0700112 onpass="ONOS summary command succeded",
113 onfail="ONOS summary command failed" )
Jon Hall1efcb3f2016-08-23 13:42:15 -0700114 if not ready:
115 main.log.error( "ONOS startup failed!" )
Devin Lim44075962017-08-11 10:56:37 -0700116 main.cleanAndExit()
Jon Hall1efcb3f2016-08-23 13:42:15 -0700117
Devin Lim142b5342017-07-20 15:22:39 -0700118 for ctrl in main.Cluster.active():
119 ctrl.CLI.logSet( "DEBUG", "org.onosproject.segmentrouting" )
You Wangf5f104f2018-03-30 17:09:10 -0700120 ctrl.CLI.logSet( "DEBUG", "org.onosproject.driver" )
Devin Lim142b5342017-07-20 15:22:39 -0700121 ctrl.CLI.logSet( "DEBUG", "org.onosproject.net.flowobjective.impl" )
You Wangf5f104f2018-03-30 17:09:10 -0700122 ctrl.CLI.logSet( "DEBUG", "org.onosproject.routeservice.impl" )
123 ctrl.CLI.logSet( "DEBUG", "org.onosproject.routeservice.store" )
124 ctrl.CLI.logSet( "DEBUG", "org.onosproject.routing.fpm" )
Jon Hall9677ed32018-04-24 11:16:23 -0700125 ctrl.CLI.logSet( "TRACE", "org.onosproject.events" )
126 ctrl.CLI.logSet( "DEBUG", "org.onosproject.mcast" )
Jon Hall1efcb3f2016-08-23 13:42:15 -0700127
128 @staticmethod
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -0800129 def loadCount( main ):
130 with open("%s/count/%s.count" % (main.configPath, main.cfgName)) as count:
You Wang5df1c6d2018-04-06 18:02:02 -0700131 main.count = json.load(count)
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -0800132
133 @staticmethod
Devin Lim57221b02018-02-14 15:45:36 -0800134 def loadJson( main ):
135 with open( "%s%s.json" % ( main.configPath + main.forJson,
136 main.cfgName ) ) as cfg:
137 main.Cluster.active( 0 ).REST.setNetCfg( json.load( cfg ) )
138
139 @staticmethod
140 def loadChart( main ):
141 try:
142 with open( "%s%s.chart" % ( main.configPath + main.forChart,
143 main.cfgName ) ) as chart:
144 main.pingChart = json.load(chart)
145 except IOError:
146 main.log.warn( "No chart file found." )
147
148 @staticmethod
149 def loadHost( main ):
150 with open( "%s%s.host" % ( main.configPath + main.forHost,
151 main.cfgName ) ) as host:
152 main.expectedHosts = json.load( host )
153
154 @staticmethod
You Wang27317572018-03-06 12:13:11 -0800155 def loadSwitchFailureChart( main ):
156 with open( "%s%s.switchFailureChart" % ( main.configPath + main.forSwitchFailure,
157 main.cfgName ) ) as sfc:
158 main.switchFailureChart = json.load( sfc )
159
160 @staticmethod
Andreas Pantelopoulosfab6bf32018-03-06 18:56:35 -0800161 def loadLinkFailureChart( main ):
162 with open( "%s%s.linkFailureChart" % ( main.configPath + main.forLinkFailure,
You Wange24d6272018-03-27 21:18:50 -0700163 main.cfgName ) ) as lfc:
164 main.linkFailureChart = json.load( lfc )
165
166 @staticmethod
167 def loadMulticastConfig( main ):
168 with open( "%s%s.multicastConfig" % ( main.configPath + main.forMulticast,
169 main.cfgName ) ) as cfg:
170 main.multicastConfig = json.load( cfg )
Andreas Pantelopoulosfab6bf32018-03-06 18:56:35 -0800171
172 @staticmethod
Jon Hall1efcb3f2016-08-23 13:42:15 -0700173 def startMininet( main, topology, args="" ):
You Wangd87b2312018-01-30 12:47:17 -0800174 copyResult = main.ONOSbench.scp( main.Mininet1,
175 main.topoPath + main.topology,
You Wang5da39c82018-04-26 22:55:08 -0700176 main.Mininet1.home + "custom",
You Wangd87b2312018-01-30 12:47:17 -0800177 direction="to" )
178 if main.topologyLib:
179 for lib in main.topologyLib.split(","):
180 copyResult = copyResult and main.ONOSbench.scp( main.Mininet1,
181 main.topoPath + lib,
You Wang5da39c82018-04-26 22:55:08 -0700182 main.Mininet1.home + "custom",
You Wangd87b2312018-01-30 12:47:17 -0800183 direction="to" )
184 if main.topologyConf:
You Wanga877ea42018-04-05 15:27:40 -0700185 import re
186 controllerIPs = [ ctrl.ipAddress for ctrl in main.Cluster.runningNodes ]
187 index = 0
You Wangd87b2312018-01-30 12:47:17 -0800188 for conf in main.topologyConf.split(","):
You Wanga877ea42018-04-05 15:27:40 -0700189 # Update zebra configurations with correct ONOS instance IP
190 if conf in [ "zebradbgp1.conf", "zebradbgp2.conf" ]:
191 ip = controllerIPs[ index ]
192 index = ( index + 1 ) % len( controllerIPs )
193 with open( main.configPath + main.forConfig + conf ) as f:
194 s = f.read()
195 s = re.sub( r"(fpm connection ip).*(port 2620)", r"\1 " + ip + r" \2", s )
196 with open( main.configPath + main.forConfig + conf, "w" ) as f:
197 f.write( s )
You Wangd87b2312018-01-30 12:47:17 -0800198 copyResult = copyResult and main.ONOSbench.scp( main.Mininet1,
Devin Lim57221b02018-02-14 15:45:36 -0800199 main.configPath + main.forConfig + conf,
You Wangd87b2312018-01-30 12:47:17 -0800200 "~/",
201 direction="to" )
202 stepResult = copyResult
203 utilities.assert_equals( expect=main.TRUE,
204 actual=stepResult,
205 onpass="Successfully copied topo files",
206 onfail="Failed to copy topo files" )
Jon Hall1efcb3f2016-08-23 13:42:15 -0700207 main.step( "Starting Mininet Topology" )
Jonghwan Hyun3731d6a2017-10-19 11:59:31 -0700208 arg = "--onos-ip=%s %s" % (",".join([ctrl.ipAddress for ctrl in main.Cluster.runningNodes]), args)
Jon Hall1efcb3f2016-08-23 13:42:15 -0700209 main.topology = topology
210 topoResult = main.Mininet1.startNet(
You Wang5da39c82018-04-26 22:55:08 -0700211 topoFile=main.Mininet1.home + "custom/" + main.topology, args=arg )
Jon Hall1efcb3f2016-08-23 13:42:15 -0700212 stepResult = topoResult
213 utilities.assert_equals( expect=main.TRUE,
214 actual=stepResult,
215 onpass="Successfully loaded topology",
216 onfail="Failed to load topology" )
217 # Exit if topology did not load properly
218 if not topoResult:
Devin Lim44075962017-08-11 10:56:37 -0700219 main.cleanAndExit()
Jon Hall1efcb3f2016-08-23 13:42:15 -0700220
221 @staticmethod
You Wang84f981d2018-01-12 16:11:50 -0800222 def connectToPhysicalNetwork( main, switchNames ):
223 main.step( "Connecting to physical netowrk" )
224 topoResult = main.NetworkBench.connectToNet()
225 stepResult = topoResult
226 utilities.assert_equals( expect=main.TRUE,
227 actual=stepResult,
228 onpass="Successfully loaded topology",
229 onfail="Failed to load topology" )
230 # Exit if topology did not load properly
231 if not topoResult:
232 main.cleanAndExit()
233
234 main.step( "Assign switches to controllers." )
235 assignResult = main.TRUE
236 for name in switchNames:
237 assignResult = assignResult & main.NetworkBench.assignSwController( sw=name,
238 ip=main.Cluster.getIps(),
239 port='6653' )
240 utilities.assert_equals( expect=main.TRUE,
241 actual=stepResult,
242 onpass="Successfully assign switches to controllers",
243 onfail="Failed to assign switches to controllers" )
244
245 @staticmethod
You Wang5df1c6d2018-04-06 18:02:02 -0700246 def saveOnosDiagnostics( main ):
247 """
248 Get onos-diags.tar.gz and save it to the log directory.
249 suffix: suffix string of the file name. E.g. onos-diags-case1.tar.gz
250 """
251 main.log.info( "Collecting onos-diags..." )
252 main.ONOSbench.onosDiagnostics( [ctrl.ipAddress for ctrl in main.Cluster.runningNodes],
253 main.logdir,
254 "-CASE%d" % main.CurrentTestCaseNumber )
255
256 @staticmethod
Devin Lim142b5342017-07-20 15:22:39 -0700257 def config( main, cfgName ):
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700258 main.spines = []
Piera2a7e1b2016-10-04 11:51:43 -0700259
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700260 main.failures = int( main.params[ 'failures' ] )
261 main.cfgName = cfgName
Piera2a7e1b2016-10-04 11:51:43 -0700262
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700263 if main.cfgName == '2x2':
264 spine = {}
265 spine[ 'name' ] = main.params[ 'switches' ][ 'spine1' ]
266 spine[ 'dpid' ] = main.params[ 'switches' ][ 'spinedpid1' ]
267 main.spines.append( spine )
Piera2a7e1b2016-10-04 11:51:43 -0700268
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700269 spine = {}
270 spine[ 'name' ] = main.params[ 'switches' ][ 'spine2' ]
271 spine[ 'dpid' ] = main.params[ 'switches' ][ 'spinedpid2' ]
272 main.spines.append( spine )
Piera2a7e1b2016-10-04 11:51:43 -0700273
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700274 elif main.cfgName == '4x4':
275 spine = {}
276 spine[ 'name' ] = main.params[ 'switches' ][ 'spine1' ]
277 spine[ 'dpid' ] = main.params[ 'switches' ][ 'spinedpid1' ]
278 main.spines.append( spine )
Piera2a7e1b2016-10-04 11:51:43 -0700279
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700280 spine = {}
281 spine[ 'name' ] = main.params[ 'switches' ][ 'spine2' ]
282 spine[ 'dpid' ] = main.params[ 'switches' ][ 'spinedpid2' ]
283 main.spines.append( spine )
Piera2a7e1b2016-10-04 11:51:43 -0700284
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700285 spine = {}
286 spine[ 'name' ] = main.params[ 'switches' ][ 'spine3' ]
287 spine[ 'dpid' ] = main.params[ 'switches' ][ 'spinedpid3' ]
288 main.spines.append( spine )
Piera2a7e1b2016-10-04 11:51:43 -0700289
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700290 spine = {}
291 spine[ 'name' ] = main.params[ 'switches' ][ 'spine4' ]
292 spine[ 'dpid' ] = main.params[ 'switches' ][ 'spinedpid4' ]
293 main.spines.append( spine )
Piera2a7e1b2016-10-04 11:51:43 -0700294
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700295 else:
Piera2a7e1b2016-10-04 11:51:43 -0700296 main.log.error( "Configuration failed!" )
Devin Lim44075962017-08-11 10:56:37 -0700297 main.cleanAndExit()
You Wang27317572018-03-06 12:13:11 -0800298
Andreas Pantelopoulos2eae3242018-03-06 13:47:20 -0800299 @staticmethod
300 def addStaticOnosRoute( main, subnet, intf):
301 """
302 Adds an ONOS static route with the use route-add command.
303 """
304 main.step("Add static route for subnet {0} towards router interface {1}".format(subnet, intf))
305 routeResult = main.Cluster.active( 0 ).addStaticRoute(subnet, intf)
306
307 utilities.assert_equals( expect=True, actual=( not routeResult ),
308 onpass="route-add command succeeded",
309 onfail="route-add command failed")
Piera2a7e1b2016-10-04 11:51:43 -0700310
311 @staticmethod
Jonghwan Hyun76a02b72018-01-30 16:40:48 +0900312 def checkFlows( main, minFlowCount, tag="", dumpflows=True, sleep=10 ):
Jon Hall1efcb3f2016-08-23 13:42:15 -0700313 main.step(
Jon Hall3c910162018-03-07 14:42:16 -0800314 "Check whether the flow count is bigger than %s" % minFlowCount )
Jonghwan Hyun76a02b72018-01-30 16:40:48 +0900315 if tag == "":
316 tag = 'CASE%d' % main.CurrentTestCaseNumber
Devin Lim142b5342017-07-20 15:22:39 -0700317 count = utilities.retry( main.Cluster.active( 0 ).CLI.checkFlowCount,
Jon Hall1efcb3f2016-08-23 13:42:15 -0700318 main.FALSE,
319 kwargs={ 'min': minFlowCount },
320 attempts=10,
You Wang1cdc5f52017-12-19 16:47:51 -0800321 sleep=sleep )
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700322 utilities.assertEquals(
Jon Hall1efcb3f2016-08-23 13:42:15 -0700323 expect=True,
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700324 actual=( count > 0 ),
Jon Hall1efcb3f2016-08-23 13:42:15 -0700325 onpass="Flow count looks correct: " + str( count ),
326 onfail="Flow count looks wrong: " + str( count ) )
327
328 main.step( "Check whether all flow status are ADDED" )
Devin Lim142b5342017-07-20 15:22:39 -0700329 flowCheck = utilities.retry( main.Cluster.active( 0 ).CLI.checkFlowsState,
Jon Hall1efcb3f2016-08-23 13:42:15 -0700330 main.FALSE,
331 kwargs={ 'isPENDING': False },
Jonghwan Hyun98fb40a2018-01-04 16:16:28 -0800332 attempts=5,
You Wang1cdc5f52017-12-19 16:47:51 -0800333 sleep=sleep )
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700334 utilities.assertEquals(
Jon Hall1efcb3f2016-08-23 13:42:15 -0700335 expect=main.TRUE,
336 actual=flowCheck,
337 onpass="Flow status is correct!",
338 onfail="Flow status is wrong!" )
339 if dumpflows:
Devin Lim142b5342017-07-20 15:22:39 -0700340 main.ONOSbench.dumpONOSCmd( main.Cluster.active( 0 ).ipAddress,
Pier50f0bc62016-09-07 17:53:40 -0700341 "flows",
342 main.logdir,
Jonghwan Hyun76a02b72018-01-30 16:40:48 +0900343 tag + "_FlowsBefore" )
Devin Lim142b5342017-07-20 15:22:39 -0700344 main.ONOSbench.dumpONOSCmd( main.Cluster.active( 0 ).ipAddress,
Pier50f0bc62016-09-07 17:53:40 -0700345 "groups",
346 main.logdir,
Jonghwan Hyun76a02b72018-01-30 16:40:48 +0900347 tag + "_GroupsBefore" )
Jon Hall1efcb3f2016-08-23 13:42:15 -0700348
349 @staticmethod
Pier6a0c4de2018-03-18 16:01:30 -0700350 def checkDevices( main, switches, tag="", sleep=10 ):
351 main.step(
352 "Check whether the switches count is equal to %s" % switches )
353 if tag == "":
354 tag = 'CASE%d' % main.CurrentTestCaseNumber
355 result = utilities.retry( main.Cluster.active( 0 ).CLI.checkStatus,
356 main.FALSE,
357 kwargs={ 'numoswitch': switches},
358 attempts=10,
359 sleep=sleep )
360 utilities.assert_equals( expect=main.TRUE, actual=result,
361 onpass="Device up successful",
362 onfail="Failed to boot up devices?" )
363
364 @staticmethod
Jonghwan Hyun98fb40a2018-01-04 16:16:28 -0800365 def checkFlowsByDpid( main, dpid, minFlowCount, sleep=10 ):
366 main.step(
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -0800367 " Check whether the flow count of device %s is bigger than %s" % ( dpid, minFlowCount ) )
368 count = utilities.retry( main.Cluster.active( 0 ).CLI.checkFlowAddedCount,
369 main.FALSE,
370 args=( dpid, minFlowCount ),
Jonghwan Hyun98fb40a2018-01-04 16:16:28 -0800371 attempts=5,
372 sleep=sleep )
373 utilities.assertEquals(
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -0800374 expect=True,
375 actual=( count > minFlowCount ),
376 onpass="Flow count looks correct: " + str( count ),
377 onfail="Flow count looks wrong. " )
Jonghwan Hyun98fb40a2018-01-04 16:16:28 -0800378
379 @staticmethod
Jon Hall9677ed32018-04-24 11:16:23 -0700380 def checkFlowEqualityByDpid( main, dpid, flowCount, sleep=10 ):
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -0800381 main.step(
382 " Check whether the flow count of device %s is equal to %s" % ( dpid, flowCount ) )
383 count = utilities.retry( main.Cluster.active( 0 ).CLI.checkFlowAddedCount,
384 main.FALSE,
Jon Hall9677ed32018-04-24 11:16:23 -0700385 args=( dpid, flowCount, False, 1 ),
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -0800386 attempts=5,
387 sleep=sleep )
388
389 utilities.assertEquals(
390 expect=True,
391 actual=( int( count ) == flowCount ),
Jon Hall9677ed32018-04-24 11:16:23 -0700392 onpass="Flow count looks correct: " + str( count ) ,
393 onfail="Flow count looks wrong. found {}, should be {}.".format( count, flowCount ) )
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -0800394
395 @staticmethod
396 def checkGroupEqualityByDpid( main, dpid, groupCount, sleep=10):
397 main.step(
398 " Check whether the group count of device %s is equal to %s" % ( dpid, groupCount ) )
399 count = utilities.retry( main.Cluster.active( 0 ).CLI.checkGroupAddedCount,
400 main.FALSE,
401 args=( dpid, groupCount, False, 1),
402 attempts=5,
403 sleep=sleep )
404
405 utilities.assertEquals(
406 expect=True,
407 actual=( count == groupCount ),
Jon Hall9677ed32018-04-24 11:16:23 -0700408 onpass="Group count looks correct: " + str( count ) ,
409 onfail="Group count looks wrong. found {}, should be {}.".format( count, groupCount ) )
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -0800410
411 @staticmethod
Jon Hall9677ed32018-04-24 11:16:23 -0700412 def checkFlowsGroupsFromFile( main ):
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -0800413
414 for dpid, values in main.count.items():
415 flowCount = values["flows"]
416 groupCount = values["groups"]
Jon Hall9677ed32018-04-24 11:16:23 -0700417 main.log.report( "Check flow count for dpid " + str( dpid ) +
418 ", should be " + str( flowCount ) )
419 Testcaselib.checkFlowEqualityByDpid( main, dpid, flowCount )
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -0800420
Jon Hall9677ed32018-04-24 11:16:23 -0700421 main.log.report( "Check group count for dpid " + str( dpid ) +
422 ", should be " + str( groupCount ) )
423 Testcaselib.checkGroupEqualityByDpid( main, dpid, groupCount )
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -0800424
425 return
426
427 @staticmethod
Jon Halla604fd42018-05-04 14:27:27 -0700428 def pingAll( main, tag="", dumpflows=True, acceptableFailed=0, basedOnIp=False,
429 sleep=10, retryAttempts=1, skipOnFail=False ):
You Wangf19d9f42018-02-23 16:34:19 -0800430 '''
You Wangba231e72018-03-01 13:18:21 -0800431 Verify connectivity between hosts according to the ping chart
432 acceptableFailed: max number of acceptable failed pings.
You Wangf19d9f42018-02-23 16:34:19 -0800433 basedOnIp: if True, run ping or ping6 based on suffix of host names
Jonghwan Hyun812c70f2018-02-16 16:33:16 -0800434 retryAttempts: the number of retry ping. Only works for IPv4 hosts.
You Wangf19d9f42018-02-23 16:34:19 -0800435 '''
You Wangba231e72018-03-01 13:18:21 -0800436 main.log.report( "Check host connectivity" )
437 main.log.debug( "Ping chart: %s" % main.pingChart )
Andreas Pantelopoulosf6ed5012018-02-08 21:26:01 -0800438 if tag == "":
439 tag = 'CASE%d' % main.CurrentTestCaseNumber
440 for entry in main.pingChart.itervalues():
You Wangba231e72018-03-01 13:18:21 -0800441 main.log.debug( "Entry in ping chart: %s" % entry )
442 expect = entry[ 'expect' ]
443 if expect == "Unidirectional":
444 # Verify ping from each src host to each dst host
445 src = entry[ 'src' ]
446 dst = entry[ 'dst' ]
447 expect = main.TRUE
448 main.step( "Verify unidirectional connectivity from %s to %s with tag %s" % ( str( src ), str( dst ), tag ) )
449 if basedOnIp:
450 if ("v4" in src[0]):
451 pa = main.Network.pingallHostsUnidirectional( src, dst, acceptableFailed=acceptableFailed )
452 utilities.assert_equals( expect=expect, actual=pa,
453 onpass="IPv4 connectivity successfully tested",
454 onfail="IPv4 connectivity failed" )
455 if ("v6" in src[0]):
456 pa = main.Network.pingallHostsUnidirectional( src, dst, ipv6=True, acceptableFailed=acceptableFailed )
457 utilities.assert_equals( expect=expect, actual=pa,
458 onpass="IPv6 connectivity successfully tested",
459 onfail="IPv6 connectivity failed" )
460 else:
461 pa = main.Network.pingallHostsUnidirectional( src, dst, acceptableFailed=acceptableFailed )
462 utilities.assert_equals( expect=expect, actual=pa,
463 onpass="IP connectivity successfully tested",
464 onfail="IP connectivity failed" )
465 else:
466 # Verify ping between each host pair
467 hosts = entry[ 'hosts' ]
468 try:
469 expect = main.TRUE if str(expect).lower() == 'true' else main.FALSE
470 except:
471 expect = main.FALSE
472 main.step( "Verify full connectivity for %s with tag %s" % ( str( hosts ), tag ) )
473 if basedOnIp:
474 if ("v4" in hosts[0]):
Jonghwan Hyun812c70f2018-02-16 16:33:16 -0800475 pa = utilities.retry( main.Network.pingallHosts,
476 main.FALSE if expect else main.TRUE,
477 args=(hosts,),
478 attempts=retryAttempts,
479 sleep=sleep )
You Wangba231e72018-03-01 13:18:21 -0800480 utilities.assert_equals( expect=expect, actual=pa,
481 onpass="IPv4 connectivity successfully tested",
482 onfail="IPv4 connectivity failed" )
483 if ("v6" in hosts[0]):
484 pa = main.Network.pingIpv6Hosts( hosts, acceptableFailed=acceptableFailed )
485 utilities.assert_equals( expect=expect, actual=pa,
486 onpass="IPv6 connectivity successfully tested",
487 onfail="IPv6 connectivity failed" )
488 else:
You Wangf19d9f42018-02-23 16:34:19 -0800489 pa = main.Network.pingallHosts( hosts )
490 utilities.assert_equals( expect=expect, actual=pa,
You Wangba231e72018-03-01 13:18:21 -0800491 onpass="IP connectivity successfully tested",
492 onfail="IP connectivity failed" )
You Wang5df1c6d2018-04-06 18:02:02 -0700493 if skipOnFail and pa != expect:
494 Testcaselib.saveOnosDiagnostics( main )
You Wang24ad2f52018-04-10 10:47:12 -0700495 Testcaselib.cleanup( main, copyKarafLog=False )
You Wang5df1c6d2018-04-06 18:02:02 -0700496 main.skipCase()
Andreas Pantelopoulosf6ed5012018-02-08 21:26:01 -0800497
498 if dumpflows:
499 main.ONOSbench.dumpONOSCmd( main.Cluster.active( 0 ).ipAddress,
500 "flows",
501 main.logdir,
502 tag + "_FlowsOn" )
503 main.ONOSbench.dumpONOSCmd( main.Cluster.active( 0 ).ipAddress,
504 "groups",
505 main.logdir,
506 tag + "_GroupsOn" )
507
508 @staticmethod
Jon Halla604fd42018-05-04 14:27:27 -0700509 def killLink( main, end1, end2, switches, links, sleep=None ):
Jon Hall1efcb3f2016-08-23 13:42:15 -0700510 """
511 end1,end2: identify the switches, ex.: 'leaf1', 'spine1'
512 switches, links: number of expected switches and links after linkDown, ex.: '4', '6'
513 Kill a link and verify ONOS can see the proper link change
514 """
Jon Halla604fd42018-05-04 14:27:27 -0700515 if sleep is None:
516 sleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
517 else:
518 sleep = float( sleep )
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700519 main.step( "Kill link between %s and %s" % ( end1, end2 ) )
Jon Halla604fd42018-05-04 14:27:27 -0700520 linkDown = main.Network.link( END1=end1, END2=end2, OPTION="down" )
521 linkDown = linkDown and main.Network.link( END2=end1, END1=end2, OPTION="down" )
522 # TODO: Can remove this, since in the retry we will wait anyways if topology is incorrect
Jon Hall1efcb3f2016-08-23 13:42:15 -0700523 main.log.info(
Jon Halla604fd42018-05-04 14:27:27 -0700524 "Waiting %s seconds for link down to be discovered" % sleep )
525 time.sleep( sleep )
Devin Lim142b5342017-07-20 15:22:39 -0700526 topology = utilities.retry( main.Cluster.active( 0 ).CLI.checkStatus,
Jon Hall1efcb3f2016-08-23 13:42:15 -0700527 main.FALSE,
528 kwargs={ 'numoswitch': switches,
529 'numolink': links },
530 attempts=10,
Jon Halla604fd42018-05-04 14:27:27 -0700531 sleep=sleep )
532 result = topology and linkDown
Jon Hall1efcb3f2016-08-23 13:42:15 -0700533 utilities.assert_equals( expect=main.TRUE, actual=result,
534 onpass="Link down successful",
535 onfail="Failed to turn off link?" )
536
537 @staticmethod
Jon Halla604fd42018-05-04 14:27:27 -0700538 def killLinkBatch( main, links, linksAfter, switches, sleep=None ):
Andreas Pantelopoulosfab6bf32018-03-06 18:56:35 -0800539 """
540 links = list of links (src, dst) to bring down.
541 """
542
543 main.step("Killing a batch of links {0}".format(links))
Jon Halla604fd42018-05-04 14:27:27 -0700544 if sleep is None:
545 sleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
546 else:
547 sleep = float( sleep )
Andreas Pantelopoulosfab6bf32018-03-06 18:56:35 -0800548
549 for end1, end2 in links:
550 main.Network.link( END1=end1, END2=end2, OPTION="down")
551 main.Network.link( END1=end2, END2=end1, OPTION="down")
552
Jon Halla604fd42018-05-04 14:27:27 -0700553 # TODO: Can remove this, since in the retry we will wait anyways if topology is incorrect
Andreas Pantelopoulosfab6bf32018-03-06 18:56:35 -0800554 main.log.info(
Jon Halla604fd42018-05-04 14:27:27 -0700555 "Waiting %s seconds for links down to be discovered" % sleep )
556 time.sleep( sleep )
Andreas Pantelopoulosfab6bf32018-03-06 18:56:35 -0800557
558 topology = utilities.retry( main.Cluster.active( 0 ).CLI.checkStatus,
559 main.FALSE,
560 kwargs={ 'numoswitch': switches,
561 'numolink': linksAfter },
562 attempts=10,
Jon Halla604fd42018-05-04 14:27:27 -0700563 sleep=sleep )
Andreas Pantelopoulosfab6bf32018-03-06 18:56:35 -0800564
You Wang2854bce2018-03-30 10:15:32 -0700565 utilities.assert_equals( expect=main.TRUE, actual=topology,
566 onpass="Link batch down successful",
567 onfail="Link batch down failed" )
568
Andreas Pantelopoulosfab6bf32018-03-06 18:56:35 -0800569 @staticmethod
Jon Halla604fd42018-05-04 14:27:27 -0700570 def restoreLinkBatch( main, links, linksAfter, switches, sleep=None ):
Andreas Pantelopoulosfab6bf32018-03-06 18:56:35 -0800571 """
572 links = list of link (src, dst) to bring up again.
573 """
574
575 main.step("Restoring a batch of links {0}".format(links))
Jon Halla604fd42018-05-04 14:27:27 -0700576 if sleep is None:
577 sleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
578 else:
579 sleep = float( sleep )
Andreas Pantelopoulosfab6bf32018-03-06 18:56:35 -0800580
581 for end1, end2 in links:
582 main.Network.link( END1=end1, END2=end2, OPTION="up")
583 main.Network.link( END1=end2, END2=end1, OPTION="up")
584
Andreas Pantelopoulosfab6bf32018-03-06 18:56:35 -0800585 main.log.info(
Jon Halla604fd42018-05-04 14:27:27 -0700586 "Waiting %s seconds for links up to be discovered" % sleep )
587 time.sleep( sleep )
Andreas Pantelopoulosfab6bf32018-03-06 18:56:35 -0800588
589 topology = utilities.retry( main.Cluster.active( 0 ).CLI.checkStatus,
590 main.FALSE,
591 kwargs={ 'numoswitch': switches,
592 'numolink': linksAfter },
593 attempts=10,
Jon Halla604fd42018-05-04 14:27:27 -0700594 sleep=sleep )
Andreas Pantelopoulosfab6bf32018-03-06 18:56:35 -0800595
You Wang2854bce2018-03-30 10:15:32 -0700596 utilities.assert_equals( expect=main.TRUE, actual=topology,
597 onpass="Link batch up successful",
598 onfail="Link batch up failed" )
599
Andreas Pantelopoulosfab6bf32018-03-06 18:56:35 -0800600 @staticmethod
You Wang85747762018-05-11 15:51:50 -0700601 def disablePortBatch( main, ports, switches=None, links=None, sleep=None ):
602 """
603 Disable a list of switch ports using 'portstate' and verify ONOS can see the proper link change
604 ports: a list of ports to disable ex. [ [ "of:0000000000000001", 1 ] ]
605 switches, links: number of expected switches and links after link change, ex.: '4', '6'
606 """
607 if sleep is None:
608 sleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
609 else:
610 sleep = float( sleep )
611 main.step( "Disable a batch of ports" )
612 for dpid, port in ports:
613 main.Cluster.active( 0 ).CLI.portstate( dpid=dpid, port=port, state="disable" )
614 main.log.info( "Waiting {} seconds for port down to be discovered".format( sleep ) )
615 time.sleep( sleep )
616 if switches and links:
617 result = main.Cluster.active( 0 ).CLI.checkStatus( numoswitch=switches,
618 numolink=links )
619 utilities.assert_equals( expect=main.TRUE, actual=result,
620 onpass="Port down successful",
621 onfail="Port down failed" )
622
623 @staticmethod
624 def enablePortBatch( main, ports, switches, links, sleep=None ):
625 """
626 Enable a list of switch ports using 'portstate' and verify ONOS can see the proper link change
627 ports: a list of ports to enable ex. [ [ "of:0000000000000001", 1 ] ]
628 switches, links: number of expected switches and links after link change, ex.: '4', '6'
629 """
630 if sleep is None:
631 sleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
632 else:
633 sleep = float( sleep )
634 main.step( "Enable a batch of ports" )
635 for dpid, port in ports:
636 main.Cluster.active( 0 ).CLI.portstate( dpid=dpid, port=port, state="enable" )
637 main.log.info( "Waiting {} seconds for port up to be discovered".format( sleep ) )
638 time.sleep( sleep )
639 if switches and links:
640 result = main.Cluster.active( 0 ).CLI.checkStatus( numoswitch=switches,
641 numolink=links )
642 utilities.assert_equals( expect=main.TRUE, actual=result,
643 onpass="Port up successful",
644 onfail="Port up failed" )
645
646 @staticmethod
You Wangc02d8352018-04-17 16:42:10 -0700647 def restoreLink( main, end1, end2, switches, links,
Jon Halla604fd42018-05-04 14:27:27 -0700648 portUp=False, dpid1='', dpid2='', port1='', port2='', sleep=None ):
Jon Hall1efcb3f2016-08-23 13:42:15 -0700649 """
650 Params:
651 end1,end2: identify the end switches, ex.: 'leaf1', 'spine1'
You Wangc02d8352018-04-17 16:42:10 -0700652 portUp: enable portstate after restoring link
Jon Hall1efcb3f2016-08-23 13:42:15 -0700653 dpid1, dpid2: dpid of the end switches respectively, ex.: 'of:0000000000000002'
654 port1, port2: respective port of the end switches that connects to the link, ex.:'1'
655 switches, links: number of expected switches and links after linkDown, ex.: '4', '6'
656 Kill a link and verify ONOS can see the proper link change
657 """
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700658 main.step( "Restore link between %s and %s" % ( end1, end2 ) )
Jon Halla604fd42018-05-04 14:27:27 -0700659 if sleep is None:
660 sleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
661 else:
662 sleep = float( sleep )
Jon Hall1efcb3f2016-08-23 13:42:15 -0700663 result = False
664 count = 0
665 while True:
666 count += 1
Jon Halla604fd42018-05-04 14:27:27 -0700667 ctrl = main.Cluster.next()
You Wangd5873482018-01-24 12:30:00 -0800668 main.Network.link( END1=end1, END2=end2, OPTION="up" )
669 main.Network.link( END2=end1, END1=end2, OPTION="up" )
Jon Hall1efcb3f2016-08-23 13:42:15 -0700670 main.log.info(
Jon Halla604fd42018-05-04 14:27:27 -0700671 "Waiting %s seconds for link up to be discovered" % sleep )
672 time.sleep( sleep )
Pierfb719b12016-09-19 14:51:44 -0700673
You Wangc02d8352018-04-17 16:42:10 -0700674 if portUp:
675 ctrl.CLI.portstate( dpid=dpid1, port=port1, state='Enable' )
676 ctrl.CLI.portstate( dpid=dpid2, port=port2, state='Enable' )
Jon Halla604fd42018-05-04 14:27:27 -0700677 time.sleep( sleep )
Jon Hall1efcb3f2016-08-23 13:42:15 -0700678
Jon Halla604fd42018-05-04 14:27:27 -0700679 result = ctrl.CLI.checkStatus( numoswitch=switches,
680 numolink=links )
Jon Hall1efcb3f2016-08-23 13:42:15 -0700681 if count > 5 or result:
682 break
683 utilities.assert_equals( expect=main.TRUE, actual=result,
684 onpass="Link up successful",
685 onfail="Failed to bring link up" )
686
687 @staticmethod
Jon Halla604fd42018-05-04 14:27:27 -0700688 def killSwitch( main, switch, switches, links, sleep=None ):
Jon Hall1efcb3f2016-08-23 13:42:15 -0700689 """
690 Params: switches, links: number of expected switches and links after SwitchDown, ex.: '4', '6'
691 Completely kill a switch and verify ONOS can see the proper change
692 """
Jon Halla604fd42018-05-04 14:27:27 -0700693 if sleep is None:
694 sleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
695 else:
696 sleep = float( sleep )
You Wangc02d8352018-04-17 16:42:10 -0700697 switch = switch if isinstance( switch, list ) else [ switch ]
698 main.step( "Kill " + str( switch ) )
699 for s in switch:
700 main.log.info( "Stopping " + s )
701 main.Network.switch( SW=s, OPTION="stop" )
Jon Hall1efcb3f2016-08-23 13:42:15 -0700702 # todo make this repeatable
Jon Halla604fd42018-05-04 14:27:27 -0700703
704 # TODO: Can remove this, since in the retry we will wait anyways if topology is incorrect
Jon Hall1efcb3f2016-08-23 13:42:15 -0700705 main.log.info( "Waiting %s seconds for switch down to be discovered" % (
Jon Halla604fd42018-05-04 14:27:27 -0700706 sleep ) )
707 time.sleep( sleep )
Devin Lim142b5342017-07-20 15:22:39 -0700708 topology = utilities.retry( main.Cluster.active( 0 ).CLI.checkStatus,
Jon Hall1efcb3f2016-08-23 13:42:15 -0700709 main.FALSE,
710 kwargs={ 'numoswitch': switches,
711 'numolink': links },
712 attempts=10,
Jon Halla604fd42018-05-04 14:27:27 -0700713 sleep=sleep )
Jon Hall1efcb3f2016-08-23 13:42:15 -0700714 utilities.assert_equals( expect=main.TRUE, actual=topology,
715 onpass="Kill switch successful",
716 onfail="Failed to kill switch?" )
717
718 @staticmethod
Jon Halla604fd42018-05-04 14:27:27 -0700719 def recoverSwitch( main, switch, switches, links, rediscoverHosts=False, hostsToDiscover=[], sleep=None ):
Jon Hall1efcb3f2016-08-23 13:42:15 -0700720 """
721 Params: switches, links: number of expected switches and links after SwitchUp, ex.: '4', '6'
722 Recover a switch and verify ONOS can see the proper change
723 """
Jon Halla604fd42018-05-04 14:27:27 -0700724 if sleep is None:
725 sleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
726 else:
727 sleep = float( sleep )
728 # TODO make this repeatable
You Wangc02d8352018-04-17 16:42:10 -0700729 switch = switch if isinstance( switch, list ) else [ switch ]
730 main.step( "Recovering " + str( switch ) )
731 for s in switch:
732 main.log.info( "Starting " + s )
733 main.Network.switch( SW=s, OPTION="start" )
Jon Hall1efcb3f2016-08-23 13:42:15 -0700734 main.log.info( "Waiting %s seconds for switch up to be discovered" % (
Jon Halla604fd42018-05-04 14:27:27 -0700735 sleep ) )
736 time.sleep( sleep )
Andreas Pantelopoulos74c7ff22018-05-01 15:42:02 -0700737 if rediscoverHosts:
You Wang48381752018-05-07 13:50:57 -0700738 main.Network.discoverHosts( hostList=hostsToDiscover )
Andreas Pantelopoulos74c7ff22018-05-01 15:42:02 -0700739 main.log.info( "Waiting %s seconds for hosts to get re-discovered" % (
Jon Halla604fd42018-05-04 14:27:27 -0700740 sleep ) )
741 time.sleep( sleep )
Andreas Pantelopoulos74c7ff22018-05-01 15:42:02 -0700742
Devin Lim142b5342017-07-20 15:22:39 -0700743 topology = utilities.retry( main.Cluster.active( 0 ).CLI.checkStatus,
Jon Hall1efcb3f2016-08-23 13:42:15 -0700744 main.FALSE,
745 kwargs={ 'numoswitch': switches,
746 'numolink': links },
747 attempts=10,
Jon Halla604fd42018-05-04 14:27:27 -0700748 sleep=sleep )
Jon Hall1efcb3f2016-08-23 13:42:15 -0700749 utilities.assert_equals( expect=main.TRUE, actual=topology,
750 onpass="Switch recovery successful",
751 onfail="Failed to recover switch?" )
752
Jonghwan Hyun25c98a62018-05-04 13:59:09 -0700753 @staticmethod
You Wang5da39c82018-04-26 22:55:08 -0700754 def cleanup( main, copyKarafLog=True, removeHostComponent=False ):
Jon Hall1efcb3f2016-08-23 13:42:15 -0700755 """
756 Stop Onos-cluster.
757 Stops Mininet
758 Copies ONOS log
759 """
Devin Lim58046fa2017-07-05 16:55:00 -0700760 try:
761 from tests.dependencies.utils import Utils
762 except ImportError:
763 main.log.error( "Utils not found exiting the test" )
Devin Lim44075962017-08-11 10:56:37 -0700764 main.cleanAndExit()
Devin Lim58046fa2017-07-05 16:55:00 -0700765 try:
Devin Lim142b5342017-07-20 15:22:39 -0700766 main.utils
Devin Lim58046fa2017-07-05 16:55:00 -0700767 except ( NameError, AttributeError ):
Devin Lim142b5342017-07-20 15:22:39 -0700768 main.utils = Utils()
Devin Lim58046fa2017-07-05 16:55:00 -0700769
You Wange24d6272018-03-27 21:18:50 -0700770 if hasattr( main, "scapyHosts" ):
771 scapyResult = main.TRUE
772 for host in main.scapyHosts:
773 scapyResult = host.stopScapy() and scapyResult
774 main.log.info( "Stopped Scapy Host: {0}".format( host.name ) )
775 for host in main.scapyHosts:
776 scapyResult = main.Scapy.removeHostComponent( host.name ) and scapyResult
777 main.log.info( "Removed Scapy Host Component: {0}".format( host.name ) )
778 main.scapyHosts = []
779
You Wang5da39c82018-04-26 22:55:08 -0700780 if removeHostComponent:
781 for host in main.internalIpv4Hosts + main.internalIpv6Hosts + main.externalIpv4Hosts + main.externalIpv6Hosts:
782 if hasattr( main, host ):
783 main.Network.removeHostComponent( host )
784
You Wang5df1c6d2018-04-06 18:02:02 -0700785 if hasattr( main, 'Mininet1' ):
Pier6a0c4de2018-03-18 16:01:30 -0700786 main.utils.mininetCleanup( main.Mininet1 )
Devin Lim58046fa2017-07-05 16:55:00 -0700787
You Wang5df1c6d2018-04-06 18:02:02 -0700788 if copyKarafLog:
789 main.utils.copyKarafLog( "CASE%d" % main.CurrentTestCaseNumber, before=True, includeCaseDesc=False )
Devin Lim58046fa2017-07-05 16:55:00 -0700790
Devin Lim142b5342017-07-20 15:22:39 -0700791 for ctrl in main.Cluster.active():
792 main.ONOSbench.onosStop( ctrl.ipAddress )
Jon Hall1efcb3f2016-08-23 13:42:15 -0700793
794 @staticmethod
Jon Halla604fd42018-05-04 14:27:27 -0700795 def verifyNodes( main ):
796 """
797 Verifies Each active node in the cluster has an accurate view of other node's and their status
798
799 Params:
800 nodes, integer array with position of the ONOS nodes in the CLIs array
801 """
802 nodeResults = utilities.retry( main.Cluster.nodesCheck,
803 False,
804 attempts=10,
805 sleep=10 )
806 utilities.assert_equals( expect=True, actual=nodeResults,
807 onpass="Nodes check successful",
808 onfail="Nodes check NOT successful" )
809
810 if not nodeResults:
811 for ctrl in main.Cluster.runningNodes:
812 main.log.debug( "{} components not ACTIVE: \n{}".format(
813 ctrl.name,
814 ctrl.CLI.sendline( "scr:list | grep -v ACTIVE" ) ) )
815 main.log.error( "Failed to kill ONOS, stopping test" )
816 main.cleanAndExit()
817
818 @staticmethod
819 def verifyTopology( main, switches, links, expNodes ):
820 """
821 Verifies that the ONOS cluster has an acuurate view of the topology
822
823 Params:
824 switches, links, expNodes: number of expected switches, links, and nodes at this point in the test ex.: '4', '6', '2'
825 """
826 main.step( "Check number of topology elements" )
827 topology = utilities.retry( main.Cluster.active( 0 ).CLI.checkStatus,
828 main.FALSE,
829 kwargs={ 'numoswitch': switches,
830 'numolink': links,
831 'numoctrl': expNodes },
832 attempts=10,
833 sleep=12 )
834 utilities.assert_equals( expect=main.TRUE, actual=topology,
835 onpass="Number of topology elements are correct",
836 onfail="Unexpected number of links, switches, and/or controllers" )
837
838 @staticmethod
839 def killOnos( main, nodes, switches, links, expNodes, sleep=None ):
Jon Hall1efcb3f2016-08-23 13:42:15 -0700840 """
841 Params: nodes, integer array with position of the ONOS nodes in the CLIs array
842 switches, links, nodes: number of expected switches, links and nodes after KillOnos, ex.: '4', '6'
843 Completely Kill an ONOS instance and verify the ONOS cluster can see the proper change
844 """
Jon Halla604fd42018-05-04 14:27:27 -0700845 # TODO: We have enough information in the Cluster instance to remove expNodes from here and verifyTopology
Jon Hall3c910162018-03-07 14:42:16 -0800846 main.step( "Killing ONOS instances with index(es): {}".format( nodes ) )
Jon Halla604fd42018-05-04 14:27:27 -0700847 if sleep is None:
848 sleep = float( main.params[ 'timers' ][ 'OnosDiscovery' ] )
849 else:
850 sleep = float( sleep )
Pier3b58c652016-09-26 12:03:31 -0700851
Jon Hall1efcb3f2016-08-23 13:42:15 -0700852 for i in nodes:
Devin Lim142b5342017-07-20 15:22:39 -0700853 killResult = main.ONOSbench.onosDie( main.Cluster.runningNodes[ i ].ipAddress )
Jon Hall1efcb3f2016-08-23 13:42:15 -0700854 utilities.assert_equals( expect=main.TRUE, actual=killResult,
855 onpass="ONOS instance Killed",
856 onfail="Error killing ONOS instance" )
Devin Lim142b5342017-07-20 15:22:39 -0700857 main.Cluster.runningNodes[ i ].active = False
Jon Halla604fd42018-05-04 14:27:27 -0700858 main.Cluster.reset()
859 time.sleep( sleep )
Pier3b58c652016-09-26 12:03:31 -0700860
Devin Lim142b5342017-07-20 15:22:39 -0700861 if len( nodes ) < main.Cluster.numCtrls:
Jon Halla604fd42018-05-04 14:27:27 -0700862 Testcaselib.verifyNodes( main )
863 Testcaselib.verifyTopology( main, switches, links, expNodes )
Jon Hall1efcb3f2016-08-23 13:42:15 -0700864
865 @staticmethod
Jon Halla604fd42018-05-04 14:27:27 -0700866 def recoverOnos( main, nodes, switches, links, expNodes, sleep=None ):
Jon Hall1efcb3f2016-08-23 13:42:15 -0700867 """
868 Params: nodes, integer array with position of the ONOS nodes in the CLIs array
869 switches, links, nodes: number of expected switches, links and nodes after recoverOnos, ex.: '4', '6'
870 Recover an ONOS instance and verify the ONOS cluster can see the proper change
871 """
Jon Hall3c910162018-03-07 14:42:16 -0800872 main.step( "Recovering ONOS instances with index(es): {}".format( nodes ) )
Jon Halla604fd42018-05-04 14:27:27 -0700873 if sleep is None:
874 sleep = float( main.params[ 'timers' ][ 'OnosDiscovery' ] )
875 else:
876 sleep = float( sleep )
Devin Lim142b5342017-07-20 15:22:39 -0700877 [ main.ONOSbench.onosStart( main.Cluster.runningNodes[ i ].ipAddress ) for i in nodes ]
Jon Halla604fd42018-05-04 14:27:27 -0700878 time.sleep( sleep )
Jon Hall1efcb3f2016-08-23 13:42:15 -0700879 for i in nodes:
Devin Lim142b5342017-07-20 15:22:39 -0700880 isUp = main.ONOSbench.isup( main.Cluster.runningNodes[ i ].ipAddress )
Jon Hall1efcb3f2016-08-23 13:42:15 -0700881 utilities.assert_equals( expect=main.TRUE, actual=isUp,
882 onpass="ONOS service is ready",
883 onfail="ONOS service did not start properly" )
884 for i in nodes:
885 main.step( "Checking if ONOS CLI is ready" )
Devin Lim142b5342017-07-20 15:22:39 -0700886 ctrl = main.Cluster.runningNodes[ i ]
Jonghwan Hyun76a02b72018-01-30 16:40:48 +0900887 # ctrl.CLI.startCellCli()
Devin Lim142b5342017-07-20 15:22:39 -0700888 cliResult = ctrl.CLI.startOnosCli( ctrl.ipAddress,
889 commandlineTimeout=60,
890 onosStartTimeout=100 )
891 ctrl.active = True
Jon Hall1efcb3f2016-08-23 13:42:15 -0700892 utilities.assert_equals( expect=main.TRUE,
893 actual=cliResult,
894 onpass="ONOS CLI is ready",
895 onfail="ONOS CLI is not ready" )
Jon Hall1efcb3f2016-08-23 13:42:15 -0700896
Jon Halla604fd42018-05-04 14:27:27 -0700897 main.Cluster.reset()
Pier3b58c652016-09-26 12:03:31 -0700898 main.step( "Checking ONOS nodes" )
Jon Halla604fd42018-05-04 14:27:27 -0700899 Testcaselib.verifyNodes( main )
900 Testcaselib.verifyTopology( main, switches, links, expNodes )
Pier3b58c652016-09-26 12:03:31 -0700901
Devin Lim142b5342017-07-20 15:22:39 -0700902 ready = utilities.retry( main.Cluster.active( 0 ).CLI.summary,
903 main.FALSE,
904 attempts=10,
905 sleep=12 )
906 if ready:
907 ready = main.TRUE
908 utilities.assert_equals( expect=main.TRUE, actual=ready,
Jon Hall1efcb3f2016-08-23 13:42:15 -0700909 onpass="ONOS summary command succeded",
910 onfail="ONOS summary command failed" )
911 if not ready:
912 main.log.error( "ONOS startup failed!" )
Devin Lim44075962017-08-11 10:56:37 -0700913 main.cleanAndExit()
Jon Hall1efcb3f2016-08-23 13:42:15 -0700914
915 @staticmethod
916 def addHostCfg( main ):
917 """
918 Adds Host Configuration to ONOS
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700919 Updates expected state of the network ( pingChart )
Jon Hall1efcb3f2016-08-23 13:42:15 -0700920 """
921 import json
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700922 hostCfg = {}
Devin Lim57221b02018-02-14 15:45:36 -0800923 with open( main.configPath + main.forJson + "extra.json" ) as template:
Jon Hall1efcb3f2016-08-23 13:42:15 -0700924 hostCfg = json.load( template )
925 main.pingChart[ 'ip' ][ 'hosts' ] += [ 'in1' ]
926 main.step( "Pushing new configuration" )
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700927 mac, cfg = hostCfg[ 'hosts' ].popitem()
Devin Lim142b5342017-07-20 15:22:39 -0700928 main.Cluster.active( 0 ).REST.setNetCfg( cfg[ 'basic' ],
929 subjectClass="hosts",
930 subjectKey=urllib.quote( mac,
931 safe='' ),
932 configKey="basic" )
Jon Hall1efcb3f2016-08-23 13:42:15 -0700933 main.pingChart[ 'ip' ][ 'hosts' ] += [ 'out1' ]
934 main.step( "Pushing new configuration" )
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700935 mac, cfg = hostCfg[ 'hosts' ].popitem()
Devin Lim142b5342017-07-20 15:22:39 -0700936 main.Cluster.active( 0 ).REST.setNetCfg( cfg[ 'basic' ],
937 subjectClass="hosts",
938 subjectKey=urllib.quote( mac,
939 safe='' ),
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700940 configKey="basic" )
Jon Hall1efcb3f2016-08-23 13:42:15 -0700941 main.pingChart.update( { 'vlan1': { "expect": "True",
942 "hosts": [ "olt1", "vsg1" ] } } )
943 main.pingChart[ 'vlan5' ][ 'expect' ] = 0
944 main.pingChart[ 'vlan10' ][ 'expect' ] = 0
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700945 ports = "[%s,%s]" % ( 5, 6 )
Jon Hall1efcb3f2016-08-23 13:42:15 -0700946 cfg = '{"of:0000000000000001":[{"vlan":1,"ports":%s,"name":"OLT 1"}]}' % ports
Devin Lim142b5342017-07-20 15:22:39 -0700947 main.Cluster.active( 0 ).REST.setNetCfg( json.loads( cfg ),
948 subjectClass="apps",
949 subjectKey="org.onosproject.segmentrouting",
950 configKey="xconnect" )
Jon Hall1efcb3f2016-08-23 13:42:15 -0700951
952 @staticmethod
953 def delHostCfg( main ):
954 """
955 Removest Host Configuration from ONOS
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700956 Updates expected state of the network ( pingChart )
Jon Hall1efcb3f2016-08-23 13:42:15 -0700957 """
958 import json
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700959 hostCfg = {}
Devin Lim57221b02018-02-14 15:45:36 -0800960 with open( main.configPath + main.forJson + "extra.json" ) as template:
Jon Hall1efcb3f2016-08-23 13:42:15 -0700961 hostCfg = json.load( template )
962 main.step( "Removing host configuration" )
963 main.pingChart[ 'ip' ][ 'expect' ] = 0
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700964 mac, cfg = hostCfg[ 'hosts' ].popitem()
Devin Lim142b5342017-07-20 15:22:39 -0700965 main.Cluster.active( 0 ).REST.removeNetCfg( subjectClass="hosts",
966 subjectKey=urllib.quote(
967 mac,
968 safe='' ),
969 configKey="basic" )
Jon Hall1efcb3f2016-08-23 13:42:15 -0700970 main.step( "Removing configuration" )
971 main.pingChart[ 'ip' ][ 'expect' ] = 0
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700972 mac, cfg = hostCfg[ 'hosts' ].popitem()
Devin Lim142b5342017-07-20 15:22:39 -0700973 main.Cluster.active( 0 ).REST.removeNetCfg( subjectClass="hosts",
974 subjectKey=urllib.quote(
975 mac,
976 safe='' ),
977 configKey="basic" )
Jon Hall1efcb3f2016-08-23 13:42:15 -0700978 main.step( "Removing vlan configuration" )
979 main.pingChart[ 'vlan1' ][ 'expect' ] = 0
Devin Lim142b5342017-07-20 15:22:39 -0700980 main.Cluster.active( 0 ).REST.removeNetCfg( subjectClass="apps",
981 subjectKey="org.onosproject.segmentrouting",
982 configKey="xconnect" )
You Wang53dba1e2018-02-02 17:45:44 -0800983
984 @staticmethod
985 def verifyNetworkHostIp( main, attempts=10, sleep=10 ):
986 """
987 Verifies IP address assignment from the hosts
988 """
989 main.step( "Verify IP address assignment from hosts" )
990 ipResult = main.TRUE
You Wangd66de192018-04-30 17:30:12 -0700991 main.Network.update()
You Wang6acb7a42018-05-04 15:12:25 -0700992 # Find out names of disconnected hosts
993 disconnectedHosts = []
994 if hasattr( main, "disconnectedIpv4Hosts" ):
995 for host in main.disconnectedIpv4Hosts:
996 disconnectedHosts.append( host )
997 if hasattr( main, "disconnectedIpv6Hosts" ):
998 for host in main.disconnectedIpv6Hosts:
999 disconnectedHosts.append( host )
You Wang53dba1e2018-02-02 17:45:44 -08001000 for hostName, ip in main.expectedHosts[ "network" ].items():
You Wang6acb7a42018-05-04 15:12:25 -07001001 # Exclude disconnected hosts
1002 if hostName in disconnectedHosts:
1003 main.log.debug( "Skip verifying IP for {} as it's disconnected".format( hostName ) )
1004 continue
You Wang53dba1e2018-02-02 17:45:44 -08001005 ipResult = ipResult and utilities.retry( main.Network.verifyHostIp,
1006 main.FALSE,
1007 kwargs={ 'hostList': [ hostName ],
You Wangd66de192018-04-30 17:30:12 -07001008 'prefix': ip,
1009 'update': False },
You Wang53dba1e2018-02-02 17:45:44 -08001010 attempts=attempts,
1011 sleep=sleep )
1012 utilities.assert_equals( expect=main.TRUE, actual=ipResult,
1013 onpass="Verify network host IP succeded",
1014 onfail="Verify network host IP failed" )
1015
1016 @staticmethod
1017 def verifyOnosHostIp( main, attempts=10, sleep=10 ):
1018 """
1019 Verifies host IP address assignment from ONOS
1020 """
1021 main.step( "Verify host IP address assignment in ONOS" )
1022 ipResult = main.TRUE
You Wang6acb7a42018-05-04 15:12:25 -07001023 # Find out IPs of disconnected hosts
1024 disconnectedIps = []
1025 if hasattr( main, "disconnectedIpv4Hosts" ):
1026 for host in main.disconnectedIpv4Hosts:
1027 disconnectedIps.append( main.expectedHosts[ "network" ][ host ] )
1028 if hasattr( main, "disconnectedIpv6Hosts" ):
1029 for host in main.disconnectedIpv6Hosts:
1030 disconnectedIps.append( main.expectedHosts[ "network" ][ host ] )
You Wang53dba1e2018-02-02 17:45:44 -08001031 for hostName, ip in main.expectedHosts[ "onos" ].items():
You Wang6acb7a42018-05-04 15:12:25 -07001032 # Exclude disconnected hosts
1033 if ip in disconnectedIps:
1034 main.log.debug( "Skip verifying IP for {} as it's disconnected".format( ip ) )
1035 continue
You Wang53dba1e2018-02-02 17:45:44 -08001036 ipResult = ipResult and utilities.retry( main.Cluster.active( 0 ).verifyHostIp,
1037 main.FALSE,
1038 kwargs={ 'hostList': [ hostName ],
1039 'prefix': ip },
1040 attempts=attempts,
1041 sleep=sleep )
1042 utilities.assert_equals( expect=main.TRUE, actual=ipResult,
1043 onpass="Verify ONOS host IP succeded",
1044 onfail="Verify ONOS host IP failed" )
Andreas Pantelopoulos2eae3242018-03-06 13:47:20 -08001045
Jonghwan Hyun812c70f2018-02-16 16:33:16 -08001046 @staticmethod
1047 def updateIntfCfg( main, connectPoint, ips=[], untagged=0, tagged=[], native=0 ):
1048 """
1049 Description:
1050 Updates interface configuration in ONOS, with given IP and vlan parameters
1051 Required:
1052 * connectPoint: connect point to update configuration
1053 Optional:
1054 * ips: list of IP addresses, combined with '/xx' subnet representation,
1055 corresponding to 'ips' field in the configuration
1056 * untagged: vlan ID as an integer, corresponding to 'vlan-untagged' field in the configuration
1057 * tagged: integer list of vlan IDs, corresponding to 'vlan-tagged' field in the configuration
1058 * native: vlan ID as an integer, corresponding to 'vlan-native' field in the configuration
1059 """
1060 cfg = dict()
1061 cfg[ "ports" ] = dict()
1062 cfg[ "ports" ][ connectPoint ] = dict()
1063 cfg[ "ports" ][ connectPoint ][ "interfaces" ] = [ dict() ]
1064 cfg[ "ports" ][ connectPoint ][ "interfaces" ][ 0 ][ "ips" ] = ips
1065 if untagged > 0:
1066 cfg[ "ports" ][ connectPoint ][ "interfaces" ][ 0 ][ "vlan-untagged" ] = untagged
1067 else:
1068 cfg[ "ports" ][ connectPoint ][ "interfaces" ][ 0 ][ "vlan-tagged" ] = tagged
1069 if native > 0:
1070 cfg[ "ports" ][ connectPoint ][ "interfaces" ][ 0 ][ "vlan-native" ] = native
1071
1072 main.Cluster.active( 0 ).REST.setNetCfg( json.loads( json.dumps( cfg ) ) )
You Wange24d6272018-03-27 21:18:50 -07001073
1074 @staticmethod
1075 def startScapyHosts( main ):
1076 """
1077 Create host components and start Scapy CLIs
1078 """
1079 main.step( "Start Scapy CLIs" )
1080 main.scapyHostNames = main.params[ 'SCAPY' ][ 'HOSTNAMES' ].split( ',' )
1081 main.scapyHosts = []
1082 for hostName in main.scapyHostNames:
1083 main.Scapy.createHostComponent( hostName )
1084 main.scapyHosts.append( getattr( main, hostName ) )
1085 for host in main.scapyHosts:
1086 host.startHostCli()
1087 host.startScapy()
1088 host.updateSelf()
1089 main.log.debug( host.name )
1090 main.log.debug( host.hostIp )
1091 main.log.debug( host.hostMac )
1092
1093 @staticmethod
You Wang547893e2018-05-08 13:34:59 -07001094 def verifyMulticastTraffic( main, routeName, expect, skipOnFail=True, maxRetry=1 ):
You Wange24d6272018-03-27 21:18:50 -07001095 """
1096 Verify multicast traffic using scapy
1097 """
You Wangc564c6f2018-05-01 15:24:57 -07001098 from tests.dependencies.topology import Topology
1099 try:
1100 main.topo
1101 except ( NameError, AttributeError ):
1102 main.topo = Topology()
You Wang85747762018-05-11 15:51:50 -07001103 main.step( "Verify {} multicast traffic".format( routeName ) )
You Wangc02d8352018-04-17 16:42:10 -07001104 routeData = main.multicastConfig[ routeName ]
1105 srcs = main.mcastRoutes[ routeName ][ "src" ]
1106 dsts = main.mcastRoutes[ routeName ][ "dst" ]
1107 main.log.info( "Sending multicast traffic from {} to {}".format( [ routeData[ "src" ][ i ][ "host" ] for i in srcs ],
1108 [ routeData[ "dst" ][ i ][ "host" ] for i in dsts ] ) )
You Wang85747762018-05-11 15:51:50 -07001109 result = main.TRUE
You Wangc02d8352018-04-17 16:42:10 -07001110 for src in srcs:
1111 srcEntry = routeData[ "src" ][ src ]
1112 for dst in dsts:
1113 dstEntry = routeData[ "dst" ][ dst ]
1114 sender = getattr( main, srcEntry[ "host" ] )
1115 receiver = getattr( main, dstEntry[ "host" ] )
1116 main.Network.addRoute( str( srcEntry[ "host" ] ),
1117 str( routeData[ "group" ] ),
1118 str( srcEntry[ "interface" ] ),
1119 True if routeData[ "ipVersion" ] == 6 else False )
1120 # Build the packet
1121 sender.buildEther( dst=str( srcEntry[ "Ether" ] ) )
1122 if routeData[ "ipVersion" ] == 4:
1123 sender.buildIP( dst=str( routeData[ "group" ] ) )
1124 elif routeData[ "ipVersion" ] == 6:
1125 sender.buildIPv6( dst=str( routeData[ "group" ] ) )
1126 sender.buildUDP( ipVersion=routeData[ "ipVersion" ], dport=srcEntry[ "UDP" ] )
1127 sIface = srcEntry[ "interface" ]
1128 dIface = dstEntry[ "interface" ] if "interface" in dstEntry.keys() else None
1129 pktFilter = srcEntry[ "filter" ]
1130 pkt = srcEntry[ "packet" ]
1131 # Send packet and check received packet
1132 expectedResult = expect.pop( 0 ) if isinstance( expect, list ) else expect
You Wangc564c6f2018-05-01 15:24:57 -07001133 t3Cmd = "t3-troubleshoot -vv -sp {} -et ipv{} -d {} -dm {}".format( srcEntry[ "port" ], routeData[ "ipVersion" ],
Jon Halla604fd42018-05-04 14:27:27 -07001134 routeData[ "group" ], srcEntry[ "Ether" ] )
You Wangc564c6f2018-05-01 15:24:57 -07001135 trafficResult = main.topo.sendScapyPackets( sender, receiver, pktFilter, pkt, sIface, dIface,
1136 expectedResult, maxRetry, True, t3Cmd )
You Wang85747762018-05-11 15:51:50 -07001137 if not trafficResult:
1138 result = main.FALSE
1139 main.log.warn( "Scapy result from {} to {} is not as expected".format( srcEntry[ "host" ],
1140 dstEntry[ "host" ] ) )
1141 utilities.assert_equals( expect=main.TRUE,
1142 actual=result,
1143 onpass="Verify {} multicast traffic: Pass".format( routeName ),
1144 onfail="Verify {} multicast traffic: Fail".format( routeName ) )
You Wangba823f02018-05-17 13:54:08 -07001145 if skipOnFail and result != main.TRUE:
You Wang85747762018-05-11 15:51:50 -07001146 Testcaselib.saveOnosDiagnostics( main )
1147 Testcaselib.cleanup( main, copyKarafLog=False )
1148 main.skipCase()
You Wangc02d8352018-04-17 16:42:10 -07001149
1150 @staticmethod
You Wang85747762018-05-11 15:51:50 -07001151 def verifyPing( main, srcList, dstList, ipv6=False, expect=True, wait=1,
1152 acceptableFailed=0, skipOnFail=True, stepMsg="Verify Ping" ):
You Wang5da39c82018-04-26 22:55:08 -07001153 """
1154 Verify reachability from each host in srcList to each host in dstList
1155 """
1156 from tests.dependencies.topology import Topology
1157 try:
1158 main.topo
1159 except ( NameError, AttributeError ):
1160 main.topo = Topology()
You Wang85747762018-05-11 15:51:50 -07001161 main.step( stepMsg )
You Wang0fa76e72018-05-18 11:33:25 -07001162 pingResult = main.topo.ping( srcList, dstList, ipv6, expect, wait, acceptableFailed, skipOnFail, True )
You Wang85747762018-05-11 15:51:50 -07001163 utilities.assert_equals( expect=main.TRUE,
1164 actual=pingResult,
1165 onpass="{}: Pass".format( stepMsg ),
1166 onfail="{}: Fail".format( stepMsg ) )
You Wang5da39c82018-04-26 22:55:08 -07001167 if not pingResult and skipOnFail:
1168 Testcaselib.saveOnosDiagnostics( main )
1169 Testcaselib.cleanup( main, copyKarafLog=False, removeHostComponent=True )
1170 main.skipCase()
You Wangbc898b82018-05-03 16:22:34 -07001171
1172 @staticmethod
You Wang85747762018-05-11 15:51:50 -07001173 def verifyHostLocations( main, locationDict, retry=2 ):
You Wangbc898b82018-05-03 16:22:34 -07001174 """
1175 Verify if the specified host is discovered by ONOS on the given locations
1176 Required:
You Wang85747762018-05-11 15:51:50 -07001177 locationDict: a dictionary that maps host names to expected locations.
1178 locations could be a string or a list.
1179 ex. { "h1v4": ["of:0000000000000005/8"] }
You Wangbc898b82018-05-03 16:22:34 -07001180 Returns:
1181 main.TRUE if host is discovered on all locations provided, otherwise main.FALSE
1182 """
You Wang85747762018-05-11 15:51:50 -07001183 main.step( "Verify locations of hosts {}".format( locationDict.keys() ) )
1184 result = main.TRUE
1185 for hostName, locations in locationDict.items():
1186 main.log.info( "Verify host {} is discovered at {}".format( hostName, locations ) )
1187 hostIp = main.Network.getIPAddress( hostName, proto='IPV4' )
1188 if not hostIp:
1189 hostIp = main.Network.getIPAddress( hostName, proto='IPV6' )
1190 if not hostIp:
1191 main.log.warn( "Failed to find IP address for host {}, skipping location verification".format( hostName ) )
1192 result = main.FALSE
1193 continue
1194 locationResult = utilities.retry( main.Cluster.active( 0 ).CLI.verifyHostLocation,
1195 main.FALSE,
1196 args=( hostIp, locations ),
1197 attempts=retry + 1,
1198 sleep=10 )
1199 if not locationResult:
1200 result = main.FALSE
1201 main.log.warn( "location verification for host {} failed".format( hostName ) )
You Wang547893e2018-05-08 13:34:59 -07001202 utilities.assert_equals( expect=main.TRUE, actual=result,
You Wang85747762018-05-11 15:51:50 -07001203 onpass="Location verification passed",
1204 onfail="Location verification failed" )
Jonghwan Hyun785471d2018-05-14 14:48:19 -07001205
1206 @staticmethod
1207 def moveHost( main, hostName, srcSw, dstSw, gw, macAddr=None, prefixLen=None, cfg='', ipv6=False ):
1208 """
1209 Move specified host from srcSw to dstSw.
1210 If srcSw and dstSw are same, the host will be moved from current port to
1211 next available port.
1212 Required:
1213 hostName: name of the host. e.g., "h1"
1214 srcSw: name of the switch that the host is attached to. e.g., "leaf1"
1215 dstSw: name of the switch that the host will be moved to. e.g., "leaf2"
1216 gw: ip address of the gateway of the new location
1217 Optional:
1218 macAddr: if specified, change MAC address of the host to the specified MAC address.
1219 prefixLen: prefix length
1220 cfg: port configuration as JSON string
1221 ipv6: Use True to move IPv6 host
1222 """
1223
1224 if not hasattr( main, 'Mininet1' ):
1225 main.log.warn( "moveHost is supposed to be used only in Mininet." )
1226 return
1227
1228 if ipv6:
1229 main.Mininet1.moveHostv6( hostName, srcSw, dstSw, macAddr )
1230 else:
1231 main.Mininet1.moveHost( hostName, srcSw, dstSw, macAddr, prefixLen )
1232
1233 main.Mininet1.changeDefaultGateway( hostName, gw )
1234 if cfg:
1235 main.Cluster.active( 0 ).REST.setNetCfg( json.loads( cfg ),
1236 subjectClass="ports" )
1237
1238 main.Mininet1.discoverHosts( [ hostName, ] )
1239
1240 # Update expectedHost when MAC address is changed.
1241 if macAddr is not None:
1242 ipAddr = main.expectedHosts[ "network" ][ hostName ]
1243 if ipAddr is not None:
1244 for hostName, ip in main.expectedHosts[ "onos" ].items():
1245 if ip == ipAddr:
1246 vlan = hostName.split( "/" )[ -1 ]
1247 del main.expectedHosts[ "onos" ][ hostName ]
1248 main.expectedHosts[ "onos" ][ "{}/{}".format( macAddr, vlan ) ] = ip
1249 break