[VOL-3812] BBSim Igmp Scale

Change-Id: Iff816b0f6eff4315411aa6e16307a06b1997eee4
diff --git a/Makefile b/Makefile
index 9e4ea04..4227fda 100755
--- a/Makefile
+++ b/Makefile
@@ -55,7 +55,7 @@
 sanity-kind-att: sanity-single-kind
 
 # for scale pipeline
-voltha-scale: ROBOT_MISC_ARGS += -i activation $(ROBOT_DEBUG_LOG_OPT)
+voltha-scale: ROBOT_MISC_ARGS += -i activation -v NAMESPACE:voltha $(ROBOT_DEBUG_LOG_OPT)
 voltha-scale: voltha-scale-test
 
 # target to invoke DT Workflow Sanity
diff --git a/libraries/bbsim.robot b/libraries/bbsim.robot
index 92e4424..3ba7bd1 100755
--- a/libraries/bbsim.robot
+++ b/libraries/bbsim.robot
@@ -17,6 +17,9 @@
 Documentation     Library for BBSimCtl interactions
 Resource          ./k8s.robot
 
+*** Variables ***
+&{IGMP_TASK_DICT}          join=0    leave=1    joinv3=2
+
 *** Keywords ***
 List ONUs
     [Documentation]  Lists ONUs via BBSimctl
@@ -50,6 +53,13 @@
     Log     ${service}
     Should Be Equal as Integers    ${rc}    0
 
+JoinOrLeave Igmp Rest Based
+    [Documentation]  Joins or Leaves Igmp on a BBSim ONU (based on Rest Endpoint)
+    [Arguments]    ${bbsim_rel_session}    ${onu}    ${task}    ${group_address}
+    ${resp}=    Post Request    ${bbsim_rel_session}
+    ...    /v1/olt/onus/${onu}/igmp/${IGMP_TASK_DICT}[${task}]/${group_address}
+    Log    ${resp}
+
 JoinOrLeave Igmp
     [Documentation]  Joins or Leaves Igmp on a BBSim ONU
     [Arguments]    ${namespace}    ${bbsim_pod_name}    ${onu}    ${task}    ${group_address}=224.0.0.22
@@ -71,3 +81,12 @@
     ${result}    ${rc}=    Exec Pod And Return Output And RC    ${namespace}    ${bbsim_pod_name}
     ...    bbsimctl onu shutdown ${onu}
     Should Contain    ${result}    successfully    msg=Can not shutdown ${onu}    values=False
