Merge pull request #24 from OPENNETWORKINGLAB/mininet_drivers
Some changes to mininet drivers
diff --git a/TestON/dependencies/Jenkins_getresult_andrew.py b/TestON/dependencies/Jenkins_getresult_andrew.py
new file mode 100755
index 0000000..0e7ef8d
--- /dev/null
+++ b/TestON/dependencies/Jenkins_getresult_andrew.py
@@ -0,0 +1,64 @@
+#!/usr/bin/env python
+
+import sys
+import os
+import re
+import datetime
+import time
+import argparse
+
+parser = argparse.ArgumentParser()
+parser.add_argument("-n", "--name", help="Comma Separated string of test names. Ex: --name='test1, test2, test3'")
+args = parser.parse_args()
+
+#Pass in test names as a comma separated string argument.
+#Example: ./Jenkins_getresult.py "Test1,Test2,Test3,Test4"
+name_list = args.name.split(",")
+result_list = map(lambda x: x.strip(), name_list)
+
+#NOTE: testnames list should be in order in which it is run
+testnames = result_list
+output = ''
+testdate = datetime.datetime.now()
+
+output +="<p>**************************************</p>"
+output +=testdate.strftime('Jenkins test result for %H:%M on %b %d, %Y. %Z')
+
+#TestON reporting
+for test in testnames:
+ name = os.popen("ls /home/admin/ONLabTest/TestON/logs/ -rt | grep %s | tail -1" % test).read().split()[0]
+ path = "/home/admin/ONLabTest/TestON/logs/" + name + "/"
+ output +="<p></p>"
+ #output +=" Date: %s, %s %s" % (name.split("_")[2], name.split("_")[1], name.split("_")[3]) + "<br>*******************<br>"
+ #Open the latest log folder
+ output += "<h2>Test "+str(test)+"</h2><p>************************************</p>"
+
+ f = open(path + name + ".rpt")
+
+ #Parse through each line of logs and look for specific strings to output to wiki.
+ #NOTE: with current implementation, you must specify which output to output to wiki by using
+ #main.log.report("") since it is looking for the [REPORT] tag in the logs
+ for line in f:
+ if re.search("Result summary for Testcase", line):
+ output += "<h3>"+str(line)+"</h3>"
+ #output += "<br>"
+ if re.search("\[REPORT\]", line):
+ line_split = line.split("] ")
+ #line string is split by bracket, and first two items (log tags) in list are omitted from output
+ #join is used to convert list to string
+ line_str = ''.join(line_split[2:])
+ output += "<p>"
+ output += line_str
+ output += "</p>"
+ if re.search("Result:", line):
+ output += "<p>"
+ output += line
+ output += "</p>"
+ f.close()
+
+ #*********************
+ #include any other phrase specific to case you would like to include in wiki here
+ if test == "IntentPerf":
+ output += "URL to Historical Performance results data: <a href='http://10.128.5.54/perf.html'>Perf Graph</a>"
+ #*********************
+print output
diff --git a/TestON/drivers/common/cli/onosclidriver.py b/TestON/drivers/common/cli/onosclidriver.py
index 66dbd23..a06a511 100644
--- a/TestON/drivers/common/cli/onosclidriver.py
+++ b/TestON/drivers/common/cli/onosclidriver.py
@@ -981,8 +981,8 @@
main.cleanup()
main.exit()
- def add_point_intent(self, ingress_device, port_ingress,
- egress_device, port_egress, ethType="", ethSrc="",
+ def add_point_intent(self, ingress_device, egress_device,
+ port_ingress="", port_egress="", ethType="", ethSrc="",
ethDst="", bandwidth="", lambda_alloc=False,
ipProto="", ipSrc="", ipDst="", tcpSrc="", tcpDst=""):
'''
@@ -1017,12 +1017,11 @@
and not bandwidth and not lambda_alloc \
and not ipProto and not ipSrc and not ipDst \
and not tcpSrc and not tcpDst:
- cmd = "add-point-intent "+\
- str(ingress_device) + "/" + str(port_ingress) + " " +\
- str(egress_device) + "/" + str(port_egress)
-
+ cmd = "add-point-intent"
+
+
else:
- cmd = "add-point-intent "
+ cmd = "add-point-intent"
if ethType:
cmd += " --ethType " + str(ethType)
@@ -1045,18 +1044,39 @@
if tcpDst:
cmd += " --tcpDst " + str(tcpDst)
- cmd += " "+str(ingress_device) +\
- "/" + str(port_ingress) + " " +\
- str(egress_device) + "/" + str(port_egress)
+ #Check whether the user appended the port
+ #or provided it as an input
+ if "/" in ingress_device:
+ cmd += " "+str(ingress_device)
+ else:
+ if not port_ingress:
+ main.log.error("You must specify "+
+ "the ingress port")
+ #TODO: perhaps more meaningful return
+ return main.FALSE
+
+ cmd += " "+ \
+ str(ingress_device) + "/" +\
+ str(port_ingress) + " "
+
+ if "/" in egress_device:
+ cmd += " "+str(egress_device)
+ else:
+ if not port_egress:
+ main.log.error("You must specify "+
+ "the egress port")
+ return main.FALSE
+
+ cmd += " "+\
+ str(egress_device) + "/" +\
+ str(port_egress)
self.handle.sendline(cmd)
+
+ main.log.info(cmd + " sent")
i = self.handle.expect([
"Error",
"onos>"])
-
- self.handle.sendline("intents")
- self.handle.expect("onos>")
- Intenthandle = self.handle.before
if i == 0:
main.log.error("Error in adding point-to-point intent")
@@ -1109,6 +1129,46 @@
main.cleanup()
main.exit()
+ # This method should be used after installing application: onos-app-sdnip
+ def routes(self, json_format=False):
+ '''
+ Optional:
+ * json_format: enable output formatting in json
+ Description:
+ Obtain all routes in the system
+ '''
+ try:
+ if json_format:
+ self.handle.sendline("routes -j")
+ self.handle.expect("routes -j")
+ self.handle.expect("onos>")
+ handle_tmp = self.handle.before
+
+ ansi_escape = re.compile(r'\r\r\n\x1b[^m]*m')
+ handle = ansi_escape.sub('', handle_tmp)
+
+ else:
+ self.handle.sendline("")
+ self.handle.expect("onos>")
+
+ self.handle.sendline("routes")
+ self.handle.expect("onos>")
+ handle = self.handle.before
+
+ return handle
+
+ except pexpect.EOF:
+ main.log.error(self.name + ": EOF exception found")
+ main.log.error(self.name + ": " + self.handle.before)
+ main.cleanup()
+ main.exit()
+ except:
+ main.log.info(self.name + " ::::::")
+ main.log.error(traceback.print_exc())
+ main.log.info(self.name + " ::::::")
+ main.cleanup()
+ main.exit()
+
def intents(self, json_format = False):
'''
Optional:
@@ -1182,6 +1242,51 @@
main.cleanup()
main.exit()
+ def push_test_intents(self, dpid_src, dpid_dst, num_intents,
+ report=True):
+ '''
+ Description:
+ Push a number of intents in a batch format to
+ a specific point-to-point intent definition
+ Required:
+ * dpid_src: specify source dpid
+ * dpid_dst: specify destination dpid
+ * num_intents: specify number of intents to push
+ Optional:
+ * report: default True, returns latency information
+ '''
+ try:
+ cmd = "push-test-intents "+\
+ str(dpid_src)+" "+str(dpid_dst)+" "+\
+ str(num_intents)
+ self.handle.sendline(cmd)
+ self.handle.expect(cmd)
+ self.handle.expect("onos>")
+
+ handle = self.handle.before
+
+ #Some color thing that we want to escape
+ ansi_escape = re.compile(r'\r\r\n\x1b[^m]*m')
+ handle = ansi_escape.sub('', handle)
+
+ if report:
+ main.log.info(handle)
+ return handle
+ else:
+ 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()
+ except:
+ main.log.info(self.name+" ::::::")
+ main.log.error( traceback.print_exc())
+ main.log.info(self.name+" ::::::")
+ main.cleanup()
+ main.exit()
+
def intents_events_metrics(self, json_format=True):
'''
Description:Returns topology metrics
diff --git a/TestON/drivers/common/cli/onosdriver.py b/TestON/drivers/common/cli/onosdriver.py
index 5cc7eb6..ca9fa01 100644
--- a/TestON/drivers/common/cli/onosdriver.py
+++ b/TestON/drivers/common/cli/onosdriver.py
@@ -405,6 +405,11 @@
print line
if report:
for line in lines[2:-1]:
+ #Bracket replacement is for Wiki-compliant
+ #formatting. '<' or '>' are interpreted
+ #as xml specific tags that cause errors
+ line = line.replace("<","[")
+ line = line.replace(">","]")
main.log.report(line)
return lines[2]
except pexpect.EOF:
diff --git a/TestON/drivers/common/cli/quaggaclidriver.py b/TestON/drivers/common/cli/quaggaclidriver.py
index 744d284..7851d13 100644
--- a/TestON/drivers/common/cli/quaggaclidriver.py
+++ b/TestON/drivers/common/cli/quaggaclidriver.py
@@ -14,12 +14,15 @@
def __init__(self):
super(CLI, self).__init__()
+ #TODO: simplify this method
def connect(self, **connectargs):
for key in connectargs:
vars(self)[key] = connectargs[key]
self.name = self.options['name']
- self.handle = super(QuaggaCliDriver,self).connect(user_name = self.user_name, ip_address = self.ip_address,port = self.port, pwd = self.pwd)
+ #self.handle = super(QuaggaCliDriver,self).connect(user_name = self.user_name, ip_address = self.ip_address,port = self.port, pwd = self.pwd)
+ self.handle = super(QuaggaCliDriver, self).connect(user_name=self.user_name, ip_address="1.1.1.1", port=self.port, pwd=self.pwd)
+ main.log.info("connect parameters:" + str(self.user_name) + ";" + str(self.ip_address) + ";" + str(self.port) + ";" + str(self.pwd))
if self.handle:
self.handle.expect("")
@@ -35,7 +38,33 @@
main.log.info("NO HANDLE")
return main.FALSE
+ def loginQuagga(self, ip_address):
+
+ self.name = self.options['name']
+ self.handle = super(QuaggaCliDriver, self).connect(
+ user_name=self.user_name, ip_address=ip_address,
+ port=self.port, pwd=self.pwd)
+ main.log.info("connect parameters:" + str(self.user_name) + ";"
+ + str(self.ip_address) + ";" + str(self.port) + ";" + str(self.pwd))
+
+ if self.handle:
+ self.handle.expect("")
+ self.handle.expect("\$")
+ self.handle.sendline("telnet localhost 2605")
+ self.handle.expect("Password:", timeout=5)
+ self.handle.sendline("hello")
+ self.handle.expect("bgpd", timeout=5)
+ self.handle.sendline("enable")
+ self.handle.expect("bgpd#", timeout=5)
+ main.log.info("I am inside BGP peer Quagga!")
+
+ return self.handle
+ else:
+ main.log.info("NO HANDLE")
+ return main.FALSE
+
def enter_config(self, asn):
+ main.log.info("I am in enter_config method!")
try:
self.handle.sendline("")
self.handle.expect("bgpd#")
@@ -52,6 +81,63 @@
return main.TRUE
except:
return main.FALSE
+
+ def generate_routes(self, net, numRoutes):
+ main.log.info("I am in generate_routes method!")
+
+ # a IP prefix will be composed by "net" + "." + m + "." + n + "." + x
+ # the length of each IP prefix is 24
+ routes = []
+ routes_gen = 0
+ m = numRoutes / 256
+ n = numRoutes % 256
+
+ for i in range(0, m):
+ for j in range(0, 256):
+ network = str(net) + "." + str(i) + "." + str(j) + ".0/24"
+ routes.append(network)
+ routes_gen = routes_gen + 1
+
+ for j in range(0, n):
+ network = str(net) + "." + str(m) + "." + str(j) + ".0/24"
+ routes.append(network)
+ routes_gen = routes_gen + 1
+
+ if routes_gen == numRoutes:
+ main.log.info("Successfully generated " + str(numRoutes)
+ + " routes!")
+ return routes
+ return main.FALSE
+
+ def add_routes(self, routes, routeRate):
+ main.log.info("I am in add_routes method!")
+
+ routes_added = 0
+ try:
+ self.handle.sendline("")
+ #self.handle.expect("config-router")
+ self.handle.expect("config-router", timeout=5)
+ except:
+ main.log.warn("Probably not in config-router mode!")
+ self.disconnect()
+ main.log.info("Start to add routes")
+
+ for i in range(0, len(routes)):
+ routeCmd = "network " + routes[i]
+ try:
+ self.handle.sendline(routeCmd)
+ self.handle.expect("bgpd", timeout=5)
+ except:
+ main.log.warn("Failed to add route")
+ self.disconnect()
+ waitTimer = 1.00 / routeRate
+ time.sleep(waitTimer)
+ if routes_added == len(routes):
+ main.log.info("Finished adding routes")
+ return main.TRUE
+ return main.FALSE
+
+ # please use the generate_routes plus add_routes instead of this one
def add_route(self, net, numRoutes, routeRate):
try:
self.handle.sendline("")
diff --git a/TestON/tests/IntentPerfNext/IntentPerfNext.params b/TestON/tests/IntentPerfNext/IntentPerfNext.params
index 7e1de77..87e7998 100644
--- a/TestON/tests/IntentPerfNext/IntentPerfNext.params
+++ b/TestON/tests/IntentPerfNext/IntentPerfNext.params
@@ -1,5 +1,5 @@
<PARAMS>
- <testcases>1,2</testcases>
+ <testcases>1,4</testcases>
<ENV>
<cellName>intent_perf_test</cellName>
@@ -32,7 +32,8 @@
<TEST>
#Number of times to iterate each case
- <numIter>5</numIter>
+ <numIter>3</numIter>
+ <batchIntentSize>50</batchIntentSize>
</TEST>
<JSON>
diff --git a/TestON/tests/IntentPerfNext/IntentPerfNext.py b/TestON/tests/IntentPerfNext/IntentPerfNext.py
index 2fb22dc..dc9fadc 100644
--- a/TestON/tests/IntentPerfNext/IntentPerfNext.py
+++ b/TestON/tests/IntentPerfNext/IntentPerfNext.py
@@ -31,7 +31,8 @@
main.step("Creating cell file")
cell_file_result = main.ONOSbench.create_cell_file(
- BENCH_ip, cell_name, MN1_ip, "onos-core",
+ BENCH_ip, cell_name, MN1_ip,
+ "onos-core,onos-app-metrics,onos-gui",
ONOS1_ip, ONOS2_ip, ONOS3_ip)
main.step("Applying cell file to environment")
@@ -53,6 +54,9 @@
build_result = main.TRUE
main.log.info("Git pull skipped by configuration")
+ main.log.report("Commit information - ")
+ main.ONOSbench.get_version(report=True)
+
main.step("Creating ONOS package")
package_result = main.ONOSbench.onos_package()
@@ -73,11 +77,6 @@
cli2 = main.ONOS2cli.start_onos_cli(ONOS2_ip)
cli3 = main.ONOS3cli.start_onos_cli(ONOS3_ip)
- main.step("Enable metrics feature")
- main.ONOS1cli.feature_install("onos-app-metrics")
- main.ONOS2cli.feature_install("onos-app-metrics")
- main.ONOS3cli.feature_install("onos-app-metrics")
-
utilities.assert_equals(expect=main.TRUE,
actual = cell_file_result and cell_apply_result and\
verify_cell_result and checkout_result and\
@@ -112,10 +111,25 @@
install_time = main.params['JSON']['installedTime']
wdRequest_time = main.params['JSON']['wdRequestTime']
withdrawn_time = main.params['JSON']['withdrawnTime']
+
+ intent_add_lat_list = []
+
+ #Assign 'linear' switch format for basic intent testing
+ main.Mininet1.assign_sw_controller(
+ sw="1", ip1=ONOS1_ip,port1=default_sw_port)
+ main.Mininet1.assign_sw_controller(
+ sw="2", ip1=ONOS2_ip,port1=default_sw_port)
+ main.Mininet1.assign_sw_controller(
+ sw="3", ip1=ONOS2_ip,port1=default_sw_port)
+ main.Mininet1.assign_sw_controller(
+ sw="4", ip1=ONOS2_ip,port1=default_sw_port)
+ main.Mininet1.assign_sw_controller(
+ sw="5", ip1=ONOS3_ip,port1=default_sw_port)
+
+ time.sleep(10)
devices_json_str = main.ONOS1cli.devices()
devices_json_obj = json.loads(devices_json_str)
-
device_id_list = []
#Obtain device id list in ONOS format.
@@ -123,14 +137,11 @@
for device in devices_json_obj:
device_id_list.append(device['id'])
- intent_add_lat_list = []
-
for i in range(0, int(num_iter)):
- #add_point_intent(ingr_device, ingr_port,
- # egr_device, egr_port)
+ #add_point_intent(ingr_device, egr_device,
+ # ingr_port, egr_port)
main.ONOS1cli.add_point_intent(
- device_id_list[0], 2,
- device_id_list[2], 1)
+ device_id_list[0]+"/1", device_id_list[4]+"/1")
#Allow some time for intents to propagate
time.sleep(5)
@@ -213,6 +224,175 @@
def CASE3(self, main):
'''
- CASE3 coming soon
+ Intent Reroute latency
'''
+ import time
+ import json
+ import requests
+ import os
+
+ ONOS1_ip = main.params['CTRL']['ip1']
+ ONOS2_ip = main.params['CTRL']['ip2']
+ ONOS3_ip = main.params['CTRL']['ip3']
+ ONOS_user = main.params['CTRL']['user']
+
+ default_sw_port = main.params['CTRL']['port1']
+
+ #number of iterations of case
+ num_iter = main.params['TEST']['numIter']
+
+ #Timestamp keys for json metrics output
+ submit_time = main.params['JSON']['submittedTime']
+ install_time = main.params['JSON']['installedTime']
+ wdRequest_time = main.params['JSON']['wdRequestTime']
+ withdrawn_time = main.params['JSON']['withdrawnTime']
+
+ devices_json_str = main.ONOS1cli.devices()
+ devices_json_obj = json.loads(devices_json_str)
+
+ device_id_list = []
+
+ #Obtain device id list in ONOS format.
+ #They should already be in order (1,2,3,10,11,12,13, etc)
+ for device in devices_json_obj:
+ device_id_list.append(device['id'])
+
+ intent_reroute_lat_list = []
+
+ print device_id_list
+
+ for i in range(0, int(num_iter)):
+ #add_point_intent(ingr_device, ingr_port,
+ # egr_device, egr_port)
+ main.ONOS1cli.add_point_intent(
+ device_id_list[0]+"/2", device_id_list[4]+"/1")
+
+ time.sleep(5)
+
+ intents_str = main.ONOS1cli.intents(json_format=True)
+ intents_obj = json.loads(intents_str)
+ for intent in intents_obj:
+ if intent['state'] == "INSTALLED":
+ main.log.info("Intent installed successfully")
+ intent_id = intent['id']
+ else:
+ #TODO: Add error handling
+ main.log.info("Intent installation failed")
+ intent_id = ""
+
+ #NOTE: this interface is specific to
+ # topo-intentFlower.py topology
+ # reroute case.
+ main.log.info("Disabling interface s2-eth3 <--> s4")
+ main.Mininet1.handle.sendline(
+ "sh ifconfig s2-eth3 down")
+ t0_system = time.time()*1000
+
+ #TODO: Check for correct intent reroute
+ time.sleep(5)
+
+ #Obtain metrics from ONOS 1, 2, 3
+ intents_json_str_1 = main.ONOS1cli.intents_events_metrics()
+ intents_json_str_2 = main.ONOS2cli.intents_events_metrics()
+ intents_json_str_3 = main.ONOS3cli.intents_events_metrics()
+
+ intents_json_obj_1 = json.loads(intents_json_str_1)
+ intents_json_obj_2 = json.loads(intents_json_str_2)
+ intents_json_obj_3 = json.loads(intents_json_str_3)
+
+ #Parse values from the json object
+ intent_install_1 = \
+ intents_json_obj_1[install_time]['value']
+ intent_install_2 = \
+ intents_json_obj_2[install_time]['value']
+ intent_install_3 = \
+ intents_json_obj_3[install_time]['value']
+
+ intent_reroute_lat_1 = \
+ int(intent_install_1) - int(t0_system)
+ intent_reroute_lat_2 = \
+ int(intent_install_2) - int(t0_system)
+ intent_reroute_lat_3 = \
+ int(intent_install_3) - int(t0_system)
+
+ intent_reroute_lat_avg = \
+ (intent_reroute_lat_1 +
+ intent_reroute_lat_2 +
+ intent_reroute_lat_3 ) / 3
+
+ main.log.info("Intent reroute latency avg for iteration "+
+ str(i)+": "+str(intent_reroute_lat_avg))
+
+ if intent_reroute_lat_avg > 0.0 and \
+ intent_reroute_lat_avg < 1000:
+ intent_reroute_lat_list.append(intent_reroute_lat_avg)
+ else:
+ main.log.info("Intent reroute latency exceeded "+
+ "threshold. Skipping iteration "+str(i))
+
+ #TODO: Possibly put this in the driver function
+ main.log.info("Removing intents for next iteration")
+
+ #NOTE: TODO: Currently, the remove intent will
+ # not trigger the intent request
+ # timestamp. Thus we cannot use the same
+ # intent to get the latency over iterations.
+ # we can 1) install different intents every
+ # time, or 2) look into state machine and
+ # determine what timestsamp to get
+ main.ONOS1cli.remove_intent(intent_id)
+
+ #TODO: Report framework
+ print intent_reroute_lat_list
+
+
+ def CASE4(self, main):
+ import time
+ import json
+ import requests
+ import os
+
+ ONOS1_ip = main.params['CTRL']['ip1']
+ ONOS2_ip = main.params['CTRL']['ip2']
+ ONOS3_ip = main.params['CTRL']['ip3']
+ ONOS_user = main.params['CTRL']['user']
+
+ default_sw_port = main.params['CTRL']['port1']
+
+ batch_intent_size = main.params['TEST']['batchIntentSize']
+
+ #number of iterations of case
+ num_iter = main.params['TEST']['numIter']
+
+ main.Mininet1.assign_sw_controller(
+ sw="1", ip1=ONOS1_ip,port1=default_sw_port)
+ main.Mininet1.assign_sw_controller(
+ sw="2", ip1=ONOS2_ip,port1=default_sw_port)
+ main.Mininet1.assign_sw_controller(
+ sw="3", ip1=ONOS2_ip,port1=default_sw_port)
+ main.Mininet1.assign_sw_controller(
+ sw="4", ip1=ONOS2_ip,port1=default_sw_port)
+ main.Mininet1.assign_sw_controller(
+ sw="5", ip1=ONOS3_ip,port1=default_sw_port)
+
+ main.log.report("Batch intent installation test of "+
+ str(batch_intent_size) +" intents")
+
+ main.log.info("Getting list of available devices")
+ device_id_list = []
+ json_str = main.ONOS1cli.devices()
+ json_obj = json.loads(json_str)
+ for device in json_obj:
+ device_id_list.append(device['id'])
+
+ for i in range(0, int(num_iter)):
+ main.log.info("Pushing "+batch_intent_size+" intents")
+
+ batch_result = main.ONOS1cli.push_test_intents(
+ "of:0000000000000001/1", "of:0000000000000005/2",
+ batch_intent_size)
+
+ time.sleep(5)
+
+
diff --git a/TestON/tests/IntentPerfNext/IntentPerfNext.topo b/TestON/tests/IntentPerfNext/IntentPerfNext.topo
index fbde0e1..75cb259 100644
--- a/TestON/tests/IntentPerfNext/IntentPerfNext.topo
+++ b/TestON/tests/IntentPerfNext/IntentPerfNext.topo
@@ -56,7 +56,7 @@
<arg1> --custom topo-intentFlower.py </arg1>
<arg2> --arp --mac --topo mytopo</arg2>
<arg3> </arg3>
- <controller> remote,ip=10.128.174.1 </controller>
+ <controller> remote </controller>
</COMPONENTS>
</Mininet1>
diff --git a/TestON/tests/MultiProd13/MultiProd13.params b/TestON/tests/MultiProd13/MultiProd13.params
index 2f99555..b60f5cf 100755
--- a/TestON/tests/MultiProd13/MultiProd13.params
+++ b/TestON/tests/MultiProd13/MultiProd13.params
@@ -1,6 +1,6 @@
<PARAMS>
- <testcases>1,4,5,6,7,8,9</testcases>
+ <testcases>1,4,10,31</testcases>
#Environment variables
<ENV>
diff --git a/TestON/tests/MultiProd13/MultiProd13.py b/TestON/tests/MultiProd13/MultiProd13.py
index 1c989c0..d825c62 100755
--- a/TestON/tests/MultiProd13/MultiProd13.py
+++ b/TestON/tests/MultiProd13/MultiProd13.py
@@ -223,9 +223,9 @@
devices1 = main.ONOScli1.devices()
devices2 = main.ONOScli2.devices()
devices3 = main.ONOScli3.devices()
- print "devices1 = ", devices1
- print "devices2 = ", devices2
- print "devices3 = ", devices3
+ #print "devices1 = ", devices1
+ #print "devices2 = ", devices2
+ #print "devices3 = ", devices3
hosts1 = main.ONOScli1.hosts()
hosts2 = main.ONOScli2.hosts()
hosts3 = main.ONOScli3.hosts()
@@ -355,14 +355,33 @@
onpass="Topology Check Test successful",
onfail="Topology Check Test NOT successful")
+
+
+
+ def CASE10(self):
+ main.log.report("This testcase uninstalls the reactive forwarding app")
+ main.log.report("__________________________________")
+ main.case("Uninstalling reactive forwarding app")
+ #Unistall onos-app-fwd app to disable reactive forwarding
+ appUninstall_result1 = main.ONOScli1.feature_uninstall("onos-app-fwd")
+ appUninstall_result2 = main.ONOScli2.feature_uninstall("onos-app-fwd")
+ appUninstall_result3 = main.ONOScli3.feature_uninstall("onos-app-fwd")
+ main.log.info("onos-app-fwd uninstalled")
+
+ #After reactive forwarding is disabled, the reactive flows on switches timeout in 10-15s
+ #So sleep for 15s
+ time.sleep(15)
+
+ case10_result = appUninstall_result1 and appUninstall_result2 and appUninstall_result3
+ utilities.assert_equals(expect=main.TRUE, actual=case10_result,onpass="Reactive forwarding app uninstallation successful",onfail="Reactive forwarding app uninstallation failed")
+
+
def CASE6(self):
main.log.report("This testcase is testing the addition of host intents and then doing pingall")
main.log.report("__________________________________")
- main.case("Uninstalling reactive forwarding app and addhost intents")
+ main.case("Obtaining hostsfor adding host intents")
main.step("Get hosts")
- main.ONOScli1.handle.sendline("hosts")
- main.ONOScli1.handle.expect("onos>")
- hosts = main.ONOScli1.handle.before
+ hosts = main.ONOScli1.hosts()
main.log.info(hosts)
main.step("Get all devices id")
@@ -371,7 +390,8 @@
#ONOS displays the hosts in hex format unlike mininet which does in decimal format
#So take care while adding intents
-
+
+ '''
main.step("Add host intents for mn hosts(h8-h18,h9-h19,h10-h20,h11-h21,h12-h22,h13-h23,h14-h24,h15-h25,h16-h26,h17-h27)")
hth_intent_result = main.ONOScli1.add_host_intent("00:00:00:00:00:08/-1", "00:00:00:00:00:12/-1")
hth_intent_result = main.ONOScli1.add_host_intent("00:00:00:00:00:09/-1", "00:00:00:00:00:13/-1")
@@ -383,16 +403,17 @@
hth_intent_result = main.ONOScli1.add_host_intent("00:00:00:00:00:0F/-1", "00:00:00:00:00:19/-1")
hth_intent_result = main.ONOScli1.add_host_intent("00:00:00:00:00:10/-1", "00:00:00:00:00:1A/-1")
hth_intent_result = main.ONOScli1.add_host_intent("00:00:00:00:00:11/-1", "00:00:00:00:00:1B/-1")
+ '''
-
- #Unistall onos-app-fwd app to disable reactive forwarding
- main.step("Unistall onos-app-fwd app to disable reactive forwarding")
- appUninstall_result = main.ONOScli1.feature_uninstall("onos-app-fwd")
- main.log.info("onos-app-fwd uninstalled")
-
- #After reactive forwarding is disabled, the reactive flows on switches timeout in 10-15s
- #So sleep for 15s
- time.sleep(15)
+ for i in range(8,18):
+ main.log.info("Adding host intent between h"+str(i)+" and h"+str(i+10))
+ host1 = "00:00:00:00:00:" + str(hex(i)[2:]).zfill(2).upper()
+ host2 = "00:00:00:00:00:" + str(hex(i+10)[2:]).zfill(2).upper()
+ #NOTE: get host can return None
+ #TODO: handle this
+ host1_id = main.ONOScli1.get_host(host1)['id']
+ host2_id = main.ONOScli1.get_host(host2)['id']
+ tmp_result = main.ONOScli1.add_host_intent(host1_id, host2_id )
flowHandle = main.ONOScli1.flows()
#print "flowHandle = ", flowHandle
@@ -634,7 +655,7 @@
def CASE8(self):
'''
- Host intents removal
+ Intent removal
'''
main.log.report("This testcase removes host intents before adding the point intents")
main.log.report("__________________________________")
@@ -643,31 +664,37 @@
main.step("Obtain the intent id's")
intent_result = main.ONOScli1.intents()
#print "intent_result = ",intent_result
+
intent_linewise = intent_result.split("\n")
- intent_linewise = intent_linewise[1:-1] #ignore the first and last item of the list obtained from split
- #for line in intent_linewise:
- #print "line = ", line
- intentids = []
+ intentList = []
for line in intent_linewise:
+ if line.startswith("id="):
+ intentList.append(line)
+
+ intentids = []
+ for line in intentList:
intentids.append(line.split(",")[0].split("=")[1])
for id in intentids:
print "id = ", id
-
+
main.step("Iterate through the intentids list and remove each intent")
for id in intentids:
main.ONOScli1.remove_intent(intent_id = id)
-
+
intent_result = main.ONOScli1.intents()
intent_linewise = intent_result.split("\n")
- intent_linewise = intent_linewise[1:-1] #ignore the first and last item of the list obtained from split
-
+ list_afterRemoval = []
+ for line in intent_linewise:
+ if line.startswith("id="):
+ list_afterRemoval.append(line)
+
intentState = {}
- for id, line in zip(intentids, intent_linewise):
+ for id, line in zip(intentids, list_afterRemoval):
#print "line after removing intent = ", line
x = line.split(",")
state = x[1].split("=")[1]
intentState[id] = state
-
+
case8_result = main.TRUE
for key,value in intentState.iteritems():
print "key,value = ", key, value
@@ -676,12 +703,36 @@
else:
case8_result = case8_result and main.FALSE
- if case8_result == main.TRUE:
+ i = 8
+ Ping_Result = main.TRUE
+ while i <18 :
+ main.log.info("\n\nh"+str(i)+" is Pinging h" + str(i+10))
+ ping = main.Mininet1.pingHost(src="h"+str(i),target="h"+str(i+10))
+ if ping==main.TRUE:
+ Ping_Result = main.TRUE
+ elif ping==main.FALSE:
+ i+=1
+ Ping_Result = main.FALSE
+ else:
+ main.log.info("Unknown error")
+ Ping_Result = main.ERROR
+
+ #Note: If the ping result failed, that means the intents have been withdrawn correctly.
+ if Ping_Result==main.TRUE:
+ main.log.report("Host intents have not been withdrawn correctly")
+ #main.cleanup()
+ #main.exit()
+ if Ping_Result==main.FALSE:
+ main.log.report("Host intents have been withdrawn correctly")
+
+ case8_result = case8_result and Ping_Result
+
+ if case8_result == main.FALSE:
main.log.report("Intent removal successful")
else:
main.log.report("Intent removal failed")
- utilities.assert_equals(expect=main.TRUE, actual=case8_result,
+ utilities.assert_equals(expect=main.FALSE, actual=case8_result,
onpass="Intent removal test successful",
onfail="Intent removal test failed")
@@ -867,3 +918,34 @@
onpass="Ping all test after Point intents addition successful",
onfail="Ping all test after Point intents addition failed")
+ def CASE31(self):
+ '''
+ This test case adds point intent related to SDN-IP matching on ICMP (ethertype=IPV4, ipProto=1)
+ '''
+ import json
+
+ main.log.report("This test case adds point intent related to SDN-IP matching on ICMP")
+ main.step("Adding bidirectional point intent")
+ #add-point-intent --ipSrc=10.0.0.8/32 --ipDst=10.0.0.18/32 --ethType=IPV4 --ipProto=1 of:0000000000003008/1 of:0000000000006018/1
+
+ hosts_json = json.loads(main.ONOScli1.hosts())
+ for i in range(8,11):
+ main.log.info("Adding point intent between h"+str(i)+" and h"+str(i+10))
+ host1 = "00:00:00:00:00:" + str(hex(i)[2:]).zfill(2).upper()
+ host2 = "00:00:00:00:00:" + str(hex(i+10)[2:]).zfill(2).upper()
+ host1_id = main.ONOScli1.get_host(host1)['id']
+ host2_id = main.ONOScli1.get_host(host2)['id']
+ for host in hosts_json:
+ if host['id'] == host1_id:
+ ip1 = host['ips']+"/"+"32"
+ device1 = str(host['location']['device'])
+ port1 = 1
+ print "ip1 = ", ip1
+ print "device1 = ", device1
+ elif host['id'] == host2_id:
+ ip2 = str(host['ips'])+"/"+"32"
+ device2 = str(host['location']["device"])
+ port2 = 1
+ print "ip2 = ", ip2
+ print "device2 = ", device2
+
diff --git a/TestON/tests/SdnIpTest/SdnIpTest.params b/TestON/tests/SdnIpTest/SdnIpTest.params
new file mode 100755
index 0000000..9d3627a
--- /dev/null
+++ b/TestON/tests/SdnIpTest/SdnIpTest.params
@@ -0,0 +1,25 @@
+<PARAMS>
+
+ <testcases>1</testcases>
+
+ #Environment variables
+ <ENV>
+ <cellName>driver_test</cellName>
+ </ENV>
+
+ <CTRL>
+ <ip1>127.0.0.1</ip1>
+ <port1>6633</port1>
+ </CTRL>
+
+ <GIT>
+ <autoPull>off</autoPull>
+ <checkout>master</checkout>
+ </GIT>
+
+ <JSON>
+ <prefix>prefix</prefix>
+ <nextHop>nextHop</nextHop>
+ </JSON>
+
+</PARAMS>
diff --git a/TestON/tests/SdnIpTest/SdnIpTest.py b/TestON/tests/SdnIpTest/SdnIpTest.py
new file mode 100755
index 0000000..18b23af
--- /dev/null
+++ b/TestON/tests/SdnIpTest/SdnIpTest.py
@@ -0,0 +1,90 @@
+
+#Testing the basic functionality of SDN-IP
+
+class SdnIpTest:
+ def __init__(self):
+ self.default = ''
+
+ def CASE1(self, main):
+
+ '''
+ Test the SDN-IP functionality
+ '''
+ import time
+ import json
+ from operator import eq
+
+ # all generated routes for all BGP peers
+ allRoutes = []
+
+ main.step("Start to generate routes for BGP peer on host1")
+ routes = main.Quaggacli.generate_routes(1, 3)
+ main.log.info(routes)
+
+ for route in routes:
+ allRoutes.append(route + "/" + "1.1.1.1")
+
+ # start to insert routes into the bgp peer
+ main.step("Start Quagga-cli on host1")
+ main.Quaggacli.loginQuagga("1.1.1.1")
+
+ main.step("Start to configure Quagga on host1")
+ main.Quaggacli.enter_config(64513)
+
+ main.step("Start to generate and add routes for BGP peer on host1")
+ routes = main.Quaggacli.generate_routes(8, 3)
+ main.Quaggacli.add_routes(routes, 1)
+
+ # add generates routes to allRoutes
+ for route in routes:
+ allRoutes.append(route + "/" + "1.1.1.1")
+
+ cell_name = main.params['ENV']['cellName']
+ ONOS1_ip = main.params['CTRL']['ip1']
+
+ main.step("Starting ONOS service")
+ # TODO: start ONOS from Mininet Script
+ # start_result = main.ONOSbench.onos_start("127.0.0.1")
+
+ main.step("Set cell for ONOS-cli environment")
+ main.ONOScli.set_cell(cell_name)
+
+ main.step("Start ONOS-cli")
+ # TODO: change the hardcode in start_onos_cli method in ONOS CLI driver
+ time.sleep(5)
+ main.ONOScli.start_onos_cli(ONOS1_ip)
+
+ main.step("Get devices in the network")
+ list_result = main.ONOScli.devices(json_format=False)
+ main.log.info(list_result)
+
+ #get all routes inside SDN-IP
+ get_routes_result = main.ONOScli.routes(json_format=True)
+
+ # parse routes from ONOS CLI
+ routes_list = []
+ routes_json_obj = json.loads(get_routes_result)
+ for route in routes_json_obj:
+ if route['prefix'] == '172.16.10.0/24':
+ continue
+ routes_list.append(route['prefix'] + "/" + route['nextHop'])
+
+ main.log.info("Start to checking routes")
+ main.log.info("Routes inserted into the system:")
+ main.log.info(sorted(allRoutes))
+ main.log.info("Routes get from ONOS CLI:")
+ main.log.info(sorted(routes_list))
+ utilities.assert_equals(expect=sorted(allRoutes), actual=sorted(routes_list),
+ onpass="***Routes in SDN-IP are correct!***",
+ onfail="***Routes in SDN-IP are wrong!***")
+
+ time.sleep(2)
+ main.step("Get intents installed on ONOS")
+ get_intents_result = main.ONOScli.intents(json_format=True)
+ main.log.info(get_intents_result)
+
+
+ #main.step("Test whether Mininet is started")
+ #main.Mininet2.handle.sendline("xterm host1")
+ #main.Mininet2.handle.expect("mininet>")
+
diff --git a/TestON/tests/SdnIpTest/SdnIpTest.topo b/TestON/tests/SdnIpTest/SdnIpTest.topo
new file mode 100755
index 0000000..1d23878
--- /dev/null
+++ b/TestON/tests/SdnIpTest/SdnIpTest.topo
@@ -0,0 +1,41 @@
+<TOPOLOGY>
+ <COMPONENT>
+
+ <ONOSbench>
+ <host>127.0.0.1</host>
+ <user>sdn</user>
+ <password>rocks</password>
+ <type>OnosDriver</type>
+ <connect_order>1</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOSbench>
+
+ <ONOScli>
+ <host>127.0.0.1</host>
+ <user>sdn</user>
+ <password>rocks</password>
+ <type>OnosCliDriver</type>
+ <connect_order>2</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOScli>
+
+ <ONOS1>
+ <host>127.0.0.1</host>
+ <user>sdn</user>
+ <password>rocks</password>
+ <type>OnosDriver</type>
+ <connect_order>3</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOS1>
+
+ <Quaggacli>
+ <host>127.0.0.1</host>
+ <user>username</user>
+ <password>password</password>
+ <type>QuaggaCliDriver</type>
+ <connect_order>5</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </Quaggacli>
+
+ </COMPONENT>
+</TOPOLOGY>
diff --git a/TestON/tests/SdnIpTest/__init__.py b/TestON/tests/SdnIpTest/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/TestON/tests/SdnIpTest/__init__.py
diff --git a/TestON/tests/TopoConvNext/TopoConvNext.py b/TestON/tests/TopoConvNext/TopoConvNext.py
index 37fb24d..966dc41 100644
--- a/TestON/tests/TopoConvNext/TopoConvNext.py
+++ b/TestON/tests/TopoConvNext/TopoConvNext.py
@@ -54,9 +54,6 @@
main.ONOSbench.onos_uninstall(node_ip = ONOS6_ip)
main.ONOSbench.onos_uninstall(node_ip = ONOS7_ip)
- main.case("Removing raft logs")
- main.ONOSbench.onos_remove_raft_logs()
-
main.log.report("Setting up test environment")
main.step("Creating cell file")
@@ -69,6 +66,9 @@
cell_apply_result = main.ONOSbench.set_cell(cell_name)
verify_cell_result = main.ONOSbench.verify_cell()
+ main.case("Removing raft logs")
+ main.ONOSbench.onos_remove_raft_logs()
+
main.step("Git checkout and pull "+checkout_branch)
if git_pull == 'on':
checkout_result = \
@@ -79,6 +79,9 @@
pull_result = main.TRUE
main.log.info("Skipped git checkout and pull")
+ main.log.report("Commit information - ")
+ main.ONOSbench.get_version()
+
main.step("Using mvn clean & install")
#mvn_result = main.ONOSbench.clean_install()
mvn_result = main.TRUE
@@ -181,10 +184,10 @@
report_str += (str(node) + " ")
main.log.report(report_str)
- main.step("Assigning "+num_sw+" switches to each ONOS")
+ main.step("Distributing "+num_sw+" switches to each ONOS")
index = 1
for node in range(1, cluster_count+1):
- for i in range(index, int(num_sw)+index):
+ for i in range(index, (int(num_sw)/cluster_count)+index):
main.Mininet1.assign_sw_controller(
sw=str(i),
ip1=ONOS_ip_list[node],
@@ -246,9 +249,11 @@
MN1_ip+" --dport "+default_sw_port+" -j DROP")
main.log.info("Please wait for switch connection to timeout")
- time.sleep(60)
- if cluster_count >= 3:
- time.sleep(60)
+
+
+ #time.sleep(60)
+ #if cluster_count >= 3:
+ # time.sleep(60)
if cluster_count >= 5:
time.sleep(30)
if cluster_count >= 6:
@@ -273,16 +278,35 @@
if cluster_count == 7:
main.ONOS7.tshark_grep("SYN, ACK",
"/tmp/syn_ack_onos7_iter"+str(i)+".txt")
+
+ loop_count = 0
+ device_count = 0
+ while loop_count < 60:
+ main.log.info("Checking devices for device down")
+ device_str = main.ONOS1cli.devices()
+ device_json = json.loads(device_str)
+ for device in device_json:
+ if device['available'] == False:
+ print device_count
+ device_count += 1
+ else:
+ device_count = 0
+ if device_count >= int(num_sw)*int(cluster_count):
+ main.step("Flushing iptables and obtaining t0")
+ t0_system = time.time()*1000
+ main.ONOS1.handle.sendline("sudo iptables -F")
+ main.ONOS2.handle.sendline("sudo iptables -F")
+ main.ONOS3.handle.sendline("sudo iptables -F")
+ main.ONOS4.handle.sendline("sudo iptables -F")
+ main.ONOS5.handle.sendline("sudo iptables -F")
+ main.ONOS6.handle.sendline("sudo iptables -F")
+ main.ONOS7.handle.sendline("sudo iptables -F")
+
+ break
+
+ time.sleep(1)
- main.step("Flushing iptables and obtaining t0")
- t0_system = time.time()*1000
- main.ONOS1.handle.sendline("sudo iptables -F")
- main.ONOS2.handle.sendline("sudo iptables -F")
- main.ONOS3.handle.sendline("sudo iptables -F")
- main.ONOS4.handle.sendline("sudo iptables -F")
- main.ONOS5.handle.sendline("sudo iptables -F")
- main.ONOS6.handle.sendline("sudo iptables -F")
- main.ONOS7.handle.sendline("sudo iptables -F")
+ main.log.info("System time t0: "+str(t0_system))
counter_loop = 0
counter_avail1 = 0
@@ -481,7 +505,7 @@
#TODO: Investigate this sleep
# added to 'pad' the results with
# plenty of time to 'catch up'
- time.sleep(20)
+ time.sleep(5)
json_str_metrics_1 =\
main.ONOS1cli.topology_events_metrics()
@@ -506,6 +530,9 @@
graph_lat_3 = \
int(graph_timestamp_3) - int(t0_system)
+ main.log.info("DEBUG: graph_timestamp_1: "+
+ str(graph_timestamp_1))
+
avg_graph_lat = \
(int(graph_lat_1) +\
int(graph_lat_2) +\
@@ -587,7 +614,7 @@
#TODO: Investigate this sleep
# added to 'pad' the results with
# plenty of time to 'catch up'
- time.sleep(20)
+ time.sleep(5)
json_str_metrics_1 =\
main.ONOS1cli.topology_events_metrics()
@@ -726,7 +753,7 @@
#TODO: Investigate this sleep
# added to 'pad' the results with
# plenty of time to 'catch up'
- time.sleep(20)
+ time.sleep(5)
json_str_metrics_1 =\
main.ONOS1cli.topology_events_metrics()
diff --git a/TestON/tests/TopoPerfNext/TopoPerfNext.py b/TestON/tests/TopoPerfNext/TopoPerfNext.py
index a710f82..21f5f44 100644
--- a/TestON/tests/TopoPerfNext/TopoPerfNext.py
+++ b/TestON/tests/TopoPerfNext/TopoPerfNext.py
@@ -75,6 +75,10 @@
pull_result = main.TRUE
main.log.info("Skipped git checkout and pull")
+ #TODO: Uncomment when wiki posting works
+ #main.log.report("Commit information - ")
+ #main.ONOSbench.get_version(report=True)
+
main.step("Using mvn clean & install")
#mvn_result = main.ONOSbench.clean_install()
mvn_result = main.TRUE
@@ -360,6 +364,17 @@
and avg_delta_ofp_graph < threshold_max\
and int(i) > iter_ignore:
latency_ofp_to_graph_list.append(avg_delta_ofp_graph)
+ elif avg_delta_ofp_graph > (-10) and \
+ avg_delta_ofp_graph < 0.0 and\
+ int(i) > iter_ignore:
+ main.log.info("Sub-millisecond result likely; "+
+ "negative result was rounded to 0")
+ #NOTE: Current metrics framework does not
+ #support sub-millisecond accuracy. Therefore,
+ #if the result is negative, we can reasonably
+ #conclude sub-millisecond results and just
+ #append the best rounded effort - 0 ms.
+ latency_ofp_to_graph_list.append(0)
else:
main.log.info("Results for ofp-to-graph "+\
"ignored due to excess in threshold")
@@ -509,7 +524,9 @@
"Avg: "+str(latency_end_to_end_avg)+" ms "+
"Std Deviation: "+latency_end_to_end_std_dev+" ms")
main.log.report("Switch add - OFP-to-Graph latency: "+\
- "Avg: "+str(latency_ofp_to_graph_avg)+" ms "+
+ "Note: results are not accurate to sub-millisecond. "+
+ "Any sub-millisecond results are rounded to 0 ms. ")
+ main.log.report("Avg: "+str(latency_ofp_to_graph_avg)+" ms "+
"Std Deviation: "+latency_ofp_to_graph_std_dev+" ms")
main.log.report("Switch add - TCP-to-OFP latency: "+\
"Avg: "+str(latency_tcp_to_ofp_avg)+" ms "+