[VOL-4468] Verify that there should be no multicast stream on sending IGMP leave packets

[VOL-4476] Verify that 2 RG which are connected to the different ONU on the same PON Port could join the same channel.

[VOL-4477] Verify that 2 RG which are connected to the different ONU on the same PON Port could join the different channels.

Change-Id: I8b196a3b0d912f96ca5c37c0e0bd9980d114487e
diff --git a/libraries/utils.robot b/libraries/utils.robot
index a6345a9..c7f673d 100755
--- a/libraries/utils.robot
+++ b/libraries/utils.robot
@@ -1255,6 +1255,12 @@
     Run Keyword If    ${value_1} < ${value_2}
     ...    Fail    The value ${value_1} is not larger than or equal to ${value_2}
 
+Should Be Lower Than
+    [Documentation]    Verify that value_1 is < value_2
+    [Arguments]    ${value_1}    ${value_2}
+    Run Keyword If    ${value_1} >= ${value_2}
+    ...    Fail    The value ${value_1} is not lower than ${value_2}
+
 Should Be Float
     [Documentation]    Verify that value is a floating point number type
     [Arguments]    ${value}
diff --git a/tests/tt-workflow/Voltha_TT_MulticastTests.robot b/tests/tt-workflow/Voltha_TT_MulticastTests.robot
index 12483d4..6ecf6ba 100644
--- a/tests/tt-workflow/Voltha_TT_MulticastTests.robot
+++ b/tests/tt-workflow/Voltha_TT_MulticastTests.robot
@@ -14,7 +14,7 @@
 # FIXME Can we use the same test against BBSim and Hardware?
 
 *** Settings ***
-Documentation     Test various functional end-to-end scenarios for TT workflow
+Documentation     Test various multicast scenarios with given input file for TT workflow
 Suite Setup       Setup Suite
 Test Setup        Setup
 Test Teardown     Teardown
@@ -49,6 +49,7 @@
 ${timeout}        60s
 ${of_id}          0
 ${logical_id}     0
+${multicast_test_duration}     60
 ${has_dataplane}    True
 ${teardown_device}    True
 ${scripts}        ../../scripts
@@ -87,7 +88,9 @@
     ${matched}    ${src_onu2}    ${dst_onu2}=    Get ONU details with Given Sn and Service and UNI    ${test_onu2_sn}    mcast
     ...    ${test_onu2_uni}
     Wait Until Keyword Succeeds    ${timeout}    15    TT 2 RG MCAST Test    ${src_onu1}    ${dst_onu1}
-    ...    ${channel_ip_1}    ${src_onu2}    ${dst_onu2}    ${channel_ip_1}
+    ...    ${channel_ip_1}    ${src_onu2}    ${dst_onu2}    ${channel_ip_1}    ${multicast_test_duration}
+    # The purpose of this sleep period is to ensure that all groups and flows are deleted from the OLT before the next test.
+    Sleep    ${multicast_test_duration}
 
 2 RG Same ONU Different Channel Multicast Test
     [Documentation]    Verify that 2 RG which are connected to the same ONU could join the different channel.
@@ -108,7 +111,56 @@
     ${matched}    ${src_onu2}    ${dst_onu2}=    Get ONU details with Given Sn and Service and UNI    ${test_onu2_sn}    mcast
     ...    ${test_onu2_uni}
     Wait Until Keyword Succeeds    ${timeout}    15    TT 2 RG MCAST Test    ${src_onu1}    ${dst_onu1}
