SEBA-752 fixing atests in voltha-1.7

Change-Id: Id99a24a72e35baa31096750bf7fb12424017124f
diff --git a/tests/atests/build/Makefile b/tests/atests/build/Makefile
index 6bbe23c..f247d66 100644
--- a/tests/atests/build/Makefile
+++ b/tests/atests/build/Makefile
@@ -23,8 +23,8 @@
 
 KAFKA_CHART_VERSION  ?= 0.8.8
 
-ponsim: $(M)/voltha-running $(M)/adapter-ponsim $(M)/voltha-adapter-running
-bbsim:  $(M)/voltha-running $(M)/adapter-bbsim $(M)/voltha-adapter-running
+ponsim: $(M)/voltha-running $(M)/simtype-ponsim $(M)/voltha-simtype-running
+bbsim:  $(M)/voltha-running $(M)/simtype-bbsim $(M)/voltha-simtype-running
 
 $(M)/setup: 
 	echo "MYDIR = ${MYDIR}"
@@ -112,29 +112,25 @@
 	$(HOME)/cord/helm-charts/scripts/wait_for_pods.sh voltha
 	touch $@
 
-$(M)/adapter-bbsim: | $(M)/voltha-running
-	cd $(HOME)/cord/helm-charts; helm upgrade --install ponnet ponnet
-	$(HOME)/cord/helm-charts/scripts/wait_for_pods.sh kube-system
+$(M)/simtype-bbsim: | $(M)/voltha-running
 	cd $(HOME)/cord/helm-charts; helm upgrade --install bbsim bbsim -f configs/seba-ponsim.yaml --set images.bbsim.repository=voltha/voltha-bbsim,images.bbsim.tag=latest,images.bbsim.pullPolicy=Never
 	touch $@
 
-$(M)/adapter-ponsim: | $(M)/voltha-running
+$(M)/simtype-ponsim: | $(M)/voltha-running
 	cd $(HOME)/cord/helm-charts; helm upgrade --install ponnet ponnet
 	$(HOME)/cord/helm-charts/scripts/wait_for_pods.sh kube-system
 	cd $(HOME)/cord/helm-charts; helm upgrade --install ponsimv2 ponsimv2 -f configs/seba-ponsim.yaml --set images.olt.repository=voltha-ponsim,images.olt.tag=latest,images.olt.pullPolicy=Never,images.onu.repository=voltha-ponsim,images.onu.tag=latest,images.onu.pullPolicy=Never,images.rg.repository=voltha-tester,images.rg.tag=latest,images.rg.pullPolicy=Never
-	touch $@
-
-$(M)/pon0-fwd: | $(M)/voltha-running
-	echo 8 > /tmp/pon0_group_fwd_mask
-	until sudo cp /tmp/pon0_group_fwd_mask /sys/class/net/pon0/bridge/group_fwd_mask; \
+	$(HOME)/cord/helm-charts/scripts/wait_for_pods.sh voltha
+	echo 8 > /tmp/group_fwd_mask
+	for bridge in /sys/class/net/pon*; \
 	do \
-		echo "waiting for pon0..."; \
-		sleep 5; \
+		echo Setting up forwarding on `basename $$bridge`; \
+		sudo cp /tmp/group_fwd_mask $$bridge/bridge/group_fwd_mask; \
 	done
-	rm /tmp/pon0_group_fwd_mask
+	rm /tmp/group_fwd_mask
 	touch $@
 	
-$(M)/voltha-adapter-running: | $(M)/pon0-fwd
+$(M)/voltha-simtype-running:
 	$(HOME)/cord/helm-charts/scripts/wait_for_pods.sh
 	until http -a karaf:karaf --ignore-stdin --check-status GET http://127.0.0.1:30120/onos/v1/configuration/org.opencord.olt.impl.Olt; \
 	do \
@@ -148,7 +144,7 @@
 
 remove-chart-milestones:
 	cd $(M); sudo rm -f setup kafka kafka-running onos voltha etcd-operator-ready etcd-cluster \
-		voltha-running adapter-ponsim adapter-bbsim pon0-fwd voltha-adapter-running
+		voltha-running simtype-ponsim simtype-bbsim voltha-simtype-running
 remove-kube-milestones:
 	cd $(M); sudo rm -f kubeadm helm-init
 
@@ -158,6 +154,8 @@
 reset-kubeadm: remove-chart-milestones remove-kube-milestones
 	sudo kubeadm reset -f || true
 	sudo iptables -F && sudo iptables -t nat -F && sudo iptables -t mangle -F && sudo iptables -X
