Support for multiple switches in cord subscriber test cases.
Configure the uplink olt device map for multiple switches correctly.

Change-Id: Ic263c445b2a14f688a6c08ea03e91b451bf37708
diff --git a/src/test/cordSubscriber/cordSubscriberTest.py b/src/test/cordSubscriber/cordSubscriberTest.py
index 2db3d82..7d72296 100644
--- a/src/test/cordSubscriber/cordSubscriberTest.py
+++ b/src/test/cordSubscriber/cordSubscriberTest.py
@@ -279,21 +279,22 @@
       @classmethod
       def setUpClass(cls):
           '''Load the OLT config and activate relevant apps'''
-          did = cls.load_device_id()
-          network_cfg = { "devices" : {
-                  "{}".format(did) : {
-                        "basic" : {
-                              "driver" : "pmc-olt"
-                              }
-                        }
-                  },
-          }
+          dids = OnosCtrl.get_device_ids()
+          device_map = {}
+          for did in dids:
+                device_map[did] = { 'basic' : { 'driver' : 'pmc-olt' } }
+          network_cfg = {}
+          network_cfg = { 'devices' : device_map }
           ## Restart ONOS with cpqd driver config for OVS
           cls.start_onos(network_cfg = network_cfg)
           cls.install_app_table()
           cls.olt = OltConfig(olt_conf_file = cls.olt_conf_file)
-          OnosCtrl.cord_olt_config(cls.olt.olt_device_data())
+          OnosCtrl.cord_olt_config(cls.olt)
           cls.port_map, cls.port_list = cls.olt.olt_port_map()
+          cls.switches = cls.port_map['switches']
+          cls.num_ports = cls.port_map['num_ports']
+          if cls.num_ports > 1:
+                cls.num_ports -= 1 ##account for the tx port
           cls.activate_apps(cls.apps + cls.olt_apps)
 
       @classmethod
@@ -1161,7 +1162,7 @@
 
       def test_cord_subscriber_join_jump(self):
           """Test subscriber join jump for channel surfing"""