-    ...    ${channel_ip_1}    ${src_onu2}    ${dst_onu2}    ${channel_ip_2}
+    ...    ${channel_ip_1}    ${src_onu2}    ${dst_onu2}    ${channel_ip_2}    ${multicast_test_duration}
+    # The purpose of this sleep period is to ensure that all groups and flows are deleted from the OLT before the next test.
+    Sleep    ${multicast_test_duration}
+
+2 RG Same PON Different ONU Same Channel Multicast Test
+    [Documentation]    Verify that 2 RG which are connected to the different ONUs
+    ...    on the same PON Ports could join the same channel.
+    [Tags]    functionalTT    2RGSamePonDifferentOnuSameChannel    multicastTT
+    [Setup]    Start Logging    2RGSamePonDifferentOnuSameChannel
+    [Teardown]    Run Keywords    Collect Logs
+    ...           AND             Stop Logging    2RGSamePonDifferentOnuSameChannel
+    ${test_onus_pon0}=    Set Variable    ${multicast_test_onu_pon_locations.pon_0[0]}
+    ${test_onu1_sn}=    Set Variable    ${test_onus_pon0['onu_1']}
+    ${test_onu1_uni}=    Set Variable    1
+    ${test_onu2_sn}=    Set Variable    ${test_onus_pon0['onu_2']}
+    ${test_onu2_uni}=    Set Variable    1
+    ${channel_ip_list}=    Set Variable    ${multicast_ip_addresses[0]}
+    ${channel_ip_1}=    Set Variable    ${channel_ip_list['channel_1']}
+    ${matched}    ${src_onu1}    ${dst_onu1}=    Get ONU details with Given Sn and Service and UNI    ${test_onu1_sn}    mcast
+    ...    ${test_onu1_uni}
+    ${matched}    ${src_onu2}    ${dst_onu2}=    Get ONU details with Given Sn and Service and UNI    ${test_onu2_sn}    mcast
+    ...    ${test_onu2_uni}
+    Wait Until Keyword Succeeds    ${timeout}    15    TT 2 RG MCAST Test    ${src_onu1}    ${dst_onu1}
+    ...    ${channel_ip_1}    ${src_onu2}    ${dst_onu2}    ${channel_ip_1}    ${multicast_test_duration}
+    # The purpose of this sleep period is to ensure that all groups and flows are deleted from the OLT before the next test.
+    Sleep    ${multicast_test_duration}
+
+2 RG Same PON Different ONU Different Channels Multicast Test
+    [Documentation]    Verify that 2 RG which are connected to the different ONUs
+    ...    on the same PON Ports could join the different channels.
+    [Tags]    functionalTT    2RGSamePonDifferentOnuDifferentChannel    multicastTT
+    [Setup]    Start Logging    2RGSamePonDifferentOnuDifferentChannel
+    [Teardown]    Run Keywords    Collect Logs
+    ...           AND             Stop Logging    2RGSamePonDifferentOnuDifferentChannel
+    ${test_onus_pon0}=    Set Variable    ${multicast_test_onu_pon_locations.pon_0[0]}
+    ${test_onu1_sn}=    Set Variable    ${test_onus_pon0['onu_1']}
+    ${test_onu1_uni}=    Set Variable    1
+    ${test_onu2_sn}=    Set Variable    ${test_onus_pon0['onu_2']}
+    ${test_onu2_uni}=    Set Variable    1
+    ${channel_ip_list}=    Set Variable    ${multicast_ip_addresses[0]}
+    ${channel_ip_1}=    Set Variable    ${channel_ip_list['channel_1']}
+    ${channel_ip_2}=    Set Variable    ${channel_ip_list['channel_2']}
+    ${matched}    ${src_onu1}    ${dst_onu1}=    Get ONU details with Given Sn and Service and UNI    ${test_onu1_sn}    mcast
+    ...    ${test_onu1_uni}
+    ${matched}    ${src_onu2}    ${dst_onu2}=    Get ONU details with Given Sn and Service and UNI    ${test_onu2_sn}    mcast
+    ...    ${test_onu2_uni}
+    Wait Until Keyword Succeeds    ${timeout}    15    TT 2 RG MCAST Test    ${src_onu1}    ${dst_onu1}
+    ...    ${channel_ip_1}    ${src_onu2}    ${dst_onu2}    ${channel_ip_2}    ${multicast_test_duration}
+    # The purpose of this sleep period is to ensure that all groups and flows are deleted from the OLT before the next test.
+    Sleep    ${multicast_test_duration}
 
 2 RG Different PON Different ONU Same Channel Multicast Test
     [Documentation]    Verify that 2 RG which are connected to the different ONUs
