[VOL-2047] patch for parameterization of onus for PODs/BBSim tests

Change-Id: Id9c32b8e8ce59ef28b5b20bf17fff8baa268ad4b
diff --git a/Makefile b/Makefile
index 58ec0d8..28636b0 100644
--- a/Makefile
+++ b/Makefile
@@ -38,7 +38,7 @@
 sanity-kind: ROBOT_MISC_ARGS += -i sanity
 sanity-kind: bbsim-kind
 
-bbsim-kind: ROBOT_MISC_ARGS += -v num_onus:1 -X
+bbsim-kind: ROBOT_MISC_ARGS += -X
 bbsim-kind: voltha-podtest
 
 # virtualenv for the robot tools
diff --git a/libraries/onos.robot b/libraries/onos.robot
index 9e3ba18..0647ada 100644
--- a/libraries/onos.robot
+++ b/libraries/onos.robot
@@ -99,6 +99,12 @@
     ${eapol_flows_added}=    Execute ONOS CLI Command    ${ip}    ${port}    flows -s -f ADDED | grep eapol | grep IN_PORT:${onu_port}
     Should Not Be Empty    ${eapol_flows_added}
 
+Verify ONU in AAA-Users
+    [Arguments]    ${ip}    ${port}    ${onu_port}
+    [Documentation]    Verifies that the specified onu_port exists in aaa-users output
+    ${aaa_users}=    Execute ONOS CLI Command    ${ip}    ${port}    aaa-users | grep AUTHORIZED | grep ${onu_port}
+    Should Not Be Empty    ${aaa_users}    ONU port ${onu_port} not found in aaa-users
+
 Verify Number of AAA-Users
     [Arguments]    ${ip}    ${port}    ${expected_onus}
     [Documentation]    Matches for number of aaa-users authorized based on number of onus
@@ -112,3 +118,10 @@
     ##TODO: filter by onu serial number instead of count
     ${allocations}=    Execute ONOS CLI Command    ${ip}    ${port}    dhcpl2relay-allocations | grep DHCPACK | wc -l
     Should Contain    ${allocations}    ${expected_onus}
+
+Validate Subscriber DHCP Allocation
+    [Arguments]    ${ip}    ${port}    ${onu_port}
+    [Documentation]    Verifies that the specified subscriber is found in DHCP allocations
+    ##TODO: Enhance the keyword to include DHCP allocated address is not 0.0.0.0
+    ${allocations}=    Execute ONOS CLI Command    ${ip}    ${port}    dhcpl2relay-allocations | grep DHCPACK | grep ${onu_port}
+    Should Not Be Empty    ${allocations}     ONU port ${onu_port} not found in dhcpl2relay-allocations
diff --git a/tests/data/bbsim-kind-2x2.yaml b/tests/data/bbsim-kind-2x2.yaml
new file mode 100644
index 0000000..47b30cb
--- /dev/null
+++ b/tests/data/bbsim-kind-2x2.yaml
@@ -0,0 +1,47 @@
+---
+
+# Copyright 2017-present Open Networking Foundation
+#
+# 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.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Automated deployment configuration for kind-voltha running BBSim
+
+# Change default values in tests
+has_dataplane: False
+external_libs: False
+teardown_device: True
+ONOS_REST_PORT: 8181
+ONOS_SSH_PORT: 8101
+OLT_PORT: 50060
+
+nodes:
+  -
+    ip: '127.0.0.1'
+
+olts:
+  -
+    ip: bbsim.voltha.svc
+    serial: BBSIM_OLT_0
+
+hosts:
+  src:
+    - onu: 'BBSM00000001'
+    - onu: 'BBSM00000002'
+    - onu: 'BBSM00000101'
+    - onu: 'BBSM00000102'
+
+  dst:
+    - ip: null
+    - ip: null
+    - ip: null
+    - ip: null
diff --git a/tests/data/bbsim-kind.yaml b/tests/data/bbsim-kind.yaml
index f88bca9..12ab725 100644
--- a/tests/data/bbsim-kind.yaml
+++ b/tests/data/bbsim-kind.yaml
@@ -20,7 +20,6 @@
 has_dataplane: False
 external_libs: False
 teardown_device: True
-ports_per_onu: 4
 ONOS_REST_PORT: 8181
 ONOS_SSH_PORT: 8101
 OLT_PORT: 50060
@@ -28,51 +27,15 @@
 nodes:
   -
     ip: '127.0.0.1'
-    user: null
-    pass: null
-
-fabric_switches:
-  -
-    mac: null
-    ip: null
-    user: null
-    pass: null
-    bngPort: null
-    oltPort: null
-    device_id: null
 
 olts:
   -
     ip: bbsim.voltha.svc