-          self.num_subscribers = 5
+          self.num_subscribers = self.num_ports * len(self.switches)
           self.num_channels = 10
           test_status = self.subscriber_join_verify(num_subscribers = self.num_subscribers,
                                                     num_channels = self.num_channels,
@@ -1173,7 +1174,7 @@
 
       def test_cord_subscriber_join_next(self):
           """Test subscriber join next for channel surfing"""
-          self.num_subscribers = 5
+          self.num_subscribers = self.num_ports * len(self.switches)
           self.num_channels = 10
           test_status = self.subscriber_join_verify(num_subscribers = self.num_subscribers,
                                                     num_channels = self.num_channels,
diff --git a/src/test/igmp/igmpTest.py b/src/test/igmp/igmpTest.py
index 55148a0..c25a8e4 100644
--- a/src/test/igmp/igmpTest.py
+++ b/src/test/igmp/igmpTest.py
@@ -84,7 +84,7 @@
     def setUpClass(cls):
           cls.olt = OltConfig(olt_conf_file = cls.olt_conf_file)
           cls.port_map, _ = cls.olt.olt_port_map()
-          OnosCtrl.cord_olt_config(cls.olt.olt_device_data())
+          OnosCtrl.cord_olt_config(cls.olt)
 
     @classmethod
     def tearDownClass(cls): pass
diff --git a/src/test/netCondition/netConditionTest.py b/src/test/netCondition/netConditionTest.py
index 601eb95..022cfbd 100644
--- a/src/test/netCondition/netConditionTest.py
+++ b/src/test/netCondition/netConditionTest.py
@@ -158,7 +158,7 @@
     def setUpClass(cls):
           cls.olt = OltConfig(olt_conf_file = cls.olt_conf_file)
           cls.port_map, _ = cls.olt.olt_port_map()
-          OnosCtrl.cord_olt_config(cls.olt.olt_device_data())
+          OnosCtrl.cord_olt_config(cls.olt)
           cls.device_id = OnosCtrl.get_device_id()
 
     @classmethod
diff --git a/src/test/subscriber/subscriberTest.py b/src/test/subscriber/subscriberTest.py
index 1a65193..c5a792d 100644
--- a/src/test/subscriber/subscriberTest.py
+++ b/src/test/subscriber/subscriberTest.py
@@ -247,7 +247,7 @@
           else:
                 log.info('Using OLT Port configuration for test setup')
                 log.info('Configuring CORD OLT access device information')
-                OnosCtrl.cord_olt_config(self.olt.olt_device_data())
+                OnosCtrl.cord_olt_config(self.olt)
                 self.activate_apps(self.olt_apps)
 
           self.activate_apps(self.apps)
diff --git a/src/test/utils/Cluster.py b/src/test/utils/Cluster.py
index f361d4d..21120a4 100644
--- a/src/test/utils/Cluster.py
+++ b/src/test/utils/Cluster.py
@@ -65,7 +65,7 @@
     def setUpClass(cls,controller=None):
           cls.olt = OltConfig(olt_conf_file = cls.olt_conf_file)
           cls.port_map, _ = cls.olt.olt_port_map()
-          OnosCtrl.cord_olt_config(cls.olt.olt_device_data(),controller=controller)
+          OnosCtrl.cord_olt_config(cls.olt, controller=controller)
 
     @classmethod
     def tearDownClass(cls): pass
@@ -1708,7 +1708,7 @@
           #time.sleep(2)
           cls.install_app_table(controller=controller)
           cls.olt = OltConfig(olt_conf_file = cls.olt_conf_file)
-          OnosCtrl.cord_olt_config(cls.olt.olt_device_data(),controller=controller)
+          OnosCtrl.cord_olt_config(cls.olt, controller=controller)
           cls.port_map, cls.port_list = cls.olt.olt_port_map()
           cls.activate_apps(cls.apps + cls.olt_apps,controller=controller)
 
diff --git a/src/test/utils/OnosCtrl.py b/src/test/utils/OnosCtrl.py
index 83cdedc..1c49325 100644
--- a/src/test/utils/OnosCtrl.py
+++ b/src/test/utils/OnosCtrl.py
@@ -119,6 +119,21 @@
         return did
 
     @classmethod
+    def get_device_ids(cls):
+        '''If running under olt, we get the first switch connected to onos'''
+        olt = OltConfig()
+        did = 'of:' + get_mac()
+        device_ids = []
+        if olt.on_olt():
+            devices = cls.get_devices()
+            if devices:
+                device_ids = map(lambda d: d['id'], devices)
+        else:
+            device_ids.append(did)
+
+        return device_ids
+
+    @classmethod
     def get_flows(cls, device_id,controller=None):
         if controller is None:
 		url = 'http://%s:8181/onos/v1/flows/' %(cls.controller) + device_id
@@ -131,23 +146,73 @@
         return None
 
     @classmethod
-    def cord_olt_config(cls, olt_device_data = None,controller=None):
+    def get_ports_device(cls, device_id, controller = None):
+        if controller is None:
+            url = 'http://{}:8181/onos/v1/devices/{}/ports'.format(cls.controller, device_id)
+        else:
+            url = 'http://{}:8181/onos/v1/devices/{}/ports'.format(controller, device_id)
+
+        result = requests.get(url, auth = cls.auth)
+        if result.ok:
+            return result.json()['ports']
+        return None
+
+    @classmethod
+    def cord_olt_device_map(cls, olt_config, controller = None):
+        olt_device_list = []
+        olt_port_map, _ = olt_config.olt_port_map()
+        switches = olt_port_map['switches']
+        if len(switches) > 1:
+            device_ids = cls.get_device_ids()
+        else:
+            did = cls.get_device_id()
+            if did is None:
+                return olt_device_list
+            uplink_dict = {}
+            uplink_dict['did'] = did
+            uplink_dict['switch'] = switches[0]
+            uplink_dict['uplink'] = str(olt_config.olt_conf['uplink'])
+            uplink_dict['vlan'] = str(olt_config.olt_conf['vlan'])
+            olt_device_list.append(uplink_dict)
+            return olt_device_list
+
+        for did in device_ids:
+            ports = cls.get_ports_device(did, controller = controller)
+            if ports:
+                matched = False
+                for port in ports:
+                    for switch in switches:
+                        if port['annotations']['portName'] == switch:
+                            uplink_dict = {}
+                            uplink = olt_port_map[switch]['uplink']
+                            uplink_dict['did'] = did
+                            uplink_dict['switch'] = switch
+                            uplink_dict['uplink'] = str(uplink)
+                            uplink_dict['vlan'] = str(olt_config.olt_conf['vlan'])
+                            olt_device_list.append(uplink_dict)
+                            matched = True
+                            break
+                    if matched == True:
+                        break
+
+        return olt_device_list
+
+    @classmethod
+    def cord_olt_config(cls, olt_config, controller=None):
         '''Configures OLT data for existing devices/switches'''
-        if olt_device_data is None:
-            return
         did_dict = {}
         config = { 'devices' : did_dict }
-        devices = cls.get_devices()
-        if not devices:
+        olt_device_list = cls.cord_olt_device_map(olt_config, controller = controller)
+        if not olt_device_list:
             return
-        device_ids = map(lambda d: d['id'], devices)
-        for did in device_ids:
+        for olt_map in olt_device_list:
             access_device_dict = {}
-            access_device_dict['accessDevice'] = olt_device_data
-            did_dict[did] = access_device_dict
+            device_data = {'uplink': olt_map['uplink'], 'vlan': olt_map['vlan']}
+            access_device_dict['accessDevice'] = device_data
+            did_dict[olt_map['did']] = access_device_dict
 
         ##configure the device list with access information
-        return cls.config(config,controller=controller)
+        return cls.config(config, controller=controller)
 
     @classmethod
     def install_app(cls, app_file, onos_ip = None):