blob: 9c48e32edf3dbd6a800aefef485a62239fee89b2 [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'
Jon Hallf2942ce2014-04-10 16:00:16 -0700166 #if utilities.assert_matches(expect=pattern,actual=response,onpass="All hosts are reaching",onfail="Unable to reach all the hosts"):
167 if re.search(pattern,response):
168 main.log.info(self.name+": All hosts are reachable")
adminbae64d82013-08-01 10:50:15 -0700169 return main.TRUE
170 else:
Jon Hallf2942ce2014-04-10 16:00:16 -0700171 main.log.error(self.name+": Unable to reach all the hosts")
adminbae64d82013-08-01 10:50:15 -0700172 return main.FALSE
173 else :
Jon Hallf2942ce2014-04-10 16:00:16 -0700174 main.log.error(self.name+": Connection failed to the host")
adminbae64d82013-08-01 10:50:15 -0700175 return main.FALSE
adminaeedddd2013-08-02 15:14:15 -0700176
177 def fpingHost(self,**pingParams):
178 '''
179 Uses the fping package for faster pinging...
180 *requires fping to be installed on machine running mininet
181 '''
182 args = utilities.parse_args(["SRC","TARGET"],**pingParams)
admin530b4c92013-08-14 16:54:35 -0700183 command = args["SRC"] + " fping -i 100 -t 20 -C 1 -q "+args["TARGET"]
adminaeedddd2013-08-02 15:14:15 -0700184 self.handle.sendline(command)
Jon Hall333fa8c2014-04-11 11:24:58 -0700185 self.handle.expect([args["TARGET"],pexpect.EOF,pexpect.TIMEOUT])
186 self.handle.expect(["mininet",pexpect.EOF,pexpect.TIMEOUT])
adminaeedddd2013-08-02 15:14:15 -0700187 response = self.handle.before
188 if re.search(":\s-" ,response):
Jon Hallf2942ce2014-04-10 16:00:16 -0700189 main.log.info(self.name+": Ping fail")
adminaeedddd2013-08-02 15:14:15 -0700190 return main.FALSE
admin530b4c92013-08-14 16:54:35 -0700191 elif re.search(":\s\d{1,2}\.\d\d", response):
Jon Hallf2942ce2014-04-10 16:00:16 -0700192 main.log.info(self.name+": Ping good!")
adminaeedddd2013-08-02 15:14:15 -0700193 return main.TRUE
Jon Hallf2942ce2014-04-10 16:00:16 -0700194 main.log.info(self.name+": Install fping on mininet machine... ")
195 main.log.info(self.name+": \n---\n"+response)
adminaeedddd2013-08-02 15:14:15 -0700196 return main.FALSE
adminbae64d82013-08-01 10:50:15 -0700197
198 def pingHost(self,**pingParams):
Jon Hallf2942ce2014-04-10 16:00:16 -0700199 '''
200 Ping from one mininet host to another
201 Currently the only supported Params: SRC and TARGET
202 '''
adminbae64d82013-08-01 10:50:15 -0700203 args = utilities.parse_args(["SRC","TARGET"],**pingParams)
204 #command = args["SRC"] + " ping -" + args["CONTROLLER"] + " " +args ["TARGET"]
Jon Hall0819fd92014-05-23 12:08:13 -0700205 command = args["SRC"] + " ping "+args ["TARGET"]+" -c 1 -i 1 -W 8"
Jon Hall6094a362014-04-11 14:46:56 -0700206 try:
Jon Hall6e18c7b2014-04-23 16:26:33 -0700207 main.log.warn("Sending: " + command)
208 #response = self.execute(cmd=command,prompt="mininet",timeout=10 )
209 self.handle.sendline(command)
210 i = self.handle.expect([command,pexpect.TIMEOUT])
211 if i == 1:
212 main.log.error(self.name + ": timeout when waiting for response from mininet")
213 main.log.error("response: " + str(self.handle.before))
214 i = self.handle.expect(["mininet>",pexpect.TIMEOUT])
215 if i == 1:
216 main.log.error(self.name + ": timeout when waiting for response from mininet")
217 main.log.error("response: " + str(self.handle.before))
218 response = self.handle.before
Jon Hall6094a362014-04-11 14:46:56 -0700219 except pexpect.EOF:
220 main.log.error(self.name + ": EOF exception found")
221 main.log.error(self.name + ": " + self.handle.before)
222 main.cleanup()
223 main.exit()
Jon Hallf2942ce2014-04-10 16:00:16 -0700224 main.log.info(self.name+": Ping Response: "+ response )
225 #if utilities.assert_matches(expect=',\s0\%\spacket\sloss',actual=response,onpass="No Packet loss",onfail="Host is not reachable"):
226 if re.search(',\s0\%\spacket\sloss',response):
Jon Hall6e18c7b2014-04-23 16:26:33 -0700227 main.log.info(self.name+": no packets lost, host is reachable")
adminbae64d82013-08-01 10:50:15 -0700228 main.last_result = main.TRUE
229 return main.TRUE
230 else :
Jon Hallf2942ce2014-04-10 16:00:16 -0700231 main.log.error(self.name+": PACKET LOST, HOST IS NOT REACHABLE")
adminbae64d82013-08-01 10:50:15 -0700232 main.last_result = main.FALSE
233 return main.FALSE
adminbae64d82013-08-01 10:50:15 -0700234
235 def checkIP(self,host):
236 '''
Jon Hall41f40e82014-04-08 16:43:17 -0700237 Verifies the host's ip configured or not.
adminbae64d82013-08-01 10:50:15 -0700238 '''
239 if self.handle :
Jon Hall6094a362014-04-11 14:46:56 -0700240 try:
241 response = self.execute(cmd=host+" ifconfig",prompt="mininet>",timeout=10)
242 except pexpect.EOF:
243 main.log.error(self.name + ": EOF exception found")
244 main.log.error(self.name + ": " + self.handle.before)
245 main.cleanup()
246 main.exit()
adminbae64d82013-08-01 10:50:15 -0700247
248 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 -0700249 #pattern = "inet addr:10.0.0.6"
Jon Hallf2942ce2014-04-10 16:00:16 -0700250 #if utilities.assert_matches(expect=pattern,actual=response,onpass="Host Ip configured properly",onfail="Host IP not found") :
251 if re.search(pattern,response):
252 main.log.info(self.name+": Host Ip configured properly")
adminbae64d82013-08-01 10:50:15 -0700253 return main.TRUE
254 else:
Jon Hallf2942ce2014-04-10 16:00:16 -0700255 main.log.error(self.name+": Host IP not found")
adminbae64d82013-08-01 10:50:15 -0700256 return main.FALSE
257 else :
Jon Hallf2942ce2014-04-10 16:00:16 -0700258 main.log.error(self.name+": Connection failed to the host")
adminbae64d82013-08-01 10:50:15 -0700259
260 def verifySSH(self,**connectargs):
Jon Hall6094a362014-04-11 14:46:56 -0700261 try:
262 response = self.execute(cmd="h1 /usr/sbin/sshd -D&",prompt="mininet>",timeout=10)
263 response = self.execute(cmd="h4 /usr/sbin/sshd -D&",prompt="mininet>",timeout=10)
264 for key in connectargs:
265 vars(self)[key] = connectargs[key]
266 response = self.execute(cmd="xterm h1 h4 ",prompt="mininet>",timeout=10)
267 except pexpect.EOF:
268 main.log.error(self.name + ": EOF exception found")
269 main.log.error(self.name + ": " + self.handle.before)
270 main.cleanup()
271 main.exit()
adminbae64d82013-08-01 10:50:15 -0700272 import time
273 time.sleep(20)
274 if self.flag == 0:
275 self.flag = 1
276 return main.FALSE
277 else :
278 return main.TRUE
279
280 def getMacAddress(self,host):
281 '''
Jon Hall41f40e82014-04-08 16:43:17 -0700282 Verifies the host's ip configured or not.
adminbae64d82013-08-01 10:50:15 -0700283 '''
284 if self.handle :
Jon Hall6094a362014-04-11 14:46:56 -0700285 try:
286 response = self.execute(cmd=host+" ifconfig",prompt="mininet>",timeout=10)
287 except pexpect.EOF:
288 main.log.error(self.name + ": EOF exception found")
289 main.log.error(self.name + ": " + self.handle.before)
290 main.cleanup()
291 main.exit()
adminbae64d82013-08-01 10:50:15 -0700292
Ahmed El-Hassanyf720e202014-04-04 16:11:36 -0700293 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
294 mac_address_search = re.search(pattern, response, re.I)
295 mac_address = mac_address_search.group().split(" ")[1]
Jon Hallf2942ce2014-04-10 16:00:16 -0700296 main.log.info(self.name+": Mac-Address of Host "+ host + " is " + mac_address)
Ahmed El-Hassanyf720e202014-04-04 16:11:36 -0700297 return mac_address
adminbae64d82013-08-01 10:50:15 -0700298 else :
Jon Hallf2942ce2014-04-10 16:00:16 -0700299 main.log.error(self.name+": Connection failed to the host")
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700300
301 def getInterfaceMACAddress(self,host, interface):
302 '''
303 Return the IP address of the interface on the given host
304 '''
305 if self.handle :
Jon Hall6094a362014-04-11 14:46:56 -0700306 try:
307 response = self.execute(cmd=host+" ifconfig " + interface,
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700308 prompt="mininet>",timeout=10)
Jon Hall6094a362014-04-11 14:46:56 -0700309 except pexpect.EOF:
310 main.log.error(self.name + ": EOF exception found")
311 main.log.error(self.name + ": " + self.handle.before)
312 main.cleanup()
313 main.exit()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700314
315 pattern = r'HWaddr\s([0-9A-F]{2}[:-]){5}([0-9A-F]{2})'
316 mac_address_search = re.search(pattern, response, re.I)
317 if mac_address_search is None:
318 main.log.info("No mac address found in %s" % response)
319 return main.FALSE
320 mac_address = mac_address_search.group().split(" ")[1]
321 main.log.info("Mac-Address of "+ host + ":"+ interface + " is " + mac_address)
322 return mac_address
323 else:
324 main.log.error("Connection failed to the host")
325
adminbae64d82013-08-01 10:50:15 -0700326 def getIPAddress(self,host):
327 '''
Jon Hall41f40e82014-04-08 16:43:17 -0700328 Verifies the host's ip configured or not.
adminbae64d82013-08-01 10:50:15 -0700329 '''
330 if self.handle :
Jon Hall6094a362014-04-11 14:46:56 -0700331 try:
332 response = self.execute(cmd=host+" ifconfig",prompt="mininet>",timeout=10)
333 except pexpect.EOF:
334 main.log.error(self.name + ": EOF exception found")
335 main.log.error(self.name + ": " + self.handle.before)
336 main.cleanup()
337 main.exit()
adminbae64d82013-08-01 10:50:15 -0700338
339 pattern = "inet\saddr:(\d+\.\d+\.\d+\.\d+)"
340 ip_address_search = re.search(pattern, response)
Jon Hallf2942ce2014-04-10 16:00:16 -0700341 main.log.info(self.name+": IP-Address of Host "+host +" is "+ip_address_search.group(1))
adminbae64d82013-08-01 10:50:15 -0700342 return ip_address_search.group(1)
343 else :
Jon Hallf2942ce2014-04-10 16:00:16 -0700344 main.log.error(self.name+": Connection failed to the host")
adminbae64d82013-08-01 10:50:15 -0700345
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700346 def getSwitchDPID(self,switch):
347 '''
348 return the datapath ID of the switch
349 '''
350 if self.handle :
351 cmd = "py %s.dpid" % switch
Jon Hall6094a362014-04-11 14:46:56 -0700352 try:
353 response = self.execute(cmd=cmd,prompt="mininet>",timeout=10)
354 except pexpect.EOF:
355 main.log.error(self.name + ": EOF exception found")
356 main.log.error(self.name + ": " + self.handle.before)
357 main.cleanup()
358 main.exit()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700359 pattern = r'^(?P<dpid>\d)+'
360 result = re.search(pattern, response, re.MULTILINE)
361 if result is None:
362 main.log.info("Couldn't find DPID for switch '', found: %s" % (switch, response))
363 return main.FALSE
Jon Hallc1a1d242014-07-21 16:03:33 -0700364 return str(result.group(0))
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700365 else:
366 main.log.error("Connection failed to the host")
367
admin2580a0e2014-07-29 11:24:34 -0700368 def getDPID(self, switch):
369 if self.handle:
370 self.handle.sendline("")
371 self.expect("mininet>")
372 cmd = "py %s.dpid" %switch
373 try:
374 response = self.execute(cmd=cmd,prompt="mininet>",timeout=10)
375 self.handle.expect("mininet>")
376 response = self.handle.before
377 return response
378 except pexpect.EOF:
379 main.log.error(self.name + ": EOF exception found")
380 main.log.error(self.name + ": " + self.handle.before)
381 main.cleanup()
382 main.exit()
383
384
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700385 def getInterfaces(self, node):
386 '''
387 return information dict about interfaces connected to the node
388 '''
389 if self.handle :
390 cmd = 'py "\\n".join(["name=%s,mac=%s,ip=%s,isUp=%s" % (i.name, i.MAC(), i.IP(), i.isUp())'
391 cmd += ' for i in %s.intfs.values()])' % node
Jon Hall6094a362014-04-11 14:46:56 -0700392 try:
393 response = self.execute(cmd=cmd,prompt="mininet>",timeout=10)
394 except pexpect.EOF:
395 main.log.error(self.name + ": EOF exception found")
396 main.log.error(self.name + ": " + self.handle.before)
397 main.cleanup()
398 main.exit()
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700399 return response
400 else:
401 main.log.error("Connection failed to the node")
402
adminbae64d82013-08-01 10:50:15 -0700403 def dump(self):
Jon Hallf2942ce2014-04-10 16:00:16 -0700404 main.log.info(self.name+": Dump node info")
Jon Hall6094a362014-04-11 14:46:56 -0700405 try:
406 response = self.execute(cmd = 'dump',prompt = 'mininet>',timeout = 10)
407 except pexpect.EOF:
408 main.log.error(self.name + ": EOF exception found")
409 main.log.error(self.name + ": " + self.handle.before)
410 main.cleanup()
411 main.exit()
Ahmed El-Hassanyd1f71702014-04-04 16:12:45 -0700412 return response
adminbae64d82013-08-01 10:50:15 -0700413
414 def intfs(self):
Jon Hallf2942ce2014-04-10 16:00:16 -0700415 main.log.info(self.name+": List interfaces")
Jon Hall6094a362014-04-11 14:46:56 -0700416 try:
417 response = self.execute(cmd = 'intfs',prompt = 'mininet>',timeout = 10)
418 except pexpect.EOF:
419 main.log.error(self.name + ": EOF exception found")
420 main.log.error(self.name + ": " + self.handle.before)
421 main.cleanup()
422 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700423 return response
adminbae64d82013-08-01 10:50:15 -0700424
425 def net(self):
Jon Hallf2942ce2014-04-10 16:00:16 -0700426 main.log.info(self.name+": List network connections")
Jon Hall6094a362014-04-11 14:46:56 -0700427 try:
428 response = self.execute(cmd = 'net',prompt = 'mininet>',timeout = 10)
429 except pexpect.EOF:
430 main.log.error(self.name + ": EOF exception found")
431 main.log.error(self.name + ": " + self.handle.before)
432 main.cleanup()
433 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700434 return response
adminbae64d82013-08-01 10:50:15 -0700435
436 def iperf(self):
Jon Hallf2942ce2014-04-10 16:00:16 -0700437 main.log.info(self.name+": Simple iperf TCP test between two (optionally specified) hosts")
Jon Hall6094a362014-04-11 14:46:56 -0700438 try:
439 response = self.execute(cmd = 'iperf',prompt = 'mininet>',timeout = 10)
440 except pexpect.EOF:
441 main.log.error(self.name + ": EOF exception found")
442 main.log.error(self.name + ": " + self.handle.before)
443 main.cleanup()
444 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700445 return response
adminbae64d82013-08-01 10:50:15 -0700446
447 def iperfudp(self):
Jon Hallf2942ce2014-04-10 16:00:16 -0700448 main.log.info(self.name+": Simple iperf TCP test between two (optionally specified) hosts")
Jon Hall6094a362014-04-11 14:46:56 -0700449 try:
450 response = self.execute(cmd = 'iperfudp',prompt = 'mininet>',timeout = 10)
451 except pexpect.EOF:
452 main.log.error(self.name + ": EOF exception found")
453 main.log.error(self.name + ": " + self.handle.before)
454 main.cleanup()
455 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700456 return response
adminbae64d82013-08-01 10:50:15 -0700457
458 def nodes(self):
Jon Hallf2942ce2014-04-10 16:00:16 -0700459 main.log.info(self.name+": List all nodes.")
Jon Hall6094a362014-04-11 14:46:56 -0700460 try:
461 response = self.execute(cmd = 'nodes',prompt = 'mininet>',timeout = 10)
462 except pexpect.EOF:
463 main.log.error(self.name + ": EOF exception found")
464 main.log.error(self.name + ": " + self.handle.before)
465 main.cleanup()
466 main.exit()
Jon Hall668ed802014-04-08 17:17:59 -0700467 return response
adminbae64d82013-08-01 10:50:15 -0700468
469 def pingpair(self):
Jon Hallf2942ce2014-04-10 16:00:16 -0700470 main.log.info(self.name+": Ping between first two hosts")
Jon Hall6094a362014-04-11 14:46:56 -0700471 try:
472 response = self.execute(cmd = 'pingpair',prompt = 'mininet>',timeout = 20)
473 except pexpect.EOF:
474 main.log.error(self.name + ": EOF exception found")
475 main.log.error(self.name + ": " + self.handle.before)
476 main.cleanup()
477 main.exit()
adminbae64d82013-08-01 10:50:15 -0700478
Jon Hallf2942ce2014-04-10 16:00:16 -0700479 #if utilities.assert_matches(expect='0% packet loss',actual=response,onpass="No Packet loss",onfail="Hosts not reachable"):
480 if re.search(',\s0\%\spacket\sloss',response):
481 main.log.info(self.name+": Ping between two hosts SUCCESSFUL")
adminbae64d82013-08-01 10:50:15 -0700482 main.last_result = main.TRUE
483 return main.TRUE
484 else :
Jon Hallf2942ce2014-04-10 16:00:16 -0700485 main.log.error(self.name+": PACKET LOST, HOSTS NOT REACHABLE")
adminbae64d82013-08-01 10:50:15 -0700486 main.last_result = main.FALSE
487 return main.FALSE
488
489 def link(self,**linkargs):
490 '''
491 Bring link(s) between two nodes up or down
492 '''
493 main.log.info('Bring link(s) between two nodes up or down')
494 args = utilities.parse_args(["END1","END2","OPTION"],**linkargs)
495 end1 = args["END1"] if args["END1"] != None else ""
496 end2 = args["END2"] if args["END2"] != None else ""
497 option = args["OPTION"] if args["OPTION"] != None else ""
498 command = "link "+str(end1) + " " + str(end2)+ " " + str(option)
Jon Hall6094a362014-04-11 14:46:56 -0700499 try:
Jon Halle80ef8c2014-04-29 15:29:13 -0700500 #response = self.execute(cmd=command,prompt="mininet>",timeout=10)
501 self.handle.sendline(command)
502 self.handle.expect("mininet>")
Jon Hall6094a362014-04-11 14:46:56 -0700503 except pexpect.EOF:
504 main.log.error(self.name + ": EOF exception found")
505 main.log.error(self.name + ": " + self.handle.before)
506 main.cleanup()
507 main.exit()
adminbae64d82013-08-01 10:50:15 -0700508 return main.TRUE
509
510
admin530b4c92013-08-14 16:54:35 -0700511 def yank(self,**yankargs):
adminaeedddd2013-08-02 15:14:15 -0700512 '''
admin530b4c92013-08-14 16:54:35 -0700513 yank a mininet switch interface to a host
adminaeedddd2013-08-02 15:14:15 -0700514 '''
admin530b4c92013-08-14 16:54:35 -0700515 main.log.info('Yank the switch interface attached to a host')
516 args = utilities.parse_args(["SW","INTF"],**yankargs)
adminaeedddd2013-08-02 15:14:15 -0700517 sw = args["SW"] if args["SW"] !=None else ""
518 intf = args["INTF"] if args["INTF"] != None else ""
519 command = "py "+ str(sw) + '.detach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -0700520 try:
521 response = self.execute(cmd=command,prompt="mininet>",timeout=10)
522 except pexpect.EOF:
523 main.log.error(self.name + ": EOF exception found")
524 main.log.error(self.name + ": " + self.handle.before)
525 main.cleanup()
526 main.exit()
adminaeedddd2013-08-02 15:14:15 -0700527 return main.TRUE
528
529 def plug(self, **plugargs):
530 '''
531 plug the yanked mininet switch interface to a switch
532 '''
533 main.log.info('Plug the switch interface attached to a switch')
admin530b4c92013-08-14 16:54:35 -0700534 args = utilities.parse_args(["SW","INTF"],**plugargs)
adminaeedddd2013-08-02 15:14:15 -0700535 sw = args["SW"] if args["SW"] !=None else ""
536 intf = args["INTF"] if args["INTF"] != None else ""
537 command = "py "+ str(sw) + '.attach("' + str(intf) + '")'
Jon Hall6094a362014-04-11 14:46:56 -0700538 try:
539 response = self.execute(cmd=command,prompt="mininet>",timeout=10)
540 except pexpect.EOF:
541 main.log.error(self.name + ": EOF exception found")
542 main.log.error(self.name + ": " + self.handle.before)
543 main.cleanup()
544 main.exit()
adminaeedddd2013-08-02 15:14:15 -0700545 return main.TRUE
546
547
548
adminbae64d82013-08-01 10:50:15 -0700549 def dpctl(self,**dpctlargs):
550 '''
Jon Hall41f40e82014-04-08 16:43:17 -0700551 Run dpctl command on all switches.
adminbae64d82013-08-01 10:50:15 -0700552 '''
553 main.log.info('Run dpctl command on all switches')
554 args = utilities.parse_args(["CMD","ARGS"],**dpctlargs)
555 cmd = args["CMD"] if args["CMD"] != None else ""
556 cmdargs = args["ARGS"] if args["ARGS"] != None else ""
557 command = "dpctl "+cmd + " " + str(cmdargs)
Jon Hall6094a362014-04-11 14:46:56 -0700558 try:
559 response = self.execute(cmd=command,prompt="mininet>",timeout=10)
560 except pexpect.EOF:
561 main.log.error(self.name + ": EOF exception found")
562 main.log.error(self.name + ": " + self.handle.before)
563 main.cleanup()
564 main.exit()
adminbae64d82013-08-01 10:50:15 -0700565 return main.TRUE
566
567
568 def get_version(self):
569 file_input = path+'/lib/Mininet/INSTALL'
570 version = super(Mininet, self).get_version()
571 pattern = 'Mininet\s\w\.\w\.\w\w*'
572 for line in open(file_input,'r').readlines():
573 result = re.match(pattern, line)
574 if result:
575 version = result.group(0)
576 return version
577
admin2a9548d2014-06-17 14:08:07 -0700578 def get_sw_controller_sanity(self, sw):
579 command = "sh ovs-vsctl get-controller "+str(sw)
580 try:
581 response = self.execute(cmd=command,prompt="mininet>",timeout=10)
582 if response:
583 return main.TRUE
584 else:
585 return main.FALSE
586 except pexpect.EOF:
587 main.log.error(self.name + ": EOF exception found")
588 main.log.error(self.name + ": " + self.handle.before)
589 main.cleanup()
590 main.exit()
591 else:
592 main.log.info(response)
593
adminbae64d82013-08-01 10:50:15 -0700594 def get_sw_controller(self,sw):
595 command = "sh ovs-vsctl get-controller "+str(sw)
Jon Hall6094a362014-04-11 14:46:56 -0700596 try:
597 response = self.execute(cmd=command,prompt="mininet>",timeout=10)
admin2a9548d2014-06-17 14:08:07 -0700598 print(response)
599 if response:
admindc1c5072014-06-24 15:57:19 -0700600 print("**********************")
admin2a9548d2014-06-17 14:08:07 -0700601 return response
602 else:
603 return main.FALSE
Jon Hall6094a362014-04-11 14:46:56 -0700604 except pexpect.EOF:
605 main.log.error(self.name + ": EOF exception found")
606 main.log.error(self.name + ": " + self.handle.before)
607 main.cleanup()
608 main.exit()
609 else:
610 main.log.info(response)
adminbae64d82013-08-01 10:50:15 -0700611
612 def assign_sw_controller(self,**kwargs):
Jon Hallf89c8552014-04-02 13:14:06 -0700613 '''
614 count is only needed if there is more than 1 controller
615 '''
616 args = utilities.parse_args(["COUNT"],**kwargs)
617 count = args["COUNT"] if args!={} else 1
618
619 argstring = "SW"
620 for j in range(count):
621 argstring = argstring + ",IP" + str(j+1) + ",PORT" + str(j+1)
622 args = utilities.parse_args(argstring.split(","),**kwargs)
623
adminbae64d82013-08-01 10:50:15 -0700624 sw = args["SW"] if args["SW"] != None else ""
admin530b4c92013-08-14 16:54:35 -0700625 ptcpA = int(args["PORT1"])+int(sw) if args["PORT1"] != None else ""
Jon Hallf89c8552014-04-02 13:14:06 -0700626 ptcpB = "ptcp:"+str(ptcpA) if ptcpA != "" else ""
627
628 command = "sh ovs-vsctl set-controller s" + str(sw) + " " + ptcpB + " "
629 for j in range(count):
630 i=j+1
631 args = utilities.parse_args(["IP"+str(i),"PORT"+str(i)],**kwargs)
632 ip = args["IP"+str(i)] if args["IP"+str(i)] != None else ""
633 port = args["PORT" + str(i)] if args["PORT" + str(i)] != None else ""
634 tcp = "tcp:" + str(ip) + ":" + str(port) + " " if ip != "" else ""
635 command = command + tcp
Jon Hall6094a362014-04-11 14:46:56 -0700636 try:
637 self.execute(cmd=command,prompt="mininet>",timeout=5)
638 except pexpect.EOF:
639 main.log.error(self.name + ": EOF exception found")
640 main.log.error(self.name + ": " + self.handle.before)
641 main.cleanup()
642 main.exit()
643 except:
644 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
645 main.log.error( traceback.print_exc() )
646 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
647 main.cleanup()
648 main.exit()
adminbae64d82013-08-01 10:50:15 -0700649
Jon Hall0819fd92014-05-23 12:08:13 -0700650 def delete_sw_controller(self,sw):
651 '''
652 Removes the controller target from sw
653 '''
654
655 command = "sh ovs-vsctl del-controller "+str(sw)
656 try:
657 response = self.execute(cmd=command,prompt="mininet>",timeout=10)
658 except pexpect.EOF:
659 main.log.error(self.name + ": EOF exception found")
660 main.log.error(self.name + ": " + self.handle.before)
661 main.cleanup()
662 main.exit()
663 else:
664 main.log.info(response)
665
666
adminbae64d82013-08-01 10:50:15 -0700667 def disconnect(self):
Jon Hallf2942ce2014-04-10 16:00:16 -0700668 main.log.info(self.name+": Disconnecting mininet...")
adminbae64d82013-08-01 10:50:15 -0700669 response = ''
670 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700671 try:
672 response = self.execute(cmd="exit",prompt="(.*)",timeout=120)
673 response = self.execute(cmd="exit",prompt="(.*)",timeout=120)
Jon Halle80ef8c2014-04-29 15:29:13 -0700674 self.handle.sendline("sudo mn -c")
Jon Hall6094a362014-04-11 14:46:56 -0700675 except pexpect.EOF:
676 main.log.error(self.name + ": EOF exception found")
677 main.log.error(self.name + ": " + self.handle.before)
678 main.cleanup()
679 main.exit()
adminbae64d82013-08-01 10:50:15 -0700680 else :
Jon Hallf2942ce2014-04-10 16:00:16 -0700681 main.log.error(self.name+": Connection failed to the host")
adminbae64d82013-08-01 10:50:15 -0700682 response = main.FALSE
683 return response
admin07529932013-11-22 14:58:28 -0800684
685 def arping(self, src, dest, destmac):
686 self.handle.sendline('')
Jon Hall333fa8c2014-04-11 11:24:58 -0700687 self.handle.expect(["mininet",pexpect.EOF,pexpect.TIMEOUT])
admin07529932013-11-22 14:58:28 -0800688
689 self.handle.sendline(src + ' arping ' + dest)
690 try:
Jon Hall333fa8c2014-04-11 11:24:58 -0700691 self.handle.expect([destmac,pexpect.EOF,pexpect.TIMEOUT])
Jon Hallf2942ce2014-04-10 16:00:16 -0700692 main.log.info(self.name+": ARP successful")
Jon Hall333fa8c2014-04-11 11:24:58 -0700693 self.handle.expect(["mininet",pexpect.EOF,pexpect.TIMEOUT])
admin07529932013-11-22 14:58:28 -0800694 return main.TRUE
695 except:
Jon Hallf2942ce2014-04-10 16:00:16 -0700696 main.log.warn(self.name+": ARP FAILURE")
Jon Hall333fa8c2014-04-11 11:24:58 -0700697 self.handle.expect(["mininet",pexpect.EOF,pexpect.TIMEOUT])
admin07529932013-11-22 14:58:28 -0800698 return main.FALSE
699
700 def decToHex(num):
701 return hex(num).split('x')[1]
admin2a9548d2014-06-17 14:08:07 -0700702
703 def getSwitchFlowCount(self, switch):
704 '''
705 return the Flow Count of the switch
706 '''
707 if self.handle:
708 cmd = "sh ovs-ofctl dump-aggregate %s" % switch
709 try:
710 response = self.execute(cmd=cmd, prompt="mininet>", timeout=10)
711 except pexpect.EOF:
712 main.log.error(self.name + ": EOF exception found")
713 main.log.error(self.name + " " + self.handle.before)
714 main.cleanup()
715 main.exit()
716 pattern = "flow_count=(\d+)"
717 result = re.search(pattern, response, re.MULTILINE)
718 if result is None:
719 print "no flow on switch print test"
720 main.log.info("Couldn't find flows on switch '', found: %s" % (switch, response))
721 return main.FALSE
722 return result.group(1)
723 else:
724 main.log.error("Connection failed to the Mininet host")
725
Ahmed El-Hassanyb6545eb2014-08-01 11:32:10 -0700726 def check_flows(self, sw, dump_format=None):
727 if dump_format:
728 command = "sh ovs-ofctl -F " + dump_format + " dump-flows " + str(sw)
729 else:
730 command = "sh ovs-ofctl dump-flows "+str(sw)
admin2a9548d2014-06-17 14:08:07 -0700731 try:
732 response=self.execute(cmd=command,prompt="mininet>",timeout=10)
733 return response
734 except pexpect.EOF:
735 main.log.error(self.name + ": EOF exception found")
736 main.log.error(self.name + ": " + self.handle.before)
737 main.cleanup()
738 main.exit()
739 else:
740 main.log.info(response)
741
742 def start_tcpdump(self, filename, intf = "eth0", port = "port 6633"):
743 '''
744 Runs tpdump on an intferface and saves the file
745 intf can be specified, or the default eth0 is used
746 '''
747 try:
748 self.handle.sendline("")
749 self.handle.expect("mininet>")
750 self.handle.sendline("sh sudo tcpdump -n -i "+ intf + " " + port + " -w " + filename.strip() + " &")
751 self.handle.sendline("")
752 self.handle.sendline("")
753 i=self.handle.expect(['No\ssuch\device','listening\son',pexpect.TIMEOUT,"mininet>"],timeout=10)
754 main.log.warn(self.handle.before + self.handle.after)
755 if i == 0:
756 main.log.error(self.name + ": tcpdump - No such device exists. tcpdump attempted on: " + intf)
757 return main.FALSE
758 elif i == 1:
759 main.log.info(self.name + ": tcpdump started on " + intf)
760 return main.TRUE
761 elif i == 2:
762 main.log.error(self.name + ": tcpdump command timed out! Check interface name, given interface was: " + intf)
763 return main.FALSE
764 elif i ==3:
765 main.log.info(self.name +": " + self.handle.before)
766 return main.TRUE
767 else:
768 main.log.error(self.name + ": tcpdump - unexpected response")
769 return main.FALSE
770 except pexpect.EOF:
771 main.log.error(self.name + ": EOF exception found")
772 main.log.error(self.name + ": " + self.handle.before)
773 main.cleanup()
774 main.exit()
775 except:
776 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
777 main.log.error( traceback.print_exc() )
778 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
779 main.cleanup()
780 main.exit()
781
782 def stop_tcpdump(self):
783 "pkills tcpdump"
784 try:
785 self.handle.sendline("sh sudo pkill tcpdump")
786 self.handle.sendline("")
787 self.handle.sendline("")
788 self.handle.expect("mininet>")
789 except pexpect.EOF:
790 main.log.error(self.name + ": EOF exception found")
791 main.log.error(self.name + ": " + self.handle.before)
792 main.cleanup()
793 main.exit()
794 except:
795 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
796 main.log.error( traceback.print_exc() )
797 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
798 main.cleanup()
799 main.exit()
800
Jon Hall3d87d502014-10-17 18:37:42 -0400801 def compare_switches(self, topo, switches_json):
802 '''
803 Compare mn and onos switches
804 topo: sts TestONTopology object
805 switches_json: parsed json object from the onos devices api
806
807 This uses the sts TestONTopology object
808
809 '''
810 import json
811 results = main.TRUE
812 output = {"switches":[]}
813 for switch in topo.graph.switches: #iterate through the MN topology and pull out switches and and port info
814 #print vars(switch)
815 ports = []
816 for port in switch.ports.values():
817 #print port.hw_addr.toStr(separator = '')
818 ports.append({'of_port': port.port_no, 'mac': str(port.hw_addr).replace('\'',''), 'name': port.name})
819 output['switches'].append({"name": switch.name, "dpid": str(switch.dpid).zfill(16), "ports": ports })
820 #print output
821
822 #print json.dumps(output, sort_keys=True,indent=4,separators=(',', ': '))
823
824
825 # created sorted list of dpid's in MN and ONOS for comparison
826 mnDPIDs=[]
827 for switch in output['switches']:
828 mnDPIDs.append(switch['dpid'])
829 mnDPIDs.sort()
830 #print mnDPIDs
831 if switches_json == "":#if rest call fails
832 main.log.error(self.name + ".compare_topo(): Empty JSON object given from ONOS")
833 return main.FALSE
834 onos=switches_json
835 onosDPIDs=[]
836 for switch in onos:
837 onosDPIDs.append(switch['id'].replace(":",'').replace("of",''))
838 #print switch
839 onosDPIDs.sort()
840 #print onosDPIDs
841
842 if mnDPIDs!=onosDPIDs:
843 switch_results = main.FALSE
844 main.log.report( "Switches in MN but not in ONOS:")
845 main.log.report( str([switch for switch in mnDPIDs if switch not in onosDPIDs]))
846 main.log.report( "Switches in ONOS but not in MN:")
847 main.log.report( str([switch for switch in onosDPIDs if switch not in mnDPIDs]))
848 else:#list of dpid's match in onos and mn
849 #main.log.report("DEBUG: The dpid's of the switches in Mininet and ONOS match")
850 switch_results = main.TRUE
851 return switch_results
852
853
854
855
856
Jon Hall7c3d1092014-08-11 15:08:31 -0700857 def compare_topo(self, topo, onos_json):
Jon Hall8412ed12014-07-24 16:33:58 -0700858 '''
859 compares mn topology with ONOS topology
860 onos_list is a list of ONOS controllers, each element of the list should be (handle, name, ip, port)
861 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 -0700862 Returns: True if MN and ONOS topology match and False if the differ.
863 Differences between ONOS and MN topology will be printed to the log.
864
865 Dependency: Requires STS to be installed on the TestON machine. STS can be pulled
866 from https://github.com/ucb-sts/sts.git . Currently the required functions from STS are located in the
867 topology_refactoring2 branch, but may be merged into the master branch soon. You may need to install some
868 python modules such as networkx to use the STS functions.
869
Jon Hall38f50122014-08-05 13:16:52 -0700870 To install sts:
871 $ git clone git://github.com/ucb-sts/sts.git
872 $ cd sts
873 $ git clone -b debugger git://github.com/ucb-sts/pox.git
874 $ sudo apt-get install python-dev
875 $ ./tools/install_hassel_python.sh
876 $ sudo pip install networkx
877
878 Include sts in your PYTHONPATH. it should looks comething like:
879 PYTHONPATH=/home/admin/TestON:/home/admin/sts
880
Jon Hall8412ed12014-07-24 16:33:58 -0700881 '''
admin680b78c2014-08-08 11:46:45 -0700882 import sys
883 sys.path.append("~/sts")
Jon Halle9341332014-08-07 10:09:36 -0700884 #NOTE: Create this once per Test and pass the TestONTopology object around. It takes too long to create this object.
885 # This will make it easier to use the sts methods for severing links and solve that issue
Jon Hall0d88a252014-07-25 11:22:40 -0700886 import json
admin2a9548d2014-06-17 14:08:07 -0700887
Jon Hall8412ed12014-07-24 16:33:58 -0700888 link_results = main.TRUE
889 switch_results = main.TRUE
890 port_results = main.TRUE
891
892 ########Switches#######
893 output = {"switches":[]}
Jon Hall0d88a252014-07-25 11:22:40 -0700894 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 -0700895 ports = []
896 for port in switch.ports.values():
Jon Hall38f50122014-08-05 13:16:52 -0700897 #print port.hw_addr.toStr(separator = '')
898 ports.append({'of_port': port.port_no, 'mac': str(port.hw_addr).replace('\'',''), 'name': port.name})
899 output['switches'].append({"name": switch.name, "dpid": str(switch.dpid).zfill(16), "ports": ports })
Jon Hall8412ed12014-07-24 16:33:58 -0700900 #print output
901
Jon Hall8412ed12014-07-24 16:33:58 -0700902 #print json.dumps(output, sort_keys=True,indent=4,separators=(',', ': '))
903
904
Jon Hall0d88a252014-07-25 11:22:40 -0700905 # created sorted list of dpid's in MN and ONOS for comparison
Jon Hall8412ed12014-07-24 16:33:58 -0700906 mnDPIDs=[]
907 for switch in output['switches']:
908 mnDPIDs.append(switch['dpid'])
909 mnDPIDs.sort()
Jon Halle9341332014-08-07 10:09:36 -0700910 #print mnDPIDs
Jon Hall0d88a252014-07-25 11:22:40 -0700911 if onos_json == "":#if rest call fails
Jon Hall8412ed12014-07-24 16:33:58 -0700912 main.log.error(self.name + ".compare_topo(): Empty JSON object given from ONOS rest call")
913 return main.FALSE
914 onos=onos_json
915 onosDPIDs=[]
916 for switch in onos['switches']:
917 onosDPIDs.append(switch['dpid'].replace(":",''))
918 onosDPIDs.sort()
Jon Halle9341332014-08-07 10:09:36 -0700919 #print onosDPIDs
Jon Hall8412ed12014-07-24 16:33:58 -0700920
921 if mnDPIDs!=onosDPIDs:
922 switch_results = main.FALSE
923 main.log.report( "Switches in MN but not in ONOS:")
924 main.log.report( str([switch for switch in mnDPIDs if switch not in onosDPIDs]))
925 main.log.report( "Switches in ONOS but not in MN:")
926 main.log.report( str([switch for switch in onosDPIDs if switch not in mnDPIDs]))
927 else:#list of dpid's match in onos and mn
928 switch_results = main.TRUE
929
930 ################ports#############
931 for switch in output['switches']:
932 mn_ports = []
933 onos_ports = []
934 for port in switch['ports']:
935 mn_ports.append(port['of_port'])
936 for onos_switch in onos['switches']:
937 if onos_switch['dpid'].replace(':','') == switch['dpid']:
938 for port in onos_switch['ports']:
939 onos_ports.append(port['portNumber'])
940 mn_ports.sort()
941 onos_ports.sort()
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700942 #print "mn_ports[] = ", mn_ports
943 #print "onos_ports90 = ", onos_ports
944
945 #if mn_ports == onos_ports:
946 #pass #don't set results to true here as this is just one of many checks and it might override a failure
947
948 #For OF1.3, the OFP_local port number is 0xfffffffe or 4294967294 instead of 0xfffe or 65534 in OF1.0, ONOS topology
949 #sees the correct port number, however MN topolofy as read from line 151 of https://github.com/ucb-sts/sts/blob/
950 #topology_refactoring2/sts/entities/teston_entities.py is 0xfffe which doesn't work correctly with OF1.3 switches.
951 #So a short term fix is to ignore the case when mn_port == 65534 and onos_port ==4294967294.
952 for mn_port,onos_port in zip(mn_ports,onos_ports):
953 if mn_port == onos_port or (mn_port == 65534 and onos_port ==4294967294):
954 continue
955 else:
956 port_results = main.FALSE
957 break
Jon Hall8412ed12014-07-24 16:33:58 -0700958 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 -0700959 '''
Jon Hall8412ed12014-07-24 16:33:58 -0700960 else: #the ports of this switch don't match
961 port_results = main.FALSE
962 main.log.report("ports in MN switch %s(%s) but not in ONOS:" % (switch['name'],switch['dpid']))
963 main.log.report( str([port for port in mn_ports if port not in onos_ports]))
964 main.log.report("ports in ONOS switch %s(%s) but not in MN:" % (switch['name'],switch['dpid']))
965 main.log.report( str([port for port in onos_ports if port not in mn_ports]))
shahshreyaf4d4d0c2014-10-10 12:11:10 -0700966 '''
967 if port_results == main.FALSE:
968 main.log.report("ports in MN switch %s(%s) but not in ONOS:" % (switch['name'],switch['dpid']))
969 main.log.report( str([port for port in mn_ports if port not in onos_ports]))
970 main.log.report("ports in ONOS switch %s(%s) but not in MN:" % (switch['name'],switch['dpid']))
971 main.log.report( str([port for port in onos_ports if port not in mn_ports]))
Jon Hall8412ed12014-07-24 16:33:58 -0700972
973 #######Links########
Jon Hall0d88a252014-07-25 11:22:40 -0700974 # iterate through MN links and check if and ONOS link exists in both directions
Jon Halle9341332014-08-07 10:09:36 -0700975 # NOTE: Will currently only show mn links as down if they are cut through STS.
976 # We can either do everything through STS or wait for up_network_links
977 # and down_network_links to be fully implemented.
Jon Hall8412ed12014-07-24 16:33:58 -0700978 for link in topo.patch_panel.network_links:
979 #print "Link: %s" % link
980 #TODO: Find a more efficient search method
981 node1 = None
982 port1 = None
983 node2 = None
984 port2 = None
985 first_dir = main.FALSE
986 second_dir = main.FALSE
987 for switch in output['switches']:
988 if switch['name'] == link.node1.name:
989 node1 = switch['dpid']
990 for port in switch['ports']:
991 if str(port['name']) == str(link.port1):
992 port1 = port['of_port']
993 if node1 is not None and node2 is not None:
994 break
995 if switch['name'] == link.node2.name:
996 node2 = switch['dpid']
997 for port in switch['ports']:
998 if str(port['name']) == str(link.port2):
999 port2 = port['of_port']
1000 if node1 is not None and node2 is not None:
1001 break
1002 # check onos link from node1 to node2
1003 for onos_link in onos['links']:
1004 if onos_link['src']['dpid'].replace(":",'') == node1 and onos_link['dst']['dpid'].replace(":",'') == node2:
1005 if onos_link['src']['portNumber'] == port1 and onos_link['dst']['portNumber'] == port2:
1006 first_dir = main.TRUE
1007 else:
1008 main.log.report('the port numbers do not match for ' +str(link) + ' between ONOS and MN')
1009 #print node1, ' to ', node2
1010 elif onos_link['src']['dpid'].replace(":",'') == node2 and onos_link['dst']['dpid'].replace(":",'') == node1:
1011 if onos_link['src']['portNumber'] == port2 and onos_link['dst']['portNumber'] == port1:
1012 second_dir = main.TRUE
1013 else:
1014 main.log.report('the port numbers do not match for ' +str(link) + ' between ONOS and MN')
1015 #print node2, ' to ', node1
1016 else:#this is not the link you're looking for
1017 pass
1018 if not first_dir:
1019 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)+")")
1020 if not second_dir:
1021 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)+")")
1022 link_results = link_results and first_dir and second_dir
1023
1024
1025 results = switch_results and port_results and link_results
Jon Halle9341332014-08-07 10:09:36 -07001026# if not results: #To print out both topologies
1027# main.log.error("Topology comparison failed, printing json objects, MN then ONOS")
1028# main.log.error(str(json.dumps(output, sort_keys=True,indent=4,separators=(',', ': '))))
1029# main.log.error('MN Links:')
1030# for link in topo.patch_panel.network_links: main.log.error(str("\tLink: %s" % link))
1031# main.log.error(str(json.dumps(onos, sort_keys=True,indent=4,separators=(',', ': '))))
Jon Hall8412ed12014-07-24 16:33:58 -07001032 return results
admin2a9548d2014-06-17 14:08:07 -07001033
andrewonlab3f0a4af2014-10-17 12:25:14 -04001034 def get_hosts(self):
1035 '''
1036 Returns a list of all hosts
1037 Don't ask questions just use it
1038 '''
1039 self.handle.sendline("")
1040 self.handle.expect("mininet>")
1041
1042 self.handle.sendline("py [ host.name for host in net.hosts ]")
1043 self.handle.expect("mininet>")
admin2a9548d2014-06-17 14:08:07 -07001044
andrewonlab3f0a4af2014-10-17 12:25:14 -04001045 handle_py = self.handle.before
1046 handle_py = handle_py.split("]\r\n",1)[1]
1047 handle_py = handle_py.rstrip()
admin2a9548d2014-06-17 14:08:07 -07001048
andrewonlab3f0a4af2014-10-17 12:25:14 -04001049 self.handle.sendline("")
1050 self.handle.expect("mininet>")
admin2a9548d2014-06-17 14:08:07 -07001051
andrewonlab3f0a4af2014-10-17 12:25:14 -04001052 host_str = handle_py.replace("]", "")
1053 host_str = host_str.replace("'", "")
1054 host_str = host_str.replace("[", "")
1055 host_list = host_str.split(",")
1056
1057 return host_list
adminbae64d82013-08-01 10:50:15 -07001058
1059if __name__ != "__main__":
1060 import sys
1061 sys.modules[__name__] = MininetCliDriver()
admin2a9548d2014-06-17 14:08:07 -07001062