blob: d05e2a7ded87a2a621e8197044e54d7acc69a05b [file] [log] [blame]
kelvin-onlab1d381fe2015-07-14 16:24:56 -07001"""
2 Wrapper function for FuncTopo
3 Includes onosclidriver and mininetclidriver functions
4"""
5import time
6import json
7import re
8
9def __init__( self ):
10 self.default = ''
11
Chiyu Chengb8c2c842016-10-05 12:40:49 -070012def getTimestampFromString( main, targetString ):
13 #Get time string from the target string
14 try:
15 assert type( targetString ) is str
16 timeString = targetString.split( ' | ' )
17 timeString = timeString[ 0 ]
18 from datetime import datetime
19 # convert time string to timestamp
20 t = datetime.strptime( timeString, "%Y-%m-%d %H:%M:%S,%f" )
21 import time
22 timestamp = time.mktime( t.timetuple() )
23 timestamp += int( t.microsecond / 1000 ) / 1000.0
24 return timestamp
25 except AssertionError:
26 main.log.error( "Got nothing firom log" )
27 return -1
28 except IndexError:
29 main.log.error( "Time string index error" )
30 return -1
31 except ValueError:
32 main.log.error( "Got wrong string from log" )
33 return -1
34
35def getInfoFromLog( main, term1, mode1, term2, mode2, index=0, funcMode='TD' ):
36 '''
37 Description:
38 Get needed informations of the search term from karaf.log
39 Includes onosclidriver functions
40 Function mode:
41 TD (time difference):
42 Get time difference between start and end
43 Term1: startTerm
44 Term2: endTerm
45 DR (disconnect rate):
46 Get switch disconnect rate
47 Term1: disconnectTerm
48 Term2: connectTerm
49
50 '''
51 try:
52 termInfo1 = main.CLIs[ index ].logSearch( term1, mode=mode1 )
53 termInfo2 = main.CLIs[ index ].logSearch( term2, mode=mode2 )
54 if funcMode == 'TD':
55 startTime = getTimestampFromString( main, termInfo1[0] )
56 endTime = getTimestampFromString ( main, termInfo2[0] )
57 if startTime == -1 or endTime == -1:
58 main.log.error( "Wrong Time!" )
59 main.writeData = -1
60 return -1
61 return endTime - startTime
62 if funcMode == 'DR':
63 #In this mode, termInfo1 means the total number of switch disconnection and
64 #termInfo2 means the total number of new switch connection
65 #termInfo2 - termInfo1 means the actual real number of switch connection.
66 disconnection = int( termInfo1 ) * 1.0
67 expectConnection = int( main.currScale ) ** 2
68 realConnection = int( termInfo2 ) - int( termInfo1 )
69 if expectConnection != realConnection:
70 main.log.error( "The number of real switch connection doesn't match the number of expected connection" )
71 main.writeData = -1
72 return -1
73 rate = disconnection / expectConnection
74 return rate
75 except IndexError:
76 main.log.error( "Catch the wrong information of search term" )
77 main.writeData = -1
78 return -1
79
kelvin-onlabd9e23de2015-08-06 10:34:44 -070080def testTopology( main, topoFile='', args='', mnCmd='', timeout=300, clean=True ):
kelvin-onlab1d381fe2015-07-14 16:24:56 -070081 """
82 Description:
83 This function combines different wrapper functions in this module
84 to simulate a topology test
85 Test Steps:
86 - Load topology
87 - Discover topology
88 - Compare topology
89 - pingall
90 - Bring links down
91 - Compare topology
92 - pingall
93 - Bring links up
94 - Compare topology
95 - pingall
96 Options:
97 clean: Does sudo mn -c to clean mininet residue
98 Please read mininetclidriver.py >> startNet( .. ) function for details
99 Returns:
100 Returns main.TRUE if the test is successful, main.FALSE otherwise
101 """
102 testTopoResult = main.TRUE
103 compareTopoResult = main.TRUE
104 topoObjectResult = main.TRUE
105 stopResult = main.TRUE
106
107 if clean:
108 # Cleans minient
109 stopResult = stopMininet( main )
110
111 # Restart ONOS to clear hosts test new mininet topology
112 reinstallOnosResult = reinstallOnos( main )
113
114 # Starts topology
kelvin-onlabd9e23de2015-08-06 10:34:44 -0700115 startResult = startNewTopology( main, topoFile, args, mnCmd, timeout=timeout )
GlennRC1c5df3c2015-08-27 16:12:09 -0700116 # onos needs time to see the links
117 time.sleep(15)
kelvin-onlab1d381fe2015-07-14 16:24:56 -0700118
119 # Gets list of switches in mininet
kelvin-onlabd9e23de2015-08-06 10:34:44 -0700120 #assignSwitch( main )
kelvin-onlab1d381fe2015-07-14 16:24:56 -0700121
kelvin-onlabd9e23de2015-08-06 10:34:44 -0700122 testTopoResult = startResult and topoObjectResult
kelvin-onlab1d381fe2015-07-14 16:24:56 -0700123
124
125 return testTopoResult
126
kelvin-onlabd9e23de2015-08-06 10:34:44 -0700127def startNewTopology( main, topoFile='', args='', mnCmd='', timeout=900 ):
kelvin-onlab1d381fe2015-07-14 16:24:56 -0700128 """
129 Description:
130 This wrapper function starts new topology
131 Options:
132 Please read mininetclidriver.py >> startNet( .. ) function for details
133 Return:
134 Returns main.TRUE if topology is successfully created by mininet,
135 main.FALSE otherwise
136 NOTE:
137 Assumes Mininet1 is the name of the handler
138 """
139 assert main, "There is no main variable"
140 assert main.Mininet1, "Mininet 1 is not created"
141 result = main.TRUE
142
143 main.log.info( main.topoName + ": Starting new Mininet topology" )
144
145 # log which method is being used
146 if topoFile:
147 main.log.info( main.topoName + ": Starting topology with " +
148 topoFile + "topology file" )
149 elif not topoFile and not mnCmd:
150 main.log.info( main.topoName + ": Starting topology using" +
151 " the topo file" )
152 elif topoFile and mnCmd:
153 main.log.error( main.topoName + ": You can only use one " +
154 "method to start a topology" )
155 elif mnCmd:
156 main.log.info( main.topoName + ": Starting topology with '" +
157 mnCmd + "' Mininet command" )
158
159
160 result = main.Mininet1.startNet( topoFile=topoFile,
161 args=args,
kelvin-onlabd9e23de2015-08-06 10:34:44 -0700162 mnCmd=mnCmd,
163 timeout=timeout)
kelvin-onlab1d381fe2015-07-14 16:24:56 -0700164
165 return result
166
167def stopMininet( main ):
168 """
169 Stops current topology and execute mn -c basically triggers
170 stopNet in mininetclidrivers
171
172 NOTE: Mininet should be running when issuing this command other wise
173 the this function will cause the test to stop
174 """
175 stopResult = main.TRUE
176 stopResult = main.Mininet1.stopNet()
177 time.sleep( 30 )
178 if not stopResult:
179 main.log.info( main.topoName + ": Did not stop Mininet topology" )
180 return stopResult
181
182def compareTopo( main ):
183 """
184 Compare topology( devices, links, ports, hosts ) between ONOS and
185 mininet using sts
186 """
187 devices = []
188 links = []
189 ports = []
190 hosts = []
191 switchResult = []
192 linksResult = []
193 portsResult = []
194 hostsResult = []
195 mnSwitches = main.Mininet1.getSwitches()
196 mnLinks = main.Mininet1.getLinks()
197 mnHosts = main.Mininet1.getHosts()
198 compareTopoResult = main.TRUE
199
200 for i in range( main.numCtrls ):
201 devices.append( json.loads( main.CLIs[ i ].devices() ) )
202 links.append( json.loads( main.CLIs[ i ].links() ) )
203 ports.append( json.loads( main.CLIs[ i ].ports() ) )
204 hosts.append( json.loads( main.CLIs[ i ].hosts() ) )
205
206 # Comparing switches
207 main.log.info( main.topoName + ": Comparing switches in each ONOS nodes" +
208 " with Mininet" )
209 for i in range( main.numCtrls ):
210 tempResult = main.Mininet1.compareSwitches( mnSwitches,
211 devices[ i ],
212 ports[ i ] )
213 switchResult.append( tempResult )
214 if tempResult == main.FALSE:
215 main.log.error( main.topoName + ": ONOS-" + str( i + 1 ) +
216 " switch view is incorrect " )
217
218 if all( result == main.TRUE for result in switchResult ):
219 main.log.info( main.topoName + ": Switch view in all ONOS nodes "+
220 "are correct " )
221 else:
222 compareTopoResult = main.FALSE
223
224 # Comparing links
225 main.log.info( main.topoName + ": Comparing links in each ONOS nodes" +
226 " with Mininet" )
227 for i in range( main.numCtrls ):
228 tempResult = main.Mininet1.compareLinks( mnSwitches,
229 mnLinks,
230 links[ i ] )
231 linksResult.append( tempResult )
232 if tempResult == main.FALSE:
233 main.log.error( main.topoName + ": ONOS-" + str( i + 1 ) +
234 " links view are incorrect " )
235
236 if all( result == main.TRUE for result in linksResult ):
237 main.log.info( main.topoName + ": Links view in all ONOS nodes "+
238 "are correct " )
239 else:
240 compareTopoResult = main.FALSE
241
242 # Comparing hosts
243 main.log.info( main.topoName + ": Comparing hosts in each ONOS nodes" +
244 " with Mininet" )
245 for i in range( main.numCtrls ):
246 tempResult = main.Mininet1.compareHosts( mnHosts, hosts[ i ] )
247 hostsResult.append( tempResult )
248 if tempResult == main.FALSE:
249 main.log.error( main.topoName + ": ONOS-" + str( i + 1 ) +
250 " hosts view are incorrect " )
251
252 if all( result == main.TRUE for result in hostsResult ):
253 main.log.info( main.topoName + ": Hosts view in all ONOS nodes "+
254 "are correct " )
255 else:
256 compareTopoResult = main.FALSE
257
258 return compareTopoResult
259
260def assignSwitch( main ):
261 """
262 Returns switch list using getSwitch in Mininet driver
263 """
264 switchList = []
265 assignResult = main.TRUE
266 switchList = main.Mininet1.getSwitch()
267 assignResult = main.Mininet1.assignSwController( sw=switchList,
268 ip=main.ONOSip[ 0 ],
GlennRC632e2892015-10-19 18:58:41 -0700269 port=6633 )
kelvin-onlab1d381fe2015-07-14 16:24:56 -0700270
271 for sw in switchList:
272 response = main.Mininet1.getSwController( sw )
273 if re.search( "tcp:" + main.ONOSip[ 0 ], response ):
274 assignResult = assignResult and main.TRUE
275 else:
276 assignResult = main.FALSE
277
278 return switchList
279
kelvin-onlabd9e23de2015-08-06 10:34:44 -0700280def connectivity( main, timeout=900, shortCircuit=True, acceptableFailed=20 ):
281 """
282 Use fwd app and pingall to discover all the hosts
283 """
284 activateResult = main.TRUE
285 appCheck = main.TRUE
286 getDataResult = main.TRUE
287 main.log.info( main.topoName + ": Activating reactive forwarding app " )
288 activateResult = main.CLIs[ 0 ].activateApp( "org.onosproject.fwd" )
289
290 if main.hostsData:
291 main.hostsData = {}
292 for i in range( main.numCtrls ):
293 appCheck = appCheck and main.CLIs[ i ].appToIDCheck()
294 if appCheck != main.TRUE:
295 main.log.warn( main.CLIs[ i ].apps() )
296 main.log.warn( main.CLIs[ i ].appIDs() )
297
298 time.sleep( main.fwdSleep )
299
300 # Discover hosts using pingall
301 pingResult = main.Mininet1.pingall( timeout=timeout,
302 shortCircuit=shortCircuit,
303 acceptableFailed=acceptableFailed )
304
305 main.log.info( main.topoName + ": Deactivate reactive forwarding app " )
306 activateResult = main.CLIs[ 0 ].deactivateApp( "org.onosproject.fwd" )
307 for i in range( main.numCtrls ):
308 appCheck = appCheck and main.CLIs[ i ].appToIDCheck()
309 if appCheck != main.TRUE:
310 main.log.warn( main.CLIs[ i ].apps() )
311 main.log.warn( main.CLIs[ i ].appIDs() )
312
313 return pingResult
314
kelvin-onlab1d381fe2015-07-14 16:24:56 -0700315def getHostsData( main ):
316 """
317 Use fwd app and pingall to discover all the hosts
318 """
319 activateResult = main.TRUE
320 appCheck = main.TRUE
321 getDataResult = main.TRUE
322 main.log.info( main.topoName + ": Activating reactive forwarding app " )
323 activateResult = main.CLIs[ 0 ].activateApp( "org.onosproject.fwd" )
324
325 if main.hostsData:
326 main.hostsData = {}
327 for i in range( main.numCtrls ):
328 appCheck = appCheck and main.CLIs[ i ].appToIDCheck()
329 if appCheck != main.TRUE:
330 main.log.warn( main.CLIs[ i ].apps() )
331 main.log.warn( main.CLIs[ i ].appIDs() )
332
333 time.sleep( main.fwdSleep )
334 # Discover hosts using pingall
335 pingResult = main.Mininet1.pingall( timeout=900 )
336
337 hostsJson = json.loads( main.CLIs[ 0 ].hosts() )
338 hosts = main.Mininet1.getHosts().keys()
339
340 for host in hosts:
341 main.hostsData[ host ] = {}
342 main.hostsData[ host ][ 'mac' ] = \
343 main.Mininet1.getMacAddress( host ).upper()
344 for hostj in hostsJson:
345 if main.hostsData[ host ][ 'mac' ] == hostj[ 'mac' ]:
346 main.hostsData[ host ][ 'id' ] = hostj[ 'id' ]
347 main.hostsData[ host ][ 'vlan' ] = hostj[ 'vlan' ]
348 main.hostsData[ host ][ 'location' ] = \
349 hostj[ 'location' ][ 'elementId' ] + '/' + \
350 hostj[ 'location' ][ 'port' ]
351 main.hostsData[ host ][ 'ipAddresses' ] = hostj[ 'ipAddresses' ]
352
353 if activateResult and main.hostsData:
354 main.log.info( main.topoName + ": Successfully used fwd app" +
355 " to discover hosts " )
356 getDataResult = main.TRUE
357 else:
358 main.log.info( main.topoName + ": Failed to use fwd app" +
359 " to discover hosts " )
360 getDataResult = main.FALSE
361
362 main.log.info( main.topoName + ": Deactivate reactive forwarding app " )
363 activateResult = main.CLIs[ 0 ].deactivateApp( "org.onosproject.fwd" )
364 for i in range( main.numCtrls ):
365 appCheck = appCheck and main.CLIs[ i ].appToIDCheck()
366 if appCheck != main.TRUE:
367 main.log.warn( main.CLIs[ i ].apps() )
368 main.log.warn( main.CLIs[ i ].appIDs() )
369
370 # This data can be use later for intents
371 print main.hostsData
372
373 return getDataResult
374
375def reinstallOnos( main ):
376 """
377 Description:
378 Stop and start ONOS that clears hosts,devices etc. in order to test
379 new mininet topology
380 Return:
381 Retruns main.TRUE for a successful restart, main.FALSE otherwise.
382 """
383 uninstallResult = []
384 installResult = []
385 stopResult = []
386 startResult = []
387 onosIsUpResult = []
388 restartResult = main.TRUE
389
390 main.log.info( main.topoName + ": Uninstall ONOS cluster" )
391 for ip in main.ONOSip:
392 uninstallResult.append( main.ONOSbench.onosUninstall( nodeIp=ip ) )
393
394 if all( result == main.TRUE for result in uninstallResult ):
395 main.log.info( main.topoName + ": Successfully uninstall ONOS cluster" )
396 else:
397 restartResult = main.FALSE
398 main.log.error( main.topoName + ": Failed to uninstall ONOS cluster" )
399
400 time.sleep( main.startUpSleep )
401
402 main.log.info( main.topoName + ": Installing ONOS cluster" )
403
404 for i in range( main.numCtrls ):
405 installResult.append( main.ONOSbench.onosInstall(
406 node=main.ONOSip[ i ] ) )
407
408 if all( result == main.TRUE for result in installResult ):
409 main.log.info( main.topoName + ": Successfully installed ONOS cluster" )
410 else:
411 restartResult = main.FALSE
412 main.log.error( main.topoName + ": Failed to install ONOS cluster" )
413
414 for i in range( main.numCtrls ):
415 onosIsUpResult.append( main.ONOSbench.isup( main.ONOSip[ i ] ) )
416
417 if all( result == main.TRUE for result in onosIsUpResult ):
418 main.log.report( "ONOS instance is up and ready" )
419 else:
420 main.log.report( "ONOS instance may not be up, stop and " +
421 "start ONOS again " )
422 for i in range( main.numCtrls ):
423 stopResult.append( main.ONOSbench.onosStop( main.ONOSip[ i ] ) )
424
425 if all( result == main.TRUE for result in stopResult ):
426 main.log.info( main.topoName + ": Successfully stop ONOS cluster" )
427 else:
428 main.log.error( main.topoName + ": Failed to stop ONOS cluster" )
429
430 for i in range( main.numCtrls ):
431 startResult.append( main.ONOSbench.onosStart( main.ONOSip[ i ] ) )
432
433 if all( result == main.TRUE for result in startResult ):
434 main.log.info( main.topoName + ": Successfully start ONOS cluster" )
435 else:
436 main.log.error( main.topoName + ": Failed to start ONOS cluster" )
437
438 main.log.info( main.topoName + ": Starting ONOS CLI" )
439 cliResult = []
440 for i in range( main.numCtrls ):
441 cliResult.append( main.CLIs[ i ].startOnosCli( main.ONOSip[ i ] ) )
442
443 if all( result == main.TRUE for result in cliResult ):
444 main.log.info( main.topoName + ": Successfully start ONOS cli" )
445 else:
446 main.log.error( main.topoName + ": Failed to start ONOS cli" )
447 restartResult = main.FALSE
448
449
450 return restartResult
451
452
453