VOL-1666: BBSim DHCP Test Case

DHCP IP Addess assignment happens between BBSIM's dhclient, DHCP server
via dhcpl2relay. This is initiated automatically once all ONUs have been
AUTHORIZED.

For the Test Case, we simply verify that all ONUs were assigned an IP
address. We do this using the onos command 'dhcpl2relay-allocations'

A few other minor cleanups were also incorporated
- Dockerfile.onos 1.13.9-rc4 --> 1.13.9
- BBSim hold waits for all ONU's to be AUTHORIZED before proceeding

Change-Id: I863ee241aa904de8267f121fdeb8826298fc1491
diff --git a/tests/atests/common/auto_test.py b/tests/atests/common/auto_test.py
index be52134..d2c5f7d 100755
--- a/tests/atests/common/auto_test.py
+++ b/tests/atests/common/auto_test.py
@@ -117,7 +117,7 @@
 
     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)
+    dhcp.run_test(ONU_COUNT, ROOT_DIR, VOLTHA_DIR, LOG_DIR, args.simtype)
 
+    if args.simtype == 'ponsim':
         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 391c2dc..9647ba6 100644
--- a/tests/atests/common/dhcp.py
+++ b/tests/atests/common/dhcp.py
@@ -41,6 +41,7 @@
         self.dirs['voltha'] = None
 
         self.__rgName = testCaseUtils.discover_rg_pod_name()
+        self.__onuCount = None
         self.__fields = None
         self.__deviceId = None
         self.__portNumber = None
@@ -48,25 +49,20 @@
     def h_set_log_dirs(self, root_dir, voltha_dir, log_dir):
         testCaseUtils.config_dirs(self, log_dir, root_dir, voltha_dir)
 
+    def h_configure(self, onu_count):
+        self.__onuCount = onu_count
+
     def discover_authorized_users(self):
         testCaseUtils.send_command_to_onos_cli(testCaseUtils.get_dir(self, 'log'),
                                                'voltha_onos_users.log', 'aaa-users')
 
-    def retrieve_authorized_users_device_id_and_port_number(self):
+    def extract_authorized_user_device_id_and_port_number(self):
         statusLines = testCaseUtils.get_fields_from_grep_command(self, 'AUTHORIZED', 'voltha_onos_users.log')
-        assert statusLines, 'No Users Authorized'
-        self.__fields = testCaseUtils.parse_fields(statusLines, ',')
-        deviceField = self.__fields[2].strip()
-        deviceStr, equal, deviceId = deviceField.partition('=')
-        self.__deviceId = deviceId
-        portField = self.__fields[4].strip()
-        portNumStr, equal, portNum = portField.partition('=')
-        self.__portNumber = portNum
+        assert statusLines, 'No ONU has been authenticated'
+        self.__deviceId, self.__portNumber = testCaseUtils.retrieve_authorized_users_device_id_and_port_number(statusLines)
 
