Test: Reorg. cord-tester code in general.
Change test cases to use olt configuration as appropriate when switch isn't running in the test container.
Remove olt multitable config and fold into olt_config.
Rename subscriberMultiTable to cordSubscriber test.
Change the eval script to reflect the new changes/design in cord tester.

Change-Id: I4849b32603ac790a31ba7cfb65b3f87a7c9e2076
diff --git a/src/test/subscriberMultiTable/__init__.py b/src/test/cordSubscriber/__init__.py
similarity index 100%
rename from src/test/subscriberMultiTable/__init__.py
rename to src/test/cordSubscriber/__init__.py
diff --git a/src/test/subscriberMultiTable/subscriberMultiTableTest.py b/src/test/cordSubscriber/cordSubscriberTest.py
similarity index 96%
rename from src/test/subscriberMultiTable/subscriberMultiTableTest.py
rename to src/test/cordSubscriber/cordSubscriberTest.py
index 75c9392..7f002df 100644
--- a/src/test/subscriberMultiTable/subscriberMultiTableTest.py
+++ b/src/test/cordSubscriber/cordSubscriberTest.py
@@ -19,7 +19,6 @@
 from threadPool import ThreadPool
 from portmaps import g_subscriber_port_map
 from OltConfig import *
-from OnosFlowCtrl import get_mac
 from CordTestServer import cord_test_onos_restart
 
 log.setLevel('INFO')
@@ -176,7 +175,7 @@
       table_app_file = os.path.join(test_path, '..', 'apps/ciena-cordigmp-multitable-2.0-SNAPSHOT.oar')
       app_file = os.path.join(test_path, '..', 'apps/ciena-cordigmp-2.0-SNAPSHOT.oar')
       onos_config_path = os.path.join(test_path, '..', 'setup/onos-config')
-      olt_conf_file = os.path.join(test_path, '..', 'setup/olt_config_multitable.json')
+      olt_conf_file = os.path.join(test_path, '..', 'setup/olt_config.json')
       cpqd_path = os.path.join(test_path, '..', 'setup')
       ovs_path = cpqd_path
       test_services = ('IGMP', 'TRAFFIC')
@@ -187,20 +186,8 @@
 
       @classmethod
       def load_device_id(cls):