+
+Get ONUs List
+    [Documentation]    Fetches ONUs via BBSimctl
+    [Arguments]    ${namespace}    ${bbsim_pod_name}
+    ${onus}    ${rc}=    Exec Pod And Return Output And RC    ${namespace}    ${bbsim_pod_name}
+    ...    bbsimctl onu list | awk 'NR>1 {print $4}'
+    @{onuList}=    Split To Lines    ${onus}
+    Should Be Equal as Integers    ${rc}    0
+    [Return]    ${onuList}
diff --git a/libraries/onos.robot b/libraries/onos.robot
index 1f785f5..e0288b3 100755
--- a/libraries/onos.robot
+++ b/libraries/onos.robot
@@ -419,6 +419,58 @@
     ${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 Empty Group in ONOS
+    [Documentation]    Verifies zero group count on the device
+    [Arguments]    ${onos_ssh_connection}    ${deviceId}
+    ${groups}=    Execute ONOS CLI Command on open connection    ${onos_ssh_connection}    groups | grep ${deviceId}
+    @{groups_arr}=    Split String    ${groups}    ,
+    @{group_count_arr}=    Split String    ${groups_arr[1]}    =
+    ${group_count}=    Set Variable    ${group_count_arr[1]}
+    Should Be Equal As Integers    ${group_count}    0
+
+Verify ONUs in Group Count in ONOS
+    [Documentation]    Verifies there exists a group bucket list with certain entries/count
+    ...    Note: Currently, this validates only if all ONUs of an OLT joined the same igmp group
+    [Arguments]    ${onos_ssh_connection}    ${count}    ${deviceId}
+    ${result}=    Execute ONOS CLI Command on open connection    ${onos_ssh_connection}    groups -j
+    Log    Groups: ${result}
+    ${groups}=    To Json    ${result}
+    ${length}=    Get Length    ${groups}
+    ${buckets}=    Create List
+    ${matched}=    Set Variable    False
+    FOR    ${INDEX}    IN RANGE    0    ${length}
+        ${value}=    Get From List    ${groups}    ${INDEX}
+        ${devId}=    Get From Dictionary    ${value}    deviceId
+        ${bucket}=    Get From Dictionary    ${value}    buckets
+        Run Keyword If    '${devId}'=='${deviceId}'
+        ...    Append To List    ${buckets}    ${bucket}
+    END
+    ${bucket_len}=    Get Length    ${buckets}
+    ${bucket_vals_len}=    Evaluate    0
+    FOR    ${INDEX_1}    IN RANGE    0    ${bucket_len}
+        ${value}=    Get From List    ${buckets}    ${INDEX_1}
+        ${bucket_vals_len}=    Get Length    ${value}
+        ${matched}=    Set Variable If    ${bucket_vals_len}==${count}    True    False
+        Exit For Loop If    ${matched}
+    END
+    Should Be True    ${matched}    Bucket list count for a group: Found:${bucket_vals_len} Expected:${count}
+
+Verify ONU in Group Bucket
+    [Documentation]    Matches if ONU port in Group Bucket
+    [Arguments]    ${group_bucket_values}    ${onu_port}
+    ${len}=    Get Length    ${group_bucket_values}
+    ${matched}=    Set Variable    False
+    FOR    ${INDEX}    IN RANGE    0    ${len}
+        ${value_bucket}=    Get From List    ${group_bucket_values}    ${INDEX}
+        ${treatment}=    Get From Dictionary    ${value_bucket}    treatment
+        ${instructions}=    Get From Dictionary    ${treatment}    instructions
+        ${instructions_val}=    Get From List    ${instructions}    0
+        ${port}=    Get From Dictionary    ${instructions_val}    port
+        ${matched}=    Set Variable If    '${port}'=='${onu_port}'    True    False
+        Exit For Loop If    ${matched}
+    END
+    [Return]    ${matched}
+
 Verify ONU in Groups
     [Arguments]    ${ip_onos}    ${port_onos}    ${deviceId}    ${onu_port}    ${group_exist}=True
     [Documentation]    Verifies that the specified onu_port exists in groups output
@@ -436,14 +488,9 @@
         ...    Append To List    ${buckets}    ${bucket}
     END
     ${bucket_len}=    Get Length    ${buckets}
-    FOR    ${INDEX1}    IN RANGE    0    ${bucket_len}
-        ${value}=    Get From List    ${buckets}    ${INDEX}
-        ${value_bucket}=    Get From List    ${value}    0
-        ${treatment}=    Get From Dictionary    ${value_bucket}    treatment
-        ${instructions}=    Get From Dictionary    ${treatment}    instructions
-        ${instructions_val}=    Get From List    ${instructions}    0
-        ${port}=    Get From Dictionary    ${instructions_val}    port
-        ${matched}=    Set Variable If    '${port}'=='${onu_port}'    True    False
+    FOR    ${INDEX_1}    IN RANGE    0    ${bucket_len}
+        ${value}=    Get From List    ${buckets}    ${INDEX_1}
+        ${matched}=    Verify ONU in Group Bucket    ${value}    ${onu_port}
         Exit For Loop If    ${matched}
     END
     Run Keyword If    ${group_exist}
diff --git a/tests/scale/Voltha_Scale_Tests.robot b/tests/scale/Voltha_Scale_Tests.robot
index 333f4a0..e903ca9 100644
--- a/tests/scale/Voltha_Scale_Tests.robot
+++ b/tests/scale/Voltha_Scale_Tests.robot
@@ -50,13 +50,21 @@
 Resource          ../../libraries/voltha.robot
 Resource          ../../libraries/flows.robot
 Resource          ../../libraries/k8s.robot
+Resource          ../../libraries/utils.robot
+Resource          ../../libraries/bbsim.robot
 Resource          ../../variables/variables.robot
 
 *** Variables ***
 ${ONOS_SSH_IP}  127.0.0.1
 ${ONOS_SSH_PORT}    8101
+${ONOS_REST_IP}  127.0.0.1
 ${ONOS_REST_PORT}    8181
 
+${BBSIM_REST_IP}    127.0.0.1
+${BBSIM_REST_PORT}    50071
+
+${NAMESPACE}      default
+
 # Scale pipeline values
 ${stackId}  1
 ${olt}  1
@@ -76,6 +84,8 @@
 # Per-test logging on failure is turned off by default; set this variable to enable
 ${container_log_dir}    ${None}
 
+${timeout}    10m
+
 *** Test Cases ***
 
 Create and Enable devices
@@ -186,6 +196,74 @@
         Wait for DHCP Ack     ${onos_ssh_connection}  ${total_onus_per_olt}     ${workflow}     ${deviceId}
     END
 
+Perform Igmp Join
+    [Documentation]    Performs Igmp Join for all the ONUs of all the OLTs (based on Rest Endpoint)
+    [Tags]    non-critical    igmp    igmp-join
+    FOR    ${INDEX}    IN RANGE    0    ${olt}
+        ${bbsim_rel}=    Catenate    SEPARATOR=    bbsim    ${INDEX}
+        ${bbsim_rel_local_port}=    Evaluate    ${BBSIM_REST_PORT}+${INDEX}
+        Create Session    ${bbsim_rel}    http://${BBSIM_REST_IP}:${bbsim_rel_local_port}
+        ${bbsim_pod}=    Get Pod Name By Label    ${NAMESPACE}    release     ${bbsim_rel}
+        ${onu_list}=    Get ONUs List    ${NAMESPACE}    ${bbsim_pod}
+        Perform Igmp Join or Leave Per OLT    ${bbsim_rel}    ${onu_list}    join
+        List Service    ${NAMESPACE}    ${bbsim_pod}
+    END
+
+Wait for ONUs Join Igmp Group
+    [Documentation]    Checks the ONUs Join the IGMP Group
+    ...    Note: Currently, it expects all the ONUs on an OLT joined the same group
+    [Tags]    non-critical    igmp    igmp-join    igmp-count-verify    igmp-join-count-verify
+    ${onos_devices}=    Compute Device IDs
+    FOR     ${deviceId}     IN  @{onos_devices}
+        Run Keyword And Continue On Failure    Wait Until Keyword Succeeds    ${timeout}    5s
+        ...    Verify ONUs in Group Count in ONOS    ${onos_ssh_connection}    ${total_onus_per_olt}    ${deviceId}
+    END
+
+#Verify Igmp Join
+#    [Documentation]    Verifies Igmp Groups in ONOS
+#    [Tags]    non-critical    igmp    igmp-join    igmp-verify    igmp-join-verify
+#    ${onos_devices}=    Compute Device IDs
+#    FOR    ${INDEX}    IN RANGE    0    ${olt}
+#        ${bbsim_rel}=    Catenate    SEPARATOR=    bbsim    ${INDEX}
+#        ${bbsim_pod}=    Get Pod Name By Label    ${NAMESPACE}    release     ${bbsim_rel}
+#        ${onu_list}=    Get ONUs List    ${NAMESPACE}    ${bbsim_pod}
+#        Verify Igmp Groups in ONOS    ${onos_devices}[${INDEX}]    ${onu_list}
+#    END
+
+Perform Igmp Leave
+    [Documentation]    Performs Igmp Leave for all the ONUs of all the OLTs (based on Rest Endpoint)
+    [Tags]    non-critical    igmp    igmp-leave
+    FOR    ${INDEX}    IN RANGE    0    ${olt}
+        ${bbsim_rel}=    Catenate    SEPARATOR=    bbsim    ${INDEX}
+        ${bbsim_rel_local_port}=    Evaluate    ${BBSIM_REST_PORT}+${INDEX}
+        Create Session    ${bbsim_rel}    http://${BBSIM_REST_IP}:${bbsim_rel_local_port}
+        ${bbsim_pod}=    Get Pod Name By Label    ${NAMESPACE}    release     ${bbsim_rel}
+        ${onu_list}=    Get ONUs List    ${NAMESPACE}    ${bbsim_pod}
+        Perform Igmp Join or Leave Per OLT    ${bbsim_rel}    ${onu_list}    leave
+        List Service    ${NAMESPACE}    ${bbsim_pod}
+    END
+
+Wait for ONUs Leave Igmp Group
+    [Documentation]    Checks the ONUs Leave the IGMP Group
+    ...    Note: Currently, it expects all the ONUs on an OLT left the same group
+    [Tags]    non-critical    igmp    igmp-leave    igmp-count-verify    igmp-leave-count-verify
+    ${onos_devices}=    Compute Device IDs
+    FOR     ${deviceId}     IN  @{onos_devices}
+        Run Keyword And Continue On Failure    Wait Until Keyword Succeeds    ${timeout}    5s
+        ...    Verify Empty Group in ONOS    ${onos_ssh_connection}    ${deviceId}
+    END
+
+#Verify Igmp Leave
+#    [Documentation]    Verifies Igmp Groups in ONOS
+#    [Tags]    non-critical    igmp    igmp-leave    igmp-verify    igmp-leave-verify
+#    ${onos_devices}=    Compute Device IDs
+#    FOR    ${INDEX}    IN RANGE    0    ${olt}
+#        ${bbsim_rel}=    Catenate    SEPARATOR=    bbsim    ${INDEX}
+#        ${bbsim_pod}=    Get Pod Name By Label    ${NAMESPACE}    release     ${bbsim_rel}
+#        ${onu_list}=    Get ONUs List    ${NAMESPACE}    ${bbsim_pod}
+#        Verify Igmp Groups in ONOS    ${onos_devices}[${INDEX}]    ${onu_list}    False
+#    END
+
 Disable and Delete devices
     [Documentation]  Disable and delete the OLTs in VOLTHA
     [Tags]      non-critical    teardown
@@ -209,6 +287,11 @@
     ${total_onus_per_olt}=   Evaluate    ${pon} * ${onu}
     Set Suite Variable  ${total_onus_per_olt}
 
+    ${onos_auth}=    Create List    karaf    karaf
+    Create Session    ONOS    http://${ONOS_REST_IP}:${ONOS_REST_PORT}    auth=${ONOS_AUTH}
+    Run Keyword If    '${workflow}'=='tt'
+    ...    Send File To Onos    ${CURDIR}/../../tests/data/onos-igmp.json    apps/
+
     ${onos_ssh_connection}    Open ONOS SSH Connection    ${ONOS_SSH_IP}    ${ONOS_SSH_PORT}
     Set Suite Variable  ${onos_ssh_connection}
 
@@ -228,4 +311,21 @@
         Append To List  ${device_ids}    ${id}
     END
 
-    [Return]    ${device_ids}
\ No newline at end of file
+    [Return]    ${device_ids}
+
+Perform Igmp Join or Leave Per OLT
+    [Documentation]    Performs Igmp Join for all the ONUs of an OLT (based on Rest Endpoint)
+    [Arguments]    ${bbsim_rel_session}    ${onu_list}    ${task}
+    FOR    ${onu}    IN    @{onu_list}
+        JoinOrLeave Igmp Rest Based    ${bbsim_rel_session}    ${onu}    ${task}    224.0.0.22
+    END
+
+Verify Igmp Groups in ONOS
+    [Documentation]   Verifies Igmp Groups in ONOS for all ONUs of an OLT
+    [Arguments]    ${devId}    ${onu_list}    ${group_exist}=True
+    FOR    ${onu}    IN    @{onu_list}
+        ${onu_port}=    Run Keyword And Continue On Failure    Wait Until Keyword Succeeds    ${timeout}    2s
+        ...    Get ONU Port in ONOS    ${onu}    ${devId}
+        Run Keyword And Continue On Failure    Wait Until Keyword Succeeds    ${timeout}    2s
+        ...    Verify ONU in Groups    ${ONOS_SSH_IP}    ${ONOS_SSH_PORT}    ${devId}    ${onu_port}    ${group_exist}
+    END