-	sudo rm -f /var/lib/cni/networks/pon0/* || true
-	sudo rm -f /var/lib/cni/networks/pon1/* || true
+	sudo rm -f /var/lib/cni/networks/pon*/* || true
+	sudo rm -f /var/lib/cni/networks/nni*/* || true
 	sudo rm -f /var/lib/cni/networks/k8s-pod-network/* || true
+	for br in /sys/class/net/pon*; do sudo ip link delete `basename $$br` type bridge; done || true
+	for br in /sys/class/net/nni*; do sudo ip link delete `basename $$br` type bridge; done || true
diff --git a/tests/atests/build/sadis_json b/tests/atests/build/sadis_json
index 882655e..a5f1fbb 100644
--- a/tests/atests/build/sadis_json
+++ b/tests/atests/build/sadis_json
@@ -169,7 +169,7 @@
           "nasId":"B100-NASID"
         },
         {  
-          "id":"olt.voltha.svc:50060",
+          "id":"olt0.voltha.svc:50060",
           "uplinkPort":2
         },
         {
diff --git a/tests/atests/common/authentication.py b/tests/atests/common/authentication.py
index aedbbf2..a03f17e 100644
--- a/tests/atests/common/authentication.py
+++ b/tests/atests/common/authentication.py
@@ -19,7 +19,6 @@
 """
 
 import time
-import os
 import subprocess
 import testCaseUtils
 import logging
@@ -37,37 +36,16 @@
         self.dirs['log'] = None
         self.dirs['root'] = None
         self.dirs['voltha'] = None
-        
+
+        self.__onuCount = None
         self.__rgName = testCaseUtils.discover_rg_pod_name()
-        self.__radiusName = None
-        self.__radiusIp = None
-        
+
     def a_set_log_dirs(self, root_dir, voltha_dir, log_dir):
         testCaseUtils.config_dirs(self, log_dir, root_dir, voltha_dir)
 
-    def discover_freeradius_pod_name(self):
-        self.__radiusName = testCaseUtils.extract_pod_name('freeradius').strip()
-        logging.info('freeradius Name = %s' % self.__radiusName)
-        
-    def discover_freeradius_ip_addr(self):
-        ipAddr = testCaseUtils.extract_radius_ip_addr(self.__radiusName)
-        assert ipAddr, 'No IP address listed for freeradius'
-        self.__radiusIp = ipAddr.strip()
-        logging.info('freeradius IP = %s' % self.__radiusIp)
-        
-    def set_current_freeradius_ip_in_aaa_json(self):
-        status = testCaseUtils.modify_radius_ip_in_json_using_sed(self, self.__radiusIp)
-        assert (status == 0), 'Setting Radius Ip in Json File did not return Success'
-          
-    def alter_aaa_application_configuration_in_onos_using_aaa_json(self):
-        logging.info('Altering the Onos NetCfg AAA apps with Freeradius IP address')
-        logging.debug('curl --user karaf:karaf -X POST -H "Content-Type: application/json" '
-                      'http://localhost:30120/onos/v1/network/configuration/apps/ -d @%s/tests/atests/build/aaa_json'
-                      % testCaseUtils.get_dir(self, 'voltha'))
-        os.system('curl --user karaf:karaf -X POST -H "Content-Type: application/json" '
-                  'http://localhost:30120/onos/v1/network/configuration/apps/ -d @%s/tests/atests/build/aaa_json'
-                  % testCaseUtils.get_dir(self, 'voltha'))
-     
+    def a_configure(self, onu_count):
+        self.__onuCount = onu_count
+
     def execute_authentication_on_rg(self):
         logging.info('Running Radius Authentication from RG')
         process_output = open('%s/%s' % (testCaseUtils.get_dir(self, 'log'), self.AUTHENTICATE_FILENAME), 'w')
@@ -126,32 +104,40 @@
 
         testCaseUtils.print_log_file(self, self.AUTHENTICATE_FILENAME)
         
-    def verify_authentication_should_have_started(self):
+    def authentication_should_have_started(self):
         statusLines = testCaseUtils.get_fields_from_grep_command(self, 'CTRL-EVENT-EAP-STARTED', self.AUTHENTICATE_FILENAME)
         assert statusLines, 'Authentication was not started'
         
-    def verify_authentication_should_have_completed(self):
+    def authentication_should_have_completed(self):
         statusLines = testCaseUtils.get_fields_from_grep_command(self, 'CTRL-EVENT-EAP-SUCCESS', self.AUTHENTICATE_FILENAME)
         assert statusLines, 'Authentication was not completed successfully'
 
-    def verify_authentication_should_have_disconnected(self):
+    def authentication_should_have_disconnected(self):
         statusLines = testCaseUtils.get_fields_from_grep_command(self, 'CTRL-EVENT-DISCONNECTED', self.AUTHENTICATE_FILENAME)
         assert statusLines, 'Authentication was not disconnected'
 
-    def verify_authentication_should_have_terminated(self):
+    def authentication_should_have_terminated(self):
         statusLines = testCaseUtils.get_fields_from_grep_command(self, 'CTRL-EVENT-TERMINATING', self.AUTHENTICATE_FILENAME)
         assert statusLines, 'Authentication was not terminated'
-       
 
-def run_test(root_dir, voltha_dir, log_dir):
+    def should_have_all_onus_authenticated(self):
+        testCaseUtils.send_command_to_onos_cli(testCaseUtils.get_dir(self, 'log'),
+                                               'voltha_onu_auth.log', 'aaa-users')
+        statusLines = testCaseUtils.get_fields_from_grep_command(self, 'AUTHORIZED', 'voltha_onu_auth.log')
+        lines = statusLines.splitlines()
+        auth_count = len(lines)
+        assert self.__onuCount == auth_count, 'There are only %s ONUS Authenticated' % auth_count
+
+
+def run_test(onu_count, root_dir, voltha_dir, log_dir, simtype):
     auth = Authentication()
     auth.a_set_log_dirs(root_dir, voltha_dir, log_dir)
-    auth.discover_freeradius_pod_name()
-    auth.discover_freeradius_ip_addr()
-    auth.set_current_freeradius_ip_in_aaa_json()
-    auth.alter_aaa_application_configuration_in_onos_using_aaa_json()
-    auth.execute_authentication_on_rg()
-    auth.verify_authentication_should_have_started()
-    auth.verify_authentication_should_have_completed()
-    auth.verify_authentication_should_have_disconnected()
-    auth.verify_authentication_should_have_terminated()
+    auth.a_configure(onu_count)
+    if simtype == 'ponsim':
+        auth.execute_authentication_on_rg()
+        auth.authentication_should_have_started()
+        auth.authentication_should_have_completed()
+        auth.authentication_should_have_disconnected()
+        auth.authentication_should_have_terminated()
+    elif simtype == 'bbsim':
+        auth.should_have_all_onus_authenticated()
diff --git a/tests/atests/common/auto_test.py b/tests/atests/common/auto_test.py
index 6e21842..be52134 100755
--- a/tests/atests/common/auto_test.py
+++ b/tests/atests/common/auto_test.py
@@ -31,7 +31,7 @@
 import logging
 
 DEFAULT_LOG_DIR = '/tmp/voltha_test_results'
-DEFAULT_ADAPTER = 'ponsim'
+DEFAULT_SIMTYPE = 'ponsim'
 logging.basicConfig(level=logging.INFO)
 
 
@@ -66,18 +66,18 @@
     return root_dir, voltha_dir, log_dir
 
 
-def adapter_init(adapter=DEFAULT_ADAPTER):
+def simtype_init(simtype=DEFAULT_SIMTYPE):
     """
 
-    :param adapter: ponsim or bbsim
+    :param simtype: ponsim or bbsim
     :return: olt_type, onu_type, olt_host_ip, onu_count
     """
-    if adapter == 'ponsim':
+    if simtype == 'ponsim':
         olt_type = 'ponsim_olt'
         onu_type = 'ponsim_onu'
-        olt_host_ip = 'olt.voltha.svc'
+        olt_host_ip = 'olt0.voltha.svc'
         onu_count = 1
-    elif adapter == 'bbsim':
+    elif simtype == 'bbsim':
         olt_type = 'openolt'
         onu_type = 'brcm_openomci_onu'
         olt_host_ip = 'bbsim.voltha.svc'
@@ -102,21 +102,22 @@
     parser = argparse.ArgumentParser(description='VOLTHA Automated Testing')
     parser.add_argument('-l', dest='logDir', default=DEFAULT_LOG_DIR,
                         help='log directory (default: %s).' % DEFAULT_LOG_DIR)
-    parser.add_argument('-a', dest='adapter', choices=['ponsim', 'bbsim'], default=DEFAULT_ADAPTER,
-                        help='adapter (default: %s).' % DEFAULT_ADAPTER)
+    parser.add_argument('-a', dest='simtype', choices=['ponsim', 'bbsim'], default=DEFAULT_SIMTYPE,
+                        help='simtype (default: %s).' % DEFAULT_SIMTYPE)
     args = parser.parse_args()
 
     ROOT_DIR, VOLTHA_DIR, LOG_DIR = dir_init(args.logDir)
-    OLT_TYPE, ONU_TYPE, OLT_HOST_IP, ONU_COUNT = adapter_init(args.adapter)
+    OLT_TYPE, ONU_TYPE, OLT_HOST_IP, ONU_COUNT = simtype_init(args.simtype)
     
-    volthaMngr.voltha_initialize(ROOT_DIR, VOLTHA_DIR, LOG_DIR, args.adapter)
+    volthaMngr.voltha_initialize(ROOT_DIR, VOLTHA_DIR, LOG_DIR, args.simtype)
 
     preprovisioning.run_test(OLT_HOST_IP, 50060, OLT_TYPE, ONU_TYPE, ONU_COUNT, LOG_DIR)
-    time.sleep(60)
-    discovery.run_test(OLT_HOST_IP, OLT_TYPE, ONU_TYPE, ONU_COUNT, LOG_DIR)
-    if args.adapter == 'ponsim':
-        authentication.run_test(ROOT_DIR, VOLTHA_DIR, LOG_DIR)
 
+    discovery.run_test(OLT_HOST_IP, OLT_TYPE, ONU_TYPE, ONU_COUNT, LOG_DIR)
+
+    authentication.run_test(ONU_COUNT, ROOT_DIR, VOLTHA_DIR, LOG_DIR, args.simtype)
+
+    if args.simtype == 'ponsim':
         dhcp.run_test(ROOT_DIR, VOLTHA_DIR, LOG_DIR)
 
         unicast.run_test(ONU_TYPE, ONU_COUNT, ROOT_DIR, VOLTHA_DIR, LOG_DIR)
diff --git a/tests/atests/common/dhcp.py b/tests/atests/common/dhcp.py
index a9acd8e..391c2dc 100644
--- a/tests/atests/common/dhcp.py
+++ b/tests/atests/common/dhcp.py
@@ -74,7 +74,7 @@
         statusLines = testCaseUtils.get_fields_from_grep_command(self, 'IP_PROTO:17', 'voltha_onos_flows.log')
         assert statusLines, 'No DHCP Detection flows'
         lines = statusLines.splitlines()
-        assert len(lines) == 2, 'Expected 2 DHCP Detection Flows but result was %s' % len(lines)
+        assert len(lines) >= 2, 'Expected at least 2 DHCP Detection Flows but result was %s' % len(lines)
         for line in lines:
             self.__fields = testCaseUtils.parse_fields(line, ',')
             inPortStr = self.__fields[5].strip()
diff --git a/tests/atests/common/preprovisioning.py b/tests/atests/common/preprovisioning.py
index fb68634..2b077c9 100755
--- a/tests/atests/common/preprovisioning.py
+++ b/tests/atests/common/preprovisioning.py
@@ -28,7 +28,7 @@
     """
     This class implements voltha pre-provisioning test
     """
-    
+
     def __init__(self):
         self.dirs = dict()
         self.dirs['log'] = None
@@ -99,6 +99,7 @@
         assert statusLines, 'No Olt listed under devices'
         self.__fields = testCaseUtils.parse_fields(statusLines, '|')
         assert self.check_states(self.__oltType), 'States of %s does match expected' % self.__oltType
+        hostPortCount = False
         for field in self.__fields:
             if field.strip() == self.__oltIpAddress + ':' + str(self.__oltPort):
                 hostPortCount = True
@@ -128,6 +129,23 @@
                                                  'voltha_devices_after_enable.log', 'devices')
         testCaseUtils.print_log_file(self, 'voltha_devices_after_enable.log')
 
+    def proceed(self):
+        logging.info('Pre-provisioning hold')
+        onuOnline = 0
+        portType = None
+        if self.__oltType == 'ponsim_olt':
+            portType = 'PON_OLT'
+        elif self.__oltType == 'openolt':
+            portType = 'ETHERNET_UNI'
+        while onuOnline < self.__onuCount:
+            testCaseUtils.send_command_to_voltha_cli(testCaseUtils.get_dir(self, 'log'), 'voltha_olt_device.log', 'device ' +
+                                                     self.__oltDeviceId, 'voltha_olt_ports.log', 'ports')
+            statusLines = testCaseUtils.get_fields_from_grep_command(self, portType, 'voltha_olt_ports.log')
+            lines = statusLines.splitlines()
+            onuOnline = len(lines)
+            time.sleep(5)
+        logging.info('All ONUs now Online!')
+
 
 def run_test(olt_ip_address, olt_port, olt_type, onu_type, onu_count, log_dir):
     preprovisioning = Preprovisioning()
@@ -142,3 +160,4 @@
     preprovisioning.query_devices_after_enabling()
     preprovisioning.check_olt_fields_after_enabling()
     preprovisioning.check_onu_fields_after_enabling()
+    preprovisioning.proceed()
diff --git a/tests/atests/common/run_robot.sh b/tests/atests/common/run_robot.sh
index 84e6bcd..17847a1 100755
--- a/tests/atests/common/run_robot.sh
+++ b/tests/atests/common/run_robot.sh
@@ -16,13 +16,13 @@
 SRC_DIR="$( cd -P "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
 VOLTHA_DIR="$SRC_DIR/../../.."
 
-echo "Run Robot Framework TEST. Log: $1, Adapter: ${2:-ponsim}"
+echo "Run Voltha Test Automation Suite. Log: $1, Simtype: ${2:-ponsim}"
 cd ${VOLTHA_DIR}
 source env.sh
 if [[ "${2:-ponsim}" == "ponsim" ]]
   then
-    robot -d $1 -v LOG_DIR:$1/voltha_test_results -v ADAPTER:ponsim ./tests/atests/robot/voltha_automated_test_suite.robot
+    robot -d $1 -v LOG_DIR:$1/voltha_test_results -v SIMTYPE:ponsim ./tests/atests/robot/voltha_automated_test_suite.robot
 elif [[ "${2}" == "bbsim" ]]
     then
-      robot -d $1 -v LOG_DIR:$1/voltha_test_results -v ADAPTER:bbsim -e ponsim ./tests/atests/robot/voltha_automated_test_suite.robot
+      robot -d $1 -v LOG_DIR:$1/voltha_test_results -v SIMTYPE:bbsim -e ponsim ./tests/atests/robot/voltha_automated_test_suite.robot
 fi
\ No newline at end of file
diff --git a/tests/atests/common/testCaseUtils.py b/tests/atests/common/testCaseUtils.py
index 1fe4f82..9b9b67d 100755
--- a/tests/atests/common/testCaseUtils.py
+++ b/tests/atests/common/testCaseUtils.py
@@ -171,4 +171,4 @@
 
 
 def discover_rg_pod_name():
-    return extract_pod_name('rg-').strip()
+    return extract_pod_name('rg0').strip()
diff --git a/tests/atests/common/unicast.py b/tests/atests/common/unicast.py
index 69d3d1a..1622b99 100644
--- a/tests/atests/common/unicast.py
+++ b/tests/atests/common/unicast.py
@@ -78,7 +78,7 @@
     def execute_tcpdump(self):
         logging.info('Execute tcpdump')
         process_output = open('%s/%s' % (testCaseUtils.get_dir(self, 'log'), self.TCPDUMP_FILENAME), 'w')
-        tcpdump = subprocess.Popen(['sudo', '/usr/sbin/tcpdump', '-nei', 'pon1'],
+        tcpdump = subprocess.Popen(['sudo', '/usr/sbin/tcpdump', '-nei', 'nni0'],
                                    stdout=process_output,
                                    stderr=process_output)
         self.__tcpdumpPid = tcpdump.pid
diff --git a/tests/atests/common/volthaMngr.py b/tests/atests/common/volthaMngr.py
index 1751fa4..84e937f 100755
--- a/tests/atests/common/volthaMngr.py
+++ b/tests/atests/common/volthaMngr.py
@@ -23,7 +23,7 @@
 import subprocess
 import testCaseUtils
 import logging
-
+import time
 
 
 class VolthaMngr(object):
@@ -32,35 +32,38 @@
     This class implements voltha startup/shutdown callable helper functions
     """
 
-    DEFAULT_ADAPTER = 'ponsim'
+    DEFAULT_SIMTYPE = 'ponsim'
 
     def __init__(self):
         self.dirs = dict()
         self.dirs['root'] = None
         self.dirs['voltha'] = None
         self.dirs['log'] = None
-        
+
+        self.__radiusName = None
+        self.__radiusIp = None
+
     def v_set_log_dirs(self, root_dir, voltha_dir, log_dir):
         testCaseUtils.config_dirs(self, log_dir, root_dir, voltha_dir)
 
-    def start_all_pods(self, adapter=DEFAULT_ADAPTER):
-        proc1 = subprocess.Popen([testCaseUtils.get_dir(self, 'root') + '/build.sh', 'start', adapter],
+    def start_all_pods(self, simtype=DEFAULT_SIMTYPE):
+        proc1 = subprocess.Popen([testCaseUtils.get_dir(self, 'root') + '/build.sh', 'start', simtype],
                                  stdout=subprocess.PIPE,
                                  stderr=subprocess.PIPE)
         output = proc1.communicate()[0]
         print(output)
         proc1.stdout.close()
 
-    def stop_all_pods(self, adapter=DEFAULT_ADAPTER):
-        proc1 = subprocess.Popen([testCaseUtils.get_dir(self, 'root') + '/build.sh', 'stop', adapter],
+    def stop_all_pods(self, simtype=DEFAULT_SIMTYPE):
+        proc1 = subprocess.Popen([testCaseUtils.get_dir(self, 'root') + '/build.sh', 'stop', simtype],
                                  stdout=subprocess.PIPE,
                                  stderr=subprocess.PIPE)
         output = proc1.communicate()[0]
         print(output)
         proc1.stdout.close()
         
-    def reset_kube_adm(self, adapter=DEFAULT_ADAPTER):
-        proc1 = subprocess.Popen([testCaseUtils.get_dir(self, 'root') + '/build.sh', 'clear', adapter],
+    def reset_kube_adm(self, simtype=DEFAULT_SIMTYPE):
+        proc1 = subprocess.Popen([testCaseUtils.get_dir(self, 'root') + '/build.sh', 'clear', simtype],
                                  stdout=subprocess.PIPE,
                                  stderr=subprocess.PIPE)
         output = proc1.communicate()[0]
@@ -98,13 +101,50 @@
                 os.system('/usr/bin/kubectl logs -n %s -f %s onos > %s/%s.log 2>&1 &' %
                           (Namespace, podName, testCaseUtils.get_dir(self, 'log'), podName))
             elif 'calico-node' in podName:
-                    os.system('/usr/bin/kubectl logs -n %s -f %s calico-node > %s/%s.log 2>&1 &' %
-                              (Namespace, podName, testCaseUtils.get_dir(self, 'log'), podName))
+                os.system('/usr/bin/kubectl logs -n %s -f %s calico-node > %s/%s.log 2>&1 &' %
+                          (Namespace, podName, testCaseUtils.get_dir(self, 'log'), podName))
             else:
                 os.system('/usr/bin/kubectl logs -n %s -f %s > %s/%s.log 2>&1 &' %
                           (Namespace, podName, testCaseUtils.get_dir(self, 'log'), podName))
 
-        
+    def discover_freeradius_pod_name(self):
+        self.__radiusName = testCaseUtils.extract_pod_name('freeradius').strip()
+        logging.info('freeradius Name = %s' % self.__radiusName)
+
+    def discover_freeradius_ip_addr(self):
+        ipAddr = testCaseUtils.extract_radius_ip_addr(self.__radiusName)
+        assert ipAddr, 'No IP address listed for freeradius'
+        self.__radiusIp = ipAddr.strip()
+        logging.info('freeradius IP = %s' % self.__radiusIp)
+
+    def prepare_current_freeradius_ip(self):
+        status = testCaseUtils.modify_radius_ip_in_json_using_sed(self, self.__radiusIp)
+        assert (status == 0), 'Setting Radius Ip in Json File did not return Success'
+
+    def alter_freeradius_ip_in_onos_aaa_application_configuration(self):
+        logging.info('Altering the Onos NetCfg AAA apps with Freeradius IP address')
+        logging.debug('curl --user karaf:karaf -X POST -H "Content-Type: application/json" '
+                      'http://localhost:30120/onos/v1/network/configuration/apps/ -d @%s/tests/atests/build/aaa_json'
+                      % testCaseUtils.get_dir(self, 'voltha'))
+        os.system('curl --user karaf:karaf -X POST -H "Content-Type: application/json" '
+                  'http://localhost:30120/onos/v1/network/configuration/apps/ -d @%s/tests/atests/build/aaa_json'
+                  % testCaseUtils.get_dir(self, 'voltha'))
+
+    def activate_aaa_app_in_onos(self):
+        logging.info('Activating AAA Application on Onos')
+        testCaseUtils.send_command_to_onos_cli(testCaseUtils.get_dir(self, 'log'),
+                                               'voltha_aaa_application_activate.log', 'app activate aaa')
+        statusLines = testCaseUtils.get_fields_from_grep_command(self, 'Activated', 'voltha_aaa_application_activate.log')
+        assert statusLines, 'AAA Application failed to be Activated'
+
+    def deactivate_aaa_app_in_onos(self):
+        logging.info('Deactivating AAA Application on Onos')
+        testCaseUtils.send_command_to_onos_cli(testCaseUtils.get_dir(self, 'log'),
+                                               'voltha_aaa_application_deactivate.log', 'app deactivate aaa')
+        statusLines = testCaseUtils.get_fields_from_grep_command(self, 'Deactivated', 'voltha_aaa_application_deactivate.log')
+        assert statusLines, 'AAA Application failed to be Deactivated'
+
+
 def get_all_running_pods():
     allRunningPods = []
     proc1 = subprocess.Popen(['/usr/bin/kubectl', 'get', 'pods', '--all-namespaces'],
@@ -127,11 +167,18 @@
     return allRunningPods
 
 
-def voltha_initialize(root_dir, voltha_dir, log_dir, adapter):
+def voltha_initialize(root_dir, voltha_dir, log_dir, simtype):
     voltha = VolthaMngr()
     voltha.v_set_log_dirs(root_dir, voltha_dir, log_dir)
-    voltha.stop_all_pods(adapter)
-    voltha.reset_kube_adm(adapter)
-    voltha.start_all_pods(adapter)
+    voltha.stop_all_pods(simtype)
+    voltha.reset_kube_adm(simtype)
+    voltha.start_all_pods(simtype)
     voltha.alter_onos_net_cfg()
     voltha.collect_pod_logs()
+    voltha.discover_freeradius_pod_name()
+    voltha.discover_freeradius_ip_addr()
+    voltha.prepare_current_freeradius_ip()
+    voltha.alter_freeradius_ip_in_onos_aaa_application_configuration()
+    voltha.deactivate_aaa_app_in_onos()
+    time.sleep(5)
+    voltha.activate_aaa_app_in_onos()
diff --git a/tests/atests/robot/voltha_automated_test_suite.robot b/tests/atests/robot/voltha_automated_test_suite.robot
index 71ec642..c86193f 100755
--- a/tests/atests/robot/voltha_automated_test_suite.robot
+++ b/tests/atests/robot/voltha_automated_test_suite.robot
@@ -41,9 +41,11 @@
 ${ONU_TYPE}             ${EMPTY}
 ${OLT_HOST_IP}          ${EMPTY}
 ${ONU_COUNT}            ${EMPTY}
-${ADAPTER}              ${EMPTY}
+${SIMTYPE}              ${EMPTY}
 ${RETRY_TIMEOUT_60}     60s
 ${RETRY_INTERVAL_2}     2s
+${PROCEED_TIMEOUT_180}  180s
+
 
 *** Test Cases ***
 Olt Pre Provisioning
@@ -59,11 +61,8 @@
     Status Should Be Success After Preprovision Command
     Check Olt Fields Before Enabling
     Enable
-    Wait Until Keyword Succeeds    ${RETRY_TIMEOUT_60}    ${RETRY_INTERVAL_2}    Query Devices After Enabling
-    Status Should Be Success After Enable Command
-    Check Olt Fields After Enabling
-    Check Onu Fields After Enabling
-    Sleep    60
+    Wait Until Keyword Succeeds    ${RETRY_TIMEOUT_60}    ${RETRY_INTERVAL_2}    Validate Number of Devices
+    Wait Until Keyword Succeeds   ${PROCEED_TIMEOUT_180}  ${RETRY_INTERVAL_2}    Proceed
 
 Olt Onu Discovery
     [Documentation]     Olt Onu Discovery
@@ -87,20 +86,15 @@
     
 Radius Authentication
     [Documentation]     Radius Authentication
-    ...                 This test attempts to perform a Radius Authentication from the RG
-    ...                 It uses the wpa_supplicant app to authenticate using EAPOL.
+    ...                 This test attempts to perform a Radius Authentication from the RG in the case
+    ...                 of the 'ponsim' simtype. It uses the wpa_supplicant app to authenticate using EAPOL.
     ...                 We then verify the generated log file confirming all the authentication steps
-    [Tags]              ponsim
+    ...                 In the case where the simtype is 'bbsim' we simply verify that all ONUs have
+    ...                 authenticated. We do this by executing the 'aaa-users command on onos
     A Set Log Dirs      ${ROOT_DIR}    ${VOLTHA_DIR}    ${LOG_DIR}
-    Discover Freeradius Pod Name
-    Discover Freeradius Ip Addr
-    Set Current Freeradius Ip In AAA Json
-    Alter AAA Application Configuration In Onos Using AAA Json
-    Execute Authentication On RG
-    Verify Authentication Should Have Started
-    Verify Authentication Should Have Completed
-    Verify Authentication Should Have Disconnected
-    Verify Authentication Should Have Terminated    
+    A Configure         ${ONU_COUNT}
+    Run Keyword If      '${SIMTYPE}' == 'ponsim'      Ponsim Authentication Steps
+    ...  ELSE IF        '${SIMTYPE}' == 'bbsim'       BBSim Authentication Verification Step
 
 Dhcp IP Address Assignment on RG
     [Documentation]     DHCP assigned IP Address
@@ -143,27 +137,55 @@
     [Documentation]     Start Voltha infrastructure to run test(s). This includes starting all 
     ...                 Kubernetes Pods and start collection of logs. PonsimV2 has now been
     ...                 containerized and does not need to be managed separately
-    ...                 Initialize working DIRs as well as Adapter specific variables
+    ...                 Initialize working DIRs as well as Simtype specific variables. We also 
+    ...                 setup Freeradius and restart AAA app in onos in preparation for 
+    ...                 authentication test case
     ${ROOT_DIR}  ${VOLTHA_DIR}  ${LOG_DIR}  Dir Init    ${LOG_DIR}
     Set Suite Variable  ${ROOT_DIR}
     Set Suite Variable  ${VOLTHA_DIR}
     Set Suite Variable  ${LOG_DIR}   
     V Set Log Dirs      ${ROOT_DIR}    ${VOLTHA_DIR}    ${LOG_DIR}
-    ${OLT_TYPE}  ${ONU_TYPE}    ${OLT_HOST_IP}  ${ONU_COUNT}  Adapter Init  ${ADAPTER}
+    ${OLT_TYPE}  ${ONU_TYPE}    ${OLT_HOST_IP}  ${ONU_COUNT}  Simtype Init  ${SIMTYPE}
     Set Suite Variable  ${OLT_TYPE}
     Set Suite Variable  ${ONU_TYPE}
     Set Suite Variable  ${OLT_HOST_IP}
     Set Suite Variable  ${ONU_COUNT}
     Stop Voltha
-    Start All Pods      ${ADAPTER}
+    Start All Pods      ${SIMTYPE}
     Sleep    60
     ${pod_status}       Run    kubectl get pods --all-namespaces
     Log To Console      \n${pod_status}\n
     Alter Onos Net Cfg
-    
+    Discover Freeradius Pod Name
+    Discover Freeradius Ip Addr
+    Prepare Current Freeradius Ip
+    Alter Freeradius Ip In Onos AAA Application Configuration
+    Deactivate Aaa App In Onos
+    Sleep   5
+    Activate Aaa App In Onos
+
 Stop Voltha
     [Documentation]     Stop Voltha infrastructure. This includes clearing all installation milestones
     ...                 files and stopping all Kubernetes pods
     Collect Pod Logs
-    Stop All Pods       ${ADAPTER}
-    Reset Kube Adm      ${ADAPTER}
+    Stop All Pods       ${SIMTYPE}
+    Reset Kube Adm      ${SIMTYPE}
+
+Ponsim Authentication Steps
+    [Documentation]     List of steps required to run manual Authentication from RG
+    Execute Authentication On RG
+    Authentication Should Have Started
+    Authentication Should Have Completed
+    Authentication Should Have Disconnected
+    Authentication Should Have Terminated
+
+BBSim Authentication Verification Step
+    [Documentation]     List of steps to verify that all BBSim ONUs have successfully authenticated
+    Wait Until Keyword Succeeds    ${RETRY_TIMEOUT_60}    ${RETRY_INTERVAL_2}    Should Have All Onus Authenticated
+   
+Validate Number of Devices
+    [Documentation]    Validate the number of expected onus to be activated
+    Query Devices After Enabling
+    Status Should Be Success After Enable Command
+    Check Olt Fields After Enabling
+    Check Onu Fields After Enabling 
diff --git a/voltha/adapters/ponsim_olt/ponsim_olt.py b/voltha/adapters/ponsim_olt/ponsim_olt.py
index 2c32904..72b30f7 100644
--- a/voltha/adapters/ponsim_olt/ponsim_olt.py
+++ b/voltha/adapters/ponsim_olt/ponsim_olt.py
@@ -388,7 +388,6 @@
         self.pm_metrics = None
         self.alarms = None
         self.frames = None
-        self.uni_ports = []
         self.ctag_map = {}
 
     def __del__(self):
@@ -548,7 +547,6 @@
                 vlan=vlan_id,
                 serial_number=onu.serial_number
             )
-            self.uni_ports.append(int(onu.uni_port))
 
         if self.ponsim_comm == 'grpc':
             self.log.info('starting-frame-grpc-stream')
@@ -692,71 +690,73 @@
                 action.output.port = ofp.OFPP_CONTROLLER
                 self.log.info('sending flow to controller')
 
-    # Lookup subscriber ctag for a particular PON port
-    def get_subscriber_ctag(self, flows, port):
-        self.log.debug('looking from subscriber flow for port', port=port)
-
-        for flow in flows:
-            in_port = fd.get_in_port(flow)
-            out_port = fd.get_out_port(flow)
-            if in_port == port and out_port == self.nni_port.port_no:
-                fields = fd.get_ofb_fields(flow)
-                self.log.debug('subscriber flow found', fields=fields)
-                for field in fields:
-                    if field.type == fd.VLAN_VID:
-                        self.log.debug('subscriber ctag found',
-                                       vlan_id=field.vlan_vid)
-                        return field.vlan_vid & 0x0fff
-        self.log.debug('No subscriber flow found', port=port)
-        return None
-
     # Lookup UNI port for a particular subscriber ctag
     def get_subscriber_uni_port(self, ctag):
-        self.log.debug('get_subscriber_uni_port', ctag=ctag, ctag_map=self.ctag_map)
+        self.log.debug('get_subscriber_uni_port', ctag=ctag)
         c = int(ctag)
         if c in self.ctag_map:
             return self.ctag_map[c]
-        # return None
-        # HACK: temporarily pass atest
-        return int(128)
-
-    def clear_ctag_map(self):
-        self.ctag_map = {}
+        elif self.is_uni_port(c):
+            return c
+        self.log.debug('get_subscriber_uni_port: no mapping found', ctag=ctag, ctag_map=self.ctag_map)
+        return None
 
     def update_ctag_map(self, ctag, uni_port):
-        c = int(ctag)
-        u = int(uni_port)
-        if not self.is_uni_port(u):
-            self.log.warning('update_ctag_map: unknown UNI port', uni_port=u)
-        if c in self.ctag_map and self.ctag_map[c] != u:
-            self.log.warning('update_ctag_map: changing UNI port for ctag',
-                ctag=c, old=self.ctag_map[c], new=u)
-        self.ctag_map[c] = u
+        if ctag is None:
+            for (c, u) in self.ctag_map.iteritems():
+                if u == int(uni_port):
+                    self.log.debug('deleting ctag mapping', ctag=c, uni_port=u)
+                    del self.ctag_map[c]
+                    return
+        else:
+            c = int(ctag)
+            u = int(uni_port)
+            if not self.is_uni_port(u):
+                self.log.warning('unknown UNI port', uni_port=u)
+            if c in self.ctag_map:
+                if self.ctag_map[c] == u:
+                    return
+                else:
+                    self.log.warning('changing UNI port for ctag',
+                        ctag=c, old=self.ctag_map[c], new=u)
 
-    # Create a new flow that's a copy of the old flow but change the vlan_vid
-    # Used to create per-subscriber DHCP and EAPOL flows
-    def create_secondary_flow(self, flow, vlan_id):
-        secondary_flow = copy.deepcopy(flow)
-        for field in fd.get_ofb_fields(secondary_flow):
-            if field.type == fd.VLAN_VID:
-                field.vlan_vid = vlan_id | 0x1000
-        return secondary_flow
+            self.ctag_map[c] = u
+            self.log.debug('added mapping', ctag=c, uni_port=u)
 
     def is_uni_port(self, vlan_id):
-        return int(vlan_id) in self.uni_ports
+        for onu in self.adapter_agent.get_child_devices(self.device_id):
+            if onu.vlan == vlan_id:
+                return True
+        return False
 
-    def create_secondary_flows(self, trapflows, allflows, type):
-        secondary_flows = []
-        for vlan_vid, flow in trapflows.iteritems():
-            if self.is_uni_port(vlan_vid):
-                self.update_ctag_map(vlan_vid, vlan_vid)
-                ctag = self.get_subscriber_ctag(allflows, fd.get_in_port(flow))
-                if ctag is not None:
-                    self.update_ctag_map(ctag, vlan_vid)
-                    if ctag not in trapflows:
-                        self.log.info('add secondary %s flow' % type, ctag=ctag)
-                        secondary_flows.append(self.create_secondary_flow(flow, ctag))
-        return secondary_flows
+    def get_classifier_info(self, flow):
+        classifier_info = {}
+        for field in fd.get_ofb_fields(flow):
+            if field.type == fd.ETH_TYPE:
+                classifier_info[ETH_TYPE] = field.eth_type
+            elif field.type == fd.IP_PROTO:
+                classifier_info[IP_PROTO] = field.ip_proto
+            elif field.type == fd.IN_PORT:
+                classifier_info[IN_PORT] = field.port
+            elif field.type == fd.VLAN_VID:
+                classifier_info[VLAN_VID] = field.vlan_vid & 0xfff
+            elif field.type == fd.VLAN_PCP:
+                classifier_info[VLAN_PCP] = field.vlan_pcp
+            elif field.type == fd.UDP_DST:
+                classifier_info[UDP_DST] = field.udp_dst
+            elif field.type == fd.UDP_SRC:
+                classifier_info[UDP_SRC] = field.udp_src
+            elif field.type == fd.IPV4_DST:
+                classifier_info[IPV4_DST] = field.ipv4_dst
+            elif field.type == fd.IPV4_SRC:
+                classifier_info[IPV4_SRC] = field.ipv4_src
+            elif field.type == fd.METADATA:
+                classifier_info[METADATA] = field.table_metadata
+            else:
+                self.log.debug('field-type-unhandled field.type={}'.format(
+                    field.type))
+
+        return classifier_info
 
     # VOLTHA's flow decomposition removes the information about which flows
     # are trap flows where traffic should be forwarded to the controller.
@@ -766,38 +766,11 @@
         stub = ponsim_pb2_grpc.PonSimStub(self.get_channel())
         self.log.info('pushing-olt-flow-table')
 
-        self.clear_ctag_map()
-        dhcp_upstream_flows = {}
         eapol_flows = {}
-        secondary_flows = []
         eapol_flow_without_vlan = False
 
         for flow in flows:
-            classifier_info = {}
-            for field in fd.get_ofb_fields(flow):
-                if field.type == fd.ETH_TYPE:
-                    classifier_info[ETH_TYPE] = field.eth_type
-                elif field.type == fd.IP_PROTO:
-                    classifier_info[IP_PROTO] = field.ip_proto
-                elif field.type == fd.IN_PORT:
-                    classifier_info[IN_PORT] = field.port
-                elif field.type == fd.VLAN_VID:
-                    classifier_info[VLAN_VID] = field.vlan_vid & 0xfff
-                elif field.type == fd.VLAN_PCP:
-                    classifier_info[VLAN_PCP] = field.vlan_pcp
-                elif field.type == fd.UDP_DST:
-                    classifier_info[UDP_DST] = field.udp_dst
-                elif field.type == fd.UDP_SRC:
-                    classifier_info[UDP_SRC] = field.udp_src
-                elif field.type == fd.IPV4_DST:
-                    classifier_info[IPV4_DST] = field.ipv4_dst
-                elif field.type == fd.IPV4_SRC:
-                    classifier_info[IPV4_SRC] = field.ipv4_src
-                elif field.type == fd.METADATA:
-                    classifier_info[METADATA] = field.table_metadata
-                else:
-                    self.log.debug('field-type-unhandled field.type={}'.format(
-                        field.type))
+            classifier_info = self.get_classifier_info(flow)
 
             self.log.debug('classifier_info', classifier_info=classifier_info)
 
@@ -806,8 +779,6 @@
                     if UDP_SRC in classifier_info:
                         if classifier_info[UDP_SRC] == 68:
                             self.log.info('dhcp upstream flow add')
-                            if VLAN_VID in classifier_info:
-                                dhcp_upstream_flows[classifier_info[VLAN_VID]] = flow
                         elif classifier_info[UDP_SRC] == 67:
                             self.log.info('dhcp downstream flow add')
                     self.to_controller(flow)
@@ -826,11 +797,6 @@
                     else:
                         eapol_flow_without_vlan = True
 
-            self.log.info('out_port', out_port=fd.get_out_port(flow))
-
-        flows.extend(self.create_secondary_flows(dhcp_upstream_flows, flows, "DHCP"))
-        flows.extend(self.create_secondary_flows(eapol_flows, flows, "EAPOL"))
-
         # The OLT app is now adding EAPOL flows with VLAN_VID=4091 but Ponsim can't
         # properly handle this because it uses VLAN_VID to encode the UNI port ID.
         # Add an EAPOL trap flow with no VLAN_VID match if we see the 4091 match.
@@ -845,8 +811,6 @@
             flows.extend(new_eapol_flow)
             self.log.info('add eapol flow with no VLAN_VID match')
 
-        self.log.debug('ctag_map', ctag_map=self.ctag_map)
-
         stub.UpdateFlowTable(FlowTable(
             port=0,
             flows=flows
@@ -875,6 +839,33 @@
         if isinstance(msg, FlowTable):
             stub = ponsim_pb2_grpc.PonSimStub(self.get_channel())
             self.log.info('pushing-onu-flow-table', port=msg.port)
+
+            # Extract ctag -> uni_port mapping from ONU flows.
+            # Below we assume that a downstream flow whose VLAN_VID is not
+            # equal to the logcal port is stripping the ctag.
+            # If we find such a flow we add the mapping to the ctag_map.
+            # Note that this wouldn't be necessary if we actually knew the logical
+            # port that an upstream packet arrived on.
+            logical_port_id = "uni-{}".format(msg.port)
+            logical_port = self.adapter_agent.get_logical_port(self.logical_device_id, logical_port_id)
+            if logical_port:
+                uni_port_id = logical_port.device_port_no
+                ctag = None
+
+                for flow in msg.flows:
+                    classifier_info = self.get_classifier_info(flow)
+                    self.log.debug('classifier_info', classifier_info=classifier_info)
+
+                    if VLAN_VID in classifier_info and IN_PORT in classifier_info:
+                        if classifier_info[IN_PORT] != uni_port_id and classifier_info[VLAN_VID] != msg.port:
+                            if ctag is not None:
+                                self.log.error('more than one ctag inferred', ctag1=ctag, ctag2=classifier_info[VLAN_VID])
+                            ctag = classifier_info[VLAN_VID]
+
+                self.update_ctag_map(ctag, msg.port)
+            else:
+                self.log.error('no logical port found', id=logical_port_id)
+
             res = stub.UpdateFlowTable(msg)
             self.adapter_agent.receive_proxied_message(proxy_address, res)
         elif isinstance(msg, PonSimMetricsRequest):