Some changes to mininet drivers
- Refactor compare ports
- Refactor pingall
- lower the log level for some statements
- remove some debug/print statements
diff --git a/TestON/drivers/common/cli/emulator/mininetclidriver.py b/TestON/drivers/common/cli/emulator/mininetclidriver.py
index 9191b89..c888e23 100644
--- a/TestON/drivers/common/cli/emulator/mininetclidriver.py
+++ b/TestON/drivers/common/cli/emulator/mininetclidriver.py
@@ -153,26 +153,33 @@
if self.handle :
main.log.info(self.name+": Checking reachabilty to the hosts using pingall")
try:
- response = self.execute(cmd="pingall",prompt="mininet>",timeout=120)
- print "response: " + str(response)
- except pexpect.EOF:
+ response = self.execute(cmd="pingall",prompt="mininet>",timeout=300)
+ except pexpect.EOF:
main.log.error(self.name + ": EOF exception found")
main.log.error(self.name + ": " + self.handle.before)
- #main.cleanup()
- #main.exit()
- pattern = 'Results\:\s0\%\sdropped\s'
- #FIXME:Pending Mininet Pull Request #408
- #pattern = 'Results\:\s0\.00\%\sdropped\s'
- #if utilities.assert_matches(expect=pattern,actual=response,onpass="All hosts are reaching",onfail="Unable to reach all the hosts"):
+ main.cleanup()
+ main.exit()
+ except pexpect.TIMEOUT:
+ #We may not want to kill the test if pexpect times out
+ main.log.error(self.name + ": TIMEOUT exception found")
+ main.log.error(self.name + ": " + str(self.handle.before) )
+ #NOTE: mininet's pingall rounds, so we will check the number of passed and number of failed
+ pattern = "Results\:\s0\%\sdropped\s\((?P<passed>[\d]+)/(?P=passed)"
if re.search(pattern,response):
main.log.info(self.name+": All hosts are reachable")
return main.TRUE
else:
main.log.error(self.name+": Unable to reach all the hosts")
+ main.log.info("Pingall ouput: " + str(response))
+ #NOTE: Send ctrl-c to make sure pingall is done
+ self.handle.send("\x03")
+ self.handle.expect("Interrupt")
+ self.handle.expect("mininet>")
return main.FALSE
else :
main.log.error(self.name+": Connection failed to the host")
- return main.FALSE
+ main.cleanup()
+ main.exit()
def fpingHost(self,**pingParams):
'''
@@ -735,9 +742,10 @@
self.handle.expect("mininet>")
self.handle.sendline("sh sudo tcpdump -n -i "+ intf + " " + port + " -w " + filename.strip() + " &")
self.handle.sendline("")
- self.handle.sendline("")
i=self.handle.expect(['No\ssuch\device','listening\son',pexpect.TIMEOUT,"mininet>"],timeout=10)
main.log.warn(self.handle.before + self.handle.after)
+ self.handle.sendline("")
+ self.handle.expect("mininet>")
if i == 0:
main.log.error(self.name + ": tcpdump - No such device exists. tcpdump attempted on: " + intf)
return main.FALSE
@@ -769,7 +777,7 @@
"pkills tcpdump"
try:
self.handle.sendline("sh sudo pkill tcpdump")
- self.handle.sendline("")
+ self.handle.expect("mininet>")
self.handle.sendline("")
self.handle.expect("mininet>")
except pexpect.EOF:
@@ -857,7 +865,7 @@
#FIXME: this does not look for extra ports in ONOS, only checks that ONOS has what is in MN
import json
from numpy import uint64
- port_results = main.TRUE
+ ports_results = main.TRUE
output = {"switches":[]}
for switch in topo.graph.switches: #iterate through the MN topology and pull out switches and and port info
ports = []
@@ -882,9 +890,12 @@
for mn_switch in output['switches']:
mn_ports = []
onos_ports = []
+ switch_result = main.TRUE
for port in mn_switch['ports']:
if port['enabled'] == True:
mn_ports.append(port['of_port'])
+ #else: #DEBUG only
+ # main.log.warn("Port %s on switch %s is down" % ( str(port['of_port']) , str(mn_switch['name'])) )
for onos_switch in ports_json:
#print "Iterating through a new switch as seen by ONOS"
#print onos_switch
@@ -894,37 +905,57 @@
if port['isEnabled']:
#print "Iterating through available ports on the switch"
#print port
- onos_ports.append(int(port['port']))
+ if port['port'] == 'local':
+ #onos_ports.append('local')
+ onos_ports.append(long(uint64(-2)))
+ else:
+ onos_ports.append(int(port['port']))
+ '''
+ else: #This is likely a new reserved port implemented
+ main.log.error("unkown port '" + str(port['port']) )
+ '''
+ #else: #DEBUG
+ # main.log.warn("Port %s on switch %s is down" % ( str(port['port']) , str(onos_switch['device']['id'])) )
+ break
mn_ports.sort(key=float)
onos_ports.sort(key=float)
#print "\nPorts for Switch %s:" % (switch['name'])
#print "\tmn_ports[] = ", mn_ports
#print "\tonos_ports[] = ", onos_ports
-
- #NOTE:For OF1.3, the OFP_local port number is 0xfffffffe or 4294967294 instead of 0xfffe or 65534 in OF1.0,
- # ONOS topology sees the correct port number, however MN topology as read from line 151 of
- # https://github.com/ucb-sts/sts/blob/topology_refactoring2/sts/entities/teston_entities.py
- # is 0xfffe which doesn't work correctly with OF1.3 switches.
-
- #NOTE: ONOS is abstracting port numbers to 64bit unsigned number(long). So we will be converting the
- # OF reserved ports to these numbers
-
+ mn_ports_log = mn_ports
+ onos_ports_log = onos_ports
+ mn_ports = [x for x in mn_ports]
+ onos_ports = [x for x in onos_ports]
#TODO: handle other reserved port numbers besides LOCAL
- for mn_port,onos_port in zip(mn_ports,onos_ports):
- #print "mn == onos port?"
- #print mn_port, onos_port
- if mn_port == onos_port or (mn_port == 65534 and onos_port == long(uint64(-2))):
- continue
+ #NOTE: List of Reserved Ports
+ # Local port: -2 in unsigned int in Openflow, the size depends on
+ # openflow version( 1.0 is 16 bit, 1.3 is 32 bit), ONOS shows
+ # 'local', we store as long(uint64(-2))
+ for mn_port in mn_ports_log:
+ if mn_port in onos_ports:
#don't set results to true here as this is just one of many checks and it might override a failure
- else: #the ports of this switch don't match
- port_results = main.FALSE
- break
- if port_results == main.FALSE:
- main.log.report("The list of ports for switch %s(%s) does not match:" % (mn_switch['name'], mn_switch['dpid']) )
- main.log.report("mn_ports[] = " + str(mn_ports))
- main.log.report("onos_ports[] = " + str(onos_ports))
- return port_results
+ mn_ports.remove(mn_port)
+ onos_ports.remove(mn_port)
+ #NOTE: OVS reports this as down since there is no link
+ # So ignoring these for now
+ #TODO: Come up with a better way of handling these
+ if 65534 in mn_ports:
+ mn_ports.remove(65534)
+ if long(uint64(-2)) in onos_ports:
+ onos_ports.remove( long(uint64(-2)) )
+ if len(mn_ports): #the ports of this switch don't match
+ switch_result = main.FALSE
+ main.log.warn("Ports in MN but not ONOS: " + str(mn_ports) )
+ if len(onos_ports): #the ports of this switch don't match
+ switch_result = main.FALSE
+ main.log.warn("Ports in ONOS but not MN: " + str(onos_ports) )
+ if switch_result == main.FALSE:
+ main.log.report("The list of active ports for switch %s(%s) does not match:" % (mn_switch['name'], mn_switch['dpid']) )
+ main.log.warn("mn_ports[] = " + str(mn_ports_log))
+ main.log.warn("onos_ports[] = " + str(onos_ports_log))
+ ports_results = ports_results and switch_result
+ return ports_results
@@ -1007,7 +1038,7 @@
if int(onos_port1) == int(port1) and int(onos_port2) == int(port2):
first_dir = main.TRUE
else:
- main.log.report('The port numbers do not match for ' +str(link) +\
+ main.log.warn('The port numbers do not match for ' +str(link) +\
' between ONOS and MN. When cheking ONOS for link '+\
'%s/%s -> %s/%s' % (node1, port1, node2, port2)+\
' ONOS has the values %s/%s -> %s/%s' %\
@@ -1018,7 +1049,7 @@
if ( int(onos_port1) == int(port2) and int(onos_port2) == int(port1) ):
second_dir = main.TRUE
else:
- main.log.report('The port numbers do not match for ' +str(link) +\
+ main.log.warn('The port numbers do not match for ' +str(link) +\
' between ONOS and MN. When cheking ONOS for link '+\
'%s/%s -> %s/%s' % (node2, port2, node1, port1)+\
' ONOS has the values %s/%s -> %s/%s' %\
@@ -1065,18 +1096,23 @@
'''
#TODO: Add error checking. currently the mininet command has no output
main.log.info("Updateing MN port information")
- self.handle.sendline("")
- self.handle.expect("mininet>")
-
- self.handle.sendline("update")
- self.handle.expect("mininet>")
+ try:
+ self.handle.sendline("")
+ self.handle.expect("mininet>")
- self.handle.sendline("")
- self.handle.expect("mininet>")
+ self.handle.sendline("update")
+ self.handle.expect("update")
+ self.handle.expect("mininet>")
- return main.TRUE
+ self.handle.sendline("")
+ self.handle.expect("mininet>")
-
+ return main.TRUE
+ except pexpect.EOF:
+ main.log.error(self.name + ": EOF exception found")
+ main.log.error(self.name + ": " + self.handle.before)
+ main.cleanup()
+ main.exit()
if __name__ != "__main__":
import sys
diff --git a/TestON/drivers/common/cli/emulator/remotemininetdriver.py b/TestON/drivers/common/cli/emulator/remotemininetdriver.py
index bb03c07..5d2a7a3 100644
--- a/TestON/drivers/common/cli/emulator/remotemininetdriver.py
+++ b/TestON/drivers/common/cli/emulator/remotemininetdriver.py
@@ -92,7 +92,8 @@
elif re.search("found multiple mininet",outputs):
return main.ERROR
else:
- print outputs
+ main.log.error("Error, unexpected output in the ping file")
+ main.log.warn( outputs )
return main.TRUE
@@ -155,6 +156,11 @@
main.log.info( "Transferring ping files to TestStation" )
command = "scp /tmp/ping.* "+ str(testONUser) + "@" + str(testONIP) + ":/tmp/"
self.execute(cmd=command,prompt="100%",timeout=20)
+ #Make sure the output is cleared
+ self.handle.sendline("")
+ self.handle.expect("\$")
+ self.handle.sendline("")
+ self.handle.expect("\$")
self.handle.sendline("")
self.handle.expect("\$")
return main.TRUE
@@ -553,7 +559,7 @@
response = ''
#print "Disconnecting Mininet"
if self.handle:
- self.handle.sendline("exit")
+ self.handle.sendline("exit")
self.handle.expect("exit")
self.handle.expect("(.*)")
response = self.handle.before
@@ -561,13 +567,15 @@
else :
main.log.error("Connection failed to the host")
response = main.FALSE
- return response
+ return response
def get_flowTable(self, protoVersion, sw):
+ #TODO document usage
+ #FIXME: clean up print statements and such
self.handle.sendline("cd")
- #self.handle.expect(["\$",pexpect.EOF,pexpect.TIMEOUT])
- print "cd expect status: "
- print self.handle.expect(["\$",pexpect.EOF,pexpect.TIMEOUT])
+ self.handle.expect(["\$",pexpect.EOF,pexpect.TIMEOUT])
+ #print "cd expect status: "
+ #print self.handle.expect(["\$",pexpect.EOF,pexpect.TIMEOUT])
#TODO: Write seperate versions of the function for this, possibly a string that tells it which switch is in use?
#For 1.0 version of OVS
#command = "sudo ovs-ofctl dump-flows " + sw + " | awk '{OFS=\",\" ; print $1 $6 $7 }' |sort -n -k1"