-    def add_subscriber_access(self):
-        testCaseUtils.send_command_to_onos_cli(testCaseUtils.get_dir(self, 'log'),
-                                               'voltha_add_subscriber_access.log', 'volt-add-subscriber-access %s %s'
-                                               % (self.__deviceId, self.__portNumber))
+    def add_onu_bound_dhcp_flows(self):
+        testCaseUtils.add_subscriber_access(self, self.__deviceId, self.__portNumber)
 
     def should_now_have_two_dhcp_flows(self):
         testCaseUtils.send_command_to_onos_cli(testCaseUtils.get_dir(self, 'log'),
@@ -206,25 +202,42 @@
         statusLines = testCaseUtils.get_fields_from_grep_command(self, 'inet', self.CHECK_ASSIGNED_IP_FILENAME)
         assert statusLines, 'DHCP IP addr not assigned'
 
+    def should_have_ips_assigned_to_all_onus(self):
+        logging.info('Verifying IP Address assignment on all ONUs')
+        testCaseUtils.send_command_to_onos_cli(testCaseUtils.get_dir(self, 'log'),
+                                               '_voltha_onos_dhcpl2relay_allocations.log', 'dhcpl2relay-allocations')
+        statusLines = testCaseUtils.get_fields_from_grep_command(self, 'DHCPACK', '_voltha_onos_dhcpl2relay_allocations.log')
+        assert statusLines, 'No DHCP addresses allocated'
+        lines = statusLines.splitlines()
+        assert len(lines) == self.__onuCount, 'Allocated IPs does not match ONU count but result was %s' % len(lines)
+        for line in lines:
+            self.__fields = testCaseUtils.parse_fields(line, ',')
+            allocIp = self.__fields[5].strip()
+            allocated, delimiter, ipAddr = allocIp.partition('=')
+            assert ipAddr != '0.0.0.0', 'Invalid IP Address Allocated'
+
 
 def set_firewall_rules():
     logging.info('Setting Firewall rules for DHCP test')
     os.system('sudo iptables -P FORWARD ACCEPT')
 
 
-def run_test(root_dir, voltha_dir, log_dir):
-
-    set_firewall_rules()
+def run_test(onu_count, root_dir, voltha_dir, log_dir, simtype):
     dhcp = DHCP()
     dhcp.h_set_log_dirs(root_dir, voltha_dir, log_dir)
-    dhcp.discover_authorized_users()
-    dhcp.retrieve_authorized_users_device_id_and_port_number()
-    dhcp.add_subscriber_access()
-    dhcp.should_now_have_two_dhcp_flows()
-    dhcp.deactivate_dhcp_server_in_onos()
-    dhcp.add_dhcp_server_configuration_data_in_onos()
-    dhcp.activate_dhcp_server_in_onos()
-    dhcp.query_for_default_ip_on_rg()
-    dhcp.de_assign_default_ip_on_rg()
-    dhcp.assign_dhcp_ip_addr_to_rg()
-    dhcp.should_have_dhcp_assigned_ip()
+    dhcp.h_configure(onu_count)
+    if simtype == 'ponsim':
+        set_firewall_rules()
+        dhcp.discover_authorized_users()
+        dhcp.extract_authorized_user_device_id_and_port_number()
+        dhcp.add_onu_bound_dhcp_flows()
+        dhcp.should_now_have_two_dhcp_flows()
+        dhcp.deactivate_dhcp_server_in_onos()
+        dhcp.add_dhcp_server_configuration_data_in_onos()
+        dhcp.activate_dhcp_server_in_onos()
+        dhcp.query_for_default_ip_on_rg()
+        dhcp.de_assign_default_ip_on_rg()
+        dhcp.assign_dhcp_ip_addr_to_rg()
+        dhcp.should_have_dhcp_assigned_ip()
+    elif simtype == 'bbsim':
+        dhcp.should_have_ips_assigned_to_all_onus()
diff --git a/tests/atests/common/preprovisioning.py b/tests/atests/common/preprovisioning.py
index 2b077c9..c0b7cc0 100755
--- a/tests/atests/common/preprovisioning.py
+++ b/tests/atests/common/preprovisioning.py
@@ -132,19 +132,25 @@
     def proceed(self):
         logging.info('Pre-provisioning hold')
         onuOnline = 0
-        portType = None
         if self.__oltType == 'ponsim_olt':
             portType = 'PON_OLT'
+            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!')
         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!')
+            while onuOnline < self.__onuCount:
+                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()
+                onuOnline = len(lines)
+                time.sleep(5)
+            logging.info('All ONUs now AUTHORIZED')
 
 
 def run_test(olt_ip_address, olt_port, olt_type, onu_type, onu_count, log_dir):
@@ -157,7 +163,7 @@
     preprovisioning.check_olt_fields_before_enabling()
     preprovisioning.enable()
     preprovisioning.status_should_be_success_after_enable_command()
+    preprovisioning.proceed()
     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/testCaseUtils.py b/tests/atests/common/testCaseUtils.py
index 9b9b67d..529d540 100755
--- a/tests/atests/common/testCaseUtils.py
+++ b/tests/atests/common/testCaseUtils.py
@@ -172,3 +172,20 @@
 
 def discover_rg_pod_name():
     return extract_pod_name('rg0').strip()
+
+
+def retrieve_authorized_users_device_id_and_port_number(status_line):
+    fields = parse_fields(status_line, ',')
+    deviceField = fields[2].strip()
+    deviceStr, equal, deviceId = deviceField.partition('=')
+    device_Id = deviceId
+    portField = fields[4].strip()
+    portNumStr, equal, portNum = portField.partition('=')
+    portNumber = portNum
+    return device_Id, portNumber
+
+
+def add_subscriber_access(self, device_id, port_number):
+    send_command_to_onos_cli(get_dir(self, 'log'),
+                             'voltha_add_subscriber_access.log', 'volt-add-subscriber-access %s %s'
+                             % (device_id, port_number))
diff --git a/tests/atests/common/volthaMngr.py b/tests/atests/common/volthaMngr.py
index 84e937f..d450494 100755
--- a/tests/atests/common/volthaMngr.py
+++ b/tests/atests/common/volthaMngr.py
@@ -90,6 +90,12 @@
         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/sadis_json'
                   % testCaseUtils.get_dir(self, 'voltha'))
+        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/dhcpl2relay_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/dhcpl2relay_json'
+                  % testCaseUtils.get_dir(self, 'voltha'))
 
     def collect_pod_logs(self):
         logging.info('Collect logs from all Pods')