Test: Support for ONOS cluster mode startup with --onos-instances option to cord-test.py setup.
Changes to igmpTest to do a rover join test with support for parallel test runs across multiple containers.
Change-Id: If9c01df4c2ff5f2f6961eef9ff6fa865abb29b53
diff --git a/src/test/utils/ACL.py b/src/test/utils/ACL.py
index 1492868..ccae5d5 100644
--- a/src/test/utils/ACL.py
+++ b/src/test/utils/ACL.py
@@ -26,7 +26,7 @@
class ACLTest:
auth = ('karaf', 'karaf')
- controller = os.getenv('ONOS_CONTROLLER_IP') or 'localhost'
+ controller = OnosCtrl.get_controller()
add_acl_rule_url = 'http://%s:8181/onos/v1/acl/rules' %(controller)
remove_acl_rule_url = 'http://%s:8181/onos/v1/acl/rules/%s' %(controller, id)
clear_all_acl_rule_url = 'http://%s:8181/onos/v1/acl/rules' %(controller)
@@ -51,7 +51,7 @@
def adding_acl_rule(self, ipv4Prefix, srcIp, dstIp, ipProto ='null', dstTpPort='null', action= 'include'):
'''This function is generating ACL json file and post to ONOS for creating a ACL rule'''
if ipv4Prefix is 'v4':
- acl_dict = {}
+ acl_dict = {}
if srcIp and dstIp and action:
acl_dict['srcIp'] = '{}'.format(srcIp)
acl_dict['dstIp'] = '{}'.format(dstIp)
@@ -78,7 +78,7 @@
remove_acl_rule_url = 'http://%s:8181/onos/v1/acl/rules/%s' %(cls.controller, id)
resp = requests.delete(remove_acl_rule_url, auth = cls.auth)
return resp.ok, resp.status_code
-
+
def generate_onos_interface_config(self,iface_num = 4, iface_name = 'null',iface_count = 1,iface_ip = '198.162.10.1'):
'''This function is generate interface config data in json format and post to ONOS for creating it '''
''' To add interfaces on ONOS to test acl with trffic'''
diff --git a/src/test/utils/CordContainer.py b/src/test/utils/CordContainer.py
index 63443b9..6f8e037 100644
--- a/src/test/utils/CordContainer.py
+++ b/src/test/utils/CordContainer.py
@@ -117,10 +117,18 @@
return self.image_name in [ctn['RepoTags'][0] if ctn['RepoTags'] else '' for ctn in self.dckr.images()]
def ip(self):
- cnt_list = filter(lambda c: c['Image'] == self.image_name, self.dckr.containers())
+ cnt_list = filter(lambda c: c['Names'][0] == '/{}'.format(self.name), self.dckr.containers())
+ #if not cnt_list:
+ # cnt_list = filter(lambda c: c['Image'] == self.image_name, self.dckr.containers())
cnt_settings = cnt_list.pop()
return cnt_settings['NetworkSettings']['Networks']['bridge']['IPAddress']
+ @classmethod
+ def ips(cls, image_name):
+ cnt_list = filter(lambda c: c['Image'] == image_name, cls.dckr.containers())
+ ips = [ cnt['NetworkSettings']['Networks']['bridge']['IPAddress'] for cnt in cnt_list ]
+ return ips
+
def kill(self, remove = True):
self.dckr.kill(self.name)
self.dckr.remove_container(self.name, force=True)
@@ -287,8 +295,12 @@
host_config_dir = os.path.join(setup_dir, 'onos-config')
guest_config_dir = '/root/onos/config'
onos_gen_partitions = os.path.join(setup_dir, 'onos-gen-partitions')
+ onos_form_cluster = os.path.join(setup_dir, 'onos-form-cluster')
cord_apps_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', 'apps')
host_guest_map = ( (host_config_dir, guest_config_dir), )
+ cluster_cfg = os.path.join(host_config_dir, 'cluster.json')
+ cluster_mode = False
+ cluster_instances = []
NAME = 'cord-onos'
##the ip of ONOS in default cluster.json in setup/onos-config
CLUSTER_CFG_IP = '172.17.0.2'
@@ -297,14 +309,26 @@
PREFIX = ''
@classmethod
- def onos_generate_cluster_cfg(cls, ip):
+ def generate_cluster_cfg(cls, ip):
+ if type(ip) in [ list, tuple ]:
+ ips = ' '.join(ip)
+ else:
+ ips = ip
try:
- cmd = '{} {}/cluster.json {}'.format(cls.onos_gen_partitions, cls.host_config_dir, ip)
+ cmd = '{} {} {}'.format(cls.onos_gen_partitions, cls.cluster_cfg, ips)
+ os.system(cmd)
+ except: pass
+
+ @classmethod
+ def form_cluster(cls, ips):
+ nodes = ' '.join(ips)
+ try:
+ cmd = '{} {}'.format(cls.onos_form_cluster, nodes)
os.system(cmd)
except: pass
def __init__(self, name = NAME, image = 'onosproject/onos', prefix = '', tag = 'latest',
- boot_delay = 60, restart = False, network_cfg = None):
+ boot_delay = 60, restart = False, network_cfg = None, cluster = False):
if restart is True:
##Find the right image to restart
running_image = filter(lambda c: c['Names'][0] == '/{}'.format(name), self.dckr.containers())
@@ -316,40 +340,145 @@
except: pass
super(Onos, self).__init__(name, image, prefix = prefix, tag = tag, quagga_config = self.quagga_config)
+ self.boot_delay = boot_delay
+ if cluster is True:
+ self.ports = []
+ if os.access(self.cluster_cfg, os.F_OK):
+ try:
+ os.unlink(self.cluster_cfg)
+ except: pass
+
+ self.host_config = self.create_host_config(port_list = self.ports,
+ host_guest_map = self.host_guest_map)
+ self.volumes = []
+ for _,g in self.host_guest_map:
+ self.volumes.append(g)
+
if restart is True and self.exists():
self.kill()
+
if not self.exists():
self.remove_container(name, force=True)
- host_config = self.create_host_config(port_list = self.ports,
- host_guest_map = self.host_guest_map)
- volumes = []
- for _,g in self.host_guest_map:
- volumes.append(g)
if network_cfg is not None:
json_data = json.dumps(network_cfg, indent=4)
with open('{}/network-cfg.json'.format(self.host_config_dir), 'w') as f:
f.write(json_data)
print('Starting ONOS container %s' %self.name)
self.start(ports = self.ports, environment = self.env,
- host_config = host_config, volumes = volumes, tty = True)
+ host_config = self.host_config, volumes = self.volumes, tty = True)
if not restart:
##wait a bit before fetching IP to regenerate cluster cfg
time.sleep(5)
ip = self.ip()
##Just a quick hack/check to ensure we don't regenerate in the common case.
##As ONOS is usually the first test container that is started
- if ip != self.CLUSTER_CFG_IP:
- print('Regenerating ONOS cluster cfg for ip %s' %ip)
- self.onos_generate_cluster_cfg(ip)
- self.kill()
- self.remove_container(self.name, force=True)
- print('Restarting ONOS container %s' %self.name)
- self.start(ports = self.ports, environment = self.env,
- host_config = host_config, volumes = volumes, tty = True)
+ if cluster is False:
+ if ip != self.CLUSTER_CFG_IP or not os.access(self.cluster_cfg, os.F_OK):
+ print('Regenerating ONOS cluster cfg for ip %s' %ip)
+ self.generate_cluster_cfg(ip)
+ self.kill()
+ self.remove_container(self.name, force=True)
+ print('Restarting ONOS container %s' %self.name)
+ self.start(ports = self.ports, environment = self.env,
+ host_config = self.host_config, volumes = self.volumes, tty = True)
print('Waiting %d seconds for ONOS to boot' %(boot_delay))
time.sleep(boot_delay)
+ self.ipaddr = self.ip()
+ if cluster is False:
+ self.install_cord_apps(self.ipaddr)
- self.install_cord_apps()
+ @classmethod
+ def setup_cluster_deprecated(cls, onos_instances, image_name = None):
+ if not onos_instances or len(onos_instances) < 2:
+ return
+ ips = []
+ if image_name is not None:
+ ips = Container.ips(image_name)
+ else:
+ for onos in onos_instances:
+ ips.append(onos.ipaddr)
+ Onos.cluster_instances = onos_instances
+ Onos.cluster_mode = True
+ ##regenerate the cluster json with the 3 instance ips before restarting them back
+ print('Generating cluster cfg for ONOS instances with ips %s' %ips)
+ Onos.generate_cluster_cfg(ips)
+ for onos in onos_instances:
+ onos.kill()
+ onos.remove_container(onos.name, force=True)
+ print('Restarting ONOS container %s for forming cluster' %onos.name)
+ onos.start(ports = onos.ports, environment = onos.env,
+ host_config = onos.host_config, volumes = onos.volumes, tty = True)
+ print('Waiting %d seconds for ONOS %s to boot' %(onos.boot_delay, onos.name))
+ time.sleep(onos.boot_delay)
+ onos.ipaddr = onos.ip()
+ onos.install_cord_apps(onos.ipaddr)
+
+ @classmethod
+ def setup_cluster(cls, onos_instances, image_name = None):
+ if not onos_instances or len(onos_instances) < 2:
+ return
+ ips = []
+ if image_name is not None:
+ ips = Container.ips(image_name)
+ else:
+ for onos in onos_instances:
+ ips.append(onos.ipaddr)
+ Onos.cluster_instances = onos_instances
+ Onos.cluster_mode = True
+ ##regenerate the cluster json with the 3 instance ips before restarting them back
+ print('Forming cluster for ONOS instances with ips %s' %ips)
+ Onos.form_cluster(ips)
+ ##wait for the cluster to be formed
+ print('Waiting for the cluster to be formed')
+ time.sleep(60)
+ for onos in onos_instances:
+ onos.install_cord_apps(onos.ipaddr)
+
+ @classmethod
+ def restart_cluster(cls, network_cfg = None):
+ if cls.cluster_mode is False:
+ return
+ if not cls.cluster_instances:
+ return
+
+ if network_cfg is not None:
+ json_data = json.dumps(network_cfg, indent=4)
+ with open('{}/network-cfg.json'.format(cls.host_config_dir), 'w') as f:
+ f.write(json_data)
+
+ for onos in cls.cluster_instances:
+ if onos.exists():
+ onos.kill()
+ onos.remove_container(onos.name, force=True)
+ print('Restarting ONOS container %s' %onos.name)
+ onos.start(ports = onos.ports, environment = onos.env,
+ host_config = onos.host_config, volumes = onos.volumes, tty = True)
+ print('Waiting %d seconds for ONOS %s to boot' %(onos.boot_delay, onos.name))
+ time.sleep(onos.boot_delay)
+ onos.ipaddr = onos.ip()
+
+ ##form the cluster
+ cls.setup_cluster(cls.cluster_instances)
+
+ @classmethod
+ def cluster_ips(cls):
+ if cls.cluster_mode is False:
+ return []
+ if not cls.cluster_instances:
+ return []
+ ips = [ onos.ipaddr for onos in cls.cluster_instances ]
+ return ips
+
+ @classmethod
+ def cleanup_cluster(cls):
+ if cls.cluster_mode is False:
+ return
+ if not cls.cluster_instances:
+ return
+ for onos in cls.cluster_instances:
+ if onos.exists():
+ onos.kill()
+ onos.remove_container(onos.name, force=True)
@classmethod
def install_cord_apps(cls, onos_ip = None):
diff --git a/src/test/utils/CordTestServer.py b/src/test/utils/CordTestServer.py
index 47b84e3..7b60620 100644
--- a/src/test/utils/CordTestServer.py
+++ b/src/test/utils/CordTestServer.py
@@ -53,7 +53,10 @@
if self.onos_cord:
self.onos_cord.start(restart = True, network_cfg = config)
else:
- Onos(restart = True, network_cfg = config, image = Onos.IMAGE, tag = Onos.TAG)
+ if Onos.cluster_mode is True:
+ Onos.restart_cluster(network_cfg = config)
+ else:
+ Onos(restart = True, network_cfg = config, image = Onos.IMAGE, tag = Onos.TAG)
return 'DONE'
def restart_onos(self, kwargs):
diff --git a/src/test/utils/EapTLS.py b/src/test/utils/EapTLS.py
index 8f31509..f4e7346 100644
--- a/src/test/utils/EapTLS.py
+++ b/src/test/utils/EapTLS.py
@@ -33,7 +33,11 @@
log.setLevel('INFO')
def bytes_to_num(data):
- return int(data.encode('hex'), 16)
+ try:
+ return int(data.encode('hex'), 16)
+ except:
+ print('Exception')
+ return -1
class TLSAuthTest(EapolPacket, CordTester):
@@ -239,10 +243,14 @@
else:
self.pkt_update(self.pkt_last, tls_data)
self.pending_bytes -= len(tls_data)
-
+ print('Offset: %d, pkt : %d, pending %d\n' %(offset, len(pkt), self.pending_bytes))
while self.pending_bytes == 0 and offset < len(pkt):
tls_data = r[offset:]
+ hexdump(tls_data)
self.pending_bytes = bytes_to_num(tls_data[3:5])
+ if self.pending_bytes < 0:
+ self.pending_bytes = 0
+ return
if tls_data[0] == self.HANDSHAKE:
pkt_type = tls_data[5]
if pkt_type in [ self.CERTIFICATE_REQUEST ]:
diff --git a/src/test/utils/OnosCtrl.py b/src/test/utils/OnosCtrl.py
index 6083d85..29f9080 100644
--- a/src/test/utils/OnosCtrl.py
+++ b/src/test/utils/OnosCtrl.py
@@ -33,10 +33,15 @@
sep = ':'
return '0'*pad + sep.join(['%02x' %ord(char) for char in info[18:24]])
+def get_controller():
+ controller = os.getenv('ONOS_CONTROLLER_IP') or 'localhost'
+ controller = controller.split(',')[0]
+ return controller
+
class OnosCtrl:
auth = ('karaf', 'karaf')
- controller = os.getenv('ONOS_CONTROLLER_IP') or 'localhost'
+ controller = get_controller()
cfg_url = 'http://%s:8181/onos/v1/network/configuration/' %(controller)
maven_repo = 'http://central.maven.org/maven2/org/onosproject'
applications_url = 'http://%s:8181/onos/v1/applications' %(controller)
diff --git a/src/test/utils/OnosFlowCtrl.py b/src/test/utils/OnosFlowCtrl.py
index 295a7ab..5b2da52 100644
--- a/src/test/utils/OnosFlowCtrl.py
+++ b/src/test/utils/OnosFlowCtrl.py
@@ -23,7 +23,7 @@
class OnosFlowCtrl:
auth = ('karaf', 'karaf')
- controller = os.getenv('ONOS_CONTROLLER_IP') or 'localhost'
+ controller = OnosCtrl.get_controller()
cfg_url = 'http://%s:8181/onos/v1/flows/' %(controller)
def __init__( self,