@@ -130,7 +182,9 @@
     ${matched}    ${src_onu2}    ${dst_onu2}=    Get ONU details with Given Sn and Service and UNI    ${test_onu2_sn}    mcast
     ...    ${test_onu2_uni}
     Wait Until Keyword Succeeds    ${timeout}    15    TT 2 RG MCAST Test    ${src_onu1}    ${dst_onu1}
-    ...    ${channel_ip_1}    ${src_onu2}    ${dst_onu2}    ${channel_ip_1}
+    ...    ${channel_ip_1}    ${src_onu2}    ${dst_onu2}    ${channel_ip_1}    ${multicast_test_duration}
+    # The purpose of this sleep period is to ensure that all groups and flows are deleted from the OLT before the next test.
+    Sleep    ${multicast_test_duration}
 
 2 RG Different PON Different ONU Different Channels Multicast Test
     [Documentation]    Verify that 2 RG which are connected to the different ONUs
@@ -153,7 +207,7 @@
     ${matched}    ${src_onu2}    ${dst_onu2}=    Get ONU details with Given Sn and Service and UNI    ${test_onu2_sn}    mcast
     ...    ${test_onu2_uni}
     Wait Until Keyword Succeeds    ${timeout}    15    TT 2 RG MCAST Test    ${src_onu1}    ${dst_onu1}
-    ...    ${channel_ip_1}    ${src_onu2}    ${dst_onu2}    ${channel_ip_2}
+    ...    ${channel_ip_1}    ${src_onu2}    ${dst_onu2}    ${channel_ip_2}    ${multicast_test_duration}
 
 *** Keywords ***
 Get ONU details with Given Sn and Service and UNI
@@ -177,8 +231,13 @@
 
 
 TT 2 RG MCAST Test
-    [Documentation]    This keyword performs MCAST two RG at the Same Time for TT workflow
+    [Documentation]    This keyword performs MCAST two RG at the Same Time for TT workflow.
+    ...    RG1 and RG2 could be join same channel or different channel.
+    ...    It will run multicast test with given multicast_test_duration variable.
+    ...    RG2 will leave channel after multicast_test_duration/2 seconds.
+    ...    Function verify that RG1's multicast stream is not affected.
     [Arguments]    ${src_rg1}    ${dst_rg1}    ${channel_ip_rg1}    ${src_rg2}    ${dst_rg2}    ${channel_ip_rg2}
+    ...    ${multicast_test_duration}
     # Check for iperf and jq tools RG1
     ${stdout}    ${stderr}    ${rc}=    Execute Remote Command    which iperf jq
     ...    ${src_rg1['ip']}    ${src_rg1['user']}    ${src_rg1['pass']}    ${src_rg1['container_type']}
@@ -233,67 +292,105 @@
 
     # Setup iperf on the BNG
     ${server_output}=    Run Keyword If    '${channel_ip_rg1}'=='${channel_ip_rg2}'
-    ...    Login And Run Command On Remote System    sudo iperf -c '${channel_ip_rg1}' -u -T 32 -t 60 -i 1 &
+    ...    Login And Run Command On Remote System
+    ...    sudo iperf -c '${channel_ip_rg1}' -u -T 32 -t ${multicast_test_duration} -i 1 &
     ...    ${dst_rg1['bng_ip']}    ${dst_rg1['bng_user']}    ${dst_rg1['bng_pass']}    ${dst_rg1['container_type']}
     ...    ${dst_rg1['container_name']}
     ...    ELSE    Run Keywords    Run Keyword And Continue On Failure
-    ...    Login And Run Command On Remote System    sudo iperf -c '${channel_ip_rg1}' -u -T 32 -t 60 -i 1 &
+    ...    Login And Run Command On Remote System
+    ...    sudo iperf -c '${channel_ip_rg1}' -u -T 32 -t ${multicast_test_duration} -i 1 &
     ...    ${dst_rg1['bng_ip']}    ${dst_rg1['bng_user']}    ${dst_rg1['bng_pass']}    ${dst_rg1['container_type']}
     ...    ${dst_rg1['container_name']}     AND    Run Keyword And Continue On Failure
