[VOL-4097] Verify that best effort BW is released to assured BW requirement as needed and that fixed BW is reserved always on the PON

Change-Id: Ib1edef53aeaf9c015afc0e8fca1f6500706ca086
diff --git a/Makefile b/Makefile
index 776c67d..b59fda4 100755
--- a/Makefile
+++ b/Makefile
@@ -508,7 +508,7 @@
 	cd tests/dt-workflow ;\
 	robot -V $(ROBOT_CONFIG_FILE) $(ROBOT_MISC_ARGS) $(ROBOT_FILE)
 
-voltha-tt-test: ROBOT_MISC_ARGS += -e notready
+voltha-tt-test: ROBOT_MISC_ARGS += -e notready  --noncritical non-critical
 
 voltha-tt-test: vst_venv
 	source ./$</bin/activate ; set -u ;\
diff --git a/libraries/onos.robot b/libraries/onos.robot
index f637ab6..82d6f76 100755
--- a/libraries/onos.robot
+++ b/libraries/onos.robot
@@ -814,6 +814,15 @@
     ${limiting_BW}=    Evaluate    ${eir}+${cir}+${air}
     [Return]    ${limiting_BW}
 
+Get Limiting Bandwidth Details for Fixed and Committed
+    [Arguments]    ${bandwidth_profile_name}
+    [Documentation]    Collects the bandwidth profile details for the given bandwidth profile and
+    ...    returns the limiting bandwidth for fixed and committed
+    ${cir}    ${cbs}    ${eir}    ${ebs}    ${air}=    Get Bandwidth Profile Details Rest
+    ...    ${bandwidth_profile_name}
+    ${limiting_BW}=    Evaluate    ${cir}+${air}
+    [Return]    ${limiting_BW}
+
 Validate Deleted Device Cleanup In ONOS
     [Arguments]    ${ip}    ${port}    ${olt_serial_number}
     [Documentation]    The keyword verifies that ports, flows, meters, subscribers, dhcp are all cleared in ONOS
diff --git a/tests/data/flex-ocp-cord-TT-multi-tcont-tests-input.yaml b/tests/data/flex-ocp-cord-TT-multi-tcont-tests-input.yaml
index 08aa74d..e99c6b2 100644
--- a/tests/data/flex-ocp-cord-TT-multi-tcont-tests-input.yaml
+++ b/tests/data/flex-ocp-cord-TT-multi-tcont-tests-input.yaml
@@ -53,7 +53,7 @@
     -
       onu: 'ALPHe3d1cea3'
       service_type: 'hsia'
-      us_bw_profile: 'TCONT_TYPE4_1Gbps_Peak_User1_HSI_Upstream'
+      us_bw_profile: 'TCONT_TYPE4_300Mbps_Peak_User1_HSI_Upstream'
     -
       onu: 'ALPHe3d1ceb7'
       service_type: 'hsia'
diff --git a/tests/data/flex-ocp-cord-sadis-TT-multi-tcont-1.json b/tests/data/flex-ocp-cord-sadis-TT-multi-tcont-1.json
new file mode 100644
index 0000000..faa38f8
--- /dev/null
+++ b/tests/data/flex-ocp-cord-sadis-TT-multi-tcont-1.json
@@ -0,0 +1,294 @@
+{
+  "ports" : { },
+  "devices" : { },
+  "hosts" : { },
+  "apps" : {
+    "org.onosproject.provider.lldp" : {
+      "suppression" : {
+        "deviceTypes" : [ "ROADM", "OTN", "FIBER_SWITCH", "OPTICAL_AMPLIFIER" ],
+        "annotation" : "{\"no-lldp\":null}"
+      }
+    },
+    "org.opencord.kafka" : { },
+    "org.onosproject.core" : {
+      "multicast" : {
+        "ingressVlan" : 550,
+        "egressVlan" : 550,
+        "egressInnerVlan" : 55
+      }
+    },
+    "org.opencord.sadis" : {
+      "bandwidthprofile" : {
+        "integration" : {
+          "cache" : {
+            "enabled" : true,
+            "maxsize" : 40,
+            "ttl" : "PT1m"
+          }
+        },
+        "entries" : [ {
+          "id" : "High-Speed-Internet",
+          "cir" : 100000,
+          "cbs" : 10000,
+          "eir" : 100000,
+          "ebs" : 10000,
+          "air" : 100000
+        }, {
+          "id" : "VOIP",
+          "cir" : 400000,
+          "cbs" : 10000,
+          "eir" : 400000,
+          "ebs" : 10000,
+          "air" : 100000
+        }, {
+          "id" : "User1-Specific",
+          "cir" : 60000,
+          "cbs" : 10000,
+          "eir" : 40000,
+          "ebs" : 10000
+        }, {
+          "id" : "User1-Specific2",
+          "cir" : 500000,
+          "cbs" : 10000,
+          "eir" : 300000,
+          "ebs" : 10000
+        },{
+          "id" : "TCONT_TYPE1_Fixed8.7Gbps",
+          "cir" : 0,
+          "cbs" : 0,
+          "eir" : 0,
+          "ebs" : 0,
+          "air" : 8700000
+        }, {
+          "id" : "TCONT_TYPE1_200Mbps_Fixed_ForVOIP",
+          "eir" : 0,
+          "ebs" : 0,
+          "cir" : 0,
+          "cbs" : 0,
+          "air" : 200000
+        }, {
+          "id" : "TCONT_TYPE1_1Mbps_Fixed",
+          "eir" : 0,
+          "ebs" : 0,
+          "cir" : 0,
+          "cbs" : 0,
+          "air" : 1000
+        }, {
+          "id" : "TCONT_TYPE2_500Mbps_Assured_ForVoD",
+          "eir" : 0,
+          "ebs" : 0,
+          "cir" : 500000,
+          "cbs" : 10000,
+          "air" : 0
+        }, {
+          "id" : "TCONT_TYPE3_700Mbps_Peak_500Mbps_Assured_ForVoD",
+          "eir" : 200000,
+          "ebs" : 10000,
+          "cir" : 500000,
+          "cbs" : 10000,
+          "air" : 0
+        }, {
+          "id" : "TCONT_TYPE3_2Mbps_Peak_1Mbps_Assured_ForVoD",
+          "eir" : 1000,
+          "ebs" : 10000,
+          "cir" : 1000,
+          "cbs" : 10000,
+          "air" : 0
+        }, {
+          "id" : "TCONT_TYPE3_1G_Peak_500Mbps_Assured_ForVoD",
+          "eir" : 500000,
+          "ebs" : 10000,
+          "cir" : 500000,
+          "cbs" : 10000,
+          "air" : 0
+        }, {
+          "id" : "TCONT_TYPE4_1Gbps_Peak_User1_HSI_Upstream",
+          "eir" : 1000000,
+          "ebs" : 10000,
+          "cir" : 0,
+          "cbs" : 0,
+          "air" : 0
+        }, {
+          "id" : "TCONT_TYPE4_300Mbps_Peak_User1_HSI_Upstream",
+          "eir" : 300000,
+          "ebs" : 10000,
+          "cir" : 0,
+          "cbs" : 0,
+          "air" : 0
+        }, {
+          "id" : "TCONT_TYPE5_1Gbps_Peak_500Mbps_Assured_200Mbps_Fixed_User1_HSI_Upstream",
+          "eir" : 300000,
+          "ebs" : 10000,
+          "cir" : 500000,
+          "cbs" : 10000,
+          "air" : 200000
+        } ]
+      },
+      "sadis" : {
+        "integration" : {
+          "cache" : {
+            "enabled" : true,
+            "maxsize" : 50,
+            "ttl" : "PT1m"
+          }
+        },
+        "entries" : [ {
+          "id" : "ALPHe3d1cfa7-1",
+          "nasPortId" : "ALPHe3d1cfa7-1",
+          "circuitId" : "ALPHe3d1cfa7-1",
+          "remoteId" : "ALPHe3d1cfa7-1",
+          "uniTagList" : [ {
+            "uniTagMatch" : 65,
+            "ponCTag" : 444,
+            "ponSTag" : 333,
+            "usPonCTagPriority" : 7,
+            "usPonSTagPriority" : 7,
+            "dsPonCTagPriority" : 7,
+            "dsPonSTagPriority" : 7,
+            "technologyProfileId" : 65,
+            "downstreamBandwidthProfile" : "VOIP",
+            "upstreamBandwidthProfile" : "TCONT_TYPE1_Fixed8.5Gbps",
+            "isDhcpRequired" : "true",
+            "configuredMacAddress" : "00:50:56:8a:fd:77",
+            "serviceName" : "VOIP"
+          } ]
+        }, {
+          "id" : "ALPHe3d1cea3-1",
+          "nasPortId" : "ALPHe3d1cea3-1",
+          "uniTagList" : [ {
+            "uniTagMatch" : 35,
+            "ponCTag" : 801,
+            "ponSTag" : 111,
+            "usPonCTagPriority" : 0,
+            "usPonSTagPriority" : 0,
+            "dsPonCTagPriority" : 0,
+            "dsPonSTagPriority" : 0,
+            "technologyProfileId" : 64,
+            "downstreamBandwidthProfile" : "High-Speed-Internet",
+            "upstreamBandwidthProfile" : "TCONT_TYPE4_300Mbps_Peak_User1_HSI_Upstream",
+            "isDhcpRequired" : "true",
+            "serviceName" : "HSIA"
+          }, {
+            "uniTagMatch" : 65,
+            "ponCTag" : 444,
+            "ponSTag" : 333,
+            "usPonCTagPriority" : 7,
+            "usPonSTagPriority" : 7,
+            "dsPonCTagPriority" : 7,
+            "dsPonSTagPriority" : 7,
+            "technologyProfileId" : 65,
+            "downstreamBandwidthProfile" : "VOIP",
+            "upstreamBandwidthProfile" : "TCONT_TYPE1_1Mbps_Fixed",
+            "isDhcpRequired" : "true",
+            "configuredMacAddress" : "2c:60:0c:ee:d6:27",
+            "serviceName" : "VOIP"
+          }, {
+            "uniTagMatch" : 55,
+            "ponCTag" : 55,
+            "ponSTag" : 555,
+            "usPonCTagPriority" : 5,
+            "usPonSTagPriority" : 5,
+            "dsPonCTagPriority" : 5,
+            "dsPonSTagPriority" : 5,
+            "technologyProfileId" : 66,
+            "downstreamBandwidthProfile" : "High-Speed-Internet",
+            "upstreamBandwidthProfile" : "TCONT_TYPE2_500Mbps_Assured_ForVoD",
+            "configuredMacAddress" : "2c:60:0c:ee:d6:27",
+            "serviceName" : "VOD",
+            "isDhcpRequired" : "true",
+            "isIgmpRequired" : "true"
+          }, {
+            "ponCTag" : 55,
+            "ponSTag" : 550,
+            "dsPonCTagPriority" : 5,
+            "dsPonSTagPriority" : 5,
+            "technologyProfileId" : 66,
+            "serviceName" : "MC"
+          } ]
+        }, {
+          "id" : "ALPHe3d1ceb7-1",
+          "nasPortId" : "ALPHe3d1ceb7-1",
+          "uniTagList" : [ {
+            "uniTagMatch" : 35,
+            "ponCTag" : 101,
+            "ponSTag" : 222,
+            "usPonCTagPriority" : 0,
+            "usPonSTagPriority" : 0,
+            "dsPonCTagPriority" : 0,
+            "dsPonSTagPriority" : 0,
+            "technologyProfileId" : 64,
+            "downstreamBandwidthProfile" : "High-Speed-Internet",
+            "upstreamBandwidthProfile" : "TCONT_TYPE5_1Gbps_Peak_500Mbps_Assured_200Mbps_Fixed_User1_HSI_Upstream",
+            "isDhcpRequired" : "true",
+            "serviceName" : "HSIA"
+          }, {
+            "uniTagMatch" : 65,
+            "ponCTag" : 444,
+            "ponSTag" : 333,
+            "usPonCTagPriority" : 7,
+            "usPonSTagPriority" : 7,
+            "dsPonCTagPriority" : 7,
+            "dsPonSTagPriority" : 7,
+            "technologyProfileId" : 65,
+            "downstreamBandwidthProfile" : "VOIP",
+            "upstreamBandwidthProfile" : "TCONT_TYPE1_1Mbps_Fixed",
+            "isDhcpRequired" : "true",
+            "configuredMacAddress" : "2c:60:0c:ee:d7:68",
+            "serviceName" : "VOIP"
+          }, {
+            "uniTagMatch" : 55,
+            "ponCTag" : 55,
+            "ponSTag" : 555,
+            "usPonCTagPriority" : 5,
+            "usPonSTagPriority" : 5,
+            "dsPonCTagPriority" : 5,
+            "dsPonSTagPriority" : 5,
+            "technologyProfileId" : 67,
+            "downstreamBandwidthProfile" : "High-Speed-Internet",
+            "upstreamBandwidthProfile" : "TCONT_TYPE3_2Mbps_Peak_1Mbps_Assured_ForVoD",
+            "configuredMacAddress" : "2c:60:0c:ee:d7:68",
+            "serviceName" : "VOD",
+            "isDhcpRequired" : "true",
+            "isIgmpRequired" : "true"
+          }, {
+            "ponCTag" : 55,
+            "ponSTag" : 550,
+            "dsPonCTagPriority" : 5,
+            "dsPonSTagPriority" : 5,
+            "technologyProfileId" : 67,
+            "serviceName" : "MC"
+          } ]
+        }, {
+          "id" : "EC1838000853",
+          "hardwareIdentifier" : "00:00:00:00:00:01",
+          "ipAddress" : "10.192.20.206",
+          "uplinkPort" : "1048576"
+        } ]
+      }
+    },
+    "org.opencord.igmpproxy" : {
+        "igmpproxy":{
+           "FastLeave":"true",
+           "LastQueryInterval":1,
+           "MaxResp":1,
+           "enableIgmpProvisioning":"false",
+           "globalConnectPointMode":"true",
+           "globalConnectPoint" : "of:0000000000000001/3",
+           "sourceDeviceAndPort":"of:0000000000000001/3",
+           "outgoingIgmpVlanId":550,
+           "outgoingIgmpInnerVlanId":55,
+           "outgoingIgmpWithV3":"true",
+           "IgmpCos":5,
+           "IgmpUniCos":5,
+           "PeriodicQuery":"true",
+           "KeepAliveInterval":60,
+           "KeepAliveCount":5,
+           "requestDsIgmpPackets":false
+        }
+    }
+  },
+  "regions" : { },
+  "links" : { },
+  "layouts" : { }
+}
+
diff --git a/tests/tt-workflow/Voltha_TT_MultiTcontTests.robot b/tests/tt-workflow/Voltha_TT_MultiTcontTests.robot
index 29db0d5..c282a18 100755
--- a/tests/tt-workflow/Voltha_TT_MultiTcontTests.robot
+++ b/tests/tt-workflow/Voltha_TT_MultiTcontTests.robot
@@ -57,6 +57,7 @@
 
 # For dataplane bandwidth testing
 ${lower_margin_pct}      90      # Allow 10% under the limit
+${upper_margin_pct}      120      # Allow 20% under the limit
 ${pon_max_bw_capacity_xgs}=    9700000      # Mbps, for xgs-pon OLT, when FEC Disabled
 
 *** Test Cases ***
@@ -96,6 +97,8 @@
     ${pct_limit_up}=    Evaluate    100*${actual_upstream_bw_used}/${limiting_bw_value_upstream}
     Should Be True    ${pct_limit_up} >= ${lower_margin_pct}
     ...    The upstream bandwidth guarantee was not met (${pct_limit_up}% of resv)
+    Should Be True    ${pct_limit_up} <= ${upper_margin_pct}
+    ...    The upstream bandwidth exceeded the limit (${pct_limit_up}% of limit)
 
 Test that assured BW is allocated as needed on the PON
     [Documentation]    Verify support for Tcont type 2 and 4.
@@ -144,6 +147,8 @@
     ${pct_limit_up}=    Evaluate    100*${actual_upstream_bw_used}/${list_onus_ut}[1][limiting_bw_us]
     Should Be True    ${pct_limit_up} >= ${lower_margin_pct}
     ...    The upstream bandwidth guarantee was not met (${pct_limit_up}% of resv)
+    Should Be True    ${pct_limit_up} <= ${upper_margin_pct}
+    ...    The upstream bandwidth exceeded the limit (${pct_limit_up}% of limit)
 
     # Case 2: Verify for VOD (with index [0]) and HSIA (with index [1]) service combined
     ${out_file_0}=    Set Variable    ${CURDIR}/../../tests/data/out_tcont2