-            '''If running under olt, we get the first switch connected to onos'''
-            olt = os.getenv('OLT_CONFIG', None)
-            if olt:
-                  devices = OnosCtrl.get_devices()
-                  if devices:
-                        dids = map(lambda d: d['id'], devices)
-                        if len(dids) == 1:
-                              did = dids[0]
-                        else:
-                              ###If we have more than 1, then check for env before using first one
-                              did = os.getenv('OLT_DEVICE_ID', dids[0])
-            else:
-                  did = 'of:' + get_mac('ovsbr0')
-
+            '''Configure the device id'''
+            did = OnosCtrl.get_device_id()
             #Set the default config
             cls.device_id = did
             cls.device_dict = { "devices" : {
@@ -230,7 +217,7 @@
           cls.install_app_table()
           cls.olt = OltConfig(olt_conf_file = cls.olt_conf_file)
           OnosCtrl.cord_olt_config(cls.olt.olt_device_data())
-          cls.port_map, cls.port_list = cls.olt.olt_port_map_multi()
+          cls.port_map, cls.port_list = cls.olt.olt_port_map()
           cls.activate_apps(cls.apps + cls.olt_apps)
 
       @classmethod
diff --git a/src/test/dhcp/dhcpTest.py b/src/test/dhcp/dhcpTest.py
index 8f14e65..38eb839 100644
--- a/src/test/dhcp/dhcpTest.py
+++ b/src/test/dhcp/dhcpTest.py
@@ -57,7 +57,7 @@
     @classmethod
     def setUpClass(cls):
         cls.olt = OltConfig()
-        cls.port_map = cls.olt.olt_port_map()
+        cls.port_map, _ = cls.olt.olt_port_map()
         if not cls.port_map:
             cls.port_map = g_subscriber_port_map
         cls.iface = cls.port_map[1]
diff --git a/src/test/dhcprelay/dhcprelayTest.py b/src/test/dhcprelay/dhcprelayTest.py
index 3b95586..769177b 100644
--- a/src/test/dhcprelay/dhcprelayTest.py
+++ b/src/test/dhcprelay/dhcprelayTest.py
@@ -21,8 +21,8 @@
 import time
 import os, sys
 from DHCP import DHCPTest
-from OnosCtrl import OnosCtrl
-from OnosFlowCtrl import get_mac
+from OnosCtrl import OnosCtrl, get_mac
+from OltConfig import OltConfig
 from portmaps import g_subscriber_port_map
 import threading, random
 from threading import current_thread
@@ -32,9 +32,7 @@
 
     app = 'org.onosproject.dhcprelay'
     app_dhcp = 'org.onosproject.dhcp'
-    relay_device_id = 'of:' + get_mac('ovsbr0')
-    relay_interface_port = 100
-    relay_interfaces = (g_subscriber_port_map[relay_interface_port],)
+    relay_interfaces_last = ()
     interface_to_mac_map = {}
     dhcp_data_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', 'setup')
     default_config = { 'default-lease-time' : 600, 'max-lease-time' : 7200, }
@@ -74,6 +72,7 @@
         status, _ = cls.onos_ctrl.activate()
         assert_equal(status, True)
         time.sleep(3)
+        cls.dhcp_relay_setup()
         ##start dhcpd initially with default config
         cls.dhcpd_start()
         cls.onos_dhcp_relay_load()
@@ -89,6 +88,20 @@
         cls.dhcpd_stop()
 
     @classmethod
+    def dhcp_relay_setup(cls):
+        did = OnosCtrl.get_device_id()
+        cls.relay_device_id = did
+        cls.olt = OltConfig()
+        cls.port_map, _ = cls.olt.olt_port_map()
+        if cls.port_map:
+            cls.relay_interface_port = cls.port_map['uplink']
+            cls.relay_interfaces = (cls.port_map[cls.relay_interface_port],)
+        else:
+            cls.relay_interface_port = 100
+            cls.relay_interfaces = (g_subscriber_port_map[cls.relay_interface_port],)
+        cls.relay_interfaces_last = cls.relay_interfaces
+
+    @classmethod
     def onos_load_config(cls, config):
         status, code = OnosCtrl.config(config)
         if status is False:
@@ -133,10 +146,12 @@
         return '{}{}{}'.format(conf, opts, subnet_config)
 
     @classmethod
-    def dhcpd_start(cls, intf_list = relay_interfaces,
+    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,
@@ -163,6 +178,7 @@
         ret = os.system(dhcpd_cmd)
         assert_equal(ret, 0)
         time.sleep(3)
+        cls.relay_interfaces_last = cls.relay_interfaces
         cls.relay_interfaces = intf_list
 
     @classmethod
@@ -171,6 +187,8 @@
         for intf in cls.relay_interfaces:
             os.system('ifconfig {} 0'.format(intf))
 
+        cls.relay_interfaces = cls.relay_interfaces_last
+
     def get_mac(self, iface):
         if self.interface_to_mac_map.has_key(iface):
             return self.interface_to_mac_map[iface]
@@ -226,8 +244,6 @@
         self.total_success += self.ip_count
 	self.total_failure += self.failure_count
 
-
-
     def send_recv(self, mac, update_seed = False, validate = True):
         cip, sip = self.dhcp.discover(mac = mac, update_seed = update_seed)
         if validate:
@@ -269,6 +285,7 @@
         self.dhcp = DHCPTest(seed_ip = '192.169.1.1', iface = iface)
         ip_map = {}
         for i in range(10):
+            mac = RandMAC()._fix()
             cip, sip = self.send_recv(mac, update_seed = True)
             if ip_map.has_key(cip):
                 log.info('IP %s given out multiple times' %cip)
@@ -300,7 +317,7 @@
         assert_equal(self.dhcp.release(cip2), True)
 
     def test_dhcpRelay_Nrelease(self, iface = 'veth0'):
-        mac = self.get_mac(iface)
+        mac = None
         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
@@ -351,29 +368,6 @@
                          config = config,
                          options = options,
                          subnet = subnet)
-        self.dhcp = DHCPTest(seed_ip = '192.169.1.1', iface = iface)
-        ip_map = {}
-        for i in range(10):
-            cip, sip = self.send_recv(mac, update_seed = True)
-            if ip_map.has_key(cip):
-                log.info('IP %s given out multiple times' %cip)
-                assert_equal(False, ip_map.has_key(cip))
-            ip_map[cip] = sip
-
-
-    def test_dhcpRelay_starvation(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 = '182.17.0.1', iface = iface)
         log.info('Verifying 1 ')
         while True:
diff --git a/src/test/flows/flowsTest.py b/src/test/flows/flowsTest.py
index 78eec17..8fa51fb 100644
--- a/src/test/flows/flowsTest.py
+++ b/src/test/flows/flowsTest.py
@@ -23,7 +23,7 @@
 import threading
 import os
 from OnosCtrl import OnosCtrl
-from OnosFlowCtrl import OnosFlowCtrl, get_mac
+from OnosFlowCtrl import OnosFlowCtrl
 from OltConfig import OltConfig
 import random
 from threading import current_thread
@@ -98,15 +98,13 @@
         return '.'.join(lst)
 
 
-
-
     @classmethod
     def setUpClass(cls):
         cls.olt = OltConfig()
-        cls.port_map = cls.olt.olt_port_map()
+        cls.port_map, _ = cls.olt.olt_port_map()
         if not cls.port_map:
             cls.port_map = cls.default_port_map
-        cls.device_id = 'of:' + get_mac() ##match against our device id
+        cls.device_id = OnosCtrl.get_device_id()
 
     def test_flow_mac(self):
         '''Test Add and verify flows with MAC selectors'''
diff --git a/src/test/proxyarp/proxyarpTest.py b/src/test/proxyarp/proxyarpTest.py
index a9083b9..5fbf28a 100644
--- a/src/test/proxyarp/proxyarpTest.py
+++ b/src/test/proxyarp/proxyarpTest.py
@@ -16,9 +16,9 @@
 import unittest
 from nose.tools import *
 from scapy.all import *
-from OnosCtrl import OnosCtrl
+from OnosCtrl import OnosCtrl, get_mac
 from OltConfig import OltConfig
-from OnosFlowCtrl import OnosFlowCtrl, get_mac
+from OnosFlowCtrl import OnosFlowCtrl
 from onosclidriver import OnosCliDriver
 from CordContainer import Container, Onos, Quagga
 from CordTestServer import cord_test_onos_restart, cord_test_quagga_restart
@@ -54,16 +54,30 @@
     @classmethod
     def setUpClass(cls):
         cls.olt = OltConfig()
-        cls.port_map = cls.olt.olt_port_map()
+        cls.port_map, _ = cls.olt.olt_port_map()
         if not cls.port_map:
             cls.port_map = g_subscriber_port_map
         time.sleep(3)
+        cls.load_device_id()
 
     @classmethod
     def tearDownClass(cls):
         '''Deactivate the vrouter apps'''
         #cls.vrouter_host_unload()
 
+    @classmethod
+    def load_device_id(cls):
+        did = OnosCtrl.get_device_id()
+        cls.device_id = did
+        cls.device_dict = { "devices" : {
+                "{}".format(did) : {
+                    "basic" : {
+                        "driver" : "softrouter"
+                    }
+                }
+            },
+        }
+
     def cliEnter(self):
         retries = 0
         while retries < 3:
diff --git a/src/test/setup/cord-test.py b/src/test/setup/cord-test.py
index ba8e2ee..022a192 100755
--- a/src/test/setup/cord-test.py
+++ b/src/test/setup/cord-test.py
@@ -59,7 +59,7 @@
             self.olt = True
             olt_conf_file = os.path.join(self.tester_base, 'olt_config.json')
             olt_config = OltConfig(olt_conf_file)
-            self.port_map = olt_config.olt_port_map()
+            self.port_map, _ = olt_config.olt_port_map()
         else:
             self.olt = False
             self.port_map = None
@@ -130,7 +130,7 @@
     def cleanup_intfs(cls):
         olt_conf_file = os.path.join(cls.tester_base, 'olt_config.json')
         olt_config = OltConfig(olt_conf_file)
-        port_map = olt_config.olt_port_map()
+        port_map, _ = olt_config.olt_port_map()
         port_num = 0
         intf_host = port_map['host']
         start_vlan = port_map['start_vlan']
@@ -275,7 +275,7 @@
 
     test_containers = []
     #These tests end up restarting ONOS/quagga/radius
-    tests_exempt = ('vrouter',)
+    tests_exempt = ('vrouter', 'cordSubscriber', 'proxyarp')
     if args.test_type.lower() == 'all':
         tests = CordTester.ALL_TESTS
         args.quagga = True
diff --git a/src/test/setup/eval.sh b/src/test/setup/eval.sh
index 51513c9..663674e 100755
--- a/src/test/setup/eval.sh
+++ b/src/test/setup/eval.sh
@@ -8,11 +8,31 @@
 docker kill cord-onos || true
 docker kill cord-quagga || true
 docker kill cord-radius || true
+olt_config="$(dirname $0)/olt_config.json"
+sub=0
+if grep -q br-int $olt_config; then
+  sub=1
+fi
+if [ $sub -eq 1 ]; then
+    sed -i 's,br-int,ovsbr0,g' $olt_config
+fi
+function finish {
+    $cord_tester cleanup --olt
+    pkill -f cord-test
+    if [ $sub -eq 1 ]; then
+        sed -i 's,ovsbr0,br-int,g' $olt_config
+    fi
+}
+trap finish EXIT
+$cord_tester setup --olt --start-switch
+cnt=`docker ps -lq`
 echo "Running TLS authentication test"
-$cord_tester run -r -t tls
-echo "Running DHCP request test"
-$cord_tester run -t dhcp
+docker exec $cnt nosetests -v /root/test/src/test/tls/tlsTest.py
+echo "Running DHCP relay request test"
+docker exec $cnt nosetests -v /root/test/src/test/dhcprelay/dhcprelayTest.py:dhcprelay_exchange.test_dhcpRelay_1request
 echo "Running IGMP join verify test"
-$cord_tester run -t igmp:igmp_exchange.test_igmp_join_verify_traffic
+docker exec $cnt nosetests -v /root/test/src/test/igmp/igmpTest.py:igmp_exchange.test_igmp_join_verify_traffic
 echo "Running VROUTER test with 5 routes"
-$cord_tester run -q -t vrouter:vrouter_exchange.test_vrouter_1
+docker exec $cnt nosetests -v /root/test/src/test/vrouter/vrouterTest.py:vrouter_exchange.test_vrouter_with_5_routes
+echo "Running CORD subscriber channel join jump test"
+docker exec $cnt nosetests -v /root/test/src/test/cordSubscriber/cordSubscriberTest.py:subscriber_exchange.test_subscriber_join_jump
diff --git a/src/test/setup/olt_config.json b/src/test/setup/olt_config.json
index db00a33..36070f7 100644
--- a/src/test/setup/olt_config.json
+++ b/src/test/setup/olt_config.json
@@ -1,2 +1 @@
-{ "olt" : false , "port_map" : { "ports" : [ "veth0", "veth2", "veth4", "veth6", "veth8", "veth10" ], "tx" : "veth2", "rx" : "veth0", "host" : "br-int", "start_vlan" : 1000 }, "uplink" : 2, "vlan" : 0 }
-
+{ "olt" : false , "port_map" : { "num_ports" : 11, "host" : "br-int", "start_vlan" : 1000 }, "uplink" : 2, "vlan" : 0 }
diff --git a/src/test/setup/olt_config_multitable.json b/src/test/setup/olt_config_multitable.json
deleted file mode 100644
index 6d4f4dc..0000000
--- a/src/test/setup/olt_config_multitable.json
+++ /dev/null
@@ -1,2 +0,0 @@
-{ "olt" : false , "port_map" : { "port" : "veth0", "num_ports" : 100, "host" : "br-int", "start_vlan" : 1000 }, "uplink" : 2, "vlan" : 0 }
-  
diff --git a/src/test/subscriber/subscriberTest.py b/src/test/subscriber/subscriberTest.py
index 6359636..ab1e6a7 100644
--- a/src/test/subscriber/subscriberTest.py
+++ b/src/test/subscriber/subscriberTest.py
@@ -237,7 +237,7 @@
       def setUp(self):
           '''Load the OLT config and activate relevant apps'''
           self.olt = OltConfig()
-          self.port_map = self.olt.olt_port_map()
+          self.port_map, _ = self.olt.olt_port_map()
           ##if no olt config, fall back to ovs port map
           if not self.port_map:
                 self.port_map = g_subscriber_port_map
diff --git a/src/test/utils/OltConfig.py b/src/test/utils/OltConfig.py
index bb78563..ac5f5db 100644
--- a/src/test/utils/OltConfig.py
+++ b/src/test/utils/OltConfig.py
@@ -38,34 +38,12 @@
     def olt_port_map(self):
         if self.on_olt() and self.olt_conf.has_key('port_map'):
             port_map = {}
-            port_map['ports'] = self.olt_conf['port_map']['ports']
-            port_map['start_vlan'] = 0
-            if self.olt_conf['port_map'].has_key('host'):
-                port_map['host'] = self.olt_conf['port_map']['host']
-            else:
-                port_map['host'] = 'ovsbr0'
-            if self.olt_conf['port_map'].has_key('start_vlan'):
-                port_map['start_vlan'] = int(self.olt_conf['port_map']['start_vlan'])
-                
-            ##Build a rx/tx port number to interface map
-            port_map[1] = self.olt_conf['port_map']['rx']
-            port_map[2] = self.olt_conf['port_map']['tx']
-            port_map[port_map[1]] = 1
-            port_map[port_map[2]] = 2
-            return port_map
-        else:
-            return None
-
-    def olt_port_map_multi(self):
-        if self.on_olt() and self.olt_conf.has_key('port_map'):
-            port_map = {}
             if self.olt_conf['port_map'].has_key('ports'):
                 port_map['ports'] = self.olt_conf['port_map']['ports']
             else:
                 port_map['ports'] = []
                 num_ports = int(self.olt_conf['port_map']['num_ports'])
-                port_map['port'] = self.olt_conf['port_map']['port']
-                for port in xrange(0, num_ports, 2):
+                for port in xrange(0, num_ports*2, 2):
                     port_map['ports'].append('veth{}'.format(port))
             port_num = 1
             port_map['uplink'] = int(self.olt_conf['uplink'])
diff --git a/src/test/utils/OnosCtrl.py b/src/test/utils/OnosCtrl.py
index e323112..9c73b4a 100644
--- a/src/test/utils/OnosCtrl.py
+++ b/src/test/utils/OnosCtrl.py
@@ -16,6 +16,20 @@
 import json
 import requests
 import os,sys,time
+from OltConfig import OltConfig
+import fcntl, socket, struct
+
+def get_mac(iface = 'ovsbr0', pad = 4):
+    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+    try:
+        info = fcntl.ioctl(s.fileno(), 0x8927, struct.pack('256s', bytes(iface[:15])))
+    except:
+        info = ['0'] * 24
+    s.close()
+    sep = ''
+    if pad == 0:
+        sep = ':'
+    return '0'*pad + sep.join(['%02x' %ord(char) for char in info[18:24]])
 
 class OnosCtrl:
 
@@ -61,6 +75,24 @@
         return None
 
     @classmethod
+    def get_device_id(cls):
+        '''If running under olt, we get the first switch connected to onos'''
+        olt = OltConfig()
+        if olt.on_olt():
+            devices = cls.get_devices()
+            if devices:
+                dids = map(lambda d: d['id'], devices)
+                if len(dids) == 1:
+                    did = dids[0]
+                else:
+                    ###If we have more than 1, then check for env before using first one
+                    did = os.getenv('OLT_DEVICE_ID', dids[0])
+            else:
+                  did = 'of:' + get_mac('ovsbr0')
+
+        return did
+
+    @classmethod
     def get_flows(cls, device_id):
         url = 'http://%s:8181/onos/v1/flows/' %(cls.controller) + device_id
         result = requests.get(url, auth = cls.auth)
diff --git a/src/test/utils/OnosFlowCtrl.py b/src/test/utils/OnosFlowCtrl.py
index f1b72cf..295a7ab 100644
--- a/src/test/utils/OnosFlowCtrl.py
+++ b/src/test/utils/OnosFlowCtrl.py
@@ -19,19 +19,6 @@
 from nose.tools import *
 from scapy.all import *
 from OnosCtrl import OnosCtrl
-import fcntl, socket, struct
-
-def get_mac(iface = 'ovsbr0', pad = 4):
-    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
-    try:
-        info = fcntl.ioctl(s.fileno(), 0x8927, struct.pack('256s', iface[:15]))
-    except:
-        info = ['0'] * 24
-    s.close()
-    sep = ''
-    if pad == 0:
-        sep = ':'
-    return '0'*pad + sep.join(['%02x' %ord(char) for char in info[18:24]])
 
 class OnosFlowCtrl:
 
diff --git a/src/test/vrouter/vrouterTest.py b/src/test/vrouter/vrouterTest.py
index b69bf5c..8e602ee 100644
--- a/src/test/vrouter/vrouterTest.py
+++ b/src/test/vrouter/vrouterTest.py
@@ -16,9 +16,9 @@
 import unittest
 from nose.tools import *
 from scapy.all import *
-from OnosCtrl import OnosCtrl
+from OnosCtrl import OnosCtrl, get_mac
 from OltConfig import OltConfig
-from OnosFlowCtrl import OnosFlowCtrl, get_mac
+from OnosFlowCtrl import OnosFlowCtrl
 from onosclidriver import OnosCliDriver
 #from quaggaclidriver import QuaggaCliDriver
 from CordContainer import Container, Onos, Quagga
@@ -82,16 +82,30 @@
     def setUpClass(cls):
         ''' Activate the vrouter apps'''
         cls.olt = OltConfig()
-        cls.port_map = cls.olt.olt_port_map()
+        cls.port_map, _ = cls.olt.olt_port_map()
         if not cls.port_map:
             cls.port_map = g_subscriber_port_map
         time.sleep(3)
+        cls.load_device_id()
 
     @classmethod
     def tearDownClass(cls):
         '''Deactivate the vrouter apps'''
         #cls.vrouter_host_unload()
 
+    @classmethod
+    def load_device_id(cls):
+        did = OnosCtrl.get_device_id()
+        cls.device_id = did
+        cls.vrouter_device_dict = { "devices" : {
+                "{}".format(did) : {
+                    "basic" : {
+                        "driver" : "softrouter"
+                    }
+                }
+            },
+        }
+
     def cliEnter(self):
         retries = 0
         while retries < 3: