Test: Changes to subscriber multitable test to work with latest ONOS.
Use CPQD over OVS with pmc-olt pipeline driver to test igmp/multicast groupid flows.

Change-Id: I83f8b3f378aee7fa3da2c8d99df128b8cd85035b
diff --git a/src/test/apps/ciena-cordigmp-multitable-2.0-SNAPSHOT.oar b/src/test/apps/ciena-cordigmp-multitable-2.0-SNAPSHOT.oar
new file mode 100644
index 0000000..892d066
--- /dev/null
+++ b/src/test/apps/ciena-cordigmp-multitable-2.0-SNAPSHOT.oar
Binary files differ
diff --git a/src/test/apps/ciena-cordigmp.multi-table/pom.xml b/src/test/apps/ciena-cordigmp.multi-table/pom.xml
index 4c49010..a9f8c85 100644
--- a/src/test/apps/ciena-cordigmp.multi-table/pom.xml
+++ b/src/test/apps/ciena-cordigmp.multi-table/pom.xml
@@ -17,23 +17,39 @@
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

     <modelVersion>4.0.0</modelVersion>

 

+        <parent>

+        <groupId>org.onosproject</groupId>

+        <artifactId>onos</artifactId>

+        <version>1.6.0-rc2</version>

+        <relativePath></relativePath>

+    </parent>

+

     <groupId>org.ciena.cordigmp</groupId>

     <artifactId>ciena-cordigmp</artifactId>

-    <version>1.0-SNAPSHOT</version>

+    <version>2.0-SNAPSHOT</version>

     <packaging>bundle</packaging>

 

+          <repositories>

+        <repository>

+          <id>oss-staging</id>

+          <name>OSS Staging</name>

+          <url>https://oss.sonatype.org/content/groups/staging</url>

+        </repository>

+      </repositories>

+

     <description>Ciena CORD IGMP for OVS</description>

     <url>http://onosproject.org</url>

 

     <properties>

         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

-        <onos.version>1.6.0-SNAPSHOT</onos.version>

+        <onos.version>1.6.0-rc2</onos.version>

         <onos.app.name>org.ciena.cordigmp</onos.app.name>

         <onos.app.title>Ciena IGMP for OVS</onos.app.title>

         <onos.app.origin>Ciena Inc.</onos.app.origin>

         <onos.app.category>default</onos.app.category>

         <onos.app.url>http://onosproject.org</onos.app.url>

         <onos.app.readme>ONOS OSGi bundle archetype.</onos.app.readme>

+        <onos.app.requires>org.opencord.config</onos.app.requires>

     </properties>

 

     <dependencies>

@@ -44,9 +60,9 @@
         </dependency>

 

         <dependency>

-            <groupId>org.onosproject</groupId>

-            <artifactId>onos-cord-config</artifactId>

-            <version>${onos.version}</version>

+            <groupId>org.opencord</groupId>

+            <artifactId>cord-config</artifactId>

+            <version>1.0-SNAPSHOT</version>

         </dependency>

 

         <dependency>

@@ -63,14 +79,6 @@
         </dependency>

 

         <dependency>

-            <groupId>org.onosproject</groupId>

-            <artifactId>onos-api</artifactId>

-            <version>${onos.version}</version>

-            <scope>test</scope>

-            <classifier>tests</classifier>

-        </dependency>

-

-        <dependency>

             <groupId>org.apache.felix</groupId>

             <artifactId>org.apache.felix.scr.annotations</artifactId>

             <version>1.9.12</version>

@@ -92,6 +100,25 @@
         <artifactId>guava</artifactId>

         <version>19.0</version>

       </dependency>

+

+              <dependency>

+            <groupId>org.onosproject</groupId>

+            <artifactId>onlab-misc</artifactId>

+            <version>${onos.version}</version>

+        </dependency>

+

+        <dependency>

+            <groupId>org.onosproject</groupId>

+            <artifactId>onos-incubator-api</artifactId>

+            <version>${onos.version}</version>

+        </dependency>

+

+        <dependency>

+            <groupId>org.onosproject</groupId>

+            <artifactId>onos-core-common</artifactId>

+            <version>${onos.version}</version>

+        </dependency>

+

     </dependencies>

 

     <build>