@@ -162,11 +167,15 @@
     ${pct_limit_up_0}=    Evaluate    100*${actual_upstream_bw_used_0}/${list_onus_ut}[0][limiting_bw_us]
     Should Be True    ${pct_limit_up_0} >= ${lower_margin_pct}
     ...    The upstream bandwidth guarantee was not met (${pct_limit_up_0}% of resv)
+    Should Be True    ${pct_limit_up_0} <= ${upper_margin_pct}
+    ...    The upstream bandwidth exceeded the limit (${pct_limit_up_0}% of limit)
     ${actual_upstream_bw_used_1}=    Evaluate    ${out_1['end']['sum_received']['bits_per_second']}/1000
     ${pct_limit_up_1}=    Evaluate
     ...    100*${actual_upstream_bw_used_1}/(${list_onus_ut}[1][limiting_bw_us]-${list_onus_ut}[0][limiting_bw_us])
     Should Be True    ${pct_limit_up_1} >= ${lower_margin_pct}
     ...    The upstream bandwidth guarantee was not met (${pct_limit_up_1}% of resv)
+    Should Be True    ${pct_limit_up_1} <= ${upper_margin_pct}
+    ...    The upstream bandwidth exceeded the limit (${pct_limit_up_1}% of limit)
 
 Test that the AIR BW is reserved for a ONU
     [Documentation]    Verify support for Tcont type 1 + type 4 at the same time.
