Test: Changes to cord-tester to make it work with latest ONOS relocating apps to opencord.
For _now_, keep prebuilt versions of cord apps since remote installation for opencord doesn't seem to work.
Also make the ciena cordigmp app compatible with latest ONOS.
Change test cases as well.

Change-Id: Ic8792eb4ee36afc4fc153bde993d0ef9f1d9a040
diff --git a/src/test/apps/aaa-1.0-SNAPSHOT.oar b/src/test/apps/aaa-1.0-SNAPSHOT.oar
new file mode 100644
index 0000000..f5a462c
--- /dev/null
+++ b/src/test/apps/aaa-1.0-SNAPSHOT.oar
Binary files differ
diff --git a/src/test/apps/ciena-cordigmp-2.0-SNAPSHOT.oar b/src/test/apps/ciena-cordigmp-2.0-SNAPSHOT.oar
new file mode 100644
index 0000000..b75faab
--- /dev/null
+++ b/src/test/apps/ciena-cordigmp-2.0-SNAPSHOT.oar
Binary files differ
diff --git a/src/test/apps/ciena-cordigmp/pom.xml b/src/test/apps/ciena-cordigmp/pom.xml
index 058b8f8..45b710a 100644
--- a/src/test/apps/ciena-cordigmp/pom.xml
+++ b/src/test/apps/ciena-cordigmp/pom.xml
@@ -17,25 +17,42 @@
 <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>

         <dependency>

             <groupId>org.onosproject</groupId>

@@ -50,9 +67,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 +80,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>

@@ -86,12 +95,26 @@
             <groupId>org.osgi</groupId>

             <artifactId>org.osgi.compendium</artifactId>

             <version>5.0.0</version>

-        </dependency>

-        <dependency>

+      </dependency>

+

+              <dependency>

             <groupId>org.onosproject</groupId>

-            <artifactId>onos-app-olt-api</artifactId>

+            <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/src/main/java/org/ciena/cordigmp/CordIgmp.java b/src/test/apps/ciena-cordigmp/src/main/java/org/ciena/cordigmp/CordIgmp.java
index 2029a4a..37f223c 100644
--- a/src/test/apps/ciena-cordigmp/src/main/java/org/ciena/cordigmp/CordIgmp.java
+++ b/src/test/apps/ciena-cordigmp/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 com.google.common.collect.Multiset;
 import com.google.common.collect.ConcurrentHashMultiset;
@@ -50,32 +49,24 @@
 import org.onosproject.net.flow.FlowEntry;
 import org.onosproject.net.flow.DefaultFlowEntry;
 import org.onosproject.net.flow.FlowRuleService;
-import org.onosproject.net.flowobjective.DefaultNextObjective;
 import org.onosproject.net.flowobjective.FlowObjectiveService;
-import org.onosproject.net.flowobjective.NextObjective;
-import org.onosproject.net.flowobjective.Objective;
-import org.onosproject.net.flowobjective.ObjectiveContext;
-import org.onosproject.net.flowobjective.ObjectiveError;
 import org.onosproject.net.mcast.McastEvent;
 import org.onosproject.net.mcast.McastListener;
 import org.onosproject.net.mcast.McastRoute;
 import org.onosproject.net.mcast.McastRouteInfo;
 import org.onosproject.net.mcast.MulticastRouteService;
-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.osgi.service.component.ComponentContext;
 import org.onosproject.net.PortNumber;
 import org.onlab.packet.IPv4;
 import org.slf4j.Logger;
 
-import java.io.IOException;
 import java.util.Dictionary;
-import java.util.List;
 import java.util.Map;
 import java.util.Collection;
 import java.util.Properties;
 import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
 
 import static com.google.common.base.Preconditions.checkNotNull;
@@ -130,7 +121,7 @@
 
     //Count of group joins
     private Multiset<IpAddress> cordIgmpCountTable = ConcurrentHashMultiset.create();
-    
+
     //TODO: move this to distributed atomic long
     private AtomicInteger channels = new AtomicInteger(0);
 
@@ -195,10 +186,10 @@
 
         CordIgmpTranslateConfig cordIgmpTranslateConfig = networkConfig.getConfig(appId, CordIgmpTranslateConfig.class);
 
-        if(cordIgmpTranslateConfig != null) {
+        if (cordIgmpTranslateConfig != null) {
             Collection<McastPorts> translations = cordIgmpTranslateConfig.getCordIgmpTranslations();
-            for(McastPorts port: translations) {
-                cordIgmpTranslateTable.put(port.group(), 
+            for (McastPorts port: translations) {
+                cordIgmpTranslateTable.put(port.group(),
                                            port.portPair());
             }
         }
@@ -282,14 +273,14 @@
             }
         }
     }