diff --git a/src/test/apps/ciena-cordigmp.multi-table/src/main/java/org/ciena/cordigmp/CordIgmp.java b/src/test/apps/ciena-cordigmp.multi-table/src/main/java/org/ciena/cordigmp/CordIgmp.java
index 5b252d2..441a0a4 100644
--- a/src/test/apps/ciena-cordigmp.multi-table/src/main/java/org/ciena/cordigmp/CordIgmp.java
+++ b/src/test/apps/ciena-cordigmp.multi-table/src/main/java/org/ciena/cordigmp/CordIgmp.java
@@ -15,7 +15,6 @@
  */
 package org.ciena.cordigmp;
 
-import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.apache.felix.scr.annotations.Activate;
@@ -29,8 +28,8 @@
 import org.onlab.packet.IpAddress;
 import org.onlab.packet.VlanId;
 import org.onosproject.cfg.ComponentConfigService;
-import org.onosproject.cordconfig.access.AccessDeviceConfig;
-import org.onosproject.cordconfig.access.AccessDeviceData;
+import org.opencord.cordconfig.access.AccessDeviceConfig;
+import org.opencord.cordconfig.access.AccessDeviceData;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.core.CoreService;
 import org.onosproject.net.ConnectPoint;
@@ -60,9 +59,7 @@
 import org.osgi.service.component.ComponentContext;
 import org.slf4j.Logger;
 
-import java.io.IOException;
 import java.util.Dictionary;
-import java.util.List;
 import java.util.Map;
 import java.util.Properties;
 import java.util.concurrent.ConcurrentHashMap;