@@ -240,6 +249,8 @@
     ...    100*${actual_upstream_bw_used}/${list_onus_ut}[1][limiting_bw_us]
     Should Be True    ${pct_limit_up} >= ${lower_margin_pct}
     ...    The upstream bandwidth guarantee was not met (${pct_limit_up}% of resv)
+    Should Be True    ${pct_limit_up} <= ${upper_margin_pct}
+    ...    The upstream bandwidth exceeded the limit (${pct_limit_up}% of limit)
 
     # Case 2: Verify ONU1 and ONU2 will share rest of bw in PON Port. (Expect provisioned fixed bw)
     ${out_file_0}=    Set Variable    /tmp/out1_tcont4
@@ -261,17 +272,23 @@
     ...    100*${actual_upstream_bw_used_0}/((${pon_max_bw_capacity_xgs}-${limiting_bw_us_fill_pon_bw})/2)
     Should Be True    ${pct_limit_up_0} >= ${lower_margin_pct}
     ...    The upstream bandwidth guarantee was not met (${pct_limit_up_0}% of resv)
+    Should Be True    ${pct_limit_up_0} <= ${upper_margin_pct}
+    ...    The upstream bandwidth exceeded the limit (${pct_limit_up_0}% of limit)
     ${actual_upstream_bw_used_1}=    Evaluate    ${out_1['end']['sum_received']['bits_per_second']}/1000
     ${pct_limit_up_1}=    Evaluate
     ...    100*${actual_upstream_bw_used_1}/((${pon_max_bw_capacity_xgs}-${limiting_bw_us_fill_pon_bw})/2)
     Should Be True    ${pct_limit_up_1} >= ${lower_margin_pct}
     ...    The upstream bandwidth guarantee was not met (${pct_limit_up_1}% of resv)
+    Should Be True    ${pct_limit_up_1} <= ${upper_margin_pct}
+    ...    The upstream bandwidth exceeded the limit (${pct_limit_up_1}% of limit)
     # Verify ONU3 (fixed bw) tcont1 air bw is reservered.
     ${actual_reserved_upstream_bw_for_tcont1}=    Evaluate
     ...    ${pon_max_bw_capacity_xgs}-(${actual_upstream_bw_used_0}+${actual_upstream_bw_used_1})
     ${pct_limit_up_tcont1}=    Evaluate    100*${actual_reserved_upstream_bw_for_tcont1}/${limiting_bw_us_fill_pon_bw}
     Should Be True    ${pct_limit_up_tcont1} >= ${lower_margin_pct}
-    ...    The upstream bandwidth guarantee was not met (${pct_limit_up_1}% of resv)
+    ...    The upstream bandwidth guarantee was not met (${pct_limit_up_tcont1}% of resv)
+    Should Be True    ${pct_limit_up_tcont1} <= ${upper_margin_pct}
+    ...    The upstream bandwidth exceeded the limit (${pct_limit_up_tcont1}% of limit)
 
     # Sent original sadis file to onos
     Send File To Onos    ${CURDIR}/../../tests/data/flex-ocp-cord-sadis-TT.json
@@ -338,6 +355,8 @@
     ${pct_limit_up}=    Evaluate    100*${actual_upstream_bw_used}/${list_onus_ut}[1][limiting_bw_us]
     Should Be True    ${pct_limit_up} >= ${lower_margin_pct}
     ...    The upstream bandwidth guarantee was not met (${pct_limit_up}% of resv)
+    Should Be True    ${pct_limit_up} <= ${upper_margin_pct}
+    ...    The upstream bandwidth exceeded the limit (${pct_limit_up}% of limit)
 
     # Case 2: Verify for ONU1 (with index [0]) and ONU2 (with index [1]) devices combined
     ${out_file_0}=    Set Variable    /tmp/out_tcont2
@@ -356,11 +375,124 @@
     ${pct_limit_up_0}=    Evaluate    100*${actual_upstream_bw_used_0}/${list_onus_ut}[0][limiting_bw_us]
     Should Be True    ${pct_limit_up_0} >= ${lower_margin_pct}
     ...    The upstream bandwidth guarantee was not met (${pct_limit_up_0}% of resv)
+    Should Be True    ${pct_limit_up_0} <= ${upper_margin_pct}
+    ...    The upstream bandwidth exceeded the limit (${pct_limit_up_0}% of limit)
     ${actual_upstream_bw_used_1}=    Evaluate    ${out_1['end']['sum_received']['bits_per_second']}/1000
     ${pct_limit_up_1}=    Evaluate
     ...    100*${actual_upstream_bw_used_1}/(${uni_capacity}-${list_onus_ut}[0][limiting_bw_us])
     Should Be True    ${pct_limit_up_1} >= ${lower_margin_pct}
     ...    The upstream bandwidth guarantee was not met (${pct_limit_up_1}% of resv)
+    Should Be True    ${pct_limit_up_1} <= ${upper_margin_pct}
+    ...    The upstream bandwidth exceeded the limit (${pct_limit_up_1}% of limit)
+
+    # Sent original sadis file to onos
+    Send File To Onos    ${CURDIR}/../../tests/data/flex-ocp-cord-sadis-TT.json
+
+Verify that best effort BW is released to assured BW requirement as needed and that fixed BW is reserved always on the PON for TT
+    [Documentation]    Verify support for Tcont type 4 and 5.
+    ...    Pump 1Gbps upstream from the RG for HSI service of ONU2.
+    ...    Verify that no more than 1Gbps is received at the BNG.
+    ...    Now pump traffic from the RG's for the HSI service both ONU1 and ONU2 at the same time.
+    ...    The BNG should receive at least 700Mbps (500 + 200 Mbps) for ONU2.
+    ...    The remaining 300Mbps on the PON should be rationed between the two ONUs.
+    ...    Now this is largely scheduler implementation dependent, so this is to be observed on the scheduler in the BAL behaves.
+    ...    If it equally distributes the remaining BW,
+    ...    ONU1 should get 150Mbps and ONU2 in total should get 850Mbps (500+200+150Mbps).
+    [Tags]    functionalTT    VOL-4097    non-critical
+    [Setup]    Run Keywords    Start Logging    TcontType4Onu1Type5Onu2
+    ...        AND             Setup
+    [Teardown]    Run Keywords    Collect Logs
+    ...           AND             Stop Logging    TcontType4Onu1Type5Onu2
+    ...           AND             Delete All Devices and Verify
+    Run Keyword If    ${has_dataplane}    Clean Up Linux
+    Send File To Onos    ${CURDIR}/../../tests/data/flex-ocp-cord-sadis-TT-multi-tcont-1.json
+    Wait Until Keyword Succeeds    ${timeout}    2s    Perform Sanity Test TT
+
+    # The test expects the first entry in multi_tcont_tests.tcont4tcont5 input will be for service: hsıa and tcont: 4
+    # The test expects the second entry in multi_tcont_tests.tcont4tcont5 input will be for service: hsıa and tcont: 5
+    ${list_onus_ut}=    Create List
+    ${list_onus_ut_air_cir}=    Create List
+    ${num_multi_tcont_input}=    Get Length    ${multi_tcont_tests.tcont4tcont5}
+    FOR    ${I}    IN RANGE    0    ${num_multi_tcont_input}
+        ${onu}=    Set Variable    ${multi_tcont_tests.tcont4tcont5[${I}]}
+        ${onu_sn}=    Set Variable    ${onu['onu']}
+        ${service}=    Set Variable    ${onu['service_type']}
+        ${us_bw}=    Set Variable    ${onu['us_bw_profile']}
+        ${matched}    ${src}    ${dst}=    Get ONU details with Given Sn and Service    ${onu_sn}
+        ...    ${service}    ${us_bw}
+        Pass Execution If    '${matched}' != 'True'
+        ...    Skipping test: No ONU found with sn '${onu_sn}', service '${service}' and us_bw '${us_bw}'
+        # Check for iperf3 and jq tools
+        ${stdout}    ${stderr}    ${rc}=    Execute Remote Command    which iperf3 jq
+        ...    ${src['ip']}    ${src['user']}    ${src['pass']}    ${src['container_type']}    ${src['container_name']}
+        Pass Execution If    ${rc} != 0    Skipping test: iperf3 / jq not found on the RG
+        # Get Upstream BW Profile details
+        ${limiting_bw_us}=    Get Limiting Bandwidth Details    ${us_bw}
+        ${onu_ut}    Create Dictionary    src    ${src}    dst    ${dst}    limiting_bw_us    ${limiting_bw_us}
+        Append To List    ${list_onus_ut}    ${onu_ut}
+        ${limiting_bw_us_air_cir}=    Get Limiting Bandwidth Details for Fixed and Committed    ${us_bw}
+        ${onu_ut_air_cir}    Create Dictionary    src    ${src}    dst    ${dst}
+        ...    limiting_bw_us_air_cir    ${limiting_bw_us_air_cir}
+        Append To List    ${list_onus_ut_air_cir}    ${onu_ut_air_cir}
+    END
+
+    # Fill the OLT PON Bandwidth with Fixed Bandwidth Profile ONU
+    ${onu_fill_pon_bw}=    Evaluate    ${onus_fill_pon_bw}[0].get("serial")
+    ${olt_fill_pon_bw}=    Evaluate    ${onus_fill_pon_bw}[0].get("olt")
+    ${us_bw_profile_fill_pon_bw}=    Evaluate    ${onus_fill_pon_bw}[0].get("us_bw_profile")
+    ${of_id}=    Wait Until Keyword Succeeds    ${timeout}    15s    Validate OLT Device in ONOS    ${olt_fill_pon_bw}
+    ${onu_port}=    Run Keyword And Continue On Failure    Wait Until Keyword Succeeds    ${timeout}    2s
+    ...    Get ONU Port in ONOS    ${onu_fill_pon_bw}    ${of_id}
+    Run Keyword And Continue On Failure    Wait Until Keyword Succeeds    ${timeout}    2
+    ...    Execute ONOS CLI Command    ${ONOS_SSH_IP}    ${ONOS_SSH_PORT}
+    ...    volt-add-subscriber-access ${of_id} ${onu_port}
+    Sleep    10s
+    ${limiting_bw_us_fill_pon_bw}=    Get Limiting Bandwidth Details    ${us_bw_profile_fill_pon_bw}
+
+    # Case 1: Verify only for HSIA service from the RG of ONU2
+    ${dst}=    Set Variable    ${list_onus_ut}[1][dst]
+    ${updict}=    Run Iperf3 Test Client    ${list_onus_ut}[1][src]    server=${dst['dp_iface_ip_qinq']}
+    ...    args=-t 30 -p 5202
+    ${actual_upstream_bw_used}=    Evaluate    ${updict['end']['sum_received']['bits_per_second']}/1000
+    ${pct_limit_up}=    Evaluate    100*${actual_upstream_bw_used}/${list_onus_ut}[1][limiting_bw_us]
+    Should Be True    ${pct_limit_up} >= ${lower_margin_pct}
+    ...    The upstream bandwidth guarantee was not met (${pct_limit_up}% of resv)
+    Should Be True    ${pct_limit_up} <= ${upper_margin_pct}
+    ...    The upstream bandwidth exceeded the limit (${pct_limit_up}% of limit)
+
+    # Case 2: Verify for ONU1 (with index [0]) and ONU2 (with index [1]) devices combined
+    ${out_file_0}=    Set Variable    /tmp/out_tcont4
+    ${dst_0}=    Set Variable    ${list_onus_ut}[0][dst]
+    Run Iperf3 Test Client in Background    ${list_onus_ut}[0][src]    server=${dst_0['dp_iface_ip_qinq']}
+    ...    args=-t 30 -p 5201    out_file=${out_file_0}
+    ${out_file_1}=    Set Variable    /tmp/out_tcont5
+    ${dst_1}=    Set Variable    ${list_onus_ut}[1][dst]
+    Run Iperf3 Test Client in Background    ${list_onus_ut}[1][src]    server=${dst_1['dp_iface_ip_qinq']}
+    ...    args=-t 30 -p 5202    out_file=${out_file_1}
+    # Wait for the above iperf commands to finish (sleep time depends on -t arg value passed in iperf command)
+    Sleep    35s
+    ${out_0}=    Read Output File on System    ${out_file_0}
+    ${out_1}=    Read Output File on Remote System    ${list_onus_ut}[1][src]    ${out_file_1}
+    ${actual_upstream_bw_used_0}=    Evaluate    ${out_0['end']['sum_received']['bits_per_second']}/1000
+    ${limit_up_0_denominator}=    Evaluate
+    ...    ((${pon_max_bw_capacity_xgs}-${limiting_bw_us_fill_pon_bw}-${list_onus_ut_air_cir}[1][limiting_bw_us_air_cir])/2)
+    ${pct_limit_up_0}=    Evaluate
+    ...    100*${actual_upstream_bw_used_0}/${limit_up_0_denominator}
+    Should Be True    ${pct_limit_up_0} >= ${lower_margin_pct}
+    ...    The upstream bandwidth guarantee was not met (${pct_limit_up_0}% of resv)
+    Should Be True    ${pct_limit_up_0} <= ${upper_margin_pct}
+    ...    The upstream bandwidth exceeded the limit (${pct_limit_up_0}% of limit)
+    ${actual_upstream_bw_used_1}=    Evaluate    ${out_1['end']['sum_received']['bits_per_second']}/1000
+    ${limit_up_1_numerator}=    Evaluate
+    ...    (${actual_upstream_bw_used_1}-${list_onus_ut_air_cir}[1][limiting_bw_us_air_cir])
+    ${limit_up_1_denominator}=    Evaluate
+    ...    ((${pon_max_bw_capacity_xgs}-${limiting_bw_us_fill_pon_bw}-${list_onus_ut_air_cir}[1][limiting_bw_us_air_cir])/2)
+    ${pct_limit_up_1}=    Evaluate
+    ...    100*${limit_up_1_numerator}/${limit_up_1_denominator}
+    Should Be True    ${pct_limit_up_1} >= ${lower_margin_pct}
+    ...    The upstream bandwidth guarantee was not met (${pct_limit_up_1}% of resv)
+    Should Be True    ${pct_limit_up_1} <= ${upper_margin_pct}
+    ...    The upstream bandwidth exceeded the limit (${pct_limit_up_1}% of limit)
 
     # Sent original sadis file to onos
     Send File To Onos    ${CURDIR}/../../tests/data/flex-ocp-cord-sadis-TT.json