-    ...    Login And Run Command On Remote System    sudo iperf -c '${channel_ip_rg2}' -u -T 32 -t 60 -i 1 &
+    ...    Login And Run Command On Remote System
+    ...    sudo iperf -c '${channel_ip_rg2}' -u -T 32 -t ${multicast_test_duration} -i 1 &
     ...    ${dst_rg2['bng_ip']}    ${dst_rg2['bng_user']}    ${dst_rg2['bng_pass']}    ${dst_rg2['container_type']}
     ...    ${dst_rg2['container_name']}
 
     # Setup iperf on the RG1
-    ${rg_output_rg1}=    Run Keyword and Continue On Failure    Wait Until Keyword Succeeds     90s    5s
+    ${rg_output_rg1}=    Run Keyword and Continue On Failure    Wait Until Keyword Succeeds     ${timeout}    5s
     ...    Login And Run Command On Remote System
-    ...    rm -rf /tmp/rg_output ; sudo iperf -s -u -B '${channel_ip_rg1}' -i 1 -D >> /tmp/rg_output
+    ...    rm -rf /tmp/rg1_output ; date >> /tmp/rg1_output ; sudo iperf -s -u -B '${channel_ip_rg1}' -i 1 -D >> /tmp/rg1_output
     ...    ${src_rg1['ip']}    ${src_rg1['user']}    ${src_rg1['pass']}    ${src_rg1['container_type']}
     ...    ${src_rg1['container_name']}
 
     # Setup iperf on the RG2
-    ${rg_output_rg2}=    Run Keyword and Continue On Failure    Wait Until Keyword Succeeds     90s    5s
+    ${rg_output_rg2}=    Run Keyword and Continue On Failure    Wait Until Keyword Succeeds     ${timeout}    5s
     ...    Login And Run Command On Remote System
-    ...    rm -rf /tmp/rg_output ; sudo iperf -s -u -B '${channel_ip_rg2}' -i 1 -D >> /tmp/rg_output
+    ...    rm -rf /tmp/rg2_output ; date >> /tmp/rg2_output ; sudo iperf -s -u -B '${channel_ip_rg2}' -i 1 -D >> /tmp/rg2_output
     ...    ${src_rg2['ip']}    ${src_rg2['user']}    ${src_rg2['pass']}    ${src_rg2['container_type']}
     ...    ${src_rg2['container_name']}
 
     #Logging Outputs and Check iperf UDP Stream Outputs
     Log    ${rg_output_rg1}
     Log    ${rg_output_rg2}
-    Sleep    60s
-    ${output}=    Run Keyword and Continue On Failure     Wait Until Keyword Succeeds     90s    5s
+    ${igmp_leave_time}=     Evaluate    ${multicast_test_duration}/2
+    ${s}=    Set Variable   s
+    ${sleep_time}=    Set Variable   ${igmp_leave_time}${s}
+    Sleep    ${sleep_time}
+    ${onos_delay_tolerance}=    Set Variable   5
+    ${igmp_leave_time_with_delay}=     Evaluate    ${igmp_leave_time} + ${onos_delay_tolerance}
+
+    # Kill iperf on the RG2
+    ${rg_kill_output_rg2}=    Run Keyword and Continue On Failure    Login And Run Command On Remote System
+    ...    sudo kill -9 `pidof iperf` ; date >> /tmp/rg2_output    ${src_rg2['ip']}    ${src_rg2['user']}
+    ...    ${src_rg2['pass']}    ${src_rg2['container_type']}    ${src_rg2['container_name']}
+
+    Sleep    ${sleep_time}
+
+    # Kill iperf on the RG1
+    ${output}=    Run Keyword and Continue On Failure    Login And Run Command On Remote System
+    ...    sudo kill -9 `pidof iperf` ; date >> /tmp/rg1_output    ${src_rg1['ip']}    ${src_rg1['user']}
+    ...    ${src_rg1['pass']}    ${src_rg1['container_type']}    ${src_rg1['container_name']}
+
+    ${output_rg1}=    Run Keyword and Continue On Failure     Wait Until Keyword Succeeds     ${timeout}    5s
     ...    Login And Run Command On Remote System
-    ...    cat /tmp/rg_output | grep KBytes
+    ...    cat /tmp/rg1_output | grep KBytes
     ...    ${src_rg1['ip']}    ${src_rg1['user']}    ${src_rg1['pass']}    ${src_rg1['container_type']}
     ...    ${src_rg1['container_name']}
