blob: f8ee9c21d273970fc24d23069be47b5cc532b4bb [file] [log] [blame]
adminbae64d82013-08-01 10:50:15 -07001#!/usr/bin/env python
2'''
3Created on 26-Oct-2012
4
5@author: Anil Kumar (anilkumar.s@paxterrasolutions.com)
6
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
22MininetCliDriver is the basic driver which will handle the Mininet functions
23'''
admin2a9548d2014-06-17 14:08:07 -070024import traceback
adminbae64d82013-08-01 10:50:15 -070025import pexpect
26import struct
27import fcntl
28import os
29import signal
30import re
31import sys
32import core.teston
33sys.path.append("../")
Jon Hall1ccf82c2014-10-15 14:55:16 -040034from math import pow
adminbae64d82013-08-01 10:50:15 -070035from drivers.common.cli.emulatordriver import Emulator
36from drivers.common.clidriver import CLI
37
38class MininetCliDriver(Emulator):
39 '''
Jon Hall41f40e82014-04-08 16:43:17 -070040 MininetCliDriver is the basic driver which will handle the Mininet functions
adminbae64d82013-08-01 10:50:15 -070041 '''
42 def __init__(self):
43 super(Emulator, self).__init__()
44 self.handle = self
45 self.wrapped = sys.modules[__name__]
46 self.flag = 0
47
48 def connect(self, **connectargs):
Jon Hall41f40e82014-04-08 16:43:17 -070049 '''
50 Here the main is the TestON instance after creating all the log handles.
51 '''
adminbae64d82013-08-01 10:50:15 -070052 for key in connectargs:
53 vars(self)[key] = connectargs[key]
54
55 self.name = self.options['name']
56 self.handle = super(MininetCliDriver, self).connect(user_name = self.user_name, ip_address = self.ip_address,port = None, pwd = self.pwd)
57
58 self.ssh_handle = self.handle
59
adminbae64d82013-08-01 10:50:15 -070060 if self.handle :
Jon Hallf2942ce2014-04-10 16:00:16 -070061 main.log.info(self.name+": Clearing any residual state or processes")
adminbae64d82013-08-01 10:50:15 -070062 self.handle.sendline("sudo mn -c")
adminf939f8b2014-04-03 17:22:56 -070063 i=self.handle.expect(['password\sfor\s','Cleanup\scomplete',pexpect.EOF,pexpect.TIMEOUT],120)
adminbae64d82013-08-01 10:50:15 -070064 if i==0:
Jon Hallf2942ce2014-04-10 16:00:16 -070065 main.log.info(self.name+": Sending sudo password")
adminf939f8b2014-04-03 17:22:56 -070066 self.handle.sendline(self.pwd)
67 i=self.handle.expect(['%s:'%(self.user),'\$',pexpect.EOF,pexpect.TIMEOUT],120)
adminbae64d82013-08-01 10:50:15 -070068 if i==1:
Jon Hallf2942ce2014-04-10 16:00:16 -070069 main.log.info(self.name+": Clean")
adminbae64d82013-08-01 10:50:15 -070070 elif i==2:
Jon Hallf2942ce2014-04-10 16:00:16 -070071 main.log.error(self.name+": Connection terminated")
adminbae64d82013-08-01 10:50:15 -070072 elif i==3: #timeout
Jon Hallf2942ce2014-04-10 16:00:16 -070073 main.log.error(self.name+": Something while cleaning MN took too long... " )
adminbae64d82013-08-01 10:50:15 -070074
Jon Hallf2942ce2014-04-10 16:00:16 -070075 main.log.info(self.name+": building fresh mininet")
adminbeea0032014-01-23 14:54:13 -080076 #### for reactive/PARP enabled tests
shahshreyaf4d4d0c2014-10-10 12:11:10 -070077 cmdString = "sudo mn " + self.options['arg1'] + " " + self.options['arg2'] + " --mac --controller " + self.options['controller'] + " " + self.options['arg3']
Jon Hall1ccf82c2014-10-15 14:55:16 -040078
79 argList = self.options['arg1'].split(",")
80 global topoArgList
81 topoArgList = argList[0].split(" ")
82 argList = map(int, argList[1:])
83 topoArgList = topoArgList[1:] + argList
84
85 #### for proactive flow with static ARP entries
shahshreyaf4d4d0c2014-10-10 12:11:10 -070086 #cmdString = "sudo mn " + self.options['arg1'] + " " + self.options['arg2'] + " --mac --arp --controller " + self.options['controller'] + " " + self.options['arg3']
adminbae64d82013-08-01 10:50:15 -070087 self.handle.sendline(cmdString)
Jon Hall333fa8c2014-04-11 11:24:58 -070088 self.handle.expect(["sudo mn",pexpect.EOF,pexpect.TIMEOUT])
adminbae64d82013-08-01 10:50:15 -070089 while 1:
90 i=self.handle.expect(['mininet>','\*\*\*','Exception',pexpect.EOF,pexpect.TIMEOUT],300)
91 if i==0:
Jon Hallf2942ce2014-04-10 16:00:16 -070092 main.log.info(self.name+": mininet built")
adminbae64d82013-08-01 10:50:15 -070093 return main.TRUE
94 if i==1:
Jon Hall333fa8c2014-04-11 11:24:58 -070095 self.handle.expect(["\n",pexpect.EOF,pexpect.TIMEOUT])
adminbae64d82013-08-01 10:50:15 -070096 main.log.info(self.handle.before)
97 elif i==2:
Jon Hallf2942ce2014-04-10 16:00:16 -070098 main.log.error(self.name+": Launching mininet failed...")
adminbae64d82013-08-01 10:50:15 -070099 return main.FALSE
100 elif i==3:
Jon Hallf2942ce2014-04-10 16:00:16 -0700101 main.log.error(self.name+": Connection timeout")
adminbae64d82013-08-01 10:50:15 -0700102 return main.FALSE
103 elif i==4: #timeout
Jon Hallf2942ce2014-04-10 16:00:16 -0700104 main.log.error(self.name+": Something took too long... " )
adminbae64d82013-08-01 10:50:15 -0700105 return main.FALSE
adminbae64d82013-08-01 10:50:15 -0700106 #if utilities.assert_matches(expect=patterns,actual=resultCommand,onpass="Network is being launched",onfail="Network launching is being failed "):
107 return main.TRUE
Jon Hallf2942ce2014-04-10 16:00:16 -0700108 else:#if no handle
109 main.log.error(self.name+": Connection failed to the host "+self.user_name+"@"+self.ip_address)
110 main.log.error(self.name+": Failed to connect to the Mininet")
adminbae64d82013-08-01 10:50:15 -0700111 return main.FALSE
Jon Hall1ccf82c2014-10-15 14:55:16 -0400112
113 def num_switches_n_links(self,topoType,depth,fanout):
114 if topoType == 'tree':
115 if fanout is None: #In tree topology, if fanout arg is not given, by default it is 2
116 fanout = 2
117 k = 0
118 sum = 0
119 while(k <= depth-1):
120 sum = sum + pow(fanout,k)
121 k = k+1
122 num_switches = sum
123 while(k <= depth-2):
124 '''depth-2 gives you only core links and not considering edge links as seen by ONOS
125 If all the links including edge links are required, do depth-1
126 '''
127 sum = sum + pow(fanout,k)
128 k = k+1
129 num_links = sum * fanout
130 #print "num_switches for %s(%d,%d) = %d and links=%d" %(topoType,depth,fanout,num_switches,num_links)
131
132 elif topoType =='linear':
133 if fanout is None: #In linear topology, if fanout or num_hosts_per_sw is not given, by default it is 1
134 fanout = 1
135 num_switches = depth
136 num_hosts_per_sw = fanout
137 total_num_hosts = num_switches * num_hosts_per_sw
138 num_links = total_num_hosts + (num_switches - 1)
139 print "num_switches for %s(%d,%d) = %d and links=%d" %(topoType,depth,fanout,num_switches,num_links)
140 topoDict = {}
141 topoDict = {"num_switches":int(num_switches), "num_corelinks":int(num_links)}
142 return topoDict
143
144
145 def calculate_sw_and_links(self):
146 topoDict = self.num_switches_n_links(*topoArgList)
147 return topoDict
148
adminbae64d82013-08-01 10:50:15 -0700149 def pingall(self):
150 '''
Jon Hall41f40e82014-04-08 16:43:17 -0700151 Verifies the reachability of the hosts using pingall command.
adminbae64d82013-08-01 10:50:15 -0700152 '''
153 if self.handle :
Jon Hallf2942ce2014-04-10 16:00:16 -0700154 main.log.info(self.name+": Checking reachabilty to the hosts using pingall")
Jon Hall6094a362014-04-11 14:46:56 -0700155 try:
Jon Hallefa4fa12014-04-14 11:40:21 -0700156 response = self.execute(cmd="pingall",prompt="mininet>",timeout=120)
Jon Hall77f53ce2014-10-13 18:02:06 -0400157 print "response: " + str(response)
Jon Hall6094a362014-04-11 14:46:56 -0700158 except pexpect.EOF:
159 main.log.error(self.name + ": EOF exception found")
160 main.log.error(self.name + ": " + self.handle.before)
161 main.cleanup()
162 main.exit()
Jon Hallf4c8d012014-10-09 19:35:08 -0400163 pattern = 'Results\:\s0\%\sdropped\s'
andrew@onlab.us59e8f692014-10-09 21:41:48 -0400164 #FIXME:Pending Mininet Pull Request #408
Jon Hallf4c8d012014-10-09 19:35:08 -0400165 #pattern = 'Results\:\s0\.00\%\sdropped\s'
166 print response
Jon Hallf2942ce2014-04-10 16:00:16 -0700167 #if utilities.assert_matches(expect=pattern,actual=response,onpass="All hosts are reaching",onfail="Unable to reach all the hosts"):
168 if re.search(pattern,response):
169 main.log.info(self.name+": All hosts are reachable")
adminbae64d82013-08-01 10:50:15 -0700170 return main.TRUE
171 else:
Jon Hallf2942ce2014-04-10 16:00:16 -0700172 main.log.error(self.name+": Unable to reach all the hosts")
adminbae64d82013-08-01 10:50:15 -0700173 return main.FALSE
174 else :
Jon Hallf2942ce2014-04-10 16:00:16 -0700175 main.log.error(self.name+": Connection failed to the host")
adminbae64d82013-08-01 10:50:15 -0700176 return main.FALSE
adminaeedddd2013-08-02 15:14:15 -0700177
178 def fpingHost(self,**pingParams):
179 '''
180 Uses the fping package for faster pinging...
181 *requires fping to be installed on machine running mininet
182 '''
183 args = utilities.parse_args(["SRC","TARGET"],**pingParams)
admin530b4c92013-08-14 16:54:35 -0700184 command = args["SRC"] + " fping -i 100 -t 20 -C 1 -q "+args["TARGET"]
adminaeedddd2013-08-02 15:14:15 -0700185 self.handle.sendline(command)
Jon Hall333fa8c2014-04-11 11:24:58 -0700186 self.handle.expect([args["TARGET"],pexpect.EOF,pexpect.TIMEOUT])
187 self.handle.expect(["mininet",pexpect.EOF,pexpect.TIMEOUT])
adminaeedddd2013-08-02 15:14:15 -0700188 response = self.handle.before
189 if re.search(":\s-" ,response):
Jon Hallf2942ce2014-04-10 16:00:16 -0700190 main.log.info(self.name+": Ping fail")
adminaeedddd2013-08-02 15:14:15 -0700191 return main.FALSE
admin530b4c92013-08-14 16:54:35 -0700192 elif re.search(":\s\d{1,2}\.\d\d", response):
Jon Hallf2942ce2014-04-10 16:00:16 -0700193 main.log.info(self.name+": Ping good!")
adminaeedddd2013-08-02 15:14:15 -0700194 return main.TRUE
Jon Hallf2942ce2014-04-10 16:00:16 -0700195 main.log.info(self.name+": Install fping on mininet machine... ")
196 main.log.info(self.name+": \n---\n"+response)
adminaeedddd2013-08-02 15:14:15 -0700197 return main.FALSE
adminbae64d82013-08-01 10:50:15 -0700198
199 def pingHost(self,**pingParams):
Jon Hallf2942ce2014-04-10 16:00:16 -0700200 '''
201 Ping from one mininet host to another
202 Currently the only supported Params: SRC and TARGET
203 '''
adminbae64d82013-08-01 10:50:15 -0700204 args = utilities.parse_args(["SRC","TARGET"],**pingParams)
205 #command = args["SRC"] + " ping -" + args["CONTROLLER"] + " " +args ["TARGET"]
Jon Hall0819fd92014-05-23 12:08:13 -0700206 command = args["SRC"] + " ping "+args ["TARGET"]+" -c 1 -i 1 -W 8"
Jon Hall6094a362014-04-11 14:46:56 -0700207 try:
Jon Hall6e18c7b2014-04-23 16:26:33 -0700208 main.log.warn("Sending: " + command)
209 #response = self.execute(cmd=command,prompt="mininet",timeout=10 )
210 self.handle.sendline(command)
211 i = self.handle.expect([command,pexpect.TIMEOUT])
212 if i == 1:
213 main.log.error(self.name + ": timeout when waiting for response from mininet")
214 main.log.error("response: " + str(self.handle.before))
215 i = self.handle.expect(["mininet>",pexpect.TIMEOUT])
216 if i == 1:
217 main.log.error(self.name + ": timeout when waiting for response from mininet")
218 main.log.error("response: " + str(self.handle.before))
219 response = self.handle.before
Jon Hall6094a362014-04-11 14:46:56 -0700220 except pexpect.EOF:
221 main.log.error(self.name + ": EOF exception found")
222 main.log.error(self.name + ": " + self.handle.before)
223 main.cleanup()
224 main.exit()
Jon Hallf2942ce2014-04-10 16:00:16 -0700225 main.log.info(self.name+": Ping Response: "+ response )
226 #if utilities.assert_matches(expect=',\s0\%\spacket\sloss',actual=response,onpass="No Packet loss",onfail="Host is not reachable"):
227 if re.search(',\s0\%\spacket\sloss',response):
Jon Hall6e18c7b2014-04-23 16:26:33 -0700228 main.log.info(self.name+": no packets lost, host is reachable")
adminbae64d82013-08-01 10:50:15 -0700229 main.last_result = main.TRUE
230 return main.TRUE
231 else :
Jon Hallf2942ce2014-04-10 16:00:16 -0700232 main.log.error(self.name+": PACKET LOST, HOST IS NOT REACHABLE")
adminbae64d82013-08-01 10:50:15 -0700233 main.last_result = main.FALSE
234 return main.FALSE
adminbae64d82013-08-01 10:50:15 -0700235
236 def checkIP(self,host):
237 '''
Jon Hall41f40e82014-04-08 16:43:17 -0700238 Verifies the host's ip configured or not.
adminbae64d82013-08-01 10:50:15 -0700239 '''
240 if self.handle :
Jon Hall6094a362014-04-11 14:46:56 -0700241 try:
242 response = self.execute(cmd=host+" ifconfig",prompt="mininet>",timeout=10)
243 except pexpect.EOF:
244 main.log.error(self.name + ": EOF exception found")
245 main.log.error(self.name + ": " + self.handle.before)
246 main.cleanup()
247 main.exit()
adminbae64d82013-08-01 10:50:15 -0700248
249 pattern = "inet\s(addr|Mask):([0-1]{1}[0-9]{1,2}|2[0-4][0-9]|25[0-5]|[0-9]{1,2}).([0-1]{1}[0-9]{1,2}|2[0-4][0-9]|25[0-5]|[0-9]{1,2}).([0-1]{1}[0-9]{1,2}|2[0-4][0-9]|25[0-5]|[0-9]{1,2}).([0-1]{1}[0-9]{1,2}|2[0-4][0-9]|25[0-5]|[0-9]{1,2})"
admin2a9548d2014-06-17 14:08:07 -0700250 #pattern = "inet addr:10.0.0.6"
Jon Hallf2942ce2014-04-10 16:00:16 -0700251 #if utilities.assert_matches(expect=pattern,actual=response,onpass="Host Ip configured properly",onfail="Host IP not found") :
252 if re.search(pattern,response):
253 main.log.info(self.name+": Host Ip configured properly")
adminbae64d82013-08-01 10:50:15 -0700254 return main.TRUE
255 else:
Jon Hallf2942ce2014-04-10 16:00:16 -0700256 main.log.error(self.name+": Host IP not found")
adminbae64d82013-08-01 10:50:15 -0700257 return main.FALSE
258 else :
Jon Hallf2942ce2014-04-10 16:00:16 -0700259 main.log.error(self.name+": Connection failed to the host")
adminbae64d82013-08-01 10:50:15 -0700260
261 def verifySSH(self,**connectargs):
Jon Hall6094a362014-04-11 14:46:56 -0700262 try:
263 response = self.execute(cmd="h1 /usr/sbin/sshd -D&",prompt="mininet>",timeout=10)
264 response = self.execute(cmd="h4 /usr/sbin/sshd -D&",prompt="mininet>",timeout=10)
265 for key in connectargs:
266 vars(self)[key] = connectargs[key]
267 response = self.execute(cmd="xterm h1 h4 ",prompt="mininet>",timeout=10)
268 except pexpect.EOF:
269 main.log.error(self.name + ": EOF exception found")
270 main.log.error(self.name + ": " + self.handle.before)
271 main.cleanup()
272 main.exit()
adminbae64d82013-08-01 10:50:15 -0700273 import time
274 time.sleep(20)
275 if self.flag == 0:
276 self.flag = 1
277 return main.FALSE
278 else :
279 return main.TRUE
280
281 def getMacAddress(self,host):
282 '''
Jon Hall41f40e82014-04-08 16:43:17 -0700283 Verifies the host's ip configured or not.
adminbae64d82013-08-01 10:50:15 -0700284 '''
285 if self.handle :
Jon Hall6094a362014-04-11 14:46:56 -0700286 try:
287 response = self.execute(cmd=host+" ifconfig",prompt="mininet>",timeout=10)
288 except pexpect.EOF:
289 main.log.error(self.name + ": EOF exception found")
290 main.log.error(self.name + ": " + self.handle.before)
291 main.cleanup()
292 main.exit()
adminbae64d82013-08-01 10:50:15 -0700293
Ahmed El-Hassanyf720e202014-04-04 16:11:36 -0700294 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
295 mac_address_search = re.search(pattern, response, re.I)
296 mac_address = mac_address_search.group().split(" ")[1]
Jon Hallf2942ce2014-04-10 16:00:16 -0700297 main.log.info(self.name+": Mac-Address of Host "+ host + " is " + mac_address)
Ahmed El-Hassanyf720e202014-04-04 16:11:36 -0700298 return mac_address
adminbae64d82013-08-01 10:50:15 -0700299 else :
Jon Hallf2942ce2014-04-10 16:00:16 -0700300 main.log.error(self.name+": Connection failed to the host")
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700301
302 def getInterfaceMACAddress(self,host, interface):
303 '''
304 Return the IP address of the interface on the given host
305 '''
306 if self.handle :
Jon Hall6094a362014-04-11 14:46:56 -0700307 try:
308 response = self.execute(cmd=host+" ifconfig " + interface,
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700309 prompt="mininet>",timeout=10)
Jon Hall6094a362014-04-11 14:46:56 -0700310 except pexpect.EOF:
311 main.log.error(self.name + ": EOF exception found")
312 main.log.error(self.name + ": " + self.handle.before)
313 main.cleanup()
314 main.exit()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700315
316 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
317 mac_address_search = re.search(pattern, response, re.I)
318 if mac_address_search is None:
319 main.log.info("No mac address found in %s" % response)
320 return main.FALSE
321 mac_address = mac_address_search.group().split(" ")[1]
322 main.log.info("Mac-Address of "+ host + ":"+ interface + " is " + mac_address)
323 return mac_address
324 else:
325 main.log.error("Connection failed to the host")
326
adminbae64d82013-08-01 10:50:15 -0700327 def getIPAddress(self,host):
328 '''
Jon Hall41f40e82014-04-08 16:43:17 -0700329 Verifies the host's ip configured or not.
adminbae64d82013-08-01 10:50:15 -0700330 '''
331 if self.handle :
Jon Hall6094a362014-04-11 14:46:56 -0700332 try:
333 response = self.execute(cmd=host+" ifconfig",prompt="mininet>",timeout=10)
334 except pexpect.EOF:
335 main.log.error(self.name + ": EOF exception found")
336 main.log.error(self.name + ": " + self.handle.before)
337 main.cleanup()
338 main.exit()
adminbae64d82013-08-01 10:50:15 -0700339
340 pattern = "inet\saddr:(\d+\.\d+\.\d+\.\d+)"
341 ip_address_search = re.search(pattern, response)
Jon Hallf2942ce2014-04-10 16:00:16 -0700342 main.log.info(self.name+": IP-Address of Host "+host +" is "+ip_address_search.group(1))
adminbae64d82013-08-01 10:50:15 -0700343 return ip_address_search.group(1)
344 else :
Jon Hallf2942ce2014-04-10 16:00:16 -0700345 main.log.error(self.name+": Connection failed to the host")
adminbae64d82013-08-01 10:50:15 -0700346
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700347 def getSwitchDPID(self,switch):
348 '''
349 return the datapath ID of the switch
350 '''
351 if self.handle :
352 cmd = "py %s.dpid" % switch
Jon Hall6094a362014-04-11 14:46:56 -0700353 try:
354 response = self.execute(cmd=cmd,prompt="mininet>",timeout=10)
355 except pexpect.EOF:
356 main.log.error(self.name + ": EOF exception found")
357 main.log.error(self.name + ": " + self.handle.before)
358 main.cleanup()
359 main.exit()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700360 pattern = r'^(?P<dpid>\d)+'
361 result = re.search(pattern, response, re.MULTILINE)
362 if result is None:
363 main.log.info("Couldn't find DPID for switch '', found: %s" % (switch, response))
364 return main.FALSE
Jon Hallc1a1d242014-07-21 16:03:33 -0700365 return str(result.group(0))
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700366 else:
367 main.log.error("Connection failed to the host")
368
admin2580a0e2014-07-29 11:24:34 -0700369 def getDPID(self, switch):
370 if self.handle:
371 self.handle.sendline("")
372 self.expect("mininet>")
373 cmd = "py %s.dpid" %switch
374 try:
375 response = self.execute(cmd=cmd,prompt="mininet>",timeout=10)
376 self.handle.expect("mininet>")
377 response = self.handle.before
378 return response
379 except pexpect.EOF:
380 main.log.error(self.name + ": EOF exception found")
381 main.log.error(self.name + ": " + self.handle.before)
382 main.cleanup()
383 main.exit()
384
385
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700386 def getInterfaces(self, node):
387 '''
388 return information dict about interfaces connected to the node
389 '''
390 if self.handle :
391 cmd = 'py "\\n".join(["name=%s,mac=%s,ip=%s,isUp=%s" % (i.name, i.MAC(), i.IP(), i.isUp())'
392 cmd += ' for i in %s.intfs.values()])' % node
Jon Hall6094a362014-04-11 14:46:56 -0700393 try:
394 response = self.execute(cmd=cmd,prompt="mininet>",timeout=10)
395 except pexpect.EOF:
396 main.log.error(self.name + ": EOF exception found")
397 main.log.error(self.name + ": " + self.handle.before)
398 main.cleanup()
399 main.exit()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700400 return response
401 else:
402 main.log.error("Connection failed to the node")
403
adminbae64d82013-08-01 10:50:15 -0700404 def dump(self):
Jon Hallf2942ce2014-04-10 16:00:16 -0700405 main.log.info(self.name+": Dump node info")
Jon Hall6094a362014-04-11 14:46:56 -0700406 try:
407 response = self.execute(cmd = 'dump',prompt = 'mininet>',timeout = 10)
408 except pexpect.EOF:
409 main.log.error(self.name + ": EOF exception found")
410 main.log.error(self.name + ": " + self.handle.before)
411 main.cleanup()
412 main.exit()
Ahmed El-Hassanyd1f71702014-04-04 16:12:45 -0700413 return response
adminbae64d82013-08-01 10:50:15 -0700414
415 def intfs(self):
Jon Hallf2942ce2014-04-10 16:00:16 -0700416 main.log.info(self.name+": List interfaces")
Jon Hall6094a362014-04-11 14:46:56 -0700417 try:
418 response = self.execute(cmd = 'intfs',prompt = 'mininet>',timeout = 10)
419 except pexpect.EOF:
420 main.log.error(self.name + ": EOF exception found")
421 main.log.error(self.name + ": " + self.handle.before)
422 main.cleanup()
423 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700424 return response
adminbae64d82013-08-01 10:50:15 -0700425
426 def net(self):
Jon Hallf2942ce2014-04-10 16:00:16 -0700427 main.log.info(self.name+": List network connections")
Jon Hall6094a362014-04-11 14:46:56 -0700428 try:
429 response = self.execute(cmd = 'net',prompt = 'mininet>',timeout = 10)
430 except pexpect.EOF:
431 main.log.error(self.name + ": EOF exception found")
432 main.log.error(self.name + ": " + self.handle.before)
433 main.cleanup()
434 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700435 return response
adminbae64d82013-08-01 10:50:15 -0700436
437 def iperf(self):
Jon Hallf2942ce2014-04-10 16:00:16 -0700438 main.log.info(self.name+": Simple iperf TCP test between two (optionally specified) hosts")
Jon Hall6094a362014-04-11 14:46:56 -0700439 try:
440 response = self.execute(cmd = 'iperf',prompt = 'mininet>',timeout = 10)
441 except pexpect.EOF:
442 main.log.error(self.name + ": EOF exception found")
443 main.log.error(self.name + ": " + self.handle.before)
444 main.cleanup()
445 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700446 return response
adminbae64d82013-08-01 10:50:15 -0700447
448 def iperfudp(self):
Jon Hallf2942ce2014-04-10 16:00:16 -0700449 main.log.info(self.name+": Simple iperf TCP test between two (optionally specified) hosts")
Jon Hall6094a362014-04-11 14:46:56 -0700450 try:
451 response = self.execute(cmd = 'iperfudp',prompt = 'mininet>',timeout = 10)
452 except pexpect.EOF:
453 main.log.error(self.name + ": EOF exception found")
454 main.log.error(self.name + ": " + self.handle.before)
455 main.cleanup()
456 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700457 return response
adminbae64d82013-08-01 10:50:15 -0700458
459 def nodes(self):
Jon Hallf2942ce2014-04-10 16:00:16 -0700460 main.log.info(self.name+": List all nodes.")
Jon Hall6094a362014-04-11 14:46:56 -0700461 try:
462 response = self.execute(cmd = 'nodes',prompt = 'mininet>',timeout = 10)
463 except pexpect.EOF:
464 main.log.error(self.name + ": EOF exception found")
465 main.log.error(self.name + ": " + self.handle.before)
466 main.cleanup()
467 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700468 return response
adminbae64d82013-08-01 10:50:15 -0700469
470 def pingpair(self):
Jon Hallf2942ce2014-04-10 16:00:16 -0700471 main.log.info(self.name+": Ping between first two hosts")
Jon Hall6094a362014-04-11 14:46:56 -0700472 try:
473 response = self.execute(cmd = 'pingpair',prompt = 'mininet>',timeout = 20)
474 except pexpect.EOF:
475 main.log.error(self.name + ": EOF exception found")
476 main.log.error(self.name + ": " + self.handle.before)
477 main.cleanup()
478 main.exit()
adminbae64d82013-08-01 10:50:15 -0700479
Jon Hallf2942ce2014-04-10 16:00:16 -0700480 #if utilities.assert_matches(expect='0% packet loss',actual=response,onpass="No Packet loss",onfail="Hosts not reachable"):
481 if re.search(',\s0\%\spacket\sloss',response):
482 main.log.info(self.name+": Ping between two hosts SUCCESSFUL")
adminbae64d82013-08-01 10:50:15 -0700483 main.last_result = main.TRUE
484 return main.TRUE
485 else :
Jon Hallf2942ce2014-04-10 16:00:16 -0700486 main.log.error(self.name+": PACKET LOST, HOSTS NOT REACHABLE")
adminbae64d82013-08-01 10:50:15 -0700487 main.last_result = main.FALSE
488 return main.FALSE
489
490 def link(self,**linkargs):
491 '''
492 Bring link(s) between two nodes up or down
493 '''
494 main.log.info('Bring link(s) between two nodes up or down')
495 args = utilities.parse_args(["END1","END2","OPTION"],**linkargs)
496 end1 = args["END1"] if args["END1"] != None else ""
497 end2 = args["END2"] if args["END2"] != None else ""
498 option = args["OPTION"] if args["OPTION"] != None else ""
499 command = "link "+str(end1) + " " + str(end2)+ " " + str(option)
Jon Hall6094a362014-04-11 14:46:56 -0700500 try:
Jon Halle80ef8c2014-04-29 15:29:13 -0700501 #response = self.execute(cmd=command,prompt="mininet>",timeout=10)
502 self.handle.sendline(command)
503 self.handle.expect("mininet>")
Jon Hall6094a362014-04-11 14:46:56 -0700504 except pexpect.EOF:
505 main.log.error(self.name + ": EOF exception found")
506 main.log.error(self.name + ": " + self.handle.before)
507 main.cleanup()
508 main.exit()
adminbae64d82013-08-01 10:50:15 -0700509 return main.TRUE
510
511
admin530b4c92013-08-14 16:54:35 -0700512 def yank(self,**yankargs):
adminaeedddd2013-08-02 15:14:15 -0700513 '''
admin530b4c92013-08-14 16:54:35 -0700514 yank a mininet switch interface to a host
adminaeedddd2013-08-02 15:14:15 -0700515 '''
admin530b4c92013-08-14 16:54:35 -0700516 main.log.info('Yank the switch interface attached to a host')
517 args = utilities.parse_args(["SW","INTF"],**yankargs)
adminaeedddd2013-08-02 15:14:15 -0700518 sw = args["SW"] if args["SW"] !=None else ""
519 intf = args["INTF"] if args["INTF"] != None else ""
520 command = "py "+ str(sw) + '.detach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -0700521 try:
522 response = self.execute(cmd=command,prompt="mininet>",timeout=10)
523 except pexpect.EOF:
524 main.log.error(self.name + ": EOF exception found")
525 main.log.error(self.name + ": " + self.handle.before)
526 main.cleanup()
527 main.exit()
adminaeedddd2013-08-02 15:14:15 -0700528 return main.TRUE
529
530 def plug(self, **plugargs):
531 '''
532 plug the yanked mininet switch interface to a switch
533 '''
534 main.log.info('Plug the switch interface attached to a switch')
admin530b4c92013-08-14 16:54:35 -0700535 args = utilities.parse_args(["SW","INTF"],**plugargs)
adminaeedddd2013-08-02 15:14:15 -0700536 sw = args["SW"] if args["SW"] !=None else ""
537 intf = args["INTF"] if args["INTF"] != None else ""
538 command = "py "+ str(sw) + '.attach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -0700539 try:
540 response = self.execute(cmd=command,prompt="mininet>",timeout=10)
541 except pexpect.EOF:
542 main.log.error(self.name + ": EOF exception found")
543 main.log.error(self.name + ": " + self.handle.before)
544 main.cleanup()
545 main.exit()
adminaeedddd2013-08-02 15:14:15 -0700546 return main.TRUE
547
548
549
adminbae64d82013-08-01 10:50:15 -0700550 def dpctl(self,**dpctlargs):
551 '''
Jon Hall41f40e82014-04-08 16:43:17 -0700552 Run dpctl command on all switches.
adminbae64d82013-08-01 10:50:15 -0700553 '''
554 main.log.info('Run dpctl command on all switches')
555 args = utilities.parse_args(["CMD","ARGS"],**dpctlargs)
556 cmd = args["CMD"] if args["CMD"] != None else ""
557 cmdargs = args["ARGS"] if args["ARGS"] != None else ""
558 command = "dpctl "+cmd + " " + str(cmdargs)
Jon Hall6094a362014-04-11 14:46:56 -0700559 try:
560 response = self.execute(cmd=command,prompt="mininet>",timeout=10)
561 except pexpect.EOF:
562 main.log.error(self.name + ": EOF exception found")
563 main.log.error(self.name + ": " + self.handle.before)
564 main.cleanup()
565 main.exit()
adminbae64d82013-08-01 10:50:15 -0700566 return main.TRUE
567
568
569 def get_version(self):
570 file_input = path+'/lib/Mininet/INSTALL'
571 version = super(Mininet, self).get_version()
572 pattern = 'Mininet\s\w\.\w\.\w\w*'
573 for line in open(file_input,'r').readlines():
574 result = re.match(pattern, line)
575 if result:
576 version = result.group(0)
577 return version
578
admin2a9548d2014-06-17 14:08:07 -0700579 def get_sw_controller_sanity(self, sw):
580 command = "sh ovs-vsctl get-controller "+str(sw)
581 try:
582 response = self.execute(cmd=command,prompt="mininet>",timeout=10)
583 if response:
584 return main.TRUE
585 else:
586 return main.FALSE
587 except pexpect.EOF:
588 main.log.error(self.name + ": EOF exception found")
589 main.log.error(self.name + ": " + self.handle.before)
590 main.cleanup()
591 main.exit()
592 else:
593 main.log.info(response)
594
adminbae64d82013-08-01 10:50:15 -0700595 def get_sw_controller(self,sw):
596 command = "sh ovs-vsctl get-controller "+str(sw)
Jon Hall6094a362014-04-11 14:46:56 -0700597 try:
598 response = self.execute(cmd=command,prompt="mininet>",timeout=10)
admin2a9548d2014-06-17 14:08:07 -0700599 print(response)
600 if response:
admindc1c5072014-06-24 15:57:19 -0700601 print("**********************")
admin2a9548d2014-06-17 14:08:07 -0700602 return response
603 else:
604 return main.FALSE
Jon Hall6094a362014-04-11 14:46:56 -0700605 except pexpect.EOF:
606 main.log.error(self.name + ": EOF exception found")
607 main.log.error(self.name + ": " + self.handle.before)
608 main.cleanup()
609 main.exit()
610 else:
611 main.log.info(response)
adminbae64d82013-08-01 10:50:15 -0700612
613 def assign_sw_controller(self,**kwargs):
Jon Hallf89c8552014-04-02 13:14:06 -0700614 '''
615 count is only needed if there is more than 1 controller
616 '''
617 args = utilities.parse_args(["COUNT"],**kwargs)
618 count = args["COUNT"] if args!={} else 1
619
620 argstring = "SW"
621 for j in range(count):
622 argstring = argstring + ",IP" + str(j+1) + ",PORT" + str(j+1)
623 args = utilities.parse_args(argstring.split(","),**kwargs)
624
adminbae64d82013-08-01 10:50:15 -0700625 sw = args["SW"] if args["SW"] != None else ""
admin530b4c92013-08-14 16:54:35 -0700626 ptcpA = int(args["PORT1"])+int(sw) if args["PORT1"] != None else ""
Jon Hallf89c8552014-04-02 13:14:06 -0700627 ptcpB = "ptcp:"+str(ptcpA) if ptcpA != "" else ""
628
629 command = "sh ovs-vsctl set-controller s" + str(sw) + " " + ptcpB + " "
630 for j in range(count):
631 i=j+1
632 args = utilities.parse_args(["IP"+str(i),"PORT"+str(i)],**kwargs)
633 ip = args["IP"+str(i)] if args["IP"+str(i)] != None else ""
634 port = args["PORT" + str(i)] if args["PORT" + str(i)] != None else ""
635 tcp = "tcp:" + str(ip) + ":" + str(port) + " " if ip != "" else ""
636 command = command + tcp
Jon Hall6094a362014-04-11 14:46:56 -0700637 try:
638 self.execute(cmd=command,prompt="mininet>",timeout=5)
639 except pexpect.EOF:
640 main.log.error(self.name + ": EOF exception found")
641 main.log.error(self.name + ": " + self.handle.before)
642 main.cleanup()
643 main.exit()
644 except:
645 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
646 main.log.error( traceback.print_exc() )
647 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
648 main.cleanup()
649 main.exit()
adminbae64d82013-08-01 10:50:15 -0700650
Jon Hall0819fd92014-05-23 12:08:13 -0700651 def delete_sw_controller(self,sw):
652 '''
653 Removes the controller target from sw
654 '''
655
656 command = "sh ovs-vsctl del-controller "+str(sw)
657 try:
658 response = self.execute(cmd=command,prompt="mininet>",timeout=10)
659 except pexpect.EOF:
660 main.log.error(self.name + ": EOF exception found")
661 main.log.error(self.name + ": " + self.handle.before)
662 main.cleanup()
663 main.exit()
664 else:
665 main.log.info(response)
666
667
adminbae64d82013-08-01 10:50:15 -0700668 def disconnect(self):
Jon Hallf2942ce2014-04-10 16:00:16 -0700669 main.log.info(self.name+": Disconnecting mininet...")
adminbae64d82013-08-01 10:50:15 -0700670 response = ''
671 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700672 try:
673 response = self.execute(cmd="exit",prompt="(.*)",timeout=120)
674 response = self.execute(cmd="exit",prompt="(.*)",timeout=120)
Jon Halle80ef8c2014-04-29 15:29:13 -0700675 self.handle.sendline("sudo mn -c")
Jon Hall6094a362014-04-11 14:46:56 -0700676 except pexpect.EOF:
677 main.log.error(self.name + ": EOF exception found")
678 main.log.error(self.name + ": " + self.handle.before)
679 main.cleanup()
680 main.exit()
adminbae64d82013-08-01 10:50:15 -0700681 else :
Jon Hallf2942ce2014-04-10 16:00:16 -0700682 main.log.error(self.name+": Connection failed to the host")
adminbae64d82013-08-01 10:50:15 -0700683 response = main.FALSE
684 return response
admin07529932013-11-22 14:58:28 -0800685
686 def arping(self, src, dest, destmac):
687 self.handle.sendline('')
Jon Hall333fa8c2014-04-11 11:24:58 -0700688 self.handle.expect(["mininet",pexpect.EOF,pexpect.TIMEOUT])
admin07529932013-11-22 14:58:28 -0800689
690 self.handle.sendline(src + ' arping ' + dest)
691 try:
Jon Hall333fa8c2014-04-11 11:24:58 -0700692 self.handle.expect([destmac,pexpect.EOF,pexpect.TIMEOUT])
Jon Hallf2942ce2014-04-10 16:00:16 -0700693 main.log.info(self.name+": ARP successful")
Jon Hall333fa8c2014-04-11 11:24:58 -0700694 self.handle.expect(["mininet",pexpect.EOF,pexpect.TIMEOUT])
admin07529932013-11-22 14:58:28 -0800695 return main.TRUE
696 except:
Jon Hallf2942ce2014-04-10 16:00:16 -0700697 main.log.warn(self.name+": ARP FAILURE")
Jon Hall333fa8c2014-04-11 11:24:58 -0700698 self.handle.expect(["mininet",pexpect.EOF,pexpect.TIMEOUT])
admin07529932013-11-22 14:58:28 -0800699 return main.FALSE
700
701 def decToHex(num):
702 return hex(num).split('x')[1]
admin2a9548d2014-06-17 14:08:07 -0700703
704 def getSwitchFlowCount(self, switch):
705 '''
706 return the Flow Count of the switch
707 '''
708 if self.handle:
709 cmd = "sh ovs-ofctl dump-aggregate %s" % switch
710 try:
711 response = self.execute(cmd=cmd, prompt="mininet>", timeout=10)
712 except pexpect.EOF:
713 main.log.error(self.name + ": EOF exception found")
714 main.log.error(self.name + " " + self.handle.before)
715 main.cleanup()
716 main.exit()
717 pattern = "flow_count=(\d+)"
718 result = re.search(pattern, response, re.MULTILINE)
719 if result is None:
720 print "no flow on switch print test"
721 main.log.info("Couldn't find flows on switch '', found: %s" % (switch, response))
722 return main.FALSE
723 return result.group(1)
724 else:
725 main.log.error("Connection failed to the Mininet host")
726
Ahmed El-Hassanyb6545eb2014-08-01 11:32:10 -0700727 def check_flows(self, sw, dump_format=None):
728 if dump_format:
729 command = "sh ovs-ofctl -F " + dump_format + " dump-flows " + str(sw)
730 else:
731 command = "sh ovs-ofctl dump-flows "+str(sw)
admin2a9548d2014-06-17 14:08:07 -0700732 try:
733 response=self.execute(cmd=command,prompt="mininet>",timeout=10)
734 return response
735 except pexpect.EOF:
736 main.log.error(self.name + ": EOF exception found")
737 main.log.error(self.name + ": " + self.handle.before)
738 main.cleanup()
739 main.exit()
740 else:
741 main.log.info(response)
742
743 def start_tcpdump(self, filename, intf = "eth0", port = "port 6633"):
744 '''
745 Runs tpdump on an intferface and saves the file
746 intf can be specified, or the default eth0 is used
747 '''
748 try:
749 self.handle.sendline("")
750 self.handle.expect("mininet>")
751 self.handle.sendline("sh sudo tcpdump -n -i "+ intf + " " + port + " -w " + filename.strip() + " &")
752 self.handle.sendline("")
753 self.handle.sendline("")
754 i=self.handle.expect(['No\ssuch\device','listening\son',pexpect.TIMEOUT,"mininet>"],timeout=10)
755 main.log.warn(self.handle.before + self.handle.after)
756 if i == 0:
757 main.log.error(self.name + ": tcpdump - No such device exists. tcpdump attempted on: " + intf)
758 return main.FALSE
759 elif i == 1:
760 main.log.info(self.name + ": tcpdump started on " + intf)
761 return main.TRUE
762 elif i == 2:
763 main.log.error(self.name + ": tcpdump command timed out! Check interface name, given interface was: " + intf)
764 return main.FALSE
765 elif i ==3:
766 main.log.info(self.name +": " + self.handle.before)
767 return main.TRUE
768 else:
769 main.log.error(self.name + ": tcpdump - unexpected response")
770 return main.FALSE
771 except pexpect.EOF:
772 main.log.error(self.name + ": EOF exception found")
773 main.log.error(self.name + ": " + self.handle.before)
774 main.cleanup()
775 main.exit()
776 except:
777 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
778 main.log.error( traceback.print_exc() )
779 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
780 main.cleanup()
781 main.exit()
782
783 def stop_tcpdump(self):
784 "pkills tcpdump"
785 try:
786 self.handle.sendline("sh sudo pkill tcpdump")
787 self.handle.sendline("")
788 self.handle.sendline("")
789 self.handle.expect("mininet>")
790 except pexpect.EOF:
791 main.log.error(self.name + ": EOF exception found")
792 main.log.error(self.name + ": " + self.handle.before)
793 main.cleanup()
794 main.exit()
795 except:
796 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
797 main.log.error( traceback.print_exc() )
798 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
799 main.cleanup()
800 main.exit()
801
Jon Hall7c3d1092014-08-11 15:08:31 -0700802 def compare_topo(self, topo, onos_json):
Jon Hall8412ed12014-07-24 16:33:58 -0700803 '''
804 compares mn topology with ONOS topology
805 onos_list is a list of ONOS controllers, each element of the list should be (handle, name, ip, port)
806 onos_json is the output of the onos get_json function calling the /wm/onos/topology REST API
Jon Halle3a74502014-07-25 11:13:16 -0700807 Returns: True if MN and ONOS topology match and False if the differ.
808 Differences between ONOS and MN topology will be printed to the log.
809
810 Dependency: Requires STS to be installed on the TestON machine. STS can be pulled
811 from https://github.com/ucb-sts/sts.git . Currently the required functions from STS are located in the
812 topology_refactoring2 branch, but may be merged into the master branch soon. You may need to install some
813 python modules such as networkx to use the STS functions.
814
Jon Hall38f50122014-08-05 13:16:52 -0700815 To install sts:
816 $ git clone git://github.com/ucb-sts/sts.git
817 $ cd sts
818 $ git clone -b debugger git://github.com/ucb-sts/pox.git
819 $ sudo apt-get install python-dev
820 $ ./tools/install_hassel_python.sh
821 $ sudo pip install networkx
822
823 Include sts in your PYTHONPATH. it should looks comething like:
824 PYTHONPATH=/home/admin/TestON:/home/admin/sts
825
Jon Hall8412ed12014-07-24 16:33:58 -0700826 '''
admin680b78c2014-08-08 11:46:45 -0700827 import sys
828 sys.path.append("~/sts")
Jon Halle9341332014-08-07 10:09:36 -0700829 #NOTE: Create this once per Test and pass the TestONTopology object around. It takes too long to create this object.
830 # This will make it easier to use the sts methods for severing links and solve that issue
Jon Hall0d88a252014-07-25 11:22:40 -0700831 import json
admin2a9548d2014-06-17 14:08:07 -0700832
Jon Hall8412ed12014-07-24 16:33:58 -0700833 link_results = main.TRUE
834 switch_results = main.TRUE
835 port_results = main.TRUE
836
837 ########Switches#######
838 output = {"switches":[]}
Jon Hall0d88a252014-07-25 11:22:40 -0700839 for switch in topo.graph.switches: #iterate through the MN topology and pull out switches and and port info
Jon Hall8412ed12014-07-24 16:33:58 -0700840 ports = []
841 for port in switch.ports.values():
Jon Hall38f50122014-08-05 13:16:52 -0700842 #print port.hw_addr.toStr(separator = '')
843 ports.append({'of_port': port.port_no, 'mac': str(port.hw_addr).replace('\'',''), 'name': port.name})
844 output['switches'].append({"name": switch.name, "dpid": str(switch.dpid).zfill(16), "ports": ports })
Jon Hall8412ed12014-07-24 16:33:58 -0700845 #print output
846
Jon Hall8412ed12014-07-24 16:33:58 -0700847 #print json.dumps(output, sort_keys=True,indent=4,separators=(',', ': '))
848
849
Jon Hall0d88a252014-07-25 11:22:40 -0700850 # created sorted list of dpid's in MN and ONOS for comparison
Jon Hall8412ed12014-07-24 16:33:58 -0700851 mnDPIDs=[]
852 for switch in output['switches']:
853 mnDPIDs.append(switch['dpid'])
854 mnDPIDs.sort()
Jon Halle9341332014-08-07 10:09:36 -0700855 #print mnDPIDs
Jon Hall0d88a252014-07-25 11:22:40 -0700856 if onos_json == "":#if rest call fails
Jon Hall8412ed12014-07-24 16:33:58 -0700857 main.log.error(self.name + ".compare_topo(): Empty JSON object given from ONOS rest call")
858 return main.FALSE
859 onos=onos_json
860 onosDPIDs=[]
861 for switch in onos['switches']:
862 onosDPIDs.append(switch['dpid'].replace(":",''))
863 onosDPIDs.sort()
Jon Halle9341332014-08-07 10:09:36 -0700864 #print onosDPIDs
Jon Hall8412ed12014-07-24 16:33:58 -0700865
866 if mnDPIDs!=onosDPIDs:
867 switch_results = main.FALSE
868 main.log.report( "Switches in MN but not in ONOS:")
869 main.log.report( str([switch for switch in mnDPIDs if switch not in onosDPIDs]))
870 main.log.report( "Switches in ONOS but not in MN:")
871 main.log.report( str([switch for switch in onosDPIDs if switch not in mnDPIDs]))
872 else:#list of dpid's match in onos and mn
873 switch_results = main.TRUE
874
875 ################ports#############
876 for switch in output['switches']:
877 mn_ports = []
878 onos_ports = []
879 for port in switch['ports']:
880 mn_ports.append(port['of_port'])
881 for onos_switch in onos['switches']:
882 if onos_switch['dpid'].replace(':','') == switch['dpid']:
883 for port in onos_switch['ports']:
884 onos_ports.append(port['portNumber'])
885 mn_ports.sort()
886 onos_ports.sort()
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700887 #print "mn_ports[] = ", mn_ports
888 #print "onos_ports90 = ", onos_ports
889
890 #if mn_ports == onos_ports:
891 #pass #don't set results to true here as this is just one of many checks and it might override a failure
892
893 #For OF1.3, the OFP_local port number is 0xfffffffe or 4294967294 instead of 0xfffe or 65534 in OF1.0, ONOS topology
894 #sees the correct port number, however MN topolofy as read from line 151 of https://github.com/ucb-sts/sts/blob/
895 #topology_refactoring2/sts/entities/teston_entities.py is 0xfffe which doesn't work correctly with OF1.3 switches.
896 #So a short term fix is to ignore the case when mn_port == 65534 and onos_port ==4294967294.
897 for mn_port,onos_port in zip(mn_ports,onos_ports):
898 if mn_port == onos_port or (mn_port == 65534 and onos_port ==4294967294):
899 continue
900 else:
901 port_results = main.FALSE
902 break
Jon Hall8412ed12014-07-24 16:33:58 -0700903 pass #don't set results to true here as this is just one of many checks and it might override a failure
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700904 '''
Jon Hall8412ed12014-07-24 16:33:58 -0700905 else: #the ports of this switch don't match
906 port_results = main.FALSE
907 main.log.report("ports in MN switch %s(%s) but not in ONOS:" % (switch['name'],switch['dpid']))
908 main.log.report( str([port for port in mn_ports if port not in onos_ports]))
909 main.log.report("ports in ONOS switch %s(%s) but not in MN:" % (switch['name'],switch['dpid']))
910 main.log.report( str([port for port in onos_ports if port not in mn_ports]))
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700911 '''
912 if port_results == main.FALSE:
913 main.log.report("ports in MN switch %s(%s) but not in ONOS:" % (switch['name'],switch['dpid']))
914 main.log.report( str([port for port in mn_ports if port not in onos_ports]))
915 main.log.report("ports in ONOS switch %s(%s) but not in MN:" % (switch['name'],switch['dpid']))
916 main.log.report( str([port for port in onos_ports if port not in mn_ports]))
Jon Hall8412ed12014-07-24 16:33:58 -0700917
918 #######Links########
Jon Hall0d88a252014-07-25 11:22:40 -0700919 # iterate through MN links and check if and ONOS link exists in both directions
Jon Halle9341332014-08-07 10:09:36 -0700920 # NOTE: Will currently only show mn links as down if they are cut through STS.
921 # We can either do everything through STS or wait for up_network_links
922 # and down_network_links to be fully implemented.
Jon Hall8412ed12014-07-24 16:33:58 -0700923 for link in topo.patch_panel.network_links:
924 #print "Link: %s" % link
925 #TODO: Find a more efficient search method
926 node1 = None
927 port1 = None
928 node2 = None
929 port2 = None
930 first_dir = main.FALSE
931 second_dir = main.FALSE
932 for switch in output['switches']:
933 if switch['name'] == link.node1.name:
934 node1 = switch['dpid']
935 for port in switch['ports']:
936 if str(port['name']) == str(link.port1):
937 port1 = port['of_port']
938 if node1 is not None and node2 is not None:
939 break
940 if switch['name'] == link.node2.name:
941 node2 = switch['dpid']
942 for port in switch['ports']:
943 if str(port['name']) == str(link.port2):
944 port2 = port['of_port']
945 if node1 is not None and node2 is not None:
946 break
947 # check onos link from node1 to node2
948 for onos_link in onos['links']:
949 if onos_link['src']['dpid'].replace(":",'') == node1 and onos_link['dst']['dpid'].replace(":",'') == node2:
950 if onos_link['src']['portNumber'] == port1 and onos_link['dst']['portNumber'] == port2:
951 first_dir = main.TRUE
952 else:
953 main.log.report('the port numbers do not match for ' +str(link) + ' between ONOS and MN')
954 #print node1, ' to ', node2
955 elif onos_link['src']['dpid'].replace(":",'') == node2 and onos_link['dst']['dpid'].replace(":",'') == node1:
956 if onos_link['src']['portNumber'] == port2 and onos_link['dst']['portNumber'] == port1:
957 second_dir = main.TRUE
958 else:
959 main.log.report('the port numbers do not match for ' +str(link) + ' between ONOS and MN')
960 #print node2, ' to ', node1
961 else:#this is not the link you're looking for
962 pass
963 if not first_dir:
964 main.log.report('ONOS has issues with the link from '+str(link.node1.name) +"(dpid: "+ str(node1)+"):"+str(link.port1)+"(portNumber: "+str(port1)+")"+ ' to ' + str(link.node2.name) +"(dpid: "+ str(node2)+"):"+str(link.port2)+"(portNumber: "+str(port2)+")")
965 if not second_dir:
966 main.log.report('ONOS has issues with the link from '+str(link.node2.name) +"(dpid: "+ str(node2)+"):"+str(link.port2)+"(portNumber: "+str(port2)+")"+ ' to ' + str(link.node1.name) +"(dpid: "+ str(node1)+"):"+str(link.port1)+"(portNumber: "+str(port1)+")")
967 link_results = link_results and first_dir and second_dir
968
969
970 results = switch_results and port_results and link_results
Jon Halle9341332014-08-07 10:09:36 -0700971# if not results: #To print out both topologies
972# main.log.error("Topology comparison failed, printing json objects, MN then ONOS")
973# main.log.error(str(json.dumps(output, sort_keys=True,indent=4,separators=(',', ': '))))
974# main.log.error('MN Links:')
975# for link in topo.patch_panel.network_links: main.log.error(str("\tLink: %s" % link))
976# main.log.error(str(json.dumps(onos, sort_keys=True,indent=4,separators=(',', ': '))))
Jon Hall8412ed12014-07-24 16:33:58 -0700977 return results
admin2a9548d2014-06-17 14:08:07 -0700978
979
980
981
adminbae64d82013-08-01 10:50:15 -0700982
983if __name__ != "__main__":
984 import sys
985 sys.modules[__name__] = MininetCliDriver()
admin2a9548d2014-06-17 14:08:07 -0700986