blob: ae3072399b6b8e04f89d5de61e4bd06635aa46b4 [file] [log] [blame]
kelvin-onlab1d381fe2015-07-14 16:24:56 -07001"""
Jeremy Ronquillob27ce4c2017-07-17 12:41:28 -07002Copyright 2015 Open Networking Foundation (ONF)
3
4Please refer questions to either the onos test mailing list at <onos-test@onosproject.org>,
5the System Testing Plans and Results wiki page at <https://wiki.onosproject.org/x/voMg>,
6or the System Testing Guide page at <https://wiki.onosproject.org/x/WYQg>
7
8 TestON is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 2 of the License, or
11 (at your option) any later version.
12
13 TestON is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with TestON. If not, see <http://www.gnu.org/licenses/>.
20"""
21
22"""
kelvin-onlab1d381fe2015-07-14 16:24:56 -070023 Wrapper function for FuncTopo
24 Includes onosclidriver and mininetclidriver functions
25"""
26import time
27import json
28import re
29
30def __init__( self ):
31 self.default = ''
32
Chiyu Chengb8c2c842016-10-05 12:40:49 -070033def getTimestampFromString( main, targetString ):
34 #Get time string from the target string
35 try:
36 assert type( targetString ) is str
37 timeString = targetString.split( ' | ' )
38 timeString = timeString[ 0 ]
39 from datetime import datetime
40 # convert time string to timestamp
41 t = datetime.strptime( timeString, "%Y-%m-%d %H:%M:%S,%f" )
42 import time
43 timestamp = time.mktime( t.timetuple() )
44 timestamp += int( t.microsecond / 1000 ) / 1000.0
45 return timestamp
46 except AssertionError:
47 main.log.error( "Got nothing firom log" )
48 return -1
49 except IndexError:
50 main.log.error( "Time string index error" )
51 return -1
52 except ValueError:
53 main.log.error( "Got wrong string from log" )
54 return -1
55
Chiyu Cheng899621b2016-11-14 11:14:48 -080056def getRoleRequestTimeFromTshark( main ):
57 try:
58 main.log.info( "Get role request time" )
59 with open(main.tsharkResultPath, "r" ) as resultFile:
60 resultText = resultFile.readlines()
61 # select the last role request string
62 roleRequestString = resultText[ len( resultText ) - 1 ]
63 main.log.info( roleRequestString )
64 # get timestamp from role request string
65 roleRequestTime = roleRequestString.split( " " )
66 resultFile.close()
67 return float(roleRequestTime[1])
68 except IndexError:
69 main.log.error("Got wrong role request string from Tshark file")
70 return -1
71
72def compareTimeDiffWithRoleRequest(main, term, Mode, index=0 ):
73 '''
74 Description:
75 Compare the time difference between the time of target term and the time of role request
76 Inclides onosclidriver functions
77
78 '''
79 try:
Devin Lim142b5342017-07-20 15:22:39 -070080 termInfo = main.Cluster.active( index ).CLI.logSearch( mode=Mode, searchTerm=term )
Chiyu Cheng899621b2016-11-14 11:14:48 -080081 termTime = getTimestampFromString( main, termInfo[ 0 ] )
82 roleRequestTime = getRoleRequestTimeFromTshark( main )
83 if termTime == -1 or roleRequestTime == -1:
84 main.writeData = -1
85 main.log.error( "Can't compare the difference with role request time" )
86 return -1
Jon Hall465d56c2016-12-05 10:03:02 -080087 # Only concern about the absolute value of difference.
Chiyu Cheng899621b2016-11-14 11:14:48 -080088 return abs( roleRequestTime - termTime )
89 except IndexError:
90 main.log.error( "Catch the wrong information of search term " )
91 main.writeData = -1
92 return -1
93
Chiyu Chengb8c2c842016-10-05 12:40:49 -070094def getInfoFromLog( main, term1, mode1, term2, mode2, index=0, funcMode='TD' ):
95 '''
96 Description:
97 Get needed informations of the search term from karaf.log
98 Includes onosclidriver functions
99 Function mode:
100 TD (time difference):
101 Get time difference between start and end
102 Term1: startTerm
103 Term2: endTerm
104 DR (disconnect rate):
105 Get switch disconnect rate
106 Term1: disconnectTerm
107 Term2: connectTerm
108
109 '''
110 try:
Devin Lim142b5342017-07-20 15:22:39 -0700111 termInfo1 = main.Cluster.active( index ).CLI.logSearch( mode=mode1, searchTerm=term1 )
112 termInfo2 = main.Cluster.active( index ).CLI.logSearch( mode=mode2, searchTerm=term2 )
Chiyu Chengb8c2c842016-10-05 12:40:49 -0700113 if funcMode == 'TD':
114 startTime = getTimestampFromString( main, termInfo1[0] )
115 endTime = getTimestampFromString ( main, termInfo2[0] )
116 if startTime == -1 or endTime == -1:
117 main.log.error( "Wrong Time!" )
118 main.writeData = -1
119 return -1
120 return endTime - startTime
121 if funcMode == 'DR':
122 #In this mode, termInfo1 means the total number of switch disconnection and
123 #termInfo2 means the total number of new switch connection
124 #termInfo2 - termInfo1 means the actual real number of switch connection.
125 disconnection = int( termInfo1 ) * 1.0
126 expectConnection = int( main.currScale ) ** 2
127 realConnection = int( termInfo2 ) - int( termInfo1 )
128 if expectConnection != realConnection:
129 main.log.error( "The number of real switch connection doesn't match the number of expected connection" )
130 main.writeData = -1
131 return -1
132 rate = disconnection / expectConnection
133 return rate
134 except IndexError:
135 main.log.error( "Catch the wrong information of search term" )
136 main.writeData = -1
137 return -1
138
kelvin-onlabd9e23de2015-08-06 10:34:44 -0700139def testTopology( main, topoFile='', args='', mnCmd='', timeout=300, clean=True ):
kelvin-onlab1d381fe2015-07-14 16:24:56 -0700140 """
141 Description:
142 This function combines different wrapper functions in this module
143 to simulate a topology test
144 Test Steps:
145 - Load topology
146 - Discover topology
147 - Compare topology
148 - pingall
149 - Bring links down
150 - Compare topology
151 - pingall
152 - Bring links up
153 - Compare topology
154 - pingall
155 Options:
156 clean: Does sudo mn -c to clean mininet residue
157 Please read mininetclidriver.py >> startNet( .. ) function for details
158 Returns:
159 Returns main.TRUE if the test is successful, main.FALSE otherwise
160 """
161 testTopoResult = main.TRUE
162 compareTopoResult = main.TRUE
163 topoObjectResult = main.TRUE
164 stopResult = main.TRUE
165
166 if clean:
167 # Cleans minient
168 stopResult = stopMininet( main )
169
170 # Restart ONOS to clear hosts test new mininet topology
171 reinstallOnosResult = reinstallOnos( main )
172
173 # Starts topology
kelvin-onlabd9e23de2015-08-06 10:34:44 -0700174 startResult = startNewTopology( main, topoFile, args, mnCmd, timeout=timeout )
GlennRC1c5df3c2015-08-27 16:12:09 -0700175 # onos needs time to see the links
176 time.sleep(15)
kelvin-onlab1d381fe2015-07-14 16:24:56 -0700177
178 # Gets list of switches in mininet
kelvin-onlabd9e23de2015-08-06 10:34:44 -0700179 #assignSwitch( main )
kelvin-onlab1d381fe2015-07-14 16:24:56 -0700180
kelvin-onlabd9e23de2015-08-06 10:34:44 -0700181 testTopoResult = startResult and topoObjectResult
kelvin-onlab1d381fe2015-07-14 16:24:56 -0700182
183
184 return testTopoResult
185
kelvin-onlabd9e23de2015-08-06 10:34:44 -0700186def startNewTopology( main, topoFile='', args='', mnCmd='', timeout=900 ):
kelvin-onlab1d381fe2015-07-14 16:24:56 -0700187 """
188 Description:
189 This wrapper function starts new topology
190 Options:
191 Please read mininetclidriver.py >> startNet( .. ) function for details
192 Return:
193 Returns main.TRUE if topology is successfully created by mininet,
194 main.FALSE otherwise
195 NOTE:
196 Assumes Mininet1 is the name of the handler
197 """
198 assert main, "There is no main variable"
199 assert main.Mininet1, "Mininet 1 is not created"
200 result = main.TRUE
201
202 main.log.info( main.topoName + ": Starting new Mininet topology" )
203
204 # log which method is being used
205 if topoFile:
206 main.log.info( main.topoName + ": Starting topology with " +
207 topoFile + "topology file" )
208 elif not topoFile and not mnCmd:
209 main.log.info( main.topoName + ": Starting topology using" +
210 " the topo file" )
211 elif topoFile and mnCmd:
212 main.log.error( main.topoName + ": You can only use one " +
213 "method to start a topology" )
214 elif mnCmd:
215 main.log.info( main.topoName + ": Starting topology with '" +
216 mnCmd + "' Mininet command" )
217
218
219 result = main.Mininet1.startNet( topoFile=topoFile,
220 args=args,
kelvin-onlabd9e23de2015-08-06 10:34:44 -0700221 mnCmd=mnCmd,
222 timeout=timeout)
kelvin-onlab1d381fe2015-07-14 16:24:56 -0700223
224 return result
225
226def stopMininet( main ):
227 """
228 Stops current topology and execute mn -c basically triggers
229 stopNet in mininetclidrivers
230
231 NOTE: Mininet should be running when issuing this command other wise
232 the this function will cause the test to stop
233 """
234 stopResult = main.TRUE
235 stopResult = main.Mininet1.stopNet()
236 time.sleep( 30 )
237 if not stopResult:
238 main.log.info( main.topoName + ": Did not stop Mininet topology" )
239 return stopResult
240
241def compareTopo( main ):
242 """
243 Compare topology( devices, links, ports, hosts ) between ONOS and
244 mininet using sts
245 """
Devin Lim142b5342017-07-20 15:22:39 -0700246 try:
247 from tests.dependencies.topology import Topology
248 except ImportError:
249 main.log.error( "Topology not found exiting the test" )
Devin Lim44075962017-08-11 10:56:37 -0700250 main.cleanAndExit()
Devin Lim142b5342017-07-20 15:22:39 -0700251 try:
252 main.topoRelated
253 except ( NameError, AttributeError ):
254 main.topoRelated = Topology()
255 return main.topoRelated.compareTopos( main.Mininet1 )
kelvin-onlab1d381fe2015-07-14 16:24:56 -0700256
257def assignSwitch( main ):
258 """
259 Returns switch list using getSwitch in Mininet driver
260 """
261 switchList = []
262 assignResult = main.TRUE
263 switchList = main.Mininet1.getSwitch()
264 assignResult = main.Mininet1.assignSwController( sw=switchList,
Devin Lim142b5342017-07-20 15:22:39 -0700265 ip=main.Cluster.active( 0 ).ipAddress,
GlennRC632e2892015-10-19 18:58:41 -0700266 port=6633 )
kelvin-onlab1d381fe2015-07-14 16:24:56 -0700267
268 for sw in switchList:
269 response = main.Mininet1.getSwController( sw )
Devin Lim142b5342017-07-20 15:22:39 -0700270 if re.search( "tcp:" + main.Cluster.active( 0 ).ipAddress, response ):
kelvin-onlab1d381fe2015-07-14 16:24:56 -0700271 assignResult = assignResult and main.TRUE
272 else:
273 assignResult = main.FALSE
274
275 return switchList
276
kelvin-onlabd9e23de2015-08-06 10:34:44 -0700277def connectivity( main, timeout=900, shortCircuit=True, acceptableFailed=20 ):
278 """
279 Use fwd app and pingall to discover all the hosts
280 """
281 activateResult = main.TRUE
282 appCheck = main.TRUE
283 getDataResult = main.TRUE
284 main.log.info( main.topoName + ": Activating reactive forwarding app " )
Devin Lim142b5342017-07-20 15:22:39 -0700285 activateResult = main.Cluster.active( 0 ).activateApp( "org.onosproject.fwd" )
kelvin-onlabd9e23de2015-08-06 10:34:44 -0700286
287 if main.hostsData:
288 main.hostsData = {}
Devin Lim142b5342017-07-20 15:22:39 -0700289 for ctrl in main.Cluster.active():
290 appCheck = appCheck and ctrl.CLI.appToIDCheck()
kelvin-onlabd9e23de2015-08-06 10:34:44 -0700291 if appCheck != main.TRUE:
Devin Lim142b5342017-07-20 15:22:39 -0700292 main.log.warn( ctrl.CLI.apps() )
293 main.log.warn( ctrl.CLI.appIDs() )
kelvin-onlabd9e23de2015-08-06 10:34:44 -0700294
295 time.sleep( main.fwdSleep )
296
297 # Discover hosts using pingall
298 pingResult = main.Mininet1.pingall( timeout=timeout,
299 shortCircuit=shortCircuit,
300 acceptableFailed=acceptableFailed )
301
302 main.log.info( main.topoName + ": Deactivate reactive forwarding app " )
Devin Lim142b5342017-07-20 15:22:39 -0700303 activateResult = main.Cluster.active( 0 ).deactivateApp( "org.onosproject.fwd" )
304 for ctrl in main.Cluster.active():
305 appCheck = appCheck and ctrl.CLI.appToIDCheck()
kelvin-onlabd9e23de2015-08-06 10:34:44 -0700306 if appCheck != main.TRUE:
Devin Lim142b5342017-07-20 15:22:39 -0700307 main.log.warn( ctrl.CLI.apps() )
308 main.log.warn( ctrl.CLI.appIDs() )
kelvin-onlabd9e23de2015-08-06 10:34:44 -0700309
310 return pingResult
311
kelvin-onlab1d381fe2015-07-14 16:24:56 -0700312def getHostsData( main ):
313 """
314 Use fwd app and pingall to discover all the hosts
315 """
316 activateResult = main.TRUE
317 appCheck = main.TRUE
318 getDataResult = main.TRUE
319 main.log.info( main.topoName + ": Activating reactive forwarding app " )
Devin Lim142b5342017-07-20 15:22:39 -0700320 activateResult = main.Cluster.active( 0 ).CLI.activateApp( "org.onosproject.fwd" )
kelvin-onlab1d381fe2015-07-14 16:24:56 -0700321
322 if main.hostsData:
323 main.hostsData = {}
Devin Lim142b5342017-07-20 15:22:39 -0700324 for ctrl in main.Cluster.active():
325 appCheck = appCheck and ctrl.CLI.appToIDCheck()
kelvin-onlab1d381fe2015-07-14 16:24:56 -0700326 if appCheck != main.TRUE:
Devin Lim142b5342017-07-20 15:22:39 -0700327 main.log.warn( ctrl.CLI.apps() )
328 main.log.warn( ctrl.CLI.appIDs() )
kelvin-onlab1d381fe2015-07-14 16:24:56 -0700329
330 time.sleep( main.fwdSleep )
331 # Discover hosts using pingall
332 pingResult = main.Mininet1.pingall( timeout=900 )
333
Devin Lim142b5342017-07-20 15:22:39 -0700334 hostsJson = json.loads( main.Cluster.active( 0 ).CLI.hosts() )
kelvin-onlab1d381fe2015-07-14 16:24:56 -0700335 hosts = main.Mininet1.getHosts().keys()
336
337 for host in hosts:
338 main.hostsData[ host ] = {}
339 main.hostsData[ host ][ 'mac' ] = \
340 main.Mininet1.getMacAddress( host ).upper()
341 for hostj in hostsJson:
342 if main.hostsData[ host ][ 'mac' ] == hostj[ 'mac' ]:
343 main.hostsData[ host ][ 'id' ] = hostj[ 'id' ]
344 main.hostsData[ host ][ 'vlan' ] = hostj[ 'vlan' ]
345 main.hostsData[ host ][ 'location' ] = \
Jeremy Ronquillo0e538bc2017-06-13 15:16:09 -0700346 hostj[ 'locations' ][ 0 ][ 'elementId' ] + '/' + \
347 hostj[ 'locations' ][ 0 ][ 'port' ]
kelvin-onlab1d381fe2015-07-14 16:24:56 -0700348 main.hostsData[ host ][ 'ipAddresses' ] = hostj[ 'ipAddresses' ]
349
350 if activateResult and main.hostsData:
351 main.log.info( main.topoName + ": Successfully used fwd app" +
352 " to discover hosts " )
353 getDataResult = main.TRUE
354 else:
355 main.log.info( main.topoName + ": Failed to use fwd app" +
356 " to discover hosts " )
357 getDataResult = main.FALSE
358
359 main.log.info( main.topoName + ": Deactivate reactive forwarding app " )
Devin Lim142b5342017-07-20 15:22:39 -0700360 activateResult = main.Cluster.active( 0 ).CLI.deactivateApp( "org.onosproject.fwd" )
361 for ctrl in main.Cluster.active():
362 appCheck = appCheck and ctrl.CLI.appToIDCheck()
kelvin-onlab1d381fe2015-07-14 16:24:56 -0700363 if appCheck != main.TRUE:
Devin Lim142b5342017-07-20 15:22:39 -0700364 main.log.warn( ctrl.CLI.apps() )
365 main.log.warn( ctrl.CLI.appIDs() )
kelvin-onlab1d381fe2015-07-14 16:24:56 -0700366
367 # This data can be use later for intents
368 print main.hostsData
369
370 return getDataResult
371
372def reinstallOnos( main ):
373 """
374 Description:
375 Stop and start ONOS that clears hosts,devices etc. in order to test
376 new mininet topology
377 Return:
378 Retruns main.TRUE for a successful restart, main.FALSE otherwise.
379 """
kelvin-onlab1d381fe2015-07-14 16:24:56 -0700380 stopResult = []
381 startResult = []
382 onosIsUpResult = []
383 restartResult = main.TRUE
384
Devin Lim142b5342017-07-20 15:22:39 -0700385 uninstallResult = main.testSetUp.uninstallOnos( main.Cluster, False )
386 if uninstallResult != main.TRUE:
kelvin-onlab1d381fe2015-07-14 16:24:56 -0700387 restartResult = main.FALSE
Devin Lim142b5342017-07-20 15:22:39 -0700388 installResult = main.testSetUp.installOnos( main.Cluster, False )
389 if installResult != main.TRUE:
You Wangf5de25b2017-01-06 15:13:01 -0800390 restartResult = main.FALSE
391
Devin Lim142b5342017-07-20 15:22:39 -0700392 secureSshResult = main.testSetUp.setupSsh( main.Cluster )
393 if secureSshResult != main.TRUE:
394 restartResult = main.FALSE
395
396 for ctrl in main.Cluster.runningNodes:
397 onosIsUpResult.append( main.ONOSbench.isup( ctrl.ipAddress ) )
kelvin-onlab1d381fe2015-07-14 16:24:56 -0700398
399 if all( result == main.TRUE for result in onosIsUpResult ):
400 main.log.report( "ONOS instance is up and ready" )
401 else:
402 main.log.report( "ONOS instance may not be up, stop and " +
403 "start ONOS again " )
Devin Lim142b5342017-07-20 15:22:39 -0700404 for ctrl in main.Cluster.runningNodes:
405 stopResult.append( main.ONOSbench.onosStop( ctrl.ipAddress ) )
kelvin-onlab1d381fe2015-07-14 16:24:56 -0700406
407 if all( result == main.TRUE for result in stopResult ):
408 main.log.info( main.topoName + ": Successfully stop ONOS cluster" )
409 else:
410 main.log.error( main.topoName + ": Failed to stop ONOS cluster" )
411
Devin Lim142b5342017-07-20 15:22:39 -0700412 for ctrl in main.Cluster.runningNodes:
413 startResult.append( main.ONOSbench.onosStart( ctrl.ipAddress ) )
kelvin-onlab1d381fe2015-07-14 16:24:56 -0700414
415 if all( result == main.TRUE for result in startResult ):
416 main.log.info( main.topoName + ": Successfully start ONOS cluster" )
417 else:
418 main.log.error( main.topoName + ": Failed to start ONOS cluster" )
419
kelvin-onlab1d381fe2015-07-14 16:24:56 -0700420 main.log.info( main.topoName + ": Starting ONOS CLI" )
Devin Lim142b5342017-07-20 15:22:39 -0700421 cliResult = main.testSetUp.startOnosClis( main.Cluster )
422 if cliResult != main.TRUE:
kelvin-onlab1d381fe2015-07-14 16:24:56 -0700423 restartResult = main.FALSE
424
425
426 return restartResult
427
428
429