blob: 9191b897bbeaf22707c4ad39d1575f0666101a71 [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
Jon Hall38481722014-11-04 16:50:05 -0500118 count = 0
Jon Hall1ccf82c2014-10-15 14:55:16 -0400119 while(k <= depth-1):
Jon Hall38481722014-11-04 16:50:05 -0500120 count = count + pow(fanout,k)
Jon Hall1ccf82c2014-10-15 14:55:16 -0400121 k = k+1
Jon Hall38481722014-11-04 16:50:05 -0500122 num_switches = count
Jon Hall1ccf82c2014-10-15 14:55:16 -0400123 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 '''
Jon Hall38481722014-11-04 16:50:05 -0500127 count = count + pow(fanout,k)
Jon Hall1ccf82c2014-10-15 14:55:16 -0400128 k = k+1
Jon Hall38481722014-11-04 16:50:05 -0500129 num_links = count * fanout
Jon Hall1ccf82c2014-10-15 14:55:16 -0400130 #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)
shahshreya328c2a72014-11-17 10:19:50 -0800161 #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 :
Jon Hall38481722014-11-04 16:50:05 -0500390 cmd = 'py "\\n".join(["name=%s,mac=%s,ip=%s,enabled=%s" % (i.name, i.MAC(), i.IP(), i.isUp())'
Ahmed El-Hassanyfd329182014-04-10 11:38:16 -0700391 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 '''
adminbae64d82013-08-01 10:50:15 -0700493 args = utilities.parse_args(["END1","END2","OPTION"],**linkargs)
494 end1 = args["END1"] if args["END1"] != None else ""
495 end2 = args["END2"] if args["END2"] != None else ""
496 option = args["OPTION"] if args["OPTION"] != None else ""
Jon Hall38481722014-11-04 16:50:05 -0500497 main.log.info("Bring link between '"+ end1 +"' and '" + end2 + "' '" + option + "'")
adminbae64d82013-08-01 10:50:15 -0700498 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)
Jon Hallec3c21e2014-11-10 22:22:37 -0500576 return version
adminbae64d82013-08-01 10:50:15 -0700577
Jon Hallec3c21e2014-11-10 22:22:37 -0500578 def get_sw_controller(self, sw):
579 '''
580 Parameters:
581 sw: The name of an OVS switch. Example "s1"
582 Return:
583 The output of the command from the mininet cli or main.FALSE on timeout
584 '''
admin2a9548d2014-06-17 14:08:07 -0700585 command = "sh ovs-vsctl get-controller "+str(sw)
586 try:
Jon Hallec3c21e2014-11-10 22:22:37 -0500587 response = self.execute(cmd=command, prompt="mininet>", timeout=10)
admin2a9548d2014-06-17 14:08:07 -0700588 if response:
Jon Hallec3c21e2014-11-10 22:22:37 -0500589 return response
admin2a9548d2014-06-17 14:08:07 -0700590 else:
591 return main.FALSE
592 except pexpect.EOF:
593 main.log.error(self.name + ": EOF exception found")
594 main.log.error(self.name + ": " + self.handle.before)
595 main.cleanup()
596 main.exit()
adminbae64d82013-08-01 10:50:15 -0700597
598 def assign_sw_controller(self,**kwargs):
Jon Hallf89c8552014-04-02 13:14:06 -0700599 '''
600 count is only needed if there is more than 1 controller
601 '''
602 args = utilities.parse_args(["COUNT"],**kwargs)
603 count = args["COUNT"] if args!={} else 1
604
605 argstring = "SW"
606 for j in range(count):
607 argstring = argstring + ",IP" + str(j+1) + ",PORT" + str(j+1)
608 args = utilities.parse_args(argstring.split(","),**kwargs)
609
adminbae64d82013-08-01 10:50:15 -0700610 sw = args["SW"] if args["SW"] != None else ""
admin530b4c92013-08-14 16:54:35 -0700611 ptcpA = int(args["PORT1"])+int(sw) if args["PORT1"] != None else ""
Jon Hallf89c8552014-04-02 13:14:06 -0700612 ptcpB = "ptcp:"+str(ptcpA) if ptcpA != "" else ""
613
614 command = "sh ovs-vsctl set-controller s" + str(sw) + " " + ptcpB + " "
615 for j in range(count):
616 i=j+1
617 args = utilities.parse_args(["IP"+str(i),"PORT"+str(i)],**kwargs)
618 ip = args["IP"+str(i)] if args["IP"+str(i)] != None else ""
619 port = args["PORT" + str(i)] if args["PORT" + str(i)] != None else ""
620 tcp = "tcp:" + str(ip) + ":" + str(port) + " " if ip != "" else ""
621 command = command + tcp
Jon Hall6094a362014-04-11 14:46:56 -0700622 try:
623 self.execute(cmd=command,prompt="mininet>",timeout=5)
624 except pexpect.EOF:
625 main.log.error(self.name + ": EOF exception found")
626 main.log.error(self.name + ": " + self.handle.before)
627 main.cleanup()
628 main.exit()
629 except:
630 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
631 main.log.error( traceback.print_exc() )
632 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
633 main.cleanup()
634 main.exit()
adminbae64d82013-08-01 10:50:15 -0700635
Jon Hall0819fd92014-05-23 12:08:13 -0700636 def delete_sw_controller(self,sw):
637 '''
638 Removes the controller target from sw
639 '''
640
641 command = "sh ovs-vsctl del-controller "+str(sw)
642 try:
643 response = self.execute(cmd=command,prompt="mininet>",timeout=10)
644 except pexpect.EOF:
645 main.log.error(self.name + ": EOF exception found")
646 main.log.error(self.name + ": " + self.handle.before)
647 main.cleanup()
648 main.exit()
649 else:
650 main.log.info(response)
651
652
adminbae64d82013-08-01 10:50:15 -0700653 def disconnect(self):
Jon Hallf2942ce2014-04-10 16:00:16 -0700654 main.log.info(self.name+": Disconnecting mininet...")
adminbae64d82013-08-01 10:50:15 -0700655 response = ''
656 if self.handle:
Jon Hall6094a362014-04-11 14:46:56 -0700657 try:
658 response = self.execute(cmd="exit",prompt="(.*)",timeout=120)
659 response = self.execute(cmd="exit",prompt="(.*)",timeout=120)
Jon Halle80ef8c2014-04-29 15:29:13 -0700660 self.handle.sendline("sudo mn -c")
shahshreya328c2a72014-11-17 10:19:50 -0800661 response = main.TRUE
Jon Hall6094a362014-04-11 14:46:56 -0700662 except pexpect.EOF:
663 main.log.error(self.name + ": EOF exception found")
664 main.log.error(self.name + ": " + self.handle.before)
665 main.cleanup()
666 main.exit()
adminbae64d82013-08-01 10:50:15 -0700667 else :
Jon Hallf2942ce2014-04-10 16:00:16 -0700668 main.log.error(self.name+": Connection failed to the host")
adminbae64d82013-08-01 10:50:15 -0700669 response = main.FALSE
670 return response
admin07529932013-11-22 14:58:28 -0800671
672 def arping(self, src, dest, destmac):
673 self.handle.sendline('')
Jon Hall333fa8c2014-04-11 11:24:58 -0700674 self.handle.expect(["mininet",pexpect.EOF,pexpect.TIMEOUT])
admin07529932013-11-22 14:58:28 -0800675
676 self.handle.sendline(src + ' arping ' + dest)
677 try:
Jon Hall333fa8c2014-04-11 11:24:58 -0700678 self.handle.expect([destmac,pexpect.EOF,pexpect.TIMEOUT])
Jon Hallf2942ce2014-04-10 16:00:16 -0700679 main.log.info(self.name+": ARP successful")
Jon Hall333fa8c2014-04-11 11:24:58 -0700680 self.handle.expect(["mininet",pexpect.EOF,pexpect.TIMEOUT])
admin07529932013-11-22 14:58:28 -0800681 return main.TRUE
682 except:
Jon Hallf2942ce2014-04-10 16:00:16 -0700683 main.log.warn(self.name+": ARP FAILURE")
Jon Hall333fa8c2014-04-11 11:24:58 -0700684 self.handle.expect(["mininet",pexpect.EOF,pexpect.TIMEOUT])
admin07529932013-11-22 14:58:28 -0800685 return main.FALSE
686
687 def decToHex(num):
688 return hex(num).split('x')[1]
admin2a9548d2014-06-17 14:08:07 -0700689
690 def getSwitchFlowCount(self, switch):
691 '''
692 return the Flow Count of the switch
693 '''
694 if self.handle:
695 cmd = "sh ovs-ofctl dump-aggregate %s" % switch
696 try:
697 response = self.execute(cmd=cmd, prompt="mininet>", timeout=10)
698 except pexpect.EOF:
699 main.log.error(self.name + ": EOF exception found")
700 main.log.error(self.name + " " + self.handle.before)
701 main.cleanup()
702 main.exit()
703 pattern = "flow_count=(\d+)"
704 result = re.search(pattern, response, re.MULTILINE)
705 if result is None:
admin2a9548d2014-06-17 14:08:07 -0700706 main.log.info("Couldn't find flows on switch '', found: %s" % (switch, response))
707 return main.FALSE
708 return result.group(1)
709 else:
710 main.log.error("Connection failed to the Mininet host")
711
Ahmed El-Hassanyb6545eb2014-08-01 11:32:10 -0700712 def check_flows(self, sw, dump_format=None):
713 if dump_format:
714 command = "sh ovs-ofctl -F " + dump_format + " dump-flows " + str(sw)
715 else:
716 command = "sh ovs-ofctl dump-flows "+str(sw)
admin2a9548d2014-06-17 14:08:07 -0700717 try:
718 response=self.execute(cmd=command,prompt="mininet>",timeout=10)
719 return response
720 except pexpect.EOF:
721 main.log.error(self.name + ": EOF exception found")
722 main.log.error(self.name + ": " + self.handle.before)
723 main.cleanup()
724 main.exit()
725 else:
726 main.log.info(response)
727
728 def start_tcpdump(self, filename, intf = "eth0", port = "port 6633"):
729 '''
730 Runs tpdump on an intferface and saves the file
731 intf can be specified, or the default eth0 is used
732 '''
733 try:
734 self.handle.sendline("")
735 self.handle.expect("mininet>")
736 self.handle.sendline("sh sudo tcpdump -n -i "+ intf + " " + port + " -w " + filename.strip() + " &")
737 self.handle.sendline("")
738 self.handle.sendline("")
739 i=self.handle.expect(['No\ssuch\device','listening\son',pexpect.TIMEOUT,"mininet>"],timeout=10)
740 main.log.warn(self.handle.before + self.handle.after)
741 if i == 0:
742 main.log.error(self.name + ": tcpdump - No such device exists. tcpdump attempted on: " + intf)
743 return main.FALSE
744 elif i == 1:
745 main.log.info(self.name + ": tcpdump started on " + intf)
746 return main.TRUE
747 elif i == 2:
748 main.log.error(self.name + ": tcpdump command timed out! Check interface name, given interface was: " + intf)
749 return main.FALSE
750 elif i ==3:
751 main.log.info(self.name +": " + self.handle.before)
752 return main.TRUE
753 else:
754 main.log.error(self.name + ": tcpdump - unexpected response")
755 return main.FALSE
756 except pexpect.EOF:
757 main.log.error(self.name + ": EOF exception found")
758 main.log.error(self.name + ": " + self.handle.before)
759 main.cleanup()
760 main.exit()
761 except:
762 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
763 main.log.error( traceback.print_exc() )
764 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
765 main.cleanup()
766 main.exit()
767
768 def stop_tcpdump(self):
769 "pkills tcpdump"
770 try:
771 self.handle.sendline("sh sudo pkill tcpdump")
772 self.handle.sendline("")
773 self.handle.sendline("")
774 self.handle.expect("mininet>")
775 except pexpect.EOF:
776 main.log.error(self.name + ": EOF exception found")
777 main.log.error(self.name + ": " + self.handle.before)
778 main.cleanup()
779 main.exit()
780 except:
781 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
782 main.log.error( traceback.print_exc() )
783 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
784 main.cleanup()
785 main.exit()
786
Jon Hall3d87d502014-10-17 18:37:42 -0400787 def compare_switches(self, topo, switches_json):
788 '''
789 Compare mn and onos switches
790 topo: sts TestONTopology object
791 switches_json: parsed json object from the onos devices api
792
793 This uses the sts TestONTopology object
794
795 '''
796 import json
Jon Hall42db6dc2014-10-24 19:03:48 -0400797 #main.log.debug("Switches_json string: ", switches_json)
Jon Hall3d87d502014-10-17 18:37:42 -0400798 output = {"switches":[]}
799 for switch in topo.graph.switches: #iterate through the MN topology and pull out switches and and port info
Jon Hall3d87d502014-10-17 18:37:42 -0400800 ports = []
801 for port in switch.ports.values():
Jon Hall3d87d502014-10-17 18:37:42 -0400802 ports.append({'of_port': port.port_no, 'mac': str(port.hw_addr).replace('\'',''), 'name': port.name})
803 output['switches'].append({"name": switch.name, "dpid": str(switch.dpid).zfill(16), "ports": ports })
Jon Hall3d87d502014-10-17 18:37:42 -0400804
Jon Hall42db6dc2014-10-24 19:03:48 -0400805 #print "mn"
Jon Hall3d87d502014-10-17 18:37:42 -0400806 #print json.dumps(output, sort_keys=True,indent=4,separators=(',', ': '))
Jon Hall42db6dc2014-10-24 19:03:48 -0400807 #print "onos"
808 #print json.dumps(switches_json, sort_keys=True,indent=4,separators=(',', ': '))
Jon Hall3d87d502014-10-17 18:37:42 -0400809
810
811 # created sorted list of dpid's in MN and ONOS for comparison
812 mnDPIDs=[]
813 for switch in output['switches']:
814 mnDPIDs.append(switch['dpid'])
815 mnDPIDs.sort()
Jon Hall38481722014-11-04 16:50:05 -0500816 #print "List of Mininet switch DPID's"
Jon Hall3d87d502014-10-17 18:37:42 -0400817 #print mnDPIDs
818 if switches_json == "":#if rest call fails
Jon Hall42db6dc2014-10-24 19:03:48 -0400819 main.log.error(self.name + ".compare_switches(): Empty JSON object given from ONOS")
Jon Hall3d87d502014-10-17 18:37:42 -0400820 return main.FALSE
821 onos=switches_json
822 onosDPIDs=[]
823 for switch in onos:
Jon Hall38481722014-11-04 16:50:05 -0500824 if switch['available'] == True:
825 onosDPIDs.append(switch['id'].replace(":",'').replace("of",''))
826 #else:
827 #print "Switch is unavailable:"
828 #print switch
Jon Hall3d87d502014-10-17 18:37:42 -0400829 onosDPIDs.sort()
Jon Hall38481722014-11-04 16:50:05 -0500830 #print "List of ONOS switch DPID's"
Jon Hall3d87d502014-10-17 18:37:42 -0400831 #print onosDPIDs
832
833 if mnDPIDs!=onosDPIDs:
834 switch_results = main.FALSE
835 main.log.report( "Switches in MN but not in ONOS:")
836 main.log.report( str([switch for switch in mnDPIDs if switch not in onosDPIDs]))
837 main.log.report( "Switches in ONOS but not in MN:")
838 main.log.report( str([switch for switch in onosDPIDs if switch not in mnDPIDs]))
839 else:#list of dpid's match in onos and mn
840 #main.log.report("DEBUG: The dpid's of the switches in Mininet and ONOS match")
841 switch_results = main.TRUE
842 return switch_results
843
844
845
Jon Hall72cf1dc2014-10-20 21:04:50 -0400846 def compare_ports(self, topo, ports_json):
847 '''
848 Compare mn and onos ports
849 topo: sts TestONTopology object
850 ports_json: parsed json object from the onos ports api
851
852 Dependencies:
853 1. This uses the sts TestONTopology object
854 2. numpy - "sudo pip install numpy"
855
856 '''
Jon Hall1c9e8732014-10-27 19:29:27 -0400857 #FIXME: this does not look for extra ports in ONOS, only checks that ONOS has what is in MN
Jon Hall72cf1dc2014-10-20 21:04:50 -0400858 import json
859 from numpy import uint64
860 port_results = main.TRUE
861 output = {"switches":[]}
862 for switch in topo.graph.switches: #iterate through the MN topology and pull out switches and and port info
Jon Hall72cf1dc2014-10-20 21:04:50 -0400863 ports = []
864 for port in switch.ports.values():
865 #print port.hw_addr.toStr(separator = '')
Jon Hall39f29df2014-11-04 19:30:21 -0500866 tmp_port = {}
867 tmp_port['of_port'] = port.port_no
868 tmp_port['mac'] = str(port.hw_addr).replace('\'','')
869 tmp_port['name'] = port.name
870 tmp_port['enabled'] = port.enabled
871
872 ports.append(tmp_port)
873 tmp_switch = {}
874 tmp_switch['name'] = switch.name
875 tmp_switch['dpid'] = str(switch.dpid).zfill(16)
876 tmp_switch['ports'] = ports
877
878 output['switches'].append(tmp_switch)
Jon Hall72cf1dc2014-10-20 21:04:50 -0400879
880
881 ################ports#############
Jon Hall39f29df2014-11-04 19:30:21 -0500882 for mn_switch in output['switches']:
Jon Hall72cf1dc2014-10-20 21:04:50 -0400883 mn_ports = []
884 onos_ports = []
Jon Hall39f29df2014-11-04 19:30:21 -0500885 for port in mn_switch['ports']:
Jon Hall38481722014-11-04 16:50:05 -0500886 if port['enabled'] == True:
887 mn_ports.append(port['of_port'])
Jon Hall72cf1dc2014-10-20 21:04:50 -0400888 for onos_switch in ports_json:
Jon Hall38481722014-11-04 16:50:05 -0500889 #print "Iterating through a new switch as seen by ONOS"
890 #print onos_switch
891 if onos_switch['device']['available'] == True:
Jon Hall39f29df2014-11-04 19:30:21 -0500892 if onos_switch['device']['id'].replace(':','').replace("of", '') == mn_switch['dpid']:
Jon Hall38481722014-11-04 16:50:05 -0500893 for port in onos_switch['ports']:
894 if port['isEnabled']:
895 #print "Iterating through available ports on the switch"
896 #print port
897 onos_ports.append(int(port['port']))
Jon Hall72cf1dc2014-10-20 21:04:50 -0400898 mn_ports.sort(key=float)
899 onos_ports.sort(key=float)
900 #print "\nPorts for Switch %s:" % (switch['name'])
901 #print "\tmn_ports[] = ", mn_ports
902 #print "\tonos_ports[] = ", onos_ports
903
Jon Hall38481722014-11-04 16:50:05 -0500904 #NOTE:For OF1.3, the OFP_local port number is 0xfffffffe or 4294967294 instead of 0xfffe or 65534 in OF1.0,
905 # ONOS topology sees the correct port number, however MN topology as read from line 151 of
906 # https://github.com/ucb-sts/sts/blob/topology_refactoring2/sts/entities/teston_entities.py
907 # is 0xfffe which doesn't work correctly with OF1.3 switches.
Jon Hall72cf1dc2014-10-20 21:04:50 -0400908
Jon Hall38481722014-11-04 16:50:05 -0500909 #NOTE: ONOS is abstracting port numbers to 64bit unsigned number(long). So we will be converting the
910 # OF reserved ports to these numbers
911
912
Jon Hall72cf1dc2014-10-20 21:04:50 -0400913 #TODO: handle other reserved port numbers besides LOCAL
914 for mn_port,onos_port in zip(mn_ports,onos_ports):
Jon Hall38481722014-11-04 16:50:05 -0500915 #print "mn == onos port?"
916 #print mn_port, onos_port
917 if mn_port == onos_port or (mn_port == 65534 and onos_port == long(uint64(-2))):
Jon Hall72cf1dc2014-10-20 21:04:50 -0400918 continue
919 #don't set results to true here as this is just one of many checks and it might override a failure
920 else: #the ports of this switch don't match
921 port_results = main.FALSE
922 break
923 if port_results == main.FALSE:
Jon Hall39f29df2014-11-04 19:30:21 -0500924 main.log.report("The list of ports for switch %s(%s) does not match:" % (mn_switch['name'], mn_switch['dpid']) )
Jon Hall72cf1dc2014-10-20 21:04:50 -0400925 main.log.report("mn_ports[] = " + str(mn_ports))
926 main.log.report("onos_ports[] = " + str(onos_ports))
927 return port_results
928
929
930
931
932 def compare_links(self, topo, links_json):
933 '''
934 Compare mn and onos links
935 topo: sts TestONTopology object
936 links_json: parsed json object from the onos links api
937
938 This uses the sts TestONTopology object
939
940 '''
Jon Hall1c9e8732014-10-27 19:29:27 -0400941 #FIXME: this does not look for extra links in ONOS, only checks that ONOS has what is in MN
Jon Hall72cf1dc2014-10-20 21:04:50 -0400942 import json
943 link_results = main.TRUE
944 output = {"switches":[]}
945 onos = links_json
946 for switch in topo.graph.switches: #iterate through the MN topology and pull out switches and and port info
Jon Hall38481722014-11-04 16:50:05 -0500947 # print "Iterating though switches as seen by Mininet"
948 # print switch
Jon Hall72cf1dc2014-10-20 21:04:50 -0400949 ports = []
950 for port in switch.ports.values():
951 #print port.hw_addr.toStr(separator = '')
952 ports.append({'of_port': port.port_no, 'mac': str(port.hw_addr).replace('\'',''), 'name': port.name})
953 output['switches'].append({"name": switch.name, "dpid": str(switch.dpid).zfill(16), "ports": ports })
954 #######Links########
955
Jon Hall38481722014-11-04 16:50:05 -0500956 mn_links = [link for link in topo.patch_panel.network_links if (link.port1.enabled and link.port2.enabled)]
957 #print "mn_links:"
958 #print mn_links
959 if 2*len(mn_links) == len(onos):
Jon Hall72cf1dc2014-10-20 21:04:50 -0400960 link_results = main.TRUE
961 else:
962 link_results = main.FALSE
Jon Hall38481722014-11-04 16:50:05 -0500963 main.log.report("Mininet has %i bidirectional links and ONOS has %i unidirectional links" % (len(mn_links), len(onos) ))
Jon Hall72cf1dc2014-10-20 21:04:50 -0400964
965
966 # iterate through MN links and check if an ONOS link exists in both directions
967 # NOTE: Will currently only show mn links as down if they are cut through STS.
968 # We can either do everything through STS or wait for up_network_links
969 # and down_network_links to be fully implemented.
Jon Hall38481722014-11-04 16:50:05 -0500970 for link in mn_links:
Jon Hall72cf1dc2014-10-20 21:04:50 -0400971 #print "Link: %s" % link
972 #TODO: Find a more efficient search method
973 node1 = None
974 port1 = None
975 node2 = None
976 port2 = None
977 first_dir = main.FALSE
978 second_dir = main.FALSE
979 for switch in output['switches']:
980 #print "Switch: %s" % switch['name']
981 if switch['name'] == link.node1.name:
982 node1 = switch['dpid']
983 for port in switch['ports']:
984 if str(port['name']) == str(link.port1):
985 port1 = port['of_port']
986 if node1 is not None and node2 is not None:
987 break
988 if switch['name'] == link.node2.name:
989 node2 = switch['dpid']
990 for port in switch['ports']:
991 if str(port['name']) == str(link.port2):
992 port2 = port['of_port']
993 if node1 is not None and node2 is not None:
994 break
995
996
997 for onos_link in onos:
998 onos_node1 = onos_link['src']['device'].replace(":",'').replace("of", '')
999 onos_node2 = onos_link['dst']['device'].replace(":",'').replace("of", '')
1000 onos_port1 = onos_link['src']['port']
1001 onos_port2 = onos_link['dst']['port']
1002
1003 #print "Checking ONOS for link %s/%s -> %s/%s and" % (node1, port1, node2, port2)
1004 #print "Checking ONOS for link %s/%s -> %s/%s" % (node2, port2, node1, port1)
1005 # check onos link from node1 to node2
1006 if str(onos_node1) == str(node1) and str(onos_node2) == str(node2):
1007 if int(onos_port1) == int(port1) and int(onos_port2) == int(port2):
1008 first_dir = main.TRUE
1009 else:
1010 main.log.report('The port numbers do not match for ' +str(link) +\
1011 ' between ONOS and MN. When cheking ONOS for link '+\
1012 '%s/%s -> %s/%s' % (node1, port1, node2, port2)+\
1013 ' ONOS has the values %s/%s -> %s/%s' %\
1014 (onos_node1, onos_port1, onos_node2, onos_port2))
1015
1016 # check onos link from node2 to node1
1017 elif ( str(onos_node1) == str(node2) and str(onos_node2) == str(node1) ):
1018 if ( int(onos_port1) == int(port2) and int(onos_port2) == int(port1) ):
1019 second_dir = main.TRUE
1020 else:
1021 main.log.report('The port numbers do not match for ' +str(link) +\
1022 ' between ONOS and MN. When cheking ONOS for link '+\
1023 '%s/%s -> %s/%s' % (node2, port2, node1, port1)+\
1024 ' ONOS has the values %s/%s -> %s/%s' %\
1025 (onos_node2, onos_port2, onos_node1, onos_port1))
1026 else:#this is not the link you're looking for
1027 pass
1028 if not first_dir:
1029 main.log.report('ONOS does not have the link %s/%s -> %s/%s' % (node1, port1, node2, port2))
1030 if not second_dir:
1031 main.log.report('ONOS does not have the link %s/%s -> %s/%s' % (node2, port2, node1, port1))
1032 link_results = link_results and first_dir and second_dir
Jon Hall62df9242014-10-22 12:20:17 -04001033 return link_results
Jon Hall72cf1dc2014-10-20 21:04:50 -04001034
1035
andrewonlab3f0a4af2014-10-17 12:25:14 -04001036 def get_hosts(self):
1037 '''
1038 Returns a list of all hosts
1039 Don't ask questions just use it
1040 '''
1041 self.handle.sendline("")
1042 self.handle.expect("mininet>")
1043
1044 self.handle.sendline("py [ host.name for host in net.hosts ]")
1045 self.handle.expect("mininet>")
admin2a9548d2014-06-17 14:08:07 -07001046
andrewonlab3f0a4af2014-10-17 12:25:14 -04001047 handle_py = self.handle.before
1048 handle_py = handle_py.split("]\r\n",1)[1]
1049 handle_py = handle_py.rstrip()
admin2a9548d2014-06-17 14:08:07 -07001050
andrewonlab3f0a4af2014-10-17 12:25:14 -04001051 self.handle.sendline("")
1052 self.handle.expect("mininet>")
admin2a9548d2014-06-17 14:08:07 -07001053
andrewonlab3f0a4af2014-10-17 12:25:14 -04001054 host_str = handle_py.replace("]", "")
1055 host_str = host_str.replace("'", "")
1056 host_str = host_str.replace("[", "")
1057 host_list = host_str.split(",")
1058
1059 return host_list
adminbae64d82013-08-01 10:50:15 -07001060
Jon Hall38481722014-11-04 16:50:05 -05001061
1062 def update(self):
1063 '''
1064 updates the port address and status information for each port in mn
1065 '''
1066 #TODO: Add error checking. currently the mininet command has no output
1067 main.log.info("Updateing MN port information")
1068 self.handle.sendline("")
1069 self.handle.expect("mininet>")
1070
1071 self.handle.sendline("update")
1072 self.handle.expect("mininet>")
1073
1074 self.handle.sendline("")
1075 self.handle.expect("mininet>")
1076
1077 return main.TRUE
1078
1079
1080
adminbae64d82013-08-01 10:50:15 -07001081if __name__ != "__main__":
1082 import sys
1083 sys.modules[__name__] = MininetCliDriver()
admin2a9548d2014-06-17 14:08:07 -07001084