-    Log    ${output}
-    Should Contain    ${output}    KBytes
-    ${output}=    Run Keyword and Continue On Failure     Wait Until Keyword Succeeds     90s    5s
+    Log    ${output_rg1}
+    # Check that RG1's stream count
+    ${output_rg1_count}=    Get Line Count    ${output_rg1}
+    ${output_rg1_count}=    Evaluate    ${output_rg1_count}-1
+    ${output_rg1_file}=    Run Keyword and Continue On Failure     Wait Until Keyword Succeeds     ${timeout}    5s
     ...    Login And Run Command On Remote System
-    ...    cat /tmp/rg_output | grep KBytes
+    ...    cat /tmp/rg1_output
+    ...    ${src_rg1['ip']}    ${src_rg1['user']}    ${src_rg1['pass']}    ${src_rg1['container_type']}
+    ...    ${src_rg1['container_name']}
+    Log    ${output_rg1_file}
+
+
+    ${output_rg2}=    Run Keyword and Continue On Failure     Wait Until Keyword Succeeds     ${timeout}    5s
+    ...    Login And Run Command On Remote System
+    ...    cat /tmp/rg2_output | grep KBytes
     ...    ${src_rg2['ip']}    ${src_rg2['user']}    ${src_rg2['pass']}    ${src_rg2['container_type']}
     ...    ${src_rg2['container_name']}
-    Log    ${output}
-    Should Contain    ${output}    KBytes
+    Log    ${output_rg2}
+    # Check that RG2's stream count
+    ${output_rg2_count}=    Get Line Count      ${output_rg2}
+    ${output_rg2_count}=    Evaluate    ${output_rg2_count}-1
+    ${output_rg2_file}=    Run Keyword and Continue On Failure     Wait Until Keyword Succeeds     ${timeout}    5s
+    ...    Login And Run Command On Remote System
+    ...    cat /tmp/rg2_output
+    ...    ${src_rg2['ip']}    ${src_rg2['user']}    ${src_rg2['pass']}    ${src_rg2['container_type']}
+    ...    ${src_rg2['container_name']}
+    Log    ${output_rg2_file}
 
     # Kill iperf  on BNG
-    ${rg_output}=    Run Keyword and Continue On Failure    Login And Run Command On Remote System
+    ${server_output}=    Run Keyword and Continue On Failure    Login And Run Command On Remote System
     ...    sudo kill -9 `pidof iperf`
     ...    ${dst_rg1['bng_ip']}    ${dst_rg1['bng_user']}    ${dst_rg1['bng_pass']}    ${dst_rg1['container_type']}
     ...    ${dst_rg1['container_name']}
 
-    # Kill iperf on the RG1
-    ${output}=    Run Keyword and Continue On Failure    Login And Run Command On Remote System
-    ...    sudo kill -9 `pidof iperf`
-    ...    ${src_rg1['ip']}    ${src_rg1['user']}    ${src_rg1['pass']}    ${src_rg1['container_type']}
-    ...    ${src_rg1['container_name']}
 
-    # Kill iperf on the RG2
-    ${output}=    Run Keyword and Continue On Failure    Login And Run Command On Remote System
-    ...    sudo kill -9 `pidof iperf`
-    ...    ${src_rg2['ip']}    ${src_rg2['user']}    ${src_rg2['pass']}    ${src_rg2['container_type']}
-    ...    ${src_rg2['container_name']}
+    Should Contain    ${output_rg1}    KBytes
+    Should Contain    ${output_rg2}    KBytes
+    # Verify that RG1's stream count is lower than multicast total test duration
+    Should Be Lower Than    ${output_rg1_count}    ${multicast_test_duration}
+    # Verify that RG1's stream count is larger than multicast igmp leave time
+    Should Be Larger Than    ${output_rg1_count}    ${igmp_leave_time_with_delay}
+    # Verify that RG2's stream count is lower than multicast igmp leave time
+    Should Be Lower Than    ${output_rg2_count}    ${igmp_leave_time_with_delay}
+
 
 Setup Suite
     [Documentation]    Set up the test suite