blob: 5ebe5dcaff3467e6e3522968eb9f5de46925f243 [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
22import imp
23import time
24import json
25import urllib
26from core import utilities
27
28
29class Testcaselib:
Pierfb719b12016-09-19 14:51:44 -070030
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -070031 useSSH = True
Pierfb719b12016-09-19 14:51:44 -070032
Jon Hall1efcb3f2016-08-23 13:42:15 -070033 @staticmethod
34 def initTest( main ):
35 """
36 - Construct tests variables
37 - GIT ( optional )
38 - Checkout ONOS master branch
39 - Pull latest ONOS code
40 - Building ONOS ( optional )
41 - Install ONOS package
42 - Build ONOS package
43 """
Devin Lim58046fa2017-07-05 16:55:00 -070044 try:
45 from tests.dependencies.ONOSSetup import ONOSSetup
46 main.testSetUp = ONOSSetup()
47 except ImportError:
48 main.log.error( "ONOSSetup not found. exiting the test" )
Devin Lim44075962017-08-11 10:56:37 -070049 main.cleanAndExit()
You Wangd5873482018-01-24 12:30:00 -080050 from tests.dependencies.Network import Network
51 main.Network = Network()
Devin Lim0c972b72018-02-08 14:53:59 -080052 main.testSetUp.envSetupDescription( False )
Devin Lim58046fa2017-07-05 16:55:00 -070053 stepResult = main.FALSE
54 try:
55 main.step( "Constructing test variables" )
56 # Test variables
57 main.cellName = main.params[ 'ENV' ][ 'cellName' ]
58 main.apps = main.params[ 'ENV' ][ 'cellApps' ]
Devin Lim58046fa2017-07-05 16:55:00 -070059 main.path = os.path.dirname( main.testFile )
Devin Lim57221b02018-02-14 15:45:36 -080060 main.useCommonTopo = main.params[ 'DEPENDENCY' ][ 'useCommonTopo' ] == 'True'
61 main.topoPath = main.path + ( "/.." if main.useCommonTopo else "" ) + "/dependencies/"
62 main.useCommonConf = main.params[ 'DEPENDENCY' ][ 'useCommonConf' ] == 'True'
63 main.configPath = main.path + ( "/.." if main.useCommonConf else "" ) + "/dependencies/"
64 main.forJson = "json/"
65 main.forChart = "chart/"
66 main.forConfig = "conf/"
67 main.forHost = "host/"
You Wang27317572018-03-06 12:13:11 -080068 main.forSwitchFailure = "switchFailure/"
Andreas Pantelopoulosfab6bf32018-03-06 18:56:35 -080069 main.forLinkFailure = "linkFailure/"
You Wange24d6272018-03-27 21:18:50 -070070 main.forMulticast = "multicast/"
Devin Lim58046fa2017-07-05 16:55:00 -070071 main.topology = main.params[ 'DEPENDENCY' ][ 'topology' ]
You Wangd87b2312018-01-30 12:47:17 -080072 main.topologyLib = main.params[ 'DEPENDENCY' ][ 'lib' ] if 'lib' in main.params[ 'DEPENDENCY' ] else None
73 main.topologyConf = main.params[ 'DEPENDENCY' ][ 'conf' ] if 'conf' in main.params[ 'DEPENDENCY' ] else None
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -070074 main.scale = ( main.params[ 'SCALE' ][ 'size' ] ).split( "," )
Devin Lim58046fa2017-07-05 16:55:00 -070075 main.maxNodes = int( main.params[ 'SCALE' ][ 'max' ] )
Jon Hall1efcb3f2016-08-23 13:42:15 -070076
Devin Lim0c972b72018-02-08 14:53:59 -080077 stepResult = main.testSetUp.envSetup( False )
Devin Lim58046fa2017-07-05 16:55:00 -070078 except Exception as e:
79 main.testSetUp.envSetupException( e )
Jonghwan Hyun3731d6a2017-10-19 11:59:31 -070080
Devin Lim58046fa2017-07-05 16:55:00 -070081 main.testSetUp.evnSetupConclusion( stepResult )
Jon Hall1efcb3f2016-08-23 13:42:15 -070082
Jon Hall1efcb3f2016-08-23 13:42:15 -070083 @staticmethod
Andreas Pantelopoulos90f0b102018-02-01 13:21:45 -080084 def installOnos( main, vlanCfg=True, skipPackage=False, cliSleep=10,
85 parallel=True ):
Jon Hall1efcb3f2016-08-23 13:42:15 -070086 """
87 - Set up cell
88 - Create cell file
89 - Set cell file
90 - Verify cell file
91 - Kill ONOS process
92 - Uninstall ONOS cluster
93 - Verify ONOS start up
94 - Install ONOS cluster
95 - Connect to cli
96 """
97 # main.scale[ 0 ] determines the current number of ONOS controller
You Wangd87b2312018-01-30 12:47:17 -080098 if not main.apps:
Jon Hall1efcb3f2016-08-23 13:42:15 -070099 main.log.error( "App list is empty" )
Jon Hall3c910162018-03-07 14:42:16 -0800100 main.log.info( "Cluster size: " + str( main.Cluster.numCtrls ) )
101 main.log.info( "Cluster ips: " + ', '.join( main.Cluster.getIps() ) )
Jon Hall1efcb3f2016-08-23 13:42:15 -0700102 main.dynamicHosts = [ 'in1', 'out1' ]
You Wanga0f6ff62018-01-11 15:46:30 -0800103 main.testSetUp.ONOSSetUp( main.Cluster, newCell=True, cellName=main.cellName,
Andreas Pantelopoulos90f0b102018-02-01 13:21:45 -0800104 skipPack=skipPackage,
105 useSSH=Testcaselib.useSSH,
Devin Lim0c972b72018-02-08 14:53:59 -0800106 installParallel=parallel, includeCaseDesc=False )
Devin Lim142b5342017-07-20 15:22:39 -0700107 ready = utilities.retry( main.Cluster.active( 0 ).CLI.summary,
108 main.FALSE,
You Wang1cdc5f52017-12-19 16:47:51 -0800109 sleep=cliSleep,
Devin Lim142b5342017-07-20 15:22:39 -0700110 attempts=10 )
111 if ready:
112 ready = main.TRUE
113 utilities.assert_equals( expect=main.TRUE, actual=ready,
Jon Hall1efcb3f2016-08-23 13:42:15 -0700114 onpass="ONOS summary command succeded",
115 onfail="ONOS summary command failed" )
Jon Hall1efcb3f2016-08-23 13:42:15 -0700116 if not ready:
117 main.log.error( "ONOS startup failed!" )
Devin Lim44075962017-08-11 10:56:37 -0700118 main.cleanAndExit()
Jon Hall1efcb3f2016-08-23 13:42:15 -0700119
Devin Lim142b5342017-07-20 15:22:39 -0700120 for ctrl in main.Cluster.active():
121 ctrl.CLI.logSet( "DEBUG", "org.onosproject.segmentrouting" )
You Wangf5f104f2018-03-30 17:09:10 -0700122 ctrl.CLI.logSet( "DEBUG", "org.onosproject.driver" )
Devin Lim142b5342017-07-20 15:22:39 -0700123 ctrl.CLI.logSet( "DEBUG", "org.onosproject.net.flowobjective.impl" )
You Wangf5f104f2018-03-30 17:09:10 -0700124 ctrl.CLI.logSet( "DEBUG", "org.onosproject.routeservice.impl" )
125 ctrl.CLI.logSet( "DEBUG", "org.onosproject.routeservice.store" )
126 ctrl.CLI.logSet( "DEBUG", "org.onosproject.routing.fpm" )
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
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -0800380 def checkFlowEqualityByDpid( main, dpid, flowCount, sleep=10):
381 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,
385 args=( dpid, flowCount, False, 1),
386 attempts=5,
387 sleep=sleep )
388
389 utilities.assertEquals(
390 expect=True,
391 actual=( int( count ) == flowCount ),
392 onpass="Flow count looks correct: " + str(count) ,
393 onfail="Flow count looks wrong, should be " + str(flowCount))
394
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 ),
408 onpass="Group count looks correct: " + str(count) ,
409 onfail="Group count looks wrong: should be " + str(groupCount))
410
411 @staticmethod
412 def checkFlowsGroupsFromFile(main):
413
414 for dpid, values in main.count.items():
415 flowCount = values["flows"]
416 groupCount = values["groups"]
417 main.log.report( "Check flow count for dpid " + str(dpid) +
418 ", should be " + str(flowCount))
419 Testcaselib.checkFlowEqualityByDpid(main, dpid, flowCount)
420
421 main.log.report( "Check group count for dpid " + str(dpid) +
422 ", should be " + str(groupCount))
423 Testcaselib.checkGroupEqualityByDpid(main, dpid, groupCount)
424
425 return
426
427 @staticmethod
You Wang5df1c6d2018-04-06 18:02:02 -0700428 def pingAll( main, tag="", dumpflows=True, acceptableFailed=0, basedOnIp=False, sleep=10, retryAttempts=1, skipOnFail=False ):
You Wangf19d9f42018-02-23 16:34:19 -0800429 '''
You Wangba231e72018-03-01 13:18:21 -0800430 Verify connectivity between hosts according to the ping chart
431 acceptableFailed: max number of acceptable failed pings.
You Wangf19d9f42018-02-23 16:34:19 -0800432 basedOnIp: if True, run ping or ping6 based on suffix of host names
Jonghwan Hyun812c70f2018-02-16 16:33:16 -0800433 retryAttempts: the number of retry ping. Only works for IPv4 hosts.
You Wangf19d9f42018-02-23 16:34:19 -0800434 '''
You Wangba231e72018-03-01 13:18:21 -0800435 main.log.report( "Check host connectivity" )
436 main.log.debug( "Ping chart: %s" % main.pingChart )
Andreas Pantelopoulosf6ed5012018-02-08 21:26:01 -0800437 if tag == "":
438 tag = 'CASE%d' % main.CurrentTestCaseNumber
439 for entry in main.pingChart.itervalues():
You Wangba231e72018-03-01 13:18:21 -0800440 main.log.debug( "Entry in ping chart: %s" % entry )
441 expect = entry[ 'expect' ]
442 if expect == "Unidirectional":
443 # Verify ping from each src host to each dst host
444 src = entry[ 'src' ]
445 dst = entry[ 'dst' ]
446 expect = main.TRUE
447 main.step( "Verify unidirectional connectivity from %s to %s with tag %s" % ( str( src ), str( dst ), tag ) )
448 if basedOnIp:
449 if ("v4" in src[0]):
450 pa = main.Network.pingallHostsUnidirectional( src, dst, acceptableFailed=acceptableFailed )
451 utilities.assert_equals( expect=expect, actual=pa,
452 onpass="IPv4 connectivity successfully tested",
453 onfail="IPv4 connectivity failed" )
454 if ("v6" in src[0]):
455 pa = main.Network.pingallHostsUnidirectional( src, dst, ipv6=True, acceptableFailed=acceptableFailed )
456 utilities.assert_equals( expect=expect, actual=pa,
457 onpass="IPv6 connectivity successfully tested",
458 onfail="IPv6 connectivity failed" )
459 else:
460 pa = main.Network.pingallHostsUnidirectional( src, dst, acceptableFailed=acceptableFailed )
461 utilities.assert_equals( expect=expect, actual=pa,
462 onpass="IP connectivity successfully tested",
463 onfail="IP connectivity failed" )
464 else:
465 # Verify ping between each host pair
466 hosts = entry[ 'hosts' ]
467 try:
468 expect = main.TRUE if str(expect).lower() == 'true' else main.FALSE
469 except:
470 expect = main.FALSE
471 main.step( "Verify full connectivity for %s with tag %s" % ( str( hosts ), tag ) )
472 if basedOnIp:
473 if ("v4" in hosts[0]):
Jonghwan Hyun812c70f2018-02-16 16:33:16 -0800474 pa = utilities.retry( main.Network.pingallHosts,
475 main.FALSE if expect else main.TRUE,
476 args=(hosts,),
477 attempts=retryAttempts,
478 sleep=sleep )
You Wangba231e72018-03-01 13:18:21 -0800479 utilities.assert_equals( expect=expect, actual=pa,
480 onpass="IPv4 connectivity successfully tested",
481 onfail="IPv4 connectivity failed" )
482 if ("v6" in hosts[0]):
483 pa = main.Network.pingIpv6Hosts( hosts, acceptableFailed=acceptableFailed )
484 utilities.assert_equals( expect=expect, actual=pa,
485 onpass="IPv6 connectivity successfully tested",
486 onfail="IPv6 connectivity failed" )
487 else:
You Wangf19d9f42018-02-23 16:34:19 -0800488 pa = main.Network.pingallHosts( hosts )
489 utilities.assert_equals( expect=expect, actual=pa,
You Wangba231e72018-03-01 13:18:21 -0800490 onpass="IP connectivity successfully tested",
491 onfail="IP connectivity failed" )
You Wang5df1c6d2018-04-06 18:02:02 -0700492 if skipOnFail and pa != expect:
493 Testcaselib.saveOnosDiagnostics( main )
You Wang24ad2f52018-04-10 10:47:12 -0700494 Testcaselib.cleanup( main, copyKarafLog=False )
You Wang5df1c6d2018-04-06 18:02:02 -0700495 main.skipCase()
Andreas Pantelopoulosf6ed5012018-02-08 21:26:01 -0800496
497 if dumpflows:
498 main.ONOSbench.dumpONOSCmd( main.Cluster.active( 0 ).ipAddress,
499 "flows",
500 main.logdir,
501 tag + "_FlowsOn" )
502 main.ONOSbench.dumpONOSCmd( main.Cluster.active( 0 ).ipAddress,
503 "groups",
504 main.logdir,
505 tag + "_GroupsOn" )
506
507 @staticmethod
Jon Hall1efcb3f2016-08-23 13:42:15 -0700508 def killLink( main, end1, end2, switches, links ):
509 """
510 end1,end2: identify the switches, ex.: 'leaf1', 'spine1'
511 switches, links: number of expected switches and links after linkDown, ex.: '4', '6'
512 Kill a link and verify ONOS can see the proper link change
513 """
514 main.linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700515 main.step( "Kill link between %s and %s" % ( end1, end2 ) )
You Wangd5873482018-01-24 12:30:00 -0800516 LinkDown = main.Network.link( END1=end1, END2=end2, OPTION="down" )
517 LinkDown = main.Network.link( END2=end1, END1=end2, OPTION="down" )
Jon Hall1efcb3f2016-08-23 13:42:15 -0700518 main.log.info(
519 "Waiting %s seconds for link down to be discovered" % main.linkSleep )
520 time.sleep( main.linkSleep )
Devin Lim142b5342017-07-20 15:22:39 -0700521 topology = utilities.retry( main.Cluster.active( 0 ).CLI.checkStatus,
Jon Hall1efcb3f2016-08-23 13:42:15 -0700522 main.FALSE,
523 kwargs={ 'numoswitch': switches,
524 'numolink': links },
525 attempts=10,
526 sleep=main.linkSleep )
527 result = topology & LinkDown
528 utilities.assert_equals( expect=main.TRUE, actual=result,
529 onpass="Link down successful",
530 onfail="Failed to turn off link?" )
531
532 @staticmethod
You Wangeb717bc2018-04-05 17:36:11 -0700533 def killLinkBatch( main, links, linksAfter, switches ):
Andreas Pantelopoulosfab6bf32018-03-06 18:56:35 -0800534 """
535 links = list of links (src, dst) to bring down.
536 """
537
538 main.step("Killing a batch of links {0}".format(links))
539
540 for end1, end2 in links:
541 main.Network.link( END1=end1, END2=end2, OPTION="down")
542 main.Network.link( END1=end2, END2=end1, OPTION="down")
543
544 main.linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
545 main.log.info(
546 "Waiting %s seconds for links down to be discovered" % main.linkSleep )
547 time.sleep( main.linkSleep )
548
549 topology = utilities.retry( main.Cluster.active( 0 ).CLI.checkStatus,
550 main.FALSE,
551 kwargs={ 'numoswitch': switches,
552 'numolink': linksAfter },
553 attempts=10,
554 sleep=main.linkSleep )
555
You Wang2854bce2018-03-30 10:15:32 -0700556 utilities.assert_equals( expect=main.TRUE, actual=topology,
557 onpass="Link batch down successful",
558 onfail="Link batch down failed" )
559
Andreas Pantelopoulosfab6bf32018-03-06 18:56:35 -0800560 @staticmethod
You Wangeb717bc2018-04-05 17:36:11 -0700561 def restoreLinkBatch( main, links, linksAfter, switches ):
Andreas Pantelopoulosfab6bf32018-03-06 18:56:35 -0800562 """
563 links = list of link (src, dst) to bring up again.
564 """
565
566 main.step("Restoring a batch of links {0}".format(links))
567
568 for end1, end2 in links:
569 main.Network.link( END1=end1, END2=end2, OPTION="up")
570 main.Network.link( END1=end2, END2=end1, OPTION="up")
571
572 main.linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
573 main.log.info(
574 "Waiting %s seconds for links down to be discovered" % main.linkSleep )
575 time.sleep( main.linkSleep )
576
577 topology = utilities.retry( main.Cluster.active( 0 ).CLI.checkStatus,
578 main.FALSE,
579 kwargs={ 'numoswitch': switches,
580 'numolink': linksAfter },
581 attempts=10,
582 sleep=main.linkSleep )
583
You Wang2854bce2018-03-30 10:15:32 -0700584 utilities.assert_equals( expect=main.TRUE, actual=topology,
585 onpass="Link batch up successful",
586 onfail="Link batch up failed" )
587
Andreas Pantelopoulosfab6bf32018-03-06 18:56:35 -0800588 @staticmethod
You Wangc02d8352018-04-17 16:42:10 -0700589 def restoreLink( main, end1, end2, switches, links,
590 portUp=False, dpid1='', dpid2='', port1='', port2='' ):
Jon Hall1efcb3f2016-08-23 13:42:15 -0700591 """
592 Params:
593 end1,end2: identify the end switches, ex.: 'leaf1', 'spine1'
You Wangc02d8352018-04-17 16:42:10 -0700594 portUp: enable portstate after restoring link
Jon Hall1efcb3f2016-08-23 13:42:15 -0700595 dpid1, dpid2: dpid of the end switches respectively, ex.: 'of:0000000000000002'
596 port1, port2: respective port of the end switches that connects to the link, ex.:'1'
597 switches, links: number of expected switches and links after linkDown, ex.: '4', '6'
598 Kill a link and verify ONOS can see the proper link change
599 """
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700600 main.step( "Restore link between %s and %s" % ( end1, end2 ) )
Jon Hall1efcb3f2016-08-23 13:42:15 -0700601 result = False
602 count = 0
603 while True:
604 count += 1
You Wangd5873482018-01-24 12:30:00 -0800605 main.Network.link( END1=end1, END2=end2, OPTION="up" )
606 main.Network.link( END2=end1, END1=end2, OPTION="up" )
Jon Hall1efcb3f2016-08-23 13:42:15 -0700607 main.log.info(
608 "Waiting %s seconds for link up to be discovered" % main.linkSleep )
609 time.sleep( main.linkSleep )
Pierfb719b12016-09-19 14:51:44 -0700610
You Wangc02d8352018-04-17 16:42:10 -0700611 if portUp:
612 ctrl.CLI.portstate( dpid=dpid1, port=port1, state='Enable' )
613 ctrl.CLI.portstate( dpid=dpid2, port=port2, state='Enable' )
614 time.sleep( main.linkSleep )
Jon Hall1efcb3f2016-08-23 13:42:15 -0700615
Devin Lim142b5342017-07-20 15:22:39 -0700616 result = main.Cluster.active( 0 ).CLI.checkStatus( numoswitch=switches,
617 numolink=links )
Jon Hall1efcb3f2016-08-23 13:42:15 -0700618 if count > 5 or result:
619 break
620 utilities.assert_equals( expect=main.TRUE, actual=result,
621 onpass="Link up successful",
622 onfail="Failed to bring link up" )
623
624 @staticmethod
625 def killSwitch( main, switch, switches, links ):
626 """
627 Params: switches, links: number of expected switches and links after SwitchDown, ex.: '4', '6'
628 Completely kill a switch and verify ONOS can see the proper change
629 """
630 main.switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
You Wangc02d8352018-04-17 16:42:10 -0700631 switch = switch if isinstance( switch, list ) else [ switch ]
632 main.step( "Kill " + str( switch ) )
633 for s in switch:
634 main.log.info( "Stopping " + s )
635 main.Network.switch( SW=s, OPTION="stop" )
Jon Hall1efcb3f2016-08-23 13:42:15 -0700636 # todo make this repeatable
637 main.log.info( "Waiting %s seconds for switch down to be discovered" % (
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700638 main.switchSleep ) )
Jon Hall1efcb3f2016-08-23 13:42:15 -0700639 time.sleep( main.switchSleep )
Devin Lim142b5342017-07-20 15:22:39 -0700640 topology = utilities.retry( main.Cluster.active( 0 ).CLI.checkStatus,
Jon Hall1efcb3f2016-08-23 13:42:15 -0700641 main.FALSE,
642 kwargs={ 'numoswitch': switches,
643 'numolink': links },
644 attempts=10,
645 sleep=main.switchSleep )
646 utilities.assert_equals( expect=main.TRUE, actual=topology,
647 onpass="Kill switch successful",
648 onfail="Failed to kill switch?" )
649
650 @staticmethod
651 def recoverSwitch( main, switch, switches, links ):
652 """
653 Params: switches, links: number of expected switches and links after SwitchUp, ex.: '4', '6'
654 Recover a switch and verify ONOS can see the proper change
655 """
656 # todo make this repeatable
You Wangc02d8352018-04-17 16:42:10 -0700657 switch = switch if isinstance( switch, list ) else [ switch ]
658 main.step( "Recovering " + str( switch ) )
659 for s in switch:
660 main.log.info( "Starting " + s )
661 main.Network.switch( SW=s, OPTION="start" )
Jon Hall1efcb3f2016-08-23 13:42:15 -0700662 main.log.info( "Waiting %s seconds for switch up to be discovered" % (
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700663 main.switchSleep ) )
Jon Hall1efcb3f2016-08-23 13:42:15 -0700664 time.sleep( main.switchSleep )
Devin Lim142b5342017-07-20 15:22:39 -0700665 topology = utilities.retry( main.Cluster.active( 0 ).CLI.checkStatus,
Jon Hall1efcb3f2016-08-23 13:42:15 -0700666 main.FALSE,
667 kwargs={ 'numoswitch': switches,
668 'numolink': links },
669 attempts=10,
670 sleep=main.switchSleep )
671 utilities.assert_equals( expect=main.TRUE, actual=topology,
672 onpass="Switch recovery successful",
673 onfail="Failed to recover switch?" )
674
You Wangc02d8352018-04-17 16:42:10 -0700675 def portstate( main, dpid, port, state, switches, links ):
676 """
677 Disable/enable a switch port using 'portstate' and verify ONOS can see the proper link change
678 Params:
679 dpid: dpid of the switch, ex.: 'of:0000000000000002'
680 port: port of the switch to disable/enable, ex.:'1'
681 state: disable or enable
682 switches, links: number of expected switches and links after link change, ex.: '4', '6'
683 """
684 main.step( "Port %s on %s:%s" % ( state, dpid, port ) )
685 main.Cluster.active( 0 ).CLI.portstate( dpid=dpid, port=port, state=state )
686 main.log.info( "Waiting %s seconds for port %s to be discovered" % ( main.linkSleep, state ) )
687 time.sleep( main.linkSleep )
688 result = main.Cluster.active( 0 ).CLI.checkStatus( numoswitch=switches,
689 numolink=links )
690 utilities.assert_equals( expect=main.TRUE, actual=result,
691 onpass="Port %s successful" % state,
692 onfail="Port %s failed" % state )
693
Jon Hall1efcb3f2016-08-23 13:42:15 -0700694 @staticmethod
You Wang5da39c82018-04-26 22:55:08 -0700695 def cleanup( main, copyKarafLog=True, removeHostComponent=False ):
Jon Hall1efcb3f2016-08-23 13:42:15 -0700696 """
697 Stop Onos-cluster.
698 Stops Mininet
699 Copies ONOS log
700 """
Devin Lim58046fa2017-07-05 16:55:00 -0700701 try:
702 from tests.dependencies.utils import Utils
703 except ImportError:
704 main.log.error( "Utils not found exiting the test" )
Devin Lim44075962017-08-11 10:56:37 -0700705 main.cleanAndExit()
Devin Lim58046fa2017-07-05 16:55:00 -0700706 try:
Devin Lim142b5342017-07-20 15:22:39 -0700707 main.utils
Devin Lim58046fa2017-07-05 16:55:00 -0700708 except ( NameError, AttributeError ):
Devin Lim142b5342017-07-20 15:22:39 -0700709 main.utils = Utils()
Devin Lim58046fa2017-07-05 16:55:00 -0700710
You Wange24d6272018-03-27 21:18:50 -0700711 if hasattr( main, "scapyHosts" ):
712 scapyResult = main.TRUE
713 for host in main.scapyHosts:
714 scapyResult = host.stopScapy() and scapyResult
715 main.log.info( "Stopped Scapy Host: {0}".format( host.name ) )
716 for host in main.scapyHosts:
717 scapyResult = main.Scapy.removeHostComponent( host.name ) and scapyResult
718 main.log.info( "Removed Scapy Host Component: {0}".format( host.name ) )
719 main.scapyHosts = []
720
You Wang5da39c82018-04-26 22:55:08 -0700721 if removeHostComponent:
722 for host in main.internalIpv4Hosts + main.internalIpv6Hosts + main.externalIpv4Hosts + main.externalIpv6Hosts:
723 if hasattr( main, host ):
724 main.Network.removeHostComponent( host )
725
You Wang5df1c6d2018-04-06 18:02:02 -0700726 if hasattr( main, 'Mininet1' ):
Pier6a0c4de2018-03-18 16:01:30 -0700727 main.utils.mininetCleanup( main.Mininet1 )
Devin Lim58046fa2017-07-05 16:55:00 -0700728
You Wang5df1c6d2018-04-06 18:02:02 -0700729 if copyKarafLog:
730 main.utils.copyKarafLog( "CASE%d" % main.CurrentTestCaseNumber, before=True, includeCaseDesc=False )
Devin Lim58046fa2017-07-05 16:55:00 -0700731
Devin Lim142b5342017-07-20 15:22:39 -0700732 for ctrl in main.Cluster.active():
733 main.ONOSbench.onosStop( ctrl.ipAddress )
Jon Hall1efcb3f2016-08-23 13:42:15 -0700734
735 @staticmethod
736 def killOnos( main, nodes, switches, links, expNodes ):
737 """
738 Params: nodes, integer array with position of the ONOS nodes in the CLIs array
739 switches, links, nodes: number of expected switches, links and nodes after KillOnos, ex.: '4', '6'
740 Completely Kill an ONOS instance and verify the ONOS cluster can see the proper change
741 """
Jon Hall3c910162018-03-07 14:42:16 -0800742 main.step( "Killing ONOS instances with index(es): {}".format( nodes ) )
You Wang5df1c6d2018-04-06 18:02:02 -0700743 main.onosSleep = float( main.params[ 'timers' ][ 'OnosDiscovery' ] )
Pier3b58c652016-09-26 12:03:31 -0700744
Jon Hall1efcb3f2016-08-23 13:42:15 -0700745 for i in nodes:
Devin Lim142b5342017-07-20 15:22:39 -0700746 killResult = main.ONOSbench.onosDie( main.Cluster.runningNodes[ i ].ipAddress )
Jon Hall1efcb3f2016-08-23 13:42:15 -0700747 utilities.assert_equals( expect=main.TRUE, actual=killResult,
748 onpass="ONOS instance Killed",
749 onfail="Error killing ONOS instance" )
Devin Lim142b5342017-07-20 15:22:39 -0700750 main.Cluster.runningNodes[ i ].active = False
You Wang5df1c6d2018-04-06 18:02:02 -0700751 time.sleep( main.onosSleep )
Pier3b58c652016-09-26 12:03:31 -0700752
Devin Lim142b5342017-07-20 15:22:39 -0700753 if len( nodes ) < main.Cluster.numCtrls:
Pier3b58c652016-09-26 12:03:31 -0700754
Jonghwan Hyun3731d6a2017-10-19 11:59:31 -0700755 nodeResults = utilities.retry( main.Cluster.nodesCheck,
Pier3b58c652016-09-26 12:03:31 -0700756 False,
Pier3b58c652016-09-26 12:03:31 -0700757 attempts=5,
758 sleep=10 )
759 utilities.assert_equals( expect=True, actual=nodeResults,
760 onpass="Nodes check successful",
761 onfail="Nodes check NOT successful" )
762
763 if not nodeResults:
764 for i in nodes:
Devin Lim142b5342017-07-20 15:22:39 -0700765 ctrl = main.Cluster.runningNodes[ i ]
Pier3b58c652016-09-26 12:03:31 -0700766 main.log.debug( "{} components not ACTIVE: \n{}".format(
Devin Lim142b5342017-07-20 15:22:39 -0700767 ctrl.name,
768 ctrl.CLI.sendline( "scr:list | grep -v ACTIVE" ) ) )
Pier3b58c652016-09-26 12:03:31 -0700769 main.log.error( "Failed to kill ONOS, stopping test" )
Devin Lim44075962017-08-11 10:56:37 -0700770 main.cleanAndExit()
Pier3b58c652016-09-26 12:03:31 -0700771
Jonghwan Hyun76a02b72018-01-30 16:40:48 +0900772 topology = utilities.retry( main.Cluster.active( 0 ).CLI.checkStatus,
Jon Hall1efcb3f2016-08-23 13:42:15 -0700773 main.FALSE,
774 kwargs={ 'numoswitch': switches,
775 'numolink': links,
776 'numoctrl': expNodes },
777 attempts=10,
778 sleep=12 )
779 utilities.assert_equals( expect=main.TRUE, actual=topology,
780 onpass="ONOS Instance down successful",
781 onfail="Failed to turn off ONOS Instance" )
Jon Hall1efcb3f2016-08-23 13:42:15 -0700782
783 @staticmethod
784 def recoverOnos( main, nodes, switches, links, expNodes ):
785 """
786 Params: nodes, integer array with position of the ONOS nodes in the CLIs array
787 switches, links, nodes: number of expected switches, links and nodes after recoverOnos, ex.: '4', '6'
788 Recover an ONOS instance and verify the ONOS cluster can see the proper change
789 """
Jon Hall3c910162018-03-07 14:42:16 -0800790 main.step( "Recovering ONOS instances with index(es): {}".format( nodes ) )
Devin Lim142b5342017-07-20 15:22:39 -0700791 [ main.ONOSbench.onosStart( main.Cluster.runningNodes[ i ].ipAddress ) for i in nodes ]
You Wang5df1c6d2018-04-06 18:02:02 -0700792 time.sleep( main.onosSleep )
Jon Hall1efcb3f2016-08-23 13:42:15 -0700793 for i in nodes:
Devin Lim142b5342017-07-20 15:22:39 -0700794 isUp = main.ONOSbench.isup( main.Cluster.runningNodes[ i ].ipAddress )
Jon Hall1efcb3f2016-08-23 13:42:15 -0700795 utilities.assert_equals( expect=main.TRUE, actual=isUp,
796 onpass="ONOS service is ready",
797 onfail="ONOS service did not start properly" )
798 for i in nodes:
799 main.step( "Checking if ONOS CLI is ready" )
Devin Lim142b5342017-07-20 15:22:39 -0700800 ctrl = main.Cluster.runningNodes[ i ]
Jonghwan Hyun76a02b72018-01-30 16:40:48 +0900801 # ctrl.CLI.startCellCli()
Devin Lim142b5342017-07-20 15:22:39 -0700802 cliResult = ctrl.CLI.startOnosCli( ctrl.ipAddress,
803 commandlineTimeout=60,
804 onosStartTimeout=100 )
805 ctrl.active = True
Jon Hall1efcb3f2016-08-23 13:42:15 -0700806 utilities.assert_equals( expect=main.TRUE,
807 actual=cliResult,
808 onpass="ONOS CLI is ready",
809 onfail="ONOS CLI is not ready" )
Jon Hall1efcb3f2016-08-23 13:42:15 -0700810
Pier3b58c652016-09-26 12:03:31 -0700811 main.step( "Checking ONOS nodes" )
Jonghwan Hyun3731d6a2017-10-19 11:59:31 -0700812 nodeResults = utilities.retry( main.Cluster.nodesCheck,
Pier3b58c652016-09-26 12:03:31 -0700813 False,
Pier3b58c652016-09-26 12:03:31 -0700814 attempts=5,
815 sleep=10 )
816 utilities.assert_equals( expect=True, actual=nodeResults,
817 onpass="Nodes check successful",
818 onfail="Nodes check NOT successful" )
819
820 if not nodeResults:
821 for i in nodes:
Devin Lim142b5342017-07-20 15:22:39 -0700822 ctrl = main.Cluster.runningNodes[ i ]
Pier3b58c652016-09-26 12:03:31 -0700823 main.log.debug( "{} components not ACTIVE: \n{}".format(
Devin Lim142b5342017-07-20 15:22:39 -0700824 ctrl.name,
825 ctrl.CLI.sendline( "scr:list | grep -v ACTIVE" ) ) )
Pier3b58c652016-09-26 12:03:31 -0700826 main.log.error( "Failed to start ONOS, stopping test" )
Devin Lim44075962017-08-11 10:56:37 -0700827 main.cleanAndExit()
Pier3b58c652016-09-26 12:03:31 -0700828
Devin Lim142b5342017-07-20 15:22:39 -0700829 topology = utilities.retry( main.Cluster.active( 0 ).CLI.checkStatus,
Jon Hall1efcb3f2016-08-23 13:42:15 -0700830 main.FALSE,
831 kwargs={ 'numoswitch': switches,
832 'numolink': links,
833 'numoctrl': expNodes },
834 attempts=10,
835 sleep=12 )
836 utilities.assert_equals( expect=main.TRUE, actual=topology,
837 onpass="ONOS Instance down successful",
838 onfail="Failed to turn off ONOS Instance" )
Devin Lim142b5342017-07-20 15:22:39 -0700839 ready = utilities.retry( main.Cluster.active( 0 ).CLI.summary,
840 main.FALSE,
841 attempts=10,
842 sleep=12 )
843 if ready:
844 ready = main.TRUE
845 utilities.assert_equals( expect=main.TRUE, actual=ready,
Jon Hall1efcb3f2016-08-23 13:42:15 -0700846 onpass="ONOS summary command succeded",
847 onfail="ONOS summary command failed" )
848 if not ready:
849 main.log.error( "ONOS startup failed!" )
Devin Lim44075962017-08-11 10:56:37 -0700850 main.cleanAndExit()
Jon Hall1efcb3f2016-08-23 13:42:15 -0700851
852 @staticmethod
853 def addHostCfg( main ):
854 """
855 Adds Host Configuration to ONOS
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700856 Updates expected state of the network ( pingChart )
Jon Hall1efcb3f2016-08-23 13:42:15 -0700857 """
858 import json
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700859 hostCfg = {}
Devin Lim57221b02018-02-14 15:45:36 -0800860 with open( main.configPath + main.forJson + "extra.json" ) as template:
Jon Hall1efcb3f2016-08-23 13:42:15 -0700861 hostCfg = json.load( template )
862 main.pingChart[ 'ip' ][ 'hosts' ] += [ 'in1' ]
863 main.step( "Pushing new configuration" )
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700864 mac, cfg = hostCfg[ 'hosts' ].popitem()
Devin Lim142b5342017-07-20 15:22:39 -0700865 main.Cluster.active( 0 ).REST.setNetCfg( cfg[ 'basic' ],
866 subjectClass="hosts",
867 subjectKey=urllib.quote( mac,
868 safe='' ),
869 configKey="basic" )
Jon Hall1efcb3f2016-08-23 13:42:15 -0700870 main.pingChart[ 'ip' ][ 'hosts' ] += [ 'out1' ]
871 main.step( "Pushing new configuration" )
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700872 mac, cfg = hostCfg[ 'hosts' ].popitem()
Devin Lim142b5342017-07-20 15:22:39 -0700873 main.Cluster.active( 0 ).REST.setNetCfg( cfg[ 'basic' ],
874 subjectClass="hosts",
875 subjectKey=urllib.quote( mac,
876 safe='' ),
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700877 configKey="basic" )
Jon Hall1efcb3f2016-08-23 13:42:15 -0700878 main.pingChart.update( { 'vlan1': { "expect": "True",
879 "hosts": [ "olt1", "vsg1" ] } } )
880 main.pingChart[ 'vlan5' ][ 'expect' ] = 0
881 main.pingChart[ 'vlan10' ][ 'expect' ] = 0
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700882 ports = "[%s,%s]" % ( 5, 6 )
Jon Hall1efcb3f2016-08-23 13:42:15 -0700883 cfg = '{"of:0000000000000001":[{"vlan":1,"ports":%s,"name":"OLT 1"}]}' % ports
Devin Lim142b5342017-07-20 15:22:39 -0700884 main.Cluster.active( 0 ).REST.setNetCfg( json.loads( cfg ),
885 subjectClass="apps",
886 subjectKey="org.onosproject.segmentrouting",
887 configKey="xconnect" )
Jon Hall1efcb3f2016-08-23 13:42:15 -0700888
889 @staticmethod
890 def delHostCfg( main ):
891 """
892 Removest Host Configuration from ONOS
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700893 Updates expected state of the network ( pingChart )
Jon Hall1efcb3f2016-08-23 13:42:15 -0700894 """
895 import json
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700896 hostCfg = {}
Devin Lim57221b02018-02-14 15:45:36 -0800897 with open( main.configPath + main.forJson + "extra.json" ) as template:
Jon Hall1efcb3f2016-08-23 13:42:15 -0700898 hostCfg = json.load( template )
899 main.step( "Removing host configuration" )
900 main.pingChart[ 'ip' ][ 'expect' ] = 0
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700901 mac, cfg = hostCfg[ 'hosts' ].popitem()
Devin Lim142b5342017-07-20 15:22:39 -0700902 main.Cluster.active( 0 ).REST.removeNetCfg( subjectClass="hosts",
903 subjectKey=urllib.quote(
904 mac,
905 safe='' ),
906 configKey="basic" )
Jon Hall1efcb3f2016-08-23 13:42:15 -0700907 main.step( "Removing configuration" )
908 main.pingChart[ 'ip' ][ 'expect' ] = 0
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700909 mac, cfg = hostCfg[ 'hosts' ].popitem()
Devin Lim142b5342017-07-20 15:22:39 -0700910 main.Cluster.active( 0 ).REST.removeNetCfg( subjectClass="hosts",
911 subjectKey=urllib.quote(
912 mac,
913 safe='' ),
914 configKey="basic" )
Jon Hall1efcb3f2016-08-23 13:42:15 -0700915 main.step( "Removing vlan configuration" )
916 main.pingChart[ 'vlan1' ][ 'expect' ] = 0
Devin Lim142b5342017-07-20 15:22:39 -0700917 main.Cluster.active( 0 ).REST.removeNetCfg( subjectClass="apps",
918 subjectKey="org.onosproject.segmentrouting",
919 configKey="xconnect" )
You Wang53dba1e2018-02-02 17:45:44 -0800920
921 @staticmethod
922 def verifyNetworkHostIp( main, attempts=10, sleep=10 ):
923 """
924 Verifies IP address assignment from the hosts
925 """
926 main.step( "Verify IP address assignment from hosts" )
927 ipResult = main.TRUE
You Wangd66de192018-04-30 17:30:12 -0700928 main.Network.update()
You Wang53dba1e2018-02-02 17:45:44 -0800929 for hostName, ip in main.expectedHosts[ "network" ].items():
930 ipResult = ipResult and utilities.retry( main.Network.verifyHostIp,
931 main.FALSE,
932 kwargs={ 'hostList': [ hostName ],
You Wangd66de192018-04-30 17:30:12 -0700933 'prefix': ip,
934 'update': False },
You Wang53dba1e2018-02-02 17:45:44 -0800935 attempts=attempts,
936 sleep=sleep )
937 utilities.assert_equals( expect=main.TRUE, actual=ipResult,
938 onpass="Verify network host IP succeded",
939 onfail="Verify network host IP failed" )
940
941 @staticmethod
942 def verifyOnosHostIp( main, attempts=10, sleep=10 ):
943 """
944 Verifies host IP address assignment from ONOS
945 """
946 main.step( "Verify host IP address assignment in ONOS" )
947 ipResult = main.TRUE
948 for hostName, ip in main.expectedHosts[ "onos" ].items():
949 ipResult = ipResult and utilities.retry( main.Cluster.active( 0 ).verifyHostIp,
950 main.FALSE,
951 kwargs={ 'hostList': [ hostName ],
952 'prefix': ip },
953 attempts=attempts,
954 sleep=sleep )
955 utilities.assert_equals( expect=main.TRUE, actual=ipResult,
956 onpass="Verify ONOS host IP succeded",
957 onfail="Verify ONOS host IP failed" )
Andreas Pantelopoulos2eae3242018-03-06 13:47:20 -0800958
Jonghwan Hyun812c70f2018-02-16 16:33:16 -0800959 @staticmethod
960 def updateIntfCfg( main, connectPoint, ips=[], untagged=0, tagged=[], native=0 ):
961 """
962 Description:
963 Updates interface configuration in ONOS, with given IP and vlan parameters
964 Required:
965 * connectPoint: connect point to update configuration
966 Optional:
967 * ips: list of IP addresses, combined with '/xx' subnet representation,
968 corresponding to 'ips' field in the configuration
969 * untagged: vlan ID as an integer, corresponding to 'vlan-untagged' field in the configuration
970 * tagged: integer list of vlan IDs, corresponding to 'vlan-tagged' field in the configuration
971 * native: vlan ID as an integer, corresponding to 'vlan-native' field in the configuration
972 """
973 cfg = dict()
974 cfg[ "ports" ] = dict()
975 cfg[ "ports" ][ connectPoint ] = dict()
976 cfg[ "ports" ][ connectPoint ][ "interfaces" ] = [ dict() ]
977 cfg[ "ports" ][ connectPoint ][ "interfaces" ][ 0 ][ "ips" ] = ips
978 if untagged > 0:
979 cfg[ "ports" ][ connectPoint ][ "interfaces" ][ 0 ][ "vlan-untagged" ] = untagged
980 else:
981 cfg[ "ports" ][ connectPoint ][ "interfaces" ][ 0 ][ "vlan-tagged" ] = tagged
982 if native > 0:
983 cfg[ "ports" ][ connectPoint ][ "interfaces" ][ 0 ][ "vlan-native" ] = native
984
985 main.Cluster.active( 0 ).REST.setNetCfg( json.loads( json.dumps( cfg ) ) )
You Wange24d6272018-03-27 21:18:50 -0700986
987 @staticmethod
988 def startScapyHosts( main ):
989 """
990 Create host components and start Scapy CLIs
991 """
992 main.step( "Start Scapy CLIs" )
993 main.scapyHostNames = main.params[ 'SCAPY' ][ 'HOSTNAMES' ].split( ',' )
994 main.scapyHosts = []
995 for hostName in main.scapyHostNames:
996 main.Scapy.createHostComponent( hostName )
997 main.scapyHosts.append( getattr( main, hostName ) )
998 for host in main.scapyHosts:
999 host.startHostCli()
1000 host.startScapy()
1001 host.updateSelf()
1002 main.log.debug( host.name )
1003 main.log.debug( host.hostIp )
1004 main.log.debug( host.hostMac )
1005
1006 @staticmethod
You Wangc02d8352018-04-17 16:42:10 -07001007 def verifyMulticastTraffic( main, routeName, expect, skipOnFail=True, maxRetry=3 ):
You Wange24d6272018-03-27 21:18:50 -07001008 """
1009 Verify multicast traffic using scapy
1010 """
You Wangc02d8352018-04-17 16:42:10 -07001011 routeData = main.multicastConfig[ routeName ]
1012 srcs = main.mcastRoutes[ routeName ][ "src" ]
1013 dsts = main.mcastRoutes[ routeName ][ "dst" ]
1014 main.log.info( "Sending multicast traffic from {} to {}".format( [ routeData[ "src" ][ i ][ "host" ] for i in srcs ],
1015 [ routeData[ "dst" ][ i ][ "host" ] for i in dsts ] ) )
1016 for src in srcs:
1017 srcEntry = routeData[ "src" ][ src ]
1018 for dst in dsts:
1019 dstEntry = routeData[ "dst" ][ dst ]
1020 sender = getattr( main, srcEntry[ "host" ] )
1021 receiver = getattr( main, dstEntry[ "host" ] )
1022 main.Network.addRoute( str( srcEntry[ "host" ] ),
1023 str( routeData[ "group" ] ),
1024 str( srcEntry[ "interface" ] ),
1025 True if routeData[ "ipVersion" ] == 6 else False )
1026 # Build the packet
1027 sender.buildEther( dst=str( srcEntry[ "Ether" ] ) )
1028 if routeData[ "ipVersion" ] == 4:
1029 sender.buildIP( dst=str( routeData[ "group" ] ) )
1030 elif routeData[ "ipVersion" ] == 6:
1031 sender.buildIPv6( dst=str( routeData[ "group" ] ) )
1032 sender.buildUDP( ipVersion=routeData[ "ipVersion" ], dport=srcEntry[ "UDP" ] )
1033 sIface = srcEntry[ "interface" ]
1034 dIface = dstEntry[ "interface" ] if "interface" in dstEntry.keys() else None
1035 pktFilter = srcEntry[ "filter" ]
1036 pkt = srcEntry[ "packet" ]
1037 # Send packet and check received packet
1038 expectedResult = expect.pop( 0 ) if isinstance( expect, list ) else expect
1039 trafficResult = utilities.retry( Testcaselib.sendMulticastTraffic,
1040 main.FALSE,
1041 args=( main, sender, receiver, pktFilter, pkt,
1042 sIface, dIface, expectedResult ),
1043 attempts=maxRetry,
1044 sleep=1 )
1045 utilities.assert_equals( expect=main.TRUE,
1046 actual=trafficResult,
1047 onpass="{} to {}: Pass".format( srcEntry[ "host" ], dstEntry[ "host" ] ),
1048 onfail="{} to {}: Fail".format( srcEntry[ "host" ], dstEntry[ "host" ] ) )
1049 if skipOnFail and trafficResult != main.TRUE:
1050 Testcaselib.saveOnosDiagnostics( main )
1051 Testcaselib.cleanup( main, copyKarafLog=False )
1052 main.skipCase()
1053
1054 @staticmethod
1055 def sendMulticastTraffic( main, sender, receiver, pktFilter, pkt, sIface=None, dIface=None, expect=True ):
1056 """
1057 Send multicast traffic using scapy
1058 """
1059 receiver.startFilter( ifaceName=dIface, pktFilter=pktFilter )
1060 sender.sendPacket( iface=sIface )
1061 finished = receiver.checkFilter()
1062 packet = ""
1063 if finished:
1064 packets = receiver.readPackets()
1065 for packet in packets.splitlines():
1066 main.log.debug( packet )
1067 else:
1068 kill = receiver.killFilter()
1069 main.log.debug( kill )
1070 sender.handle.sendline( "" )
1071 sender.handle.expect( sender.scapyPrompt )
1072 main.log.debug( sender.handle.before )
1073 packetCaptured = True if pkt in packet else False
1074 return main.TRUE if packetCaptured == expect else main.FALSE
You Wang5da39c82018-04-26 22:55:08 -07001075
1076 @staticmethod
1077 def verifyPing( main, srcList, dstList, ipv6=False, expect=True, wait=1, acceptableFailed=0, skipOnFail=True ):
1078 """
1079 Verify reachability from each host in srcList to each host in dstList
1080 """
1081 from tests.dependencies.topology import Topology
1082 try:
1083 main.topo
1084 except ( NameError, AttributeError ):
1085 main.topo = Topology()
1086 pingResult = main.topo.ping( srcList, dstList, ipv6, expect, wait, acceptableFailed, skipOnFail )
1087 if not pingResult and skipOnFail:
1088 Testcaselib.saveOnosDiagnostics( main )
1089 Testcaselib.cleanup( main, copyKarafLog=False, removeHostComponent=True )
1090 main.skipCase()