-    user: null
-    pass: null
-    fortygig: null
     serial: BBSIM_OLT_0
 
-onus:
-  -
-    serial: 'BBSM00000001'
-
 hosts:
   src:
-    -
-      ip: null
-      pass: null
-      dp_iface_name: null
-      container_type: null
-      container_name: null
-      onu: null
-      c_tag: null
-      s_tag: null
+    - onu: 'BBSM00000001'
 
   dst:
-    -
-      ip: null
-      user: null
-      pass: null
-      dp_iface_name: null
-      dp_iface_ip_qinq: null
-      dp_iface_ip: null
-      dp_iface_gateway: null
-      container_type: null
-      container_name: null
\ No newline at end of file
+    - ip: null
diff --git a/tests/data/flex-ocp-cord-sadis.json b/tests/data/flex-ocp-cord-sadis.json
index 6d4db3b..e8b971b 100644
--- a/tests/data/flex-ocp-cord-sadis.json
+++ b/tests/data/flex-ocp-cord-sadis.json
@@ -21,9 +21,9 @@
             "id": "ALPHe3d1cfa7-1",
             "cTag": 901,
             "sTag": 111,
-            "nasPortId": "",
-            "circuitId": "",
-            "remoteId": "",
+            "nasPortId": "ALPHe3d1cfa7-1",
+            "circuitId": "ALPHe3d1cfa7-1",
+            "remoteId": "EC1838000853",
             "technologyProfileId": 64,
             "upstreamBandwidthProfile": "Default",
             "downstreamBandwidthProfile": "Default"
@@ -32,9 +32,9 @@
             "id": "ALPHe3d1cfa7-2",
             "cTag": 902,
             "sTag": 111,
-            "nasPortId": "",
-            "circuitId": "",
-            "remoteId": "",
+            "nasPortId": "ALPHe3d1cfa7-2",
+            "circuitId": "ALPHe3d1cfa7-2",
+            "remoteId": "EC1838000853",
             "technologyProfileId": 64,
             "upstreamBandwidthProfile": "Default",
             "downstreamBandwidthProfile": "Default"
@@ -43,9 +43,9 @@
             "id": "ALPHe3d1cfa7-3",
             "cTag": 903,
             "sTag": 111,
-            "nasPortId": "",
-            "circuitId": "",
-            "remoteId": "",
+            "nasPortId": "ALPHe3d1cfa7-3",
+            "circuitId": "ALPHe3d1cfa7-3",
+            "remoteId": "EC1838000853",
             "technologyProfileId": 64,
             "upstreamBandwidthProfile": "Default",
             "downstreamBandwidthProfile": "Default"
@@ -54,9 +54,9 @@
             "id": "ALPHe3d1cfa7-4",
             "cTag": 904,
             "sTag": 111,
-            "nasPortId": "",
-            "circuitId": "",
-            "remoteId": "",
+            "nasPortId": "ALPHe3d1cfa7-4",
+            "circuitId": "ALPHe3d1cfa7-4",
+            "remoteId": "EC1838000853",
             "technologyProfileId": 64,
             "upstreamBandwidthProfile": "Default",
             "downstreamBandwidthProfile": "Default"
@@ -65,9 +65,64 @@
             "id": "ALPHe3d1cfa7-5",
             "cTag": 905,
             "sTag": 111,