@@ -185,7 +182,7 @@
         Dictionary<?, ?> properties = context != null ? context.getProperties() : new Properties();
 
         try {
-            
+
             String s = get(properties, "mcastVlan");
             mcastVlan = isNullOrEmpty(s) ? DEFAULT_MCAST_VLAN : Short.parseShort(s.trim());
 
@@ -239,8 +236,8 @@
         TrafficSelector.Builder metabuilder = DefaultTrafficSelector.builder()
             .matchEthType(Ethernet.TYPE_IPV4)
             .matchIPDst(info.route().group().toIpPrefix());
-        if(vlanEnabled) {
-            metabuilder.matchVlanId(VlanId.vlanId((short)mcastVlan));
+        if (vlanEnabled) {
+            metabuilder.matchVlanId(VlanId.vlanId((short) mcastVlan));
         }
         NextObjective next = DefaultNextObjective.builder()
                 .fromApp(appId)
@@ -379,7 +376,7 @@
 
             flowObjectiveService.next(sink.deviceId(), next);
 
-            log.info("Append flows for device {}, id {}, ip {}", sink.deviceId(), nextId, 
+            log.info("Append flows for device {}, id {}, ip {}", sink.deviceId(), nextId,
                      route.group().toIpPrefix());
         }
 
diff --git a/src/test/apps/ciena-cordigmp.multi-table/src/main/java/org/ciena/cordigmp/package-info.java b/src/test/apps/ciena-cordigmp.multi-table/src/main/java/org/ciena/cordigmp/package-info.java
new file mode 100644
index 0000000..75494c5
--- /dev/null
+++ b/src/test/apps/ciena-cordigmp.multi-table/src/main/java/org/ciena/cordigmp/package-info.java
@@ -0,0 +1,8 @@
+/**
+ * Ciena application for cord tester to provision flows with ovs.
+ * This is required as OVS onos driver does not support multi-table inserts.
+ * This application takes a port pair configuration per group to provision flows.
+ * To be used in simulation environments with subscriber tests.
+ * On the target, cordmcast app should be used.
+ */
+package org.ciena.cordigmp;
diff --git a/src/test/setup/of-bridge.sh b/src/test/setup/of-bridge.sh
index 1375fb5..eff43d3 100755
--- a/src/test/setup/of-bridge.sh
+++ b/src/test/setup/of-bridge.sh
@@ -7,12 +7,14 @@
 if [ x"$controller" = "x" ]; then
   controller=$ONOS_CONTROLLER_IP
 fi
+pkill -9 ofdatapath
+pkill -9 ofprotocol
 service openvswitch-switch restart
 num_ports=200
 ports=$(($num_ports-1))
 for vports in $(seq 0 2 $ports); do
    echo "Deleting veth$vports"
-   ip link del veth$vports
+   ip link del veth$vports 2>/dev/null
 done
 for vports in $(seq 0 2 $ports); do
   ip link add type veth
diff --git a/src/test/subscriber/subscriberDb.py b/src/test/subscriber/subscriberDb.py
index 9f689e4..6a8dbd1 100644
--- a/src/test/subscriber/subscriberDb.py
+++ b/src/test/subscriber/subscriberDb.py
@@ -1,12 +1,12 @@
-# 
+#
 # Copyright 2016-present Ciena Corporation
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
 # You may obtain a copy of the License at
-# 
+#
 # http://www.apache.org/licenses/LICENSE-2.0
-# 
+#
 # Unless required by applicable law or agreed to in writing, software
 # distributed under the License is distributed on an "AS IS" BASIS,
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -17,12 +17,15 @@
 import sys
 
 class SubscriberDB:
-    def __init__(self, db = 'subscriber.db', create = False):
+
+    default_services = ('TLS', 'DHCP', 'IGMP')
+
+    def __init__(self, db = 'subscriber.db', create = False, services = default_services):
         self.db = db
         self.con = sqlite3.connect(db)
         self.con.row_factory = sqlite3.Row
         self.cur = self.con.cursor()
-        self.services = [ 'TLS', 'DHCP', 'IGMP' ]
+        self.services = services
         self.create = create
         if create == True:
             self.cur.execute("DROP TABLE IF EXISTS Subscriber")
diff --git a/src/test/subscriberMultiTable/subscriberMultiTableTest.py b/src/test/subscriberMultiTable/subscriberMultiTableTest.py
index a619e7f..c245bd0 100644
--- a/src/test/subscriberMultiTable/subscriberMultiTableTest.py
+++ b/src/test/subscriberMultiTable/subscriberMultiTableTest.py
@@ -163,29 +163,39 @@
 
       aaa_loaded = False
       test_path = os.path.dirname(os.path.realpath(__file__))
-      table_app_file = os.path.join(test_path, '..', 'apps/ciena-cordigmp-multitable-1.0-SNAPSHOT.oar')
-      app_file = os.path.join(test_path, '..', 'apps/ciena-cordigmp-1.0-SNAPSHOT.oar')
+      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')
       cpqd_path = os.path.join(test_path, '..', 'setup')
       ovs_path = cpqd_path
       device_id = 'of:' + get_mac('ovsbr0')
-      cpqd_device_dict = { "devices" : {
+      device_dict = { "devices" : {
                   "{}".format(device_id) : {
                         "basic" : {
-                              "driver" : "spring-open-cpqd"
+                              "driver" : "pmc-olt"
                               }
                         }
                   },
               }
+      test_services = ('IGMP',)
 
       @classmethod
       def setUpClass(cls):
           '''Load the OLT config and activate relevant apps'''
-          ## First restart ONOS with cpqd driver config for OVS
-          #cls.start_onos(network_cfg = cls.cpqd_device_dict)
+          device_id = cls.start_cpqd(mac = RandMAC()._fix())
+          network_cfg = { "devices" : {
+                  "{}".format(device_id) : {
+                        "basic" : {
+                              "driver" : "pmc-olt"
+                              }
+                        }
+                  },
+          }
+          cls.device_id = device_id
+          ## Restart ONOS with cpqd driver config for OVS
+          cls.start_onos(network_cfg = network_cfg)
           cls.install_app_table()
-          cls.start_cpqd(mac = RandMAC()._fix())
           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()
@@ -199,6 +209,7 @@
               onos_ctrl = OnosCtrl(app)
               onos_ctrl.deactivate()
           cls.uninstall_app_table()
+          cls.remove_onos_config()
           cls.start_ovs()
 
       @classmethod
@@ -229,7 +240,7 @@
       @classmethod
       def start_onos(cls, network_cfg = None):
             if network_cfg is None:
-                  network_cfg = cls.cpqd_device_dict
+                  network_cfg = cls.device_dict
 
             if type(network_cfg) is tuple:
                   res = []
@@ -243,7 +254,16 @@
             with open('{}/network-cfg.json'.format(cls.onos_config_path), 'w') as f:
                   f.write(cfg)
 
-            return cord_test_onos_restart()
+            try:
+                  return cord_test_onos_restart()
+            except:
+                  return False
+
+      @classmethod
+      def remove_onos_config(cls):
+            try:
+                  os.unlink('{}/network-cfg.json'.format(cls.onos_config_path))
+            except: pass
 
       @classmethod
       def start_cpqd(cls, mac = '00:11:22:33:44:55'):
@@ -253,13 +273,15 @@
             ret = os.system(cpqd_cmd)
             assert_equal(ret, 0)
             time.sleep(10)
+            device_id = 'of:{}{}'.format('0'*4, dpid)
+            return device_id
 
       @classmethod
       def start_ovs(cls):
-            ovs_file = os.sep.join( (cls.ovs_path, 'of-bridge-local.sh') )
+            ovs_file = os.sep.join( (cls.ovs_path, 'of-bridge.sh') )
             ret = os.system(ovs_file)
             assert_equal(ret, 0)
-            time.sleep(2)
+            time.sleep(30)
 
       def onos_aaa_load(self):
             if self.aaa_loaded:
@@ -319,28 +341,40 @@
       def tls_verify(self, subscriber):
             if subscriber.has_service('TLS'):
                   time.sleep(2)
-                  tls = TLSAuthTest()
+                  tls = TLSAuthTest(intf = subscriber.rx_intf)
                   log.info('Running subscriber %s tls auth test' %subscriber.name)
                   tls.runTest()
                   self.test_status = True
 
       def dhcp_verify(self, subscriber):
-            cip, sip = self.dhcp_request(subscriber, update_seed = True)
-            log.info('Subscriber %s got client ip %s from server %s' %(subscriber.name, cip, sip))
-            subscriber.src_list = [cip]
-            self.test_status = True
+            if subscriber.has_service('DHCP'):
+                  cip, sip = self.dhcp_request(subscriber, update_seed = True)
+                  log.info('Subscriber %s got client ip %s from server %s' %(subscriber.name, cip, sip))
+                  subscriber.src_list = [cip]
+                  self.test_status = True
+            else:
+                  subscriber.src_list = ['10.10.10.{}'.format(subscriber.rx_port)]
+                  self.test_status = True
 
       def dhcp_jump_verify(self, subscriber):
-          cip, sip = self.dhcp_request(subscriber, seed_ip = '10.10.200.1')
-          log.info('Subscriber %s got client ip %s from server %s' %(subscriber.name, cip, sip))
-          subscriber.src_list = [cip]
-          self.test_status = True
+            if subscriber.has_service('DHCP'):
+                  cip, sip = self.dhcp_request(subscriber, seed_ip = '10.10.200.1')
+                  log.info('Subscriber %s got client ip %s from server %s' %(subscriber.name, cip, sip))
+                  subscriber.src_list = [cip]
+                  self.test_status = True
+            else:
+                  subscriber.src_list = ['10.10.10.{}'.format(subscriber.rx_port)]
+                  self.test_status = True
 
       def dhcp_next_verify(self, subscriber):
-          cip, sip = self.dhcp_request(subscriber, seed_ip = '10.10.150.1')
-          log.info('Subscriber %s got client ip %s from server %s' %(subscriber.name, cip, sip))
-          subscriber.src_list = [cip]
-          self.test_status = True
+            if subscriber.has_service('DHCP'):
+                  cip, sip = self.dhcp_request(subscriber, seed_ip = '10.10.150.1')
+                  log.info('Subscriber %s got client ip %s from server %s' %(subscriber.name, cip, sip))
+                  subscriber.src_list = [cip]
+                  self.test_status = True
+            else:
+                  subscriber.src_list = ['10.10.10.{}'.format(subscriber.rx_port)]
+                  self.test_status = True
 
       def igmp_verify(self, subscriber):
             chan = 0
@@ -385,7 +419,7 @@
 
       def subscriber_load(self, create = True, num = 10, num_channels = 1, channel_start = 0, port_list = []):
             '''Load the subscriber from the database'''
-            self.subscriber_db = SubscriberDB(create = create)
+            self.subscriber_db = SubscriberDB(create = create, services = self.test_services)
             if create is True:
                   self.subscriber_db.generate(num)
             self.subscriber_info = self.subscriber_db.read(num)
@@ -443,7 +477,7 @@
       def test_subscriber_join_jump(self):
           """Test subscriber join and receive for channel surfing"""
           num_subscribers = 5
-          num_channels = 50
+          num_channels = 5
           test_status = self.subscriber_join_verify(num_subscribers = num_subscribers,
                                                     num_channels = num_channels,
                                                     cbs = (self.tls_verify, self.dhcp_jump_verify, self.igmp_jump_verify),
@@ -453,7 +487,7 @@
       def test_subscriber_join_next(self):
           """Test subscriber join next for channels"""
           num_subscribers = 5
-          num_channels = 50
+          num_channels = 5
           test_status = self.subscriber_join_verify(num_subscribers = num_subscribers,
                                                     num_channels = num_channels,
                                                     cbs = (self.tls_verify, self.dhcp_next_verify, self.igmp_next_verify),