-    
+
     private void provisionFilterIgmp(DeviceId devId, boolean remove) {
         Boolean deviceStatus = deviceAvailability.get(devId);
-        if(deviceStatus != null) {
-            if(remove == false) {
+        if (deviceStatus != null) {
+            if (!remove) {
                 return;
             }
-        } else if(remove == true) {
+        } else if (remove) {
             return;
         }
         TrafficSelector.Builder igmp = DefaultTrafficSelector.builder()
@@ -304,14 +295,14 @@
         flowEntry.withTreatment(treatment.build());
         flowEntry.fromApp(appId);
         flowEntry.makePermanent();
-        if(remove == false) {
+        if (!remove) {
             deviceAvailability.put(devId, true);
             flowRuleService.applyFlowRules(flowEntry.build());
         } else {
             deviceAvailability.remove(devId);
             flowRuleService.removeFlowRules(flowEntry.build());
         }
-        log.warn("IGMP flow rule " + ( remove ? "removed" : "added" ) + " for device id " + devId);
+        log.warn("IGMP flow rule " + (remove ? "removed" : "added") + " for device id " + devId);
     }
 
     private class InternalDeviceListener implements DeviceListener {
@@ -325,7 +316,7 @@
                     provisionFilterIgmp(devId, false);
                     break;
                 case DEVICE_AVAILABILITY_CHANGED:
-                    if(deviceService.isAvailable(devId)) {
+                    if (deviceService.isAvailable(devId)) {
                         provisionFilterIgmp(devId, false);
                     } else {
                         provisionFilterIgmp(devId, true);
@@ -355,16 +346,16 @@
         }
         ConnectPoint loc = info.sink().get();
         AccessDeviceData oltInfo = oltData.get(loc.deviceId());
-        if(oltInfo != null) {
+        if (oltInfo != null) {
             log.warn("Ignoring deprovisioning mcast route for OLT device: " + loc.deviceId());
             return;
         }
         final IgmpPortPair portPair = cordIgmpTranslateTable.get(info.route().group());
-        if(portPair == null) {
+        if (portPair == null) {
             log.warn("Ignoring unprovisioning for group " + info.route().group() + " with no port map");
             return;
         }
-        if(cordIgmpCountTable.remove(info.route().group(), 1) <= 1) {
+        if (cordIgmpCountTable.remove(info.route().group(), 1) <= 1) {
             //Remove flow for last channel leave
             final PortNumber inPort = PortNumber.portNumber(portPair.inputPort());
             final PortNumber outPort = PortNumber.portNumber(portPair.outputPort());
@@ -391,16 +382,16 @@
         checkNotNull(sink, "Sink cannot be null");
 
         AccessDeviceData oltInfo = oltData.get(sink.deviceId());
-        if(oltInfo != null) {
+        if (oltInfo != null) {
             log.warn("Ignoring provisioning mcast route for OLT device: " + sink.deviceId());
             return;
-        } 
+        }
         final IgmpPortPair portPair = cordIgmpTranslateTable.get(route.group());
-        if(portPair == null) {
+        if (portPair == null) {
             log.warn("Ports for Group " + route.group() + " not found in cord igmp map. Skipping provisioning.");
             return;
         }
-        if(cordIgmpCountTable.count(route.group()) == 0) {
+        if (cordIgmpCountTable.count(route.group()) == 0) {
             //First group entry. Provision the flows
             final PortNumber inPort = PortNumber.portNumber(portPair.inputPort());
             final PortNumber outPort = PortNumber.portNumber(portPair.outputPort());
@@ -438,7 +429,7 @@
                             cordIgmpTranslateTable.clear();
                             cordIgmpCountTable.clear();
                             config.getCordIgmpTranslations().forEach(
-                                                                     mcastPorts -> cordIgmpTranslateTable.put(mcastPorts.group(), mcastPorts.portPair()));
+                                mcastPorts -> cordIgmpTranslateTable.put(mcastPorts.group(), mcastPorts.portPair()));
                         }
                     }
                     break;
diff --git a/src/test/apps/ciena-cordigmp/src/main/java/org/ciena/cordigmp/CordIgmpTranslateConfig.java b/src/test/apps/ciena-cordigmp/src/main/java/org/ciena/cordigmp/CordIgmpTranslateConfig.java
index e55cf11..ae46216 100644
--- a/src/test/apps/ciena-cordigmp/src/main/java/org/ciena/cordigmp/CordIgmpTranslateConfig.java
+++ b/src/test/apps/ciena-cordigmp/src/main/java/org/ciena/cordigmp/CordIgmpTranslateConfig.java
@@ -41,7 +41,7 @@
                 return false;
             }
 
-            if (!(isIpAddress((ObjectNode) node, GROUP, FieldPresence.MANDATORY) && 
+            if (!(isIpAddress((ObjectNode) node, GROUP, FieldPresence.MANDATORY) &&
                   node.get(INPUT_PORT).isInt() && node.get(OUTPUT_PORT).isInt())) {
                 return false;
             }
diff --git a/src/test/apps/ciena-cordigmp/src/main/java/org/ciena/cordigmp/McastPorts.java b/src/test/apps/ciena-cordigmp/src/main/java/org/ciena/cordigmp/McastPorts.java
index e0cd622..1ea76a1 100644
--- a/src/test/apps/ciena-cordigmp/src/main/java/org/ciena/cordigmp/McastPorts.java
+++ b/src/test/apps/ciena-cordigmp/src/main/java/org/ciena/cordigmp/McastPorts.java
@@ -22,8 +22,8 @@
 import static com.google.common.base.MoreObjects.toStringHelper;
 import static com.google.common.base.Preconditions.checkNotNull;
 
-/**
- * An entity representing a multicast group and its input and output ports
+/*
+ * An entity representing a multicast group and its input and output ports.
  */
 @Beta
 public class McastPorts {
diff --git a/src/test/apps/ciena-cordigmp/src/main/java/org/ciena/cordigmp/package-info.java b/src/test/apps/ciena-cordigmp/src/main/java/org/ciena/cordigmp/package-info.java
new file mode 100644
index 0000000..75494c5
--- /dev/null
+++ b/src/test/apps/ciena-cordigmp/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/apps/cord-config-1.0-SNAPSHOT.oar b/src/test/apps/cord-config-1.0-SNAPSHOT.oar
new file mode 100644
index 0000000..eb68e9f
--- /dev/null
+++ b/src/test/apps/cord-config-1.0-SNAPSHOT.oar
Binary files differ
diff --git a/src/test/apps/igmp-1.0-SNAPSHOT.oar b/src/test/apps/igmp-1.0-SNAPSHOT.oar
new file mode 100644
index 0000000..a4893f7
--- /dev/null
+++ b/src/test/apps/igmp-1.0-SNAPSHOT.oar
Binary files differ
diff --git a/src/test/igmp/igmpTest.py b/src/test/igmp/igmpTest.py
index 011d562..a683ee9 100644
--- a/src/test/igmp/igmpTest.py
+++ b/src/test/igmp/igmpTest.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.
@@ -41,7 +41,7 @@
             self.group_map = {} ##create a send/recv count map
             for g in groups:
                 self.group_map[g] = (Stats(), Stats())
-            
+
       def update(self, group, tx = 0, rx = 0, t = 0):
             self.counter += 1
             index = 0 if rx == 0 else 1
@@ -75,7 +75,7 @@
     PORT_TX_DEFAULT = 2
     PORT_RX_DEFAULT = 1
     max_packets = 100
-    app = 'org.onosproject.igmp'
+    app = 'org.opencord.igmp'
     olt_conf_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), '../setup/olt_config.json')
 
     @classmethod
@@ -85,7 +85,7 @@
 
     @classmethod
     def tearDownClass(cls): pass
-          
+
     def setUp(self):
         ''' Activate the dhcp app'''
         self.onos_ctrl = OnosCtrl(self.app)
@@ -99,7 +99,7 @@
             log.info('JSON request returned status %d' %code)
             assert_equal(status, True)
         time.sleep(2)
-          
+
     def onos_ssm_table_load(self, groups, src_list):
           ssm_dict = {'apps' : { 'org.onosproject.igmp' : { 'ssmTranslate' : [] } } }
           ssm_xlate_list = ssm_dict['apps']['org.onosproject.igmp']['ssmTranslate']
@@ -120,14 +120,14 @@
         sendState, recvState = igmpStateList
         ## check if the send is received for the groups
         for g in sendState.groups:
-            tx_stats = sendState.group_map[g][0]  
+            tx_stats = sendState.group_map[g][0]
             tx = tx_stats.count
             assert_greater(tx, 0)
             rx_stats = recvState.group_map[g][1]
             rx = rx_stats.count
             assert_greater(rx, 0)
             log.info('Receive stats %s for group %s' %(rx_stats, g))
-            
+
         log.info('IGMP test verification success')
 
     def igmp_verify_leave(self, igmpStateList, leave_groups):
@@ -137,14 +137,14 @@
             tx_stats = sendState.group_map[g][0]
             rx_stats = recvState.group_map[g][1]
             tx = tx_stats.count
-            rx = rx_stats.count                   
+            rx = rx_stats.count
             assert_greater(tx, 0)
             if g not in leave_groups:
                 log.info('Received %d packets for group %s' %(rx, g))
         for g in leave_groups:
             rx = recvState.group_map[g][1].count
             assert_equal(rx, 0)
-            
+
         log.info('IGMP test verification success')
 
     def mcast_traffic_timer(self):
@@ -279,12 +279,12 @@
         igmpState = IGMPTestState(groups = groups, df = df)
         igmpStateRecv = IGMPTestState(groups = groups, df = df)
         igmpStateList = (igmpState, igmpStateRecv)
-        mcastTraffic = McastTraffic(groups, iface= 'veth2', cb = self.send_mcast_cb, 
+        mcastTraffic = McastTraffic(groups, iface= 'veth2', cb = self.send_mcast_cb,
                                     arg = igmpState)
         self.df = df
         self.mcastTraffic = mcastTraffic
         self.recv_socket = L3PacketSocket(iface = 'veth0', type = ETH_P_IP)
-        
+
         def igmp_srp_task(stateList):
             igmpSendState, igmpRecvState = stateList
             if not mcastTraffic.isRecvStopped():
@@ -393,7 +393,7 @@
           sniff(prn = igmp_recv_cb, count = 1, lfilter = lambda p: IP in p and p[IP].dst in groups,
                 timeout = 3, opened_socket = recv_socket)
           recv_socket.close()
-          return self.NEGATIVE_TRAFFIC_STATUS 
+          return self.NEGATIVE_TRAFFIC_STATUS
 
     def group_latency_check(self, groups):
           tasks = []
@@ -401,7 +401,7 @@
           join_state = IGMPTestState(groups = groups)
           tasks.append(threading.Thread(target=self.igmp_join_task, args = ('veth0', groups, join_state,)))
           traffic_state = IGMPTestState(groups = groups)
-          mcast_traffic = McastTraffic(groups, iface= 'veth2', cb = self.send_mcast_cb, 
+          mcast_traffic = McastTraffic(groups, iface= 'veth2', cb = self.send_mcast_cb,
                                        arg = traffic_state)
           mcast_traffic.start()
           tasks.append(threading.Thread(target=self.igmp_recv_task, args = ('veth0', groups, join_state)))
@@ -441,7 +441,7 @@
         df = defer.Deferred()
         self.df = df
         self.recv_socket = L2Socket(iface = 'veth0', type = ETH_P_IP)
-        
+
         def igmp_query_timeout():
               def igmp_query_cb(pkt):
                     log.info('Got IGMP query packet from %s for %s' %(pkt[IP].src, pkt[IP].dst))
@@ -483,7 +483,7 @@
         if query_group1 is 'group1':
             log.info('Sending join message for the group %s and waiting for a query packet on join interface' %g1)
             self.send_igmp_join_recvQuery((g1,), None, src_list = sourcelist1, ip_pkt = eth/ip, iface = intf, delay = 2)
-        else: 
+        else:
             log.info('Sending join message for the group %s' %g1)
             self.send_igmp_join((g1,), src_list = sourcelist1, ip_pkt = eth/ip, iface = intf, delay = 2)
         eth = Ether(dst = self.MMACGROUP2, src = self.IGMP_SRC_MAC, type = ETH_P_IP)
@@ -491,7 +491,7 @@
         if query_group2 is 'group2':
             log.info('Sending join message for the group %s and waiting for a query packet on join interface' %g2)
             self.send_igmp_join_recvQuery((g2,), None, src_list = sourcelist2, ip_pkt = eth/ip, iface = intf, delay = 2)
-        else: 
+        else:
             log.info('Sending join message for group %s' %g2)
             self.send_igmp_join((g2,), src_list = sourcelist2, ip_pkt = eth/ip, iface = intf, delay = 2)
 
@@ -547,7 +547,7 @@
             log.info('Ended test case')
         mcastTraffic1.stop()
         mcastTraffic2.stop()
-        
+
 
     @deferred(timeout=MCAST_TRAFFIC_TIMEOUT+20)
     def test_igmp_2joins_1leave_functionality(self):
@@ -588,7 +588,7 @@
         assert target1 == 2, 'EXPECTED FAILURE'
         log.info('Interface is not receiving from multicast groups %s, working as expected' %groups1)
         mcastTraffic1.stop()
-        
+
     @deferred(timeout=MCAST_TRAFFIC_TIMEOUT+20)
     def test_igmp_not_in_src_list_functionality(self):
         df = defer.Deferred()
@@ -620,7 +620,7 @@
         assert target2 == 2, 'EXPECTED FAILURE'
         log.info('Interface is not receiving from multicast groups %s after sending CHANGE_TO_EXCLUDE' %groups1)
         mcastTraffic1.stop()
-        
+
     @deferred(timeout=MCAST_TRAFFIC_TIMEOUT+10)
     def test_igmp_change_to_exclude_src_list_functionality(self):
         df = defer.Deferred()
@@ -652,7 +652,7 @@
                                                       intf = self.V_INF1, delay = 2)
         target1 = self.igmp_recv_task(self.V_INF1, groups1, join_state1)
         mcastTraffic1.stop()
-        
+
     @deferred(timeout=MCAST_TRAFFIC_TIMEOUT+30)
     def test_igmp_include_to_allow_src_list_functionality(self):
         df = defer.Deferred()
@@ -684,7 +684,7 @@
         target1 = self.igmp_recv_task(self.V_INF1, groups1, join_state1)
         log.info('Interface is still receiving from old multicast group data %s even after we send block list' %groups1)
         mcastTraffic1.stop()
-        
+
     @deferred(timeout=MCAST_TRAFFIC_TIMEOUT+30)
     def test_igmp_include_to_block_src_list_functionality(self):
         df = defer.Deferred()
@@ -700,7 +700,7 @@
         groups2 = (self.MGROUP2,)
         self.send_igmp_leave(groups = groups1, src_list = ['2.2.2.2', '3.3.3.3', '4.4.4.4'],
                              iface = self.V_INF1, delay = 2)
-        
+
         dst_mac = '01:00:5e:01:02:03'
         src_ip = '2.2.2.2'
         if df is None:
@@ -720,7 +720,7 @@
         target2 = self.igmp_recv_task(self.V_INF1, groups1, join_state1)
         log.info('Interface is receiving from multicast groups %s after send Change to include message' %groups1)
         mcastTraffic1.stop()
-        
+
     @deferred(timeout=MCAST_TRAFFIC_TIMEOUT+10)
     def test_igmp_change_to_include_src_list_functionality(self):
         df = defer.Deferred()
@@ -735,7 +735,7 @@
         groups2 = (self.MGROUP2,)
         self.send_igmp_leave(groups = groups1, src_list = ['2.2.2.2', '3.3.3.3', '4.4.4.4'],
                              iface = self.V_INF1, delay = 2)
-        
+
         dst_mac = '01:00:5e:01:02:03'
         src_ip = '2.2.2.2'
         if df is None:
@@ -756,7 +756,7 @@
         assert target1 == 1, 'EXPECTED FAILURE'
         log.info('Interface is not receiving from multicast groups %s' %groups1)
         mcastTraffic1.stop()
-        
+
     @deferred(timeout=MCAST_TRAFFIC_TIMEOUT+10)
     def test_igmp_exclude_to_allow_src_list_functionality(self):
         df = defer.Deferred()
@@ -771,7 +771,7 @@
         groups2 = (self.MGROUP2,)
         self.send_igmp_leave(groups = groups1, src_list = ['2.2.2.2', '3.3.3.3', '4.4.4.4'],
                              iface = self.V_INF1, delay = 2)
-        
+
         dst_mac = '01:00:5e:01:02:03'
         src_ip = '2.2.2.2'
         if df is None:
@@ -791,7 +791,7 @@
         assert target1 == 1, 'EXPECTED FAILURE'
         log.info('Interface is not receiving from multicast groups %s' %groups1)
         mcastTraffic1.stop()
-        
+
     @deferred(timeout=MCAST_TRAFFIC_TIMEOUT+10)
     def test_igmp_exclude_to_block_src_list_functionality(self):
         df = defer.Deferred()
@@ -826,7 +826,7 @@
         target2 = self.igmp_recv_task(self.V_INF1, groups1, join_state1)
         log.info('Interface is receiving from multicast groups %s after sending join with new source list' %groups1)
         mcastTraffic1.stop()
-        
+
     @deferred(timeout=MCAST_TRAFFIC_TIMEOUT+10)
     def test_igmp_new_src_list_functionality(self):
         df = defer.Deferred()
@@ -893,7 +893,7 @@
         assert target1==1, 'EXPECTED FAILURE'
         log.info('Interface is not receiving from multicast groups %s when we sent join with source list is empty' %groups2)
         mcastTraffic1.stop()
-        
+
     @deferred(timeout=MCAST_TRAFFIC_TIMEOUT+20)
     def ztest_igmp_include_empty_src_list_functionality(self):
         ## '''Disabling this test as scapy IGMP doesn't work with empty source lists'''
@@ -922,7 +922,7 @@
         target1 = self.igmp_recv_task(self.V_INF1, groups2, join_state1)
         log.info('Interface is receiving multicast groups %s' %groups2)
         mcastTraffic1.stop()
-        
+
     @deferred(timeout=MCAST_TRAFFIC_TIMEOUT+20)
     def ztest_igmp_exclude_empty_src_list_functionality(self):
         df = defer.Deferred()
@@ -954,7 +954,7 @@
         target1 = self.igmp_recv_task(self.V_INF1, groups2, join_state1)
         log.info('Interface is receiving from multicast groups %s when we sent join with source IP  is 0.0.0.0' %groups2)
         mcastTraffic1.stop()
-        
+
     @deferred(timeout=MCAST_TRAFFIC_TIMEOUT+20)
     def test_igmp_join_sourceip_0_0_0_0_functionality(self):
         df = defer.Deferred()
@@ -987,7 +987,7 @@
         assert target1==1, 'EXPECTED FAILURE'
         log.info('Interface is not receiving from multicast groups %s when we sent invalid join packet ' %groups2)
         mcastTraffic1.stop()
-        
+
     @deferred(timeout=MCAST_TRAFFIC_TIMEOUT+20)
     def test_igmp_invalid_join_packet_functionality(self):
         df = defer.Deferred()
@@ -1028,7 +1028,7 @@
         target1 = self.igmp_recv_task(self.V_INF1, groups2, join_state1)
         log.info('Interface is receiving from multicast groups %s when we bringup interface up after down  ' %groups2)
         mcastTraffic1.stop()
-        
+
     @deferred(timeout=MCAST_TRAFFIC_TIMEOUT+20)
     def test_igmp_join_data_receiving_during_subscriber_link_up_down_functionality(self):
         df = defer.Deferred()
@@ -1090,7 +1090,7 @@
         target2 = self.igmp_recv_task(self.V_INF1, groups2, join_state2)
         log.info('Interface is receiving from multicast groups %s when we bringup interface up after down  ' %groups2)
         mcastTraffic2.stop()
-        
+
     ##  This test case is failing to receive traffic from multicast data from defferent channel interfaces TO-DO
     ###### TO DO scenario #######
     @deferred(timeout=MCAST_TRAFFIC_TIMEOUT+60)
@@ -1158,7 +1158,7 @@
         assert target1==1, 'EXPECTED FAILURE'
         log.info('Interface is not receiving from multicast groups %s when we sent invalid join packet ' %groups2)
         mcastTraffic1.stop()
-        
+
     @deferred(timeout=MCAST_TRAFFIC_TIMEOUT+20)
     def test_igmp_invalidClassD_IP_as_srclistIP_join_packet_functionality(self):
         df = defer.Deferred()
@@ -1208,7 +1208,7 @@
         assert target1==1, 'EXPECTED FAILURE'
         log.info('Interface is not receiving multicast data for group %s' %groups2)
         mcastTraffic1.stop()
-        
+
     @deferred(timeout=MCAST_TRAFFIC_TIMEOUT+250)
     def test_igmp_general_query_recv_packet_traffic_functionality(self):
         df = defer.Deferred()
@@ -1217,7 +1217,7 @@
               df.callback(0)
         reactor.callLater(0, igmp_general_query_recv_packet_functionality)
         return df
-    
+
     @deferred(timeout=MCAST_TRAFFIC_TIMEOUT+80)
     def test_igmp_query_packet_received_on_joining_interface(self):
         groups = ['224.0.1.10', '225.0.0.10']
@@ -1226,12 +1226,12 @@
         igmpState = IGMPTestState(groups = groups, df = df)
         igmpStateRecv = IGMPTestState(groups = groups, df = df)
         igmpStateList = (igmpState, igmpStateRecv)
-        mcastTraffic = McastTraffic(groups, iface= 'veth2', cb = self.send_mcast_cb, 
+        mcastTraffic = McastTraffic(groups, iface= 'veth2', cb = self.send_mcast_cb,
                                     arg = igmpState)
         self.df = df
         self.mcastTraffic = mcastTraffic
         self.recv_socket = L3PacketSocket(iface = 'veth0', type = ETH_P_IP)
-        
+
         def igmp_srp_task(stateList):
             igmpSendState, igmpRecvState = stateList
             if not mcastTraffic.isRecvStopped():
@@ -1259,12 +1259,12 @@
         igmpState = IGMPTestState(groups = groups, df = df)
         igmpStateRecv = IGMPTestState(groups = groups, df = df)
         igmpStateList = (igmpState, igmpStateRecv)
-        mcastTraffic = McastTraffic(groups, iface= 'veth2', cb = self.send_mcast_cb, 
+        mcastTraffic = McastTraffic(groups, iface= 'veth2', cb = self.send_mcast_cb,
                                     arg = igmpState)
         self.df = df
         self.mcastTraffic = mcastTraffic
         self.recv_socket = L3PacketSocket(iface = 'veth0', type = ETH_P_IP)
-        
+
         def igmp_srp_task(stateList):
             igmpSendState, igmpRecvState = stateList
             if not mcastTraffic.isRecvStopped():
@@ -1287,12 +1287,12 @@
         igmpState = IGMPTestState(groups = groups, df = df)
         igmpStateRecv = IGMPTestState(groups = groups, df = df)
         igmpStateList = (igmpState, igmpStateRecv)
-        mcastTraffic = McastTraffic(groups, iface= 'veth2', cb = self.send_mcast_cb, 
+        mcastTraffic = McastTraffic(groups, iface= 'veth2', cb = self.send_mcast_cb,
                                     arg = igmpState)
         self.df = df
         self.mcastTraffic = mcastTraffic
         self.recv_socket = L3PacketSocket(iface = 'veth0', type = ETH_P_IP)
-        
+
         def igmp_srp_task(stateList):
             igmpSendState, igmpRecvState = stateList
             if not mcastTraffic.isRecvStopped():
@@ -1319,12 +1319,12 @@
         igmpState = IGMPTestState(groups = groups, df = df)
         igmpStateRecv = IGMPTestState(groups = groups, df = df)
         igmpStateList = (igmpState, igmpStateRecv)
-        mcastTraffic = McastTraffic(groups, iface= 'veth2', cb = self.send_mcast_cb, 
+        mcastTraffic = McastTraffic(groups, iface= 'veth2', cb = self.send_mcast_cb,
                                     arg = igmpState)
         self.df = df
         self.mcastTraffic = mcastTraffic
         self.recv_socket = L3PacketSocket(iface = 'veth0', type = ETH_P_IP)
-        
+
         def igmp_srp_task(stateList):
             igmpSendState, igmpRecvState = stateList
             if not mcastTraffic.isRecvStopped():
@@ -1352,12 +1352,12 @@
         igmpState = IGMPTestState(groups = groups, df = df)
         igmpStateRecv = IGMPTestState(groups = groups, df = df)
         igmpStateList = (igmpState, igmpStateRecv)
-        mcastTraffic = McastTraffic(groups, iface= 'veth2', cb = self.send_mcast_cb, 
+        mcastTraffic = McastTraffic(groups, iface= 'veth2', cb = self.send_mcast_cb,
                                     arg = igmpState)
         self.df = df
         self.mcastTraffic = mcastTraffic
         self.recv_socket = L3PacketSocket(iface = 'veth0', type = ETH_P_IP)
-        
+
         def igmp_srp_task(stateList):
             igmpSendState, igmpRecvState = stateList
             if not mcastTraffic.isRecvStopped():
@@ -1396,7 +1396,7 @@
         assert target2 == 1, 'EXPECTED FAILURE'
         log.info('Interface is not receiving from multicast groups %s after sending CHANGE_TO_EXCLUDE' %groups2)
         mcastTraffic1.stop()
-        
+
     @deferred(timeout=MCAST_TRAFFIC_TIMEOUT+60)
     def test_igmp_change_to_exclude_src_list_check_for_group_source_specific_query(self):
         df = defer.Deferred()
@@ -1431,7 +1431,7 @@
         target2 = self.igmp_recv_task(self.V_INF1, groups1, join_state1)
         log.info('Interface is receiving from multicast groups %s after send Change to include message' %groups1)
         mcastTraffic1.stop()
-        
+
     @deferred(timeout=MCAST_TRAFFIC_TIMEOUT+80)
     def test_igmp_change_to_include_src_list_check_for_general_query(self):
         df = defer.Deferred()
@@ -1465,7 +1465,7 @@
         target2 = self.igmp_recv_task(self.V_INF1, groups1, join_state1)
         log.info('Interface is receiving from multicast groups %s after sending join with new source list' %groups1)
         mcastTraffic1.stop()
-        
+
     @deferred(timeout=MCAST_TRAFFIC_TIMEOUT+80)
     def test_igmp_allow_new_src_list_check_for_general_query(self):
         df = defer.Deferred()
@@ -1577,7 +1577,7 @@
         groups2 = (self.MGROUP2,)
         self.send_igmp_leave(groups = groups1, src_list = ['2.2.2.2', '3.3.3.3', '4.4.4.4'],
                              iface = self.V_INF1, delay = 2)
-        
+
         dst_mac = '01:00:5e:01:02:03'
         src_ip = '2.2.2.2'
         if df is None:
@@ -1597,7 +1597,7 @@
         assert target1 == 1, 'EXPECTED FAILURE'
         log.info('Interface is not receiving from multicast groups %s' %groups1)
         mcastTraffic1.stop()
-        
+
     @deferred(timeout=MCAST_TRAFFIC_TIMEOUT+90)
     def test_igmp_exclude_to_allow_src_list_check_for_general_query(self):
         df = defer.Deferred()
@@ -1612,7 +1612,7 @@
         groups2 = (self.MGROUP2,)
         self.send_igmp_leave(groups = groups1, src_list = ['2.2.2.2', '3.3.3.3', '4.4.4.4'],
                              iface = self.V_INF1, delay = 2)
-        
+
         dst_mac = '01:00:5e:01:02:03'
         src_ip = '2.2.2.2'
         if df is None:
@@ -1626,7 +1626,7 @@
         target1= self.igmp_not_recv_task(self.V_INF1, groups1, join_state1)
         assert target1 == 1, 'EXPECTED FAILURE'
         log.info('Interface is not receiving from multicast groups %s' %groups1)
-        self.send_igmp_leave_listening_group_specific_query(groups = groups1, 
+        self.send_igmp_leave_listening_group_specific_query(groups = groups1,
                                           src_list = ['2.2.2.2', '3.3.3.3', '4.4.4.4', '5.5.5.5', '7.7.7.7'],
                                           iface = self.V_INF1, delay = 2)
         target1= self.igmp_not_recv_task(self.V_INF1, groups1, join_state1)
@@ -1642,5 +1642,3 @@
               df.callback(0)
         reactor.callLater(0, igmp_exclude_to_block_src_list_check_for_group_source_specific_query)
         return df
-
-
diff --git a/src/test/setup/cord-test.py b/src/test/setup/cord-test.py
index e05a960..5b44999 100755
--- a/src/test/setup/cord-test.py
+++ b/src/test/setup/cord-test.py
@@ -1,13 +1,13 @@
 #!/usr/bin/env python
-# 
+#
 # 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.
@@ -68,7 +68,7 @@
             env['TEST_INSTANCE'] = instance
             env['TEST_INSTANCES'] = num_instances
         print('Starting test container %s, image %s, tag %s' %(self.name, self.image, self.tag))
-        self.start(rm = False, volumes = volumes, environment = env, 
+        self.start(rm = False, volumes = volumes, environment = env,
                    host_config = host_config, tty = True)
 
     def execute_switch(self, cmd, shell = False):
@@ -120,7 +120,7 @@
             pipework_cmd = 'pipework {0} -i {1} -l {2} {3} {4}'.format(host_intf, guest_if, local_if, self.name, guest_ip)
             if start_vlan != 0:
                 pipework_cmd += ' @{}'.format(start_vlan + port_num)
-                
+
             res += os.system(pipework_cmd)
             port_num += 1
 
@@ -218,7 +218,7 @@
 onos_image_default='onosproject/onos:latest'
 nose_image_default= '{}:latest'.format(CordTester.IMAGE)
 test_type_default='dhcp'
-onos_app_version = '1.0-SNAPSHOT'
+onos_app_version = '2.0-SNAPSHOT'
 cord_tester_base = os.path.dirname(os.path.realpath(__file__))
 onos_app_file = os.path.abspath('{0}/../apps/ciena-cordigmp-'.format(cord_tester_base) + onos_app_version + '.oar')
 
@@ -240,11 +240,11 @@
     nose_cnt = {'image': CordTester.IMAGE, 'tag': 'latest'}
     update_map = { 'quagga' : False, 'test' : False, 'radius' : False }
     update_map[args.update.lower()] = True
-    
+
     if args.update.lower() == 'all':
        for c in update_map.keys():
            update_map[c] = True
-    
+
     radius_ip = None
     quagga_ip = None
 
@@ -268,16 +268,16 @@
         radius = Radius( update = update_map['radius'])
         radius_ip = radius.ip()
         print('Radius server running with IP %s' %radius_ip)
-            
+
     print('Onos IP %s, Test type %s' %(onos_ip, args.test_type))
-    print('Installing ONOS app %s' %onos_app_file)
+    print('Installing cord tester ONOS app %s' %onos_app_file)
     OnosCtrl.install_app(args.app, onos_ip = onos_ip)
-    
+
     if args.quagga == True:
         #Start quagga. Builds container if required
         quagga = Quagga(update = update_map['quagga'])
         quagga_ip = quagga.ip()
-        
+
     test_cnt_env = { 'ONOS_CONTROLLER_IP' : onos_ip,
                      'ONOS_AAA_IP' : radius_ip if radius_ip is not None else '',
                      'QUAGGA_IP': quagga_ip if quagga_ip is not None else '',
@@ -345,7 +345,7 @@
 def buildImages(args):
     if args.image == 'all' or args.image == 'quagga':
         Quagga.build_image(Quagga.IMAGE)
-    
+
     if args.image == 'all' or args.image == 'radius':
         Radius.build_image(Radius.IMAGE)
 
diff --git a/src/test/subscriber/subscriberTest.py b/src/test/subscriber/subscriberTest.py
index cab69e2..4d21457 100644
--- a/src/test/subscriber/subscriberTest.py
+++ b/src/test/subscriber/subscriberTest.py
@@ -169,11 +169,11 @@
 
 class subscriber_exchange(unittest.TestCase):
 
-      apps = [ 'org.onosproject.aaa', 'org.onosproject.dhcp' ]
+      apps = [ 'org.opencord.aaa', 'org.onosproject.dhcp' ]
 
       dhcp_app = 'org.onosproject.dhcp'
 
-      olt_apps = [ 'org.onosproject.igmp', 'org.onosproject.cordmcast' ]
+      olt_apps = [ 'org.opencord.igmp', 'org.opencord.cordmcast' ]
       dhcp_server_config = {
         "ip": "10.1.11.50",
         "mac": "ca:fe:ca:fe:ca:fe",
diff --git a/src/test/subscriberMultiTable/subscriberMultiTableTest.py b/src/test/subscriberMultiTable/subscriberMultiTableTest.py
index 1f19848..a619e7f 100644
--- a/src/test/subscriberMultiTable/subscriberMultiTableTest.py
+++ b/src/test/subscriberMultiTable/subscriberMultiTableTest.py
@@ -16,7 +16,7 @@
 from Channels import Channels, IgmpChannel
 from subscriberDb import SubscriberDB
 from threadPool import ThreadPool
-from portmaps import g_subscriber_port_map 
+from portmaps import g_subscriber_port_map
 from OltConfig import *
 from OnosFlowCtrl import get_mac
 from CordTestServer import cord_test_onos_restart
@@ -48,7 +48,7 @@
                   self.tx_intf = self.port_map[self.PORT_TX_DEFAULT]
                   self.rx_intf = self.port_map[self.PORT_RX_DEFAULT]
 
-            Channels.__init__(self, num, channel_start = channel_start, 
+            Channels.__init__(self, num, channel_start = channel_start,
                               iface = self.rx_intf, iface_mcast = self.tx_intf, mcast_cb = mcast_cb)
             self.name = name
             self.service = service
@@ -112,7 +112,7 @@
                   chan_list = (chan,)
             else:
                   chan_list = chan
-            for c in chan_list: 
+            for c in chan_list:
                   if self.join_map.has_key(c):
                         self.join_map[c][stats_type].update(packets = packets, t = t)
 
@@ -142,11 +142,11 @@
             for cb in self.test_cbs:
                   if cb:
                         cb(self.subscriber)
-      
+
 class subscriber_exchange(unittest.TestCase):
 
-      apps = ('org.onosproject.aaa', 'org.onosproject.dhcp')
-      olt_apps = () #'org.onosproject.cordmcast')
+      apps = ('org.opencord.aaa', 'org.onosproject.dhcp')
+      olt_apps = () #'org.opencord.cordmcast')
       table_app = 'org.ciena.cordigmp'
       dhcp_server_config = {
         "ip": "10.1.11.50",
@@ -264,7 +264,7 @@
       def onos_aaa_load(self):
             if self.aaa_loaded:
                   return
-            aaa_dict = {'apps' : { 'org.onosproject.aaa' : { 'AAA' : { 'radiusSecret': 'radius_password', 
+            aaa_dict = {'apps' : { 'org.onosproject.aaa' : { 'AAA' : { 'radiusSecret': 'radius_password',
                                                                        'radiusIp': '172.17.0.2' } } } }
             radius_ip = os.getenv('ONOS_AAA_IP') or '172.17.0.2'
             aaa_dict['apps']['org.onosproject.aaa']['AAA']['radiusIp'] = radius_ip
@@ -395,7 +395,7 @@
 
             index = 0
             for info in self.subscriber_info:
-                  self.subscriber_list.append(Subscriber(name=info['Name'], 
+                  self.subscriber_list.append(Subscriber(name=info['Name'],
                                                          service=info['Service'],
                                                          port_map = self.port_map,
                                                          num=num_channels,
@@ -412,7 +412,7 @@
             ssm_list = reduce(lambda ssm1, ssm2: ssm1+ssm2, ssm_groups)
             igmpChannel.igmp_load_ssm_config(ssm_list)
 
-      def subscriber_join_verify( self, num_subscribers = 10, num_channels = 1, 
+      def subscriber_join_verify( self, num_subscribers = 10, num_channels = 1,
                                   channel_start = 0, cbs = None, port_list = []):
           self.test_status = False
           self.num_subscribers = num_subscribers
@@ -435,16 +435,16 @@
           """Test subscriber join and receive"""
           num_subscribers = 5
           num_channels = 1
-          test_status = self.subscriber_join_verify(num_subscribers = num_subscribers, 
+          test_status = self.subscriber_join_verify(num_subscribers = num_subscribers,
                                                     num_channels = num_channels,
                                                     port_list = self.generate_port_list(num_subscribers, num_channels))
           assert_equal(test_status, True)
 
       def test_subscriber_join_jump(self):
-          """Test subscriber join and receive for channel surfing""" 
+          """Test subscriber join and receive for channel surfing"""
           num_subscribers = 5
           num_channels = 50
-          test_status = self.subscriber_join_verify(num_subscribers = num_subscribers, 
+          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),
                                                     port_list = self.generate_port_list(num_subscribers, num_channels))
@@ -454,7 +454,7 @@
           """Test subscriber join next for channels"""
           num_subscribers = 5
           num_channels = 50
-          test_status = self.subscriber_join_verify(num_subscribers = num_subscribers, 
+          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),
                                                     port_list = self.generate_port_list(num_subscribers, num_channels))
diff --git a/src/test/tls/tlsTest.py b/src/test/tls/tlsTest.py
index 0fdd4bc..bdf06d9 100644
--- a/src/test/tls/tlsTest.py
+++ b/src/test/tls/tlsTest.py
@@ -26,7 +26,7 @@
 
 class eap_auth_exchange(unittest.TestCase):
 
-    app = 'org.onosproject.aaa'
+    app = 'org.opencord.aaa'
     TLS_TIMEOUT = 20
     CLIENT_CERT_INVALID = '''-----BEGIN CERTIFICATE-----
 MIIDvTCCAqWgAwIBAgIBAjANBgkqhkiG9w0BAQUFADCBizELMAkGA1UEBhMCVVMx
@@ -126,4 +126,3 @@
 if __name__ == '__main__':
     t = TLSAuthTest()
     t.runTest()
-
diff --git a/src/test/utils/CordContainer.py b/src/test/utils/CordContainer.py
index 4b08014..dcc5de4 100644
--- a/src/test/utils/CordContainer.py
+++ b/src/test/utils/CordContainer.py
@@ -21,6 +21,7 @@
 from nsenter import Namespace
 from docker import Client
 from shutil import copy
+from OnosCtrl import OnosCtrl
 
 class docker_netns(object):
 
@@ -89,7 +90,7 @@
         cnt_list = filter(lambda c: c['Image'] == image, cls.dckr.containers(all=True))
         for cnt in cnt_list:
             print('Cleaning container %s' %cnt['Id'])
-            if cnt['State'] == 'running':
+            if cnt.has_key('State') and cnt['State'] == 'running':
                 cls.dckr.kill(cnt['Id'])
             cls.dckr.remove_container(cnt['Id'], force=True)
 
@@ -195,10 +196,15 @@
     quagga_config = ( { 'bridge' : 'quagga-br', 'ip': '10.10.0.4', 'mask' : 16 }, )
     SYSTEM_MEMORY = (get_mem(),) * 2
     JAVA_OPTS = '-Xms{} -Xmx{} -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode'.format(*SYSTEM_MEMORY)#-XX:+PrintGCDetails -XX:+PrintGCTimeStamps'
-    env = { 'ONOS_APPS' : 'drivers,openflow,proxyarp,aaa,igmp,vrouter', 'JAVA_OPTS' : JAVA_OPTS }
+    env = { 'ONOS_APPS' : 'drivers,openflow,proxyarp,vrouter', 'JAVA_OPTS' : JAVA_OPTS }
+    onos_cord_apps = ( ('cord-config', '1.0-SNAPSHOT'),
+                       ('aaa', '1.0-SNAPSHOT'),
+                       ('igmp', '1.0-SNAPSHOT'),
+                       )
     ports = [ 8181, 8101, 9876, 6653, 6633, 2000, 2620 ]
     host_config_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', 'setup/onos-config')
     guest_config_dir = '/root/onos/config'
+    cord_apps_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', 'apps')
     host_guest_map = ( (host_config_dir, guest_config_dir), )
     NAME = 'cord-onos'
 
@@ -234,6 +240,19 @@
             print('Waiting %d seconds for ONOS to boot' %(boot_delay))
             time.sleep(boot_delay)
 
+        self.install_cord_apps()
+
+    @classmethod
+    def install_cord_apps(cls):
+        for app, version in cls.onos_cord_apps:
+            app_file = '{}/{}-{}.oar'.format(cls.cord_apps_dir, app, version)
+            ok, code = OnosCtrl.install_app(app_file)
+            ##app already installed (conflicts)
+            if code in [ 409 ]:
+                ok = True
+            print('ONOS app %s, version %s %s' %(app, version, 'installed' if ok else 'failed to install'))
+            time.sleep(2)
+
 class Radius(Container):
     ports = [ 1812, 1813 ]
     env = {'TIMEZONE':'America/Los_Angeles',
@@ -339,4 +358,3 @@
 '''.format(onos_quagga_ip)
         super(Quagga, cls).build_image(dockerfile, image)
         print('Done building image %s' %image)
-
diff --git a/src/test/utils/OnosCtrl.py b/src/test/utils/OnosCtrl.py
index 880e8f6..92437cb 100644
--- a/src/test/utils/OnosCtrl.py
+++ b/src/test/utils/OnosCtrl.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.
@@ -22,6 +22,7 @@
     auth = ('karaf', 'karaf')
     controller = os.getenv('ONOS_CONTROLLER_IP') or 'localhost'
     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)
 
     def __init__(self, app, controller = None):
@@ -97,6 +98,19 @@
         return result.ok, result.status_code
 
     @classmethod
+    def install_app_from_url(cls, app_name, app_version, app_url = None, onos_ip = None):
+        params = {'activate':'true'}
+        headers = {'content-type':'application/json'}
+        if app_url is None:
+            app_oar_file = '{}-{}.oar'.format(app_name, app_version)
+            app_url = '{0}/{1}/{2}/{3}'.format(cls.maven_repo, app_name, app_version, app_oar_file)
+        params['url'] = app_url
+        url = cls.applications_url if onos_ip is None else 'http://{0}:8181/onos/v1/applications'.format(onos_ip)
+        result = requests.post(url, auth = cls.auth,
+                               json = params, headers = headers)
+        return result.ok, result.status_code
+
+    @classmethod
     def uninstall_app(cls, app_name, onos_ip = None):
         params = {'activate':'true'}
         headers = {'content-type':'application/octet-stream'}