-            "nasPortId": "",
-            "circuitId": "",
-            "remoteId": "",
+            "nasPortId": "ALPHe3d1cfa7-5",
+            "circuitId": "ALPHe3d1cfa7-5",
+            "remoteId": "EC1838000853",
+            "technologyProfileId": 64,
+            "upstreamBandwidthProfile": "Default",
+            "downstreamBandwidthProfile": "Default"
+          },
+          {
+            "id": "ALPHe3d1cea3-1",
+            "cTag": 801,
+            "sTag": 111,
+            "nasPortId": "ALPHe3d1cea3-1",
+            "circuitId": "ALPHe3d1cea3-1",
+            "remoteId": "EC1838000853",
+            "technologyProfileId": 64,
+            "upstreamBandwidthProfile": "Default",
+            "downstreamBandwidthProfile": "Default"
+          },
+          {
+            "id": "ALPHe3d1cea3-2",
+            "cTag": 802,
+            "sTag": 111,
+            "nasPortId": "ALPHe3d1cea3-2",
+            "circuitId": "ALPHe3d1cea3-2",
+            "remoteId": "EC1838000853",
+            "technologyProfileId": 64,
+            "upstreamBandwidthProfile": "Default",
+            "downstreamBandwidthProfile": "Default"
+          },
+          {
+            "id": "ALPHe3d1cea3-3",
+            "cTag": 803,
+            "sTag": 111,
+            "nasPortId": "ALPHe3d1cea3-3",
+            "circuitId": "ALPHe3d1cea3-3",
+            "remoteId": "EC1838000853",
+            "technologyProfileId": 64,
+            "upstreamBandwidthProfile": "Default",
+            "downstreamBandwidthProfile": "Default"
+          },
+          {
+            "id": "ALPHe3d1cea3-4",
+            "cTag": 804,
+            "sTag": 111,
+            "nasPortId": "ALPHe3d1cea3-4",
+            "circuitId": "ALPHe3d1cea3-4",
+            "remoteId": "EC1838000853",
+            "technologyProfileId": 64,
+            "upstreamBandwidthProfile": "Default",
+            "downstreamBandwidthProfile": "Default"
+          },
+          {
+            "id": "ALPHe3d1cea3-5",
+            "cTag": 805,
+            "sTag": 111,
+            "nasPortId": "ALPHe3d1cea3-5",
+            "circuitId": "ALPHe3d1cea3-5",
+            "remoteId": "EC1838000853",
             "technologyProfileId": 64,
             "upstreamBandwidthProfile": "Default",
             "downstreamBandwidthProfile": "Default"
diff --git a/tests/functional/Voltha_PODTests.robot b/tests/functional/Voltha_PODTests.robot
index 1bb83c4..95479fc 100644
--- a/tests/functional/Voltha_PODTests.robot
+++ b/tests/functional/Voltha_PODTests.robot
@@ -41,10 +41,8 @@
 ${HELM_CHARTS_DIR}    ~/helm-charts
 ${VOLTHA_POD_NUM}    8
 ${timeout}        60s
-${num_onus}       1
 ${of_id}          0
 ${logical_id}     0
-${ports_per_onu}    5
 ${has_dataplane}    True
 ${external_libs}    True
 ${teardown_device}    False
@@ -57,19 +55,36 @@
     #[Setup]    Clean Up Linux
     ${of_id}=    Wait Until Keyword Succeeds    ${timeout}    15s    Validate OLT Device in ONOS    ${olt_serial_number}
     Set Global Variable    ${of_id}
-    ${onu_port}=    Wait Until Keyword Succeeds    ${timeout}    2s    Get ONU Port in ONOS    ${onu_serial_number}   ${of_id}
-    Wait Until Keyword Succeeds    ${timeout}    2s    Verify Eapol Flows Added For ONU    ${k8s_node_ip}    ${ONOS_SSH_PORT}    ${onu_port}
-    Run Keyword If    ${has_dataplane}    Validate Authentication    True    ${src0['dp_iface_name']}
-    ...    wpa_supplicant.conf    ${src0['ip']}    ${src0['user']}    ${src0['pass']}
-    ...    ${src0['container_type']}    ${src0['container_name']}
-    Wait Until Keyword Succeeds    ${timeout}    2s    Verify Number of AAA-Users    ${k8s_node_ip}    ${ONOS_SSH_PORT}    ${num_onus}
-    Wait Until Keyword Succeeds    ${timeout}    2s    Execute ONOS CLI Command    ${k8s_node_ip}    ${ONOS_SSH_PORT}
-    ...    volt-add-subscriber-access ${of_id} ${onu_port}
-    Run Keyword If    ${has_dataplane}    Validate DHCP and Ping    True    True    ${src0['dp_iface_name']}
-    ...    ${src0['s_tag']}    ${src0['c_tag']}    ${dst0['dp_iface_ip_qinq']}    ${src0['ip']}    ${src0['user']}
-    ...    ${src0['pass']}    ${src0['container_type']}    ${src0['container_name']}    ${dst0['dp_iface_name']}
-    ...    ${dst0['ip']}    ${dst0['user']}    ${dst0['pass']}    ${dst0['container_type']}    ${dst0['container_name']}
-    Wait Until Keyword Succeeds    ${timeout}    2s    Validate DHCP Allocations    ${k8s_node_ip}    ${ONOS_SSH_PORT}    ${num_onus}
+
+    FOR    ${I}    IN RANGE    0    ${num_onus}
+        ${src}=    Set Variable    ${hosts.src[${I}]}
+        ${dst}=    Set Variable    ${hosts.dst[${I}]}
+
+        ${onu_reasons}=    Create List     tech-profile-config-download-success    omci-flows-pushed
+        Wait Until Keyword Succeeds    ${timeout}    5s    Validate Device    ${src['onu']}    ENABLED    ACTIVE
+        ...    REACHABLE    onu=True    onu_reasons=${onu_reasons}
+
+        ${onu_device_id}=    Get Device ID From SN    ${src['onu']}
+        ${onu_port}=    Wait Until Keyword Succeeds    ${timeout}    2s    Get ONU Port in ONOS    ${src['onu']}   ${of_id}
+        Wait Until Keyword Succeeds    ${timeout}    2s    Verify Eapol Flows Added For ONU    ${k8s_node_ip}    ${ONOS_SSH_PORT}    ${onu_port}
+
+        Run Keyword If    ${has_dataplane}   Run Keyword And Continue On Failure    Validate Authentication    True    ${src['dp_iface_name']}
+        ...    wpa_supplicant.conf    ${src['ip']}    ${src['user']}    ${src['pass']}
+        ...    ${src['container_type']}    ${src['container_name']}
+
+        Wait Until Keyword Succeeds    ${timeout}    2s    Verify ONU in AAA-Users    ${k8s_node_ip}    ${ONOS_SSH_PORT}
+        ...    ${onu_port}
+
+        Wait Until Keyword Succeeds    ${timeout}    2s    Execute ONOS CLI Command    ${k8s_node_ip}    ${ONOS_SSH_PORT}
+        ...    volt-add-subscriber-access ${of_id} ${onu_port}
+
+        Run Keyword If    ${has_dataplane}    Run Keyword And Continue On Failure    Validate DHCP and Ping    True    True    ${src['dp_iface_name']}
+        ...    ${src['s_tag']}    ${src['c_tag']}    ${dst['dp_iface_ip_qinq']}    ${src['ip']}    ${src['user']}
+        ...    ${src['pass']}    ${src['container_type']}    ${src['container_name']}    ${dst['dp_iface_name']}
+        ...    ${dst['ip']}    ${dst['user']}    ${dst['pass']}    ${dst['container_type']}    ${dst['container_name']}
+
+        Wait Until Keyword Succeeds    ${timeout}    2s    Validate Subscriber DHCP Allocation    ${k8s_node_ip}    ${ONOS_SSH_PORT}    ${onu_port}
+    END
 
 *** Keywords ***
 Setup Suite
@@ -95,27 +110,19 @@
     ${olt_user}=    Evaluate    ${olts}[0].get("user")
     ${olt_pass}=    Evaluate    ${olts}[0].get("pass")
     ${olt_serial_number}=    Evaluate    ${olts}[0].get("serial")
-    ${onu_serial_number}=    Evaluate    ${onus}[0].get("serial")
+    ${num_onus}=    Get Length    ${hosts.src}
+    ${num_onus}=    Convert to String    ${num_onus}
+    Set Suite Variable    ${num_onus}
     Set Suite Variable    ${olt_serial_number}
-    Set Suite Variable    ${onu_serial_number}
     Set Suite Variable    ${olt_ip}
     Set Suite Variable    ${olt_user}
     Set Suite Variable    ${olt_pass}
     Set Suite Variable    ${k8s_node_ip}
     Set Suite Variable    ${k8s_node_user}
     Set Suite Variable    ${k8s_node_pass}
-    @{container_list}=    Create List
-    Append To List    ${container_list}    adapter-open-olt
-    Append To List    ${container_list}    adapter-open-onu
-    Append To List    ${container_list}    voltha-api-server
-    Append To List    ${container_list}    voltha-ro-core
-    Append To List    ${container_list}    voltha-rw-core-11
-    Append To List    ${container_list}    voltha-rw-core-12
-    Append To List    ${container_list}    voltha-ofagent
+    @{container_list}=    Create List    adapter-open-olt    adapter-open-onu    voltha-api-server
+    ...    voltha-ro-core    voltha-rw-core-11    voltha-rw-core-12    voltha-ofagent
     Set Suite Variable    ${container_list}
-    # Set Deployment Config Variables seems like a candidate for refactoring.
-    # BBSim doesn't need it right now.
-    Run Keyword If    ${external_libs}    Set Deployment Config Variables
     ${datetime}=    Get Current Date
     Set Suite Variable    ${datetime}
 
@@ -128,11 +135,6 @@
     Enable Device    ${olt_device_id}
     Wait Until Keyword Succeeds    ${timeout}    5s    Validate Device    ${olt_serial_number}    ENABLED    ACTIVE
     ...    REACHABLE
-    ${onu_reasons}=    Create List     tech-profile-config-download-success    omci-flows-pushed
-    Wait Until Keyword Succeeds    ${timeout}    5s    Validate Device    ${onu_serial_number}    ENABLED    ACTIVE
-    ...    REACHABLE    onu=True    onu_reasons=${onu_reasons}
-    ${onu_device_id}=    Get Device ID From SN    ${onu_serial_number}
-    Set Suite Variable    ${onu_device_id}
     ${logical_id}=    Get Logical Device ID From SN    ${olt_serial_number}
     Set Suite Variable    ${logical_id}
 
@@ -152,28 +154,25 @@
 
 Clean Up Linux
     [Documentation]    Kill processes and clean up interfaces on src+dst servers
-    Run Keyword And Ignore Error    Kill Linux Process    [w]pa_supplicant    ${src0['ip']}
-    ...    ${src0['user']}    ${src0['pass']}    ${src0['container_type']}    ${src0['container_name']}
-    Run Keyword And Ignore Error    Kill Linux Process    [d]hclient    ${src0['ip']}
-    ...    ${src0['user']}    ${src0['pass']}    ${src0['container_type']}    ${src0['container_name']}
-    Run Keyword If    '${dst0['ip']}' != '${None}'    Run Keyword And Ignore Error
-    ...    Kill Linux Process    [d]hcpd    ${dst0['ip']}    ${dst0['user']}
-    ...    ${dst0['pass']}    ${dst0['container_type']}    ${dst0['container_name']}
-    Delete IP Addresses from Interface on Remote Host    ${src0['dp_iface_name']}    ${src0['ip']}
-    ...    ${src0['user']}    ${src0['pass']}    ${src0['container_type']}    ${src0['container_name']}
-    Run Keyword If    '${dst0['ip']}' != '${None}'    Delete Interface on Remote Host
-    ...    ${dst0['dp_iface_name']}.${src0['s_tag']}    ${dst0['ip']}    ${dst0['user']}    ${dst0['pass']}
-    ...    ${dst0['container_type']}    ${dst0['container_name']}
+    FOR    ${I}    IN RANGE    0    ${num_onus}
+        ${src}=    Set Variable    ${hosts.src[${I}]}
+        ${dst}=    Set Variable    ${hosts.dst[${I}]}
+        Run Keyword And Ignore Error    Kill Linux Process    [w]pa_supplicant    ${src['ip']}
+        ...    ${src['user']}    ${src['pass']}    ${src['container_type']}    ${src['container_name']}
+        Run Keyword And Ignore Error    Kill Linux Process    [d]hclient    ${src['ip']}
+        ...    ${src['user']}    ${src['pass']}    ${src['container_type']}    ${src['container_name']}
+        Run Keyword If    '${dst['ip']}' != '${None}'    Run Keyword And Ignore Error
+        ...    Kill Linux Process    [d]hcpd    ${dst['ip']}    ${dst['user']}
+        ...    ${dst['pass']}    ${dst['container_type']}    ${dst['container_name']}
+        Delete IP Addresses from Interface on Remote Host    ${src['dp_iface_name']}    ${src['ip']}
+        ...    ${src['user']}    ${src['pass']}    ${src['container_type']}    ${src['container_name']}
+        Run Keyword If    '${dst['ip']}' != '${None}'    Delete Interface on Remote Host
+        ...    ${dst['dp_iface_name']}.${src['s_tag']}    ${dst['ip']}    ${dst['user']}    ${dst['pass']}
+        ...    ${dst['container_type']}    ${dst['container_name']}
+    END
 
 Delete Device and Verify
     [Documentation]    Disable -> Delete devices via voltctl and verify its removed
-    ${rc}    ${output}=    Run and Return Rc and Output    ${VOLTCTL_CONFIG}; voltctl device disable ${onu_device_id}
-    Should Be Equal As Integers    ${rc}    0
-    Wait Until Keyword Succeeds    ${timeout}    5s    Validate Device    ${onu_serial_number}    DISABLED    UNKNOWN
-    ...    REACHABLE
-    ${rc}    ${output}=    Run and Return Rc and Output    ${VOLTCTL_CONFIG}; voltctl device delete ${onu_device_id}
-    Should Be Equal As Integers    ${rc}    0
-    Wait Until Keyword Succeeds    ${timeout}    5s    Validate Device Removed    ${onu_device_id}
     ${rc}    ${output}=    Run and Return Rc and Output    ${VOLTCTL_CONFIG}; voltctl device disable ${olt_device_id}
     Should Be Equal As Integers    ${rc}    0
     Wait Until Keyword Succeeds    ${timeout}    5s    Validate Device    ${olt_serial_number}    DISABLED    UNKNOWN