Added provision in setup argument to run external dhcp server in cord-tester container and testing it from someother node. Implemented new dhcpl2relay test cases also.
Change-Id: I1e469864f24b1b5b8a1555f037dcd8c3ebdd44e2
diff --git a/src/test/dhcpl2relay/dhcpl2relayTest.py b/src/test/dhcpl2relay/dhcpl2relayTest.py
index fb143cf..f294ccf 100644
--- a/src/test/dhcpl2relay/dhcpl2relayTest.py
+++ b/src/test/dhcpl2relay/dhcpl2relayTest.py
@@ -40,14 +40,23 @@
from OnosCtrl import OnosCtrl
from OltConfig import OltConfig
from CordTestServer import cord_test_onos_restart
+from CordTestConfig import setup_module, teardown_module
from CordLogger import CordLogger
from portmaps import g_subscriber_port_map
+from CordContainer import Onos
import threading, random
from threading import current_thread
log_test.setLevel('INFO')
class dhcpl2relay_exchange(CordLogger):
+ VOLTHA_HOST = None
+ VOLTHA_REST_PORT = 8881
+ VOLTHA_ENABLED = bool(int(os.getenv('VOLTHA_ENABLED', 0)))
+ VOLTHA_OLT_TYPE = 'simulated_olt'
+ VOLTHA_OLT_MAC = '00:0c:e2:31:12:00'
+ VOLTHA_UPLINK_VLAN_MAP = { 'of:0000000000000001' : '222' }
+
app = 'org.opencord.dhcpl2relay'
sadis_app = 'org.opencord.sadis'
app_dhcp = 'org.onosproject.dhcp'
@@ -56,7 +65,9 @@
host_ip_map = {}
test_path = os.path.dirname(os.path.realpath(__file__))
dhcp_data_dir = os.path.join(test_path, '..', 'setup')
- olt_conf_file = os.getenv('OLT_CONFIG_FILE', os.path.join(test_path, '..', 'setup/olt_config.json'))
+ dhcpl2_app_file = os.path.join(test_path, '..', 'apps/dhcpl2relay-1.0.0.oar')
+ sadis_app_file = os.path.join(test_path, '..', 'apps/sadis-app-1.0.0-SNAPSHOT.oar')
+ olt_conf_file = os.getenv('OLT_CONFIG_FILE', os.path.join(test_path, '..', 'setup/olt_config_voltha_local.json'))
default_config = { 'default-lease-time' : 600, 'max-lease-time' : 7200, }
default_options = [ ('subnet-mask', '255.255.255.0'),
('broadcast-address', '192.168.1.255'),
@@ -86,37 +97,73 @@
configs = {}
@classmethod
+ def update_apps_version(cls):
+ version = Onos.getVersion()
+ major = int(version.split('.')[0])
+ minor = int(version.split('.')[1])
+ dhcpl2_app_version = '1.0.0'
+ sadis_app_version = '1.0.0-SNAPSHOT'
+# sadis-app-1.0.0-SNAPSHOT.oar
+# if major > 1:
+# cordigmp_app_version = '3.0-SNAPSHOT'
+# olt_app_version = '2.0-SNAPSHOT'
+# elif major == 1:
+# if minor > 10:
+# cordigmp_app_version = '3.0-SNAPSHOT'
+# olt_app_version = '2.0-SNAPSHOT'
+# elif minor <= 8:
+# olt_app_version = '1.1-SNAPSHOT'
+ cls.dhcpl2_app_file = os.path.join(cls.test_path, '..', 'apps/dhcpl2relay-{}.oar'.format(dhcpl2_app_version))
+ cls.sadis_app_file = os.path.join(cls.test_path, '..', 'apps/sadis-app-{}.oar'.format(sadis_app_version))
+
+
+ @classmethod
def setUpClass(cls):
''' Activate the cord dhcpl2relay app'''
+ cls.update_apps_version()
OnosCtrl(cls.app_dhcp).deactivate()
time.sleep(3)
cls.onos_ctrl = OnosCtrl(cls.app)
status, _ = cls.onos_ctrl.activate()
- assert_equal(status, True)
+ #assert_equal(status, True)
time.sleep(3)
cls.onos_ctrl = OnosCtrl(cls.sadis_app)
status, _ = cls.onos_ctrl.activate()
- assert_equal(status, True)
+ #assert_equal(status, True)
time.sleep(3)
cls.dhcp_l2_relay_setup()
+ cls.cord_sadis_load()
+ cls.cord_l2_relay_load()
##start dhcpd initially with default config
- cls.dhcpd_start()
+ #cls.dhcpd_start()
+
+ def setUp(self):
+ super(dhcpl2relay_exchange, self).setUp()
+
+ def tearDown(self):
+ super(dhcpl2relay_exchange, self).tearDown()
+ OnosCtrl.uninstall_app(cls.dhcpl2_app_file)
+ OnosCtrl.uninstall_app(cls.sadis_app_file)
@classmethod
def tearDownClass(cls):
'''Deactivate the cord dhcpl2relay app'''
- try:
- os.unlink('{}/dhcpd.conf'.format(cls.dhcp_data_dir))
- os.unlink('{}/dhcpd.leases'.format(cls.dhcp_data_dir))
- except: pass
+ #try:
+ # os.unlink('{}/dhcpd.conf'.format(cls.dhcp_data_dir))
+ # os.unlink('{}/dhcpd.leases'.format(cls.dhcp_data_dir))
+ #except: pass
+ OnosCtrl.uninstall_app(cls.dhcpl2_app_file)
+ OnosCtrl.uninstall_app(cls.sadis_app_file)
cls.onos_ctrl.deactivate()
- cls.dhcpd_stop()
+ #cls.dhcpd_stop()
cls.dhcp_l2_relay_cleanup()
@classmethod
def dhcp_l2_relay_setup(cls):
did = OnosCtrl.get_device_id()
- cls.relay_device_id = did
+ #cls.relay_device_id = did
+ ### Have to change hard coded value in relay device variable on later merges
+ cls.relay_device_id = 'of:000012b722fd4948'
cls.olt = OltConfig(olt_conf_file = cls.olt_conf_file)
cls.port_map, _ = cls.olt.olt_port_map()
if cls.port_map:
@@ -146,7 +193,7 @@
relay_ip = cls.get_host_ip(interface_list[0][0])
relay_mac = cls.get_mac(cls.port_map[cls.relay_interface_port])
interface_list.append((cls.relay_interface_port, relay_ip, relay_mac))
- cls.onos_interface_load(interface_list)
+ #cls.onos_interface_load(interface_list)
@classmethod
def dhcp_l2_relay_cleanup(cls):
@@ -184,25 +231,32 @@
@classmethod
def cord_l2_relay_load(cls):
- relay_device_id = '{}'.format(cls.relay_device_id)
- dhcp_dict = {'apps':{'org.opencord.dhcpl2relay':{'dhcpl2relay':
- {'dhcpserverConnectPoint':[relay_device_id]}
+ OnosCtrl.uninstall_app(cls.dhcpl2_app_file)
+ #relay_device_map = '{}/{}'.format(cls.relay_device_id, cls.relay_interface_port)
+ relay_device_map = "{}/veth42".format(cls.relay_device_id)
+ print relay_device_map
+ dhcp_dict = { "apps" : { "org.opencord.dhcpl2relay" : {"dhcpl2relay" :
+ {"dhcpserverConnectPoint":[relay_device_map]}
}
}
}
+ print "---------------------------------------------"
+ print dhcp_dict
+ print "---------------------------------------------"
+ OnosCtrl.uninstall_app(cls.dhcpl2_app_file)
+ OnosCtrl.install_app(cls.dhcpl2_app_file)
cls.onos_load_config(dhcp_dict)
cls.configs['relay_config'] = dhcp_dict
@classmethod
def cord_sadis_load(cls):
relay_device_id = '{}'.format(cls.relay_device_id)
- sadis_dict ={
- "apps": {
+ sadis_dict = { "apps": {
"org.opencord.sadis": {
"sadis": {
"integration": {
"cache": {
- "enabled": true,
+ "enabled": "true",
"maxsize": 50,
"ttl": "PT1m"
}
@@ -214,16 +268,18 @@
"nasPortId": "uni-254"
},
{
- "id": "eaf78b733390456d80fb24113f5150fd",
- "hardwareIdentifier": "00:1b:22:00:b1:78",
- "ipAddress": "192.168.1.252",
+ "id": "67cc7ae085204e3091493db645e8ae63",
+ "hardwareIdentifier": "00:0c:e2:31:05:00",
+ "ipAddress": "172.17.0.1",
"nasId": "B100-NASID"
}
]
- }
- }
- }
+ }
+ }
+ }
}
+ OnosCtrl.uninstall_app(cls.sadis_app_file)
+ OnosCtrl.install_app(cls.sadis_app_file)
cls.onos_load_config(sadis_dict)
cls.configs['relay_config'] = sadis_dict
@@ -231,7 +287,7 @@
def get_host_ip(cls, port):
if cls.host_ip_map.has_key(port):
return cls.host_ip_map[port]
- cls.host_ip_map[port] = '192.168.1.{}'.format(port)
+ cls.host_ip_map[port] = '192.168.100.{}'.format(port)
return cls.host_ip_map[port]
@classmethod
@@ -247,72 +303,6 @@
os.system(c)
@classmethod
- def dhcpd_conf_generate(cls, config = default_config, options = default_options,
- subnet = default_subnet_config):
- conf = ''
- for k, v in config.items():
- conf += '{} {};\n'.format(k, v)
-
- opts = ''
- for k, v in options:
- opts += 'option {} {};\n'.format(k, v)
-
- subnet_config = ''
- for _, v in subnet:
- subnet_config += '{}\n'.format(v)
-
- return '{}{}{}'.format(conf, opts, subnet_config)
-
- @classmethod
- def dhcpd_start(cls, intf_list = None,
- config = default_config, options = default_options,
- subnet = default_subnet_config):
- '''Start the dhcpd server by generating the conf file'''
- if intf_list is None:
- intf_list = cls.relay_interfaces
- ##stop dhcpd if already running
- cls.dhcpd_stop()
- dhcp_conf = cls.dhcpd_conf_generate(config = config, options = options,
- subnet = subnet)
- ##first touch dhcpd.leases if it doesn't exist
- lease_file = '{}/dhcpd.leases'.format(cls.dhcp_data_dir)
- if os.access(lease_file, os.F_OK) is False:
- with open(lease_file, 'w') as fd: pass
-
- conf_file = '{}/dhcpd.conf'.format(cls.dhcp_data_dir)
- with open(conf_file, 'w') as fd:
- fd.write(dhcp_conf)
-
- #now configure the dhcpd interfaces for various subnets
- index = 0
- intf_info = []
- for ip,_ in subnet:
- intf = intf_list[index]
- mac = cls.get_mac(intf)
- intf_info.append((ip, mac))
- index += 1
- os.system('ifconfig {} {}'.format(intf, ip))
-
- intf_str = ','.join(intf_list)
- dhcpd_cmd = '/usr/sbin/dhcpd -4 --no-pid -cf {0} -lf {1} {2}'.format(conf_file, lease_file, intf_str)
- log_test.info('Starting DHCPD server with command: %s' %dhcpd_cmd)
- ret = os.system(dhcpd_cmd)
- assert_equal(ret, 0)
- time.sleep(3)
- cls.relay_interfaces_last = cls.relay_interfaces
- cls.relay_interfaces = intf_list
- cls.cord_l2_relay_load()
- cls.cord_sadis_load()
-
- @classmethod
- def dhcpd_stop(cls):
- os.system('pkill -9 dhcpd')
- for intf in cls.relay_interfaces:
- os.system('ifconfig {} 0'.format(intf))
-
- cls.relay_interfaces = cls.relay_interfaces_last
-
- @classmethod
def get_mac(cls, iface):
if cls.interface_to_mac_map.has_key(iface):
return cls.interface_to_mac_map[iface]
@@ -368,17 +358,6 @@
def test_dhcpl2relay_with_one_request(self, iface = 'veth0'):
mac = self.get_mac(iface)
- self.host_load(iface)
- ##we use the defaults for this test that serves as an example for others
- ##You don't need to restart dhcpd server if retaining default config
- config = self.default_config
- options = self.default_options
- subnet = self.default_subnet_config
- dhcpd_interface_list = self.relay_interfaces
- self.dhcpd_start(intf_list = dhcpd_interface_list,
- config = config,
- options = options,
- subnet = subnet)
self.dhcp = DHCPTest(seed_ip = '10.10.10.1', iface = iface)
self.send_recv(mac=mac)
@@ -405,7 +384,7 @@
def test_dhcpl2relay_with_N_requests(self, iface = 'veth0',requests=10):
mac = self.get_mac(iface)
- self.dhcp = DHCPTest(seed_ip = '192.169.1.1', iface = iface)
+ self.dhcp = DHCPTest(seed_ip = '192.169.100.1', iface = iface)
ip_map = {}
for i in range(requests):
#mac = RandMAC()._fix()
diff --git a/src/test/setup/cord-test.py b/src/test/setup/cord-test.py
index 66dd299..cef7e57 100755
--- a/src/test/setup/cord-test.py
+++ b/src/test/setup/cord-test.py
@@ -60,6 +60,25 @@
'cordSubscriber', 'vrouter', 'flows', 'proxyarp', 'acl', 'xos', 'fabric',
'cbench', 'cluster', 'netCondition', 'cordvtn', 'iperf', 'mini', 'vsg')
+ dhcp_data_dir = os.path.join(tester_base, '..', 'setup')
+ default_config = { 'default-lease-time' : 600, 'max-lease-time' : 7200, }
+ default_options = [ ('subnet-mask', '255.255.255.0'),
+ ('broadcast-address', '192.168.1.255'),
+ ('domain-name-servers', '192.168.1.1'),
+ ('domain-name', '"mydomain.cord-tester"'),
+ ]
+ default_subnet_config = [ ('192.168.1.2',
+'''
+subnet 192.168.1.0 netmask 255.255.255.0 {
+ range 192.168.1.10 192.168.1.100;
+}
+'''), ]
+ host_ip_map = {}
+ relay_interfaces_last = ()
+ interface_to_mac_map = {}
+ configs = {}
+
+
def __init__(self, tests, instance = 0, num_instances = 1, ctlr_ip = None,
name = '', image = IMAGE, prefix = '', tag = 'candidate',
env = None, rm = False, update = False, network = None):
@@ -215,6 +234,148 @@
self.switch_started = True
+ def setup_dhcpd(self, manifest, boot_delay = 5):
+ if manifest.start_switch:
+ switch_starts = True
+ else:
+ return False
+ setup_for_relay = self.dhcp_relay_setup()
+ dhcp_start_status = self.dhcpd_start()
+ if setup_for_relay and dhcp_start_status:
+ return True
+ else:
+ return False
+
+ def dhcp_relay_setup(self):
+ did = OnosCtrl.get_device_id()
+ self.relay_device_id = did
+ #self.olt = OltConfig(olt_conf_file = self.olt_conf_file)
+ #self.port_map, _ = self.olt.olt_port_map()
+ if self.port_map:
+ ##Per subscriber, we use 1 relay port
+ try:
+ relay_port = self.port_map[self.port_map['relay_ports'][0]]
+ except:
+ relay_port = self.port_map['uplink']
+ self.relay_interface_port = relay_port
+ self.relay_interfaces = (self.port_map[self.relay_interface_port],)
+ else:
+ print 'Setup dhcpd we must have port_map'
+ return False
+ if self.port_map:
+ ##generate a ip/mac client virtual interface config for onos
+ interface_list = []
+ for port in self.port_map['ports']:
+ port_num = self.port_map[port]
+ if port_num == self.port_map['uplink']:
+ continue
+ ip = self.get_host_ip(port_num)
+ mac = self.get_mac(port)
+ interface_list.append((port_num, ip, mac))
+
+ #configure dhcp server virtual interface on the same subnet as first client interface
+ relay_ip = self.get_host_ip(interface_list[0][0])
+ relay_mac = self.get_mac(self.port_map[self.relay_interface_port])
+ interface_list.append((self.relay_interface_port, relay_ip, relay_mac))
+ self.onos_interface_load(interface_list)
+ return True
+
+ def onos_load_config(cls, config):
+ status, code = OnosCtrl.config(config)
+ if status is False:
+ log_test.info('JSON request returned status %d' %code)
+ assert_equal(status, True)
+ time.sleep(3)
+
+ def onos_interface_load(cls, interface_list):
+ interface_dict = { 'ports': {} }
+ for port_num, ip, mac in interface_list:
+ port_map = interface_dict['ports']
+ port = '{}/{}'.format(cls.relay_device_id, port_num)
+ port_map[port] = { 'interfaces': [] }
+ interface_list = port_map[port]['interfaces']
+ interface_map = { 'ips' : [ '{}/{}'.format(ip, 24) ],
+ 'mac' : mac,
+ 'name': 'vir-{}'.format(port_num)
+ }
+ interface_list.append(interface_map)
+
+ cls.onos_load_config(interface_dict)
+ cls.configs['interface_config'] = interface_dict
+
+ def get_host_ip(cls, port):
+ if cls.host_ip_map.has_key(port):
+ return cls.host_ip_map[port]
+ cls.host_ip_map[port] = '192.168.100.{}'.format(port)
+ return cls.host_ip_map[port]
+
+ def get_mac(cls, iface):
+ if cls.interface_to_mac_map.has_key(iface):
+ return cls.interface_to_mac_map[iface]
+ mac = get_mac(iface, pad = 0)
+ cls.interface_to_mac_map[iface] = mac
+ return mac
+
+ def dhcpd_conf_generate(cls, config = default_config, options = default_options,
+ subnet = default_subnet_config):
+ conf = ''
+ for k, v in config.items():
+ conf += '{} {};\n'.format(k, v)
+
+ opts = ''
+ for k, v in options:
+ opts += 'option {} {};\n'.format(k, v)
+
+ subnet_config = ''
+ for _, v in subnet:
+ subnet_config += '{}\n'.format(v)
+
+ return '{}{}{}'.format(conf, opts, subnet_config)
+
+ def dhcpd_start(cls, intf_list = None,
+ config = default_config, options = default_options,
+ subnet = default_subnet_config):
+ '''Start the dhcpd server by generating the conf file'''
+ if intf_list is None:
+ intf_list = cls.relay_interfaces
+ ##stop dhcpd if already running
+ #cls.dhcpd_stop()
+ dhcp_conf = cls.dhcpd_conf_generate(config = config, options = options,
+ subnet = subnet)
+ ##first touch dhcpd.leases if it doesn't exist
+ lease_file = '{}/dhcpd.leases'.format(cls.dhcp_data_dir)
+ if os.access(lease_file, os.F_OK) is False:
+ with open(lease_file, 'w') as fd: pass
+
+ conf_file = '{}/dhcpd.conf'.format(cls.dhcp_data_dir)
+ with open(conf_file, 'w') as fd:
+ fd.write(dhcp_conf)
+
+ #now configure the dhcpd interfaces for various subnets
+ index = 0
+ intf_info = []
+ for ip,_ in subnet:
+ intf = intf_list[index]
+ mac = cls.get_mac(intf)
+ intf_info.append((ip, mac))
+ index += 1
+ cmd = 'ifconfig {} {}'.format(intf, ip)
+ status = cls.execute(cmd, shell = True)
+
+ intf_str = ','.join(intf_list)
+ dhcpd_cmd = '/usr/sbin/dhcpd -4 --no-pid -cf {0} -lf {1} {2}'.format('/root/test/src/test/setup/dhcpd.conf','/root/test/src/test/setup/dhcpd.leases', intf_str)
+ print('Starting DHCPD server with command: %s' %dhcpd_cmd)
+ status = cls.execute(dhcpd_cmd, shell = True)
+ if status > 255:
+ status = 1
+ else:
+ return False
+ time.sleep(3)
+ cls.relay_interfaces_last = cls.relay_interfaces
+ cls.relay_interfaces = intf_list
+ #cls.onos_dhcp_relay_load(*intf_info[0])
+ return True
+
def setup_vcpes(self, port_num = 0):
res = 0
for vcpe in self.vcpes:
@@ -1070,6 +1231,8 @@
test_cnt.start_switch(test_manifest)
if test_cnt.olt:
test_cnt.setup_intfs(port_num = 0)
+ if test_manifest.setup_dhcpd and test_manifest.start_switch:
+ test_cnt.setup_dhcpd(test_manifest)
print('Test container %s started and provisioned to run tests using nosetests' %(test_cnt.name))
#Finally start the test server and daemonize
@@ -1389,6 +1552,7 @@
choices=['DEBUG','TRACE','ERROR','WARN','INFO'],
help='Specify the log level for the test cases')
parser_setup.add_argument('-s', '--start-switch', action='store_true', help='Start OVS when running under OLT config')
+ parser_setup.add_argument('-dh', '--setup-dhcpd', action='store_true', help='Start dhcpd Server in external container may be in cord-tester')
parser_setup.add_argument('-onos-cord', '--onos-cord', default='', type=str,
help='Specify config location for ONOS cord when running on podd')
parser_setup.add_argument('-service-profile', '--service-profile', default='', type=str,
diff --git a/src/test/utils/TestManifest.py b/src/test/utils/TestManifest.py
index 17bc370..5d29f37 100644
--- a/src/test/utils/TestManifest.py
+++ b/src/test/utils/TestManifest.py
@@ -50,6 +50,7 @@
self.olt = args.olt
self.olt_config = args.olt_config
self.start_switch = args.start_switch
+ self.setup_dhcpd = args.setup_dhcpd
self.image_prefix = args.prefix
self.onos_image = args.onos
self.test_controller = args.test_controller
@@ -90,6 +91,7 @@
self.olt = data.get('olt', True)
self.olt_config = data.get('olt_config', 'olt_config.json')
self.start_switch = data.get('start_switch', self.olt)
+ self.setup_dhcpd = data.get('setup_dhcpd', self.start_switch)
self.image_prefix = data.get('image_prefix', '')
self.onos_image = data.get('onos_image', 'onosproject/onos:latest')
self.docker_network = data.get('docker_network', None)