Merge "Test QoS max bandwidth limit for router gateways, along with other types"
This commit is contained in:
@@ -322,10 +322,16 @@ class QosBaseTest(test_qos.QoSTestMixin, base.TrafficFlowTest):
|
|||||||
# a 20% of lower deviation is allowed
|
# a 20% of lower deviation is allowed
|
||||||
self.assertGreater(measured_bw, bw_limit * 0.8)
|
self.assertGreater(measured_bw, bw_limit * 0.8)
|
||||||
|
|
||||||
def _validate_traffic_bw_limit(self, client, server,
|
def _validate_traffic_bw_limit(self, client, server, egress=True,
|
||||||
egress=True, ipv6=False, fip_qos=False):
|
ipv6=False, fip_qos=False, gw_qos=False):
|
||||||
"""Validate that bw limit is applied to the traffic between client and
|
"""Validate that bw limit is applied to the traffic between client and
|
||||||
server VMs
|
server VMs.
|
||||||
|
|
||||||
|
Precedence summary for max-bw limit:
|
||||||
|
- only port: then max-bw port
|
||||||
|
- port + gw: minimum max-bw
|
||||||
|
- port + gw/fip: minimum max-bw of port or FIP
|
||||||
|
(GW is discarded because FIP has precedence)
|
||||||
|
|
||||||
Scenario:
|
Scenario:
|
||||||
1. First make sure that bw between VMs is not limited.
|
1. First make sure that bw between VMs is not limited.
|
||||||
@@ -341,8 +347,22 @@ class QosBaseTest(test_qos.QoSTestMixin, base.TrafficFlowTest):
|
|||||||
7. Send traffic between 2 VMs and make sure that now bw is
|
7. Send traffic between 2 VMs and make sure that now bw is
|
||||||
limited according to the new value (since rule for port has higher
|
limited according to the new value (since rule for port has higher
|
||||||
priority).
|
priority).
|
||||||
8. Delete bw limit rule from the port QoS policy and make sure
|
8. Create another QoS policy applied to GW,
|
||||||
that traffic is not limited.
|
verify together with port QoS when lower/higher.
|
||||||
|
9. Delete bandwidth rule from the router gateway QoS policy
|
||||||
|
and make sure that traffic is limited for port value - step 12
|
||||||
|
(unless FIP checked, then rule kept to verify when all 3 used).
|
||||||
|
10. Create another QoS policy applied to FIP, verify
|
||||||
|
FIP and port lower/higher (if enabled also GW higher),
|
||||||
|
also verify when GW lower than FIP/port - lowest between FIP/port
|
||||||
|
prioritized (priority - A: port > FIP > GW, B: FIP > port > GW).
|
||||||
|
11. Delete bandwidth rule from FIP QoS policy,
|
||||||
|
and make sure that traffic is limited for GW value.
|
||||||
|
12. Delete bandwidth rule from GW QoS policy,
|
||||||
|
and make sure that traffic is limited for port value again.
|
||||||
|
13. Delete bandwidth limit rule from the port QoS policy and make
|
||||||
|
sure that traffic is not limited.
|
||||||
|
14. Verify a QoS policy attached to a port cannot be deleted.
|
||||||
"""
|
"""
|
||||||
# Prerequisite: install iperf3
|
# Prerequisite: install iperf3
|
||||||
self._skip_if_iperf3_not_installed(client['ssh_client'])
|
self._skip_if_iperf3_not_installed(client['ssh_client'])
|
||||||
@@ -414,6 +434,79 @@ class QosBaseTest(test_qos.QoSTestMixin, base.TrafficFlowTest):
|
|||||||
client, server, egress, bw_limit=max_kbps * 1000,
|
client, server, egress, bw_limit=max_kbps * 1000,
|
||||||
protocol=constants.PROTO_NAME_UDP)
|
protocol=constants.PROTO_NAME_UDP)
|
||||||
|
|
||||||
|
# NOTE(mblue): only enabled in north-south topology option when
|
||||||
|
# routed through gateways.
|
||||||
|
if gw_qos:
|
||||||
|
# apply policy for router gateway (no rule in policy yet)
|
||||||
|
gw_bw_policy_id = self._create_qos_policy()
|
||||||
|
self.router['external_gateway_info'][
|
||||||
|
'qos_policy_id'] = gw_bw_policy_id
|
||||||
|
self.router = self.admin_client.update_router(
|
||||||
|
self.router['id'],
|
||||||
|
external_gateway_info=self.router['external_gateway_info']
|
||||||
|
)['router']
|
||||||
|
del self.router['external_gateway_info']['qos_policy_id']
|
||||||
|
self.addCleanup(
|
||||||
|
self.admin_client.update_router,
|
||||||
|
self.router['id'],
|
||||||
|
external_gateway_info=self.router['external_gateway_info'])
|
||||||
|
# gw bw limit greater than port bw limit
|
||||||
|
gw_max_kbps = max_kbps * 20
|
||||||
|
rule_data = {
|
||||||
|
'max_kbps': gw_max_kbps,
|
||||||
|
'max_burst_kbps': gw_max_kbps * 0.8,
|
||||||
|
'direction': direction}
|
||||||
|
gw_port_rule_id = self._create_qos_bw_limit_rule(
|
||||||
|
gw_bw_policy_id, rule_data)['id']
|
||||||
|
# port bw limit is lower than gw bw limit, so max_kbps
|
||||||
|
# will be the measured bw
|
||||||
|
self._validate_bw_limit(
|
||||||
|
client, server, egress, bw_limit=max_kbps * 1000,
|
||||||
|
protocol=constants.PROTO_NAME_UDP)
|
||||||
|
|
||||||
|
# gw bw limit lower than port bw limit
|
||||||
|
gw_max_kbps = max_kbps // 2
|
||||||
|
rule_update_data = {
|
||||||
|
'max_kbps': gw_max_kbps,
|
||||||
|
'max_burst_kbps': gw_max_kbps * 0.8}
|
||||||
|
self.qos_bw_limit_rule_client.update_limit_bandwidth_rule(
|
||||||
|
qos_policy_id=gw_bw_policy_id, rule_id=gw_port_rule_id,
|
||||||
|
**rule_update_data)
|
||||||
|
|
||||||
|
# For rocky images, running iperf tests with low BW limits using
|
||||||
|
# TCP does not work well, wo UDP is used instead
|
||||||
|
# TODO(eolivare): provide link to iperf/rocky bug
|
||||||
|
protocol = (constants.PROTO_NAME_TCP
|
||||||
|
if self.username != "rocky"
|
||||||
|
else constants.PROTO_NAME_UDP)
|
||||||
|
# gw bw limit is lower than port bw limit, so gw_max_kbps
|
||||||
|
# will be the measured bw
|
||||||
|
self._validate_bw_limit(client, server, egress,
|
||||||
|
bw_limit=gw_max_kbps * 1000,
|
||||||
|
protocol=protocol)
|
||||||
|
|
||||||
|
# delete bw limit rule associated to gw qos policy,
|
||||||
|
# port bw limit applies again
|
||||||
|
# (unless FIP checked, then keep GW rule to also test
|
||||||
|
# FIP/GW precedence when each is lower).
|
||||||
|
# NOTE(mblue): port validation happens anyways at end of method.
|
||||||
|
if not fip_qos:
|
||||||
|
self.qos_bw_limit_rule_client.delete_limit_bandwidth_rule(
|
||||||
|
gw_bw_policy_id, gw_port_rule_id)
|
||||||
|
self._validate_bw_limit(client, server, egress,
|
||||||
|
bw_limit=max_kbps * 1000,
|
||||||
|
protocol=protocol)
|
||||||
|
else:
|
||||||
|
# gw bw limit greater than port/fip bw limit
|
||||||
|
gw_max_kbps = max_kbps * 20
|
||||||
|
rule_update_data = {
|
||||||
|
'max_kbps': gw_max_kbps,
|
||||||
|
'max_burst_kbps': gw_max_kbps * 0.8,
|
||||||
|
'direction': direction}
|
||||||
|
self.qos_bw_limit_rule_client.update_limit_bandwidth_rule(
|
||||||
|
qos_policy_id=gw_bw_policy_id, rule_id=gw_port_rule_id,
|
||||||
|
**rule_update_data)
|
||||||
|
|
||||||
# Create a new Qos Policy and attach to the FIP of src server
|
# Create a new Qos Policy and attach to the FIP of src server
|
||||||
# This only applies to south-north tests because the traffic from the
|
# This only applies to south-north tests because the traffic from the
|
||||||
# src server to the dst server goes through the src FIP
|
# src server to the dst server goes through the src FIP
|
||||||
@@ -434,14 +527,32 @@ class QosBaseTest(test_qos.QoSTestMixin, base.TrafficFlowTest):
|
|||||||
src_fip_id, qos_policy_id=fip_qos_pol_id)
|
src_fip_id, qos_policy_id=fip_qos_pol_id)
|
||||||
self.addCleanup(self.admin_client.update_floatingip,
|
self.addCleanup(self.admin_client.update_floatingip,
|
||||||
src_fip_id, qos_policy_id=None)
|
src_fip_id, qos_policy_id=None)
|
||||||
# port bw limit is lower than fip bw limit, so max_kbps
|
# port bw limit is lower than fip (sometimes also gw) bw limit,
|
||||||
# will be the measured bw
|
# so max_kbps will be the measured bw
|
||||||
self._validate_bw_limit(
|
self._validate_bw_limit(
|
||||||
client, server, egress, bw_limit=max_kbps * 1000,
|
client, server, egress, bw_limit=max_kbps * 1000,
|
||||||
protocol=constants.PROTO_NAME_UDP)
|
protocol=constants.PROTO_NAME_UDP)
|
||||||
|
|
||||||
# fip bw limit lower than port bw limit
|
# only if gw_qos True, test when gw lower than fip and port:
|
||||||
fip_max_kbps = max_kbps // 2
|
# expected - fip prioritzied over gw (LP#2110018),
|
||||||
|
# and port limit applied before reaching this datapath part.
|
||||||
|
if gw_qos:
|
||||||
|
gw_max_kbps = max_kbps // 2
|
||||||
|
rule_update_data = {
|
||||||
|
'max_kbps': gw_max_kbps,
|
||||||
|
'max_burst_kbps': gw_max_kbps * 0.8,
|
||||||
|
'direction': direction}
|
||||||
|
self.qos_bw_limit_rule_client.update_limit_bandwidth_rule(
|
||||||
|
qos_policy_id=gw_bw_policy_id, rule_id=gw_port_rule_id,
|
||||||
|
**rule_update_data)
|
||||||
|
# port limit expected
|
||||||
|
self._validate_bw_limit(client, server, egress,
|
||||||
|
bw_limit=max_kbps * 1000,
|
||||||
|
protocol=protocol)
|
||||||
|
|
||||||
|
# update fip bw limit lower than port bw limit
|
||||||
|
# (also lower than gw limit if exists)
|
||||||
|
fip_max_kbps = max_kbps // 3
|
||||||
rule_update_data = {
|
rule_update_data = {
|
||||||
'max_kbps': fip_max_kbps,
|
'max_kbps': fip_max_kbps,
|
||||||
'max_burst_kbps': fip_max_kbps * 0.8}
|
'max_burst_kbps': fip_max_kbps * 0.8}
|
||||||
@@ -455,16 +566,25 @@ class QosBaseTest(test_qos.QoSTestMixin, base.TrafficFlowTest):
|
|||||||
protocol = (constants.PROTO_NAME_TCP
|
protocol = (constants.PROTO_NAME_TCP
|
||||||
if self.username != "rocky"
|
if self.username != "rocky"
|
||||||
else constants.PROTO_NAME_UDP)
|
else constants.PROTO_NAME_UDP)
|
||||||
# fip bw limit is lower than port bw limit, so fip_max_kbps
|
# fip bw limit is lower than port/gw bw limit, so fip_max_kbps
|
||||||
# will be the measured bw
|
# will be the measured bw
|
||||||
self._validate_bw_limit(client, server, egress,
|
self._validate_bw_limit(client, server, egress,
|
||||||
bw_limit=fip_max_kbps * 1000,
|
bw_limit=fip_max_kbps * 1000,
|
||||||
protocol=protocol)
|
protocol=protocol)
|
||||||
|
|
||||||
# delete bw limit rule associated to fip qos policy
|
# delete bw limit rule associated to fip qos policy,
|
||||||
# port bw limit applies again
|
# so either port/gw bw limit applies again
|
||||||
self.qos_bw_limit_rule_client.delete_limit_bandwidth_rule(
|
self.qos_bw_limit_rule_client.delete_limit_bandwidth_rule(
|
||||||
fip_qos_pol_id, fip_port_rule_id)
|
fip_qos_pol_id, fip_port_rule_id)
|
||||||
|
# only for GW: test lower GW prioritized when with port (no FIP),
|
||||||
|
# delete GW rule for next checks
|
||||||
|
if gw_qos:
|
||||||
|
self._validate_bw_limit(client, server, egress,
|
||||||
|
bw_limit=gw_max_kbps * 1000,
|
||||||
|
protocol=protocol)
|
||||||
|
self.qos_bw_limit_rule_client.delete_limit_bandwidth_rule(
|
||||||
|
gw_bw_policy_id, gw_port_rule_id)
|
||||||
|
# validate port limit applies again
|
||||||
self._validate_bw_limit(client, server, egress,
|
self._validate_bw_limit(client, server, egress,
|
||||||
bw_limit=max_kbps * 1000,
|
bw_limit=max_kbps * 1000,
|
||||||
protocol=protocol)
|
protocol=protocol)
|
||||||
@@ -945,9 +1065,9 @@ class QosTestCommon(QosBaseTest):
|
|||||||
# self._create_vms_by_topology should be reverse
|
# self._create_vms_by_topology should be reverse
|
||||||
server, client = self._create_vms_by_topology(topology='north-south')
|
server, client = self._create_vms_by_topology(topology='north-south')
|
||||||
self._validate_traffic_bw_limit(
|
self._validate_traffic_bw_limit(
|
||||||
client, server, egress=True, fip_qos=True)
|
client, server, egress=True, fip_qos=True, gw_qos=True)
|
||||||
self._validate_traffic_bw_limit(
|
self._validate_traffic_bw_limit(
|
||||||
client, server, egress=False, fip_qos=True)
|
client, server, egress=False, fip_qos=True, gw_qos=True)
|
||||||
|
|
||||||
@decorators.idempotent_id('fc833d46-d18f-4edf-b082-5f5fe909fb79')
|
@decorators.idempotent_id('fc833d46-d18f-4edf-b082-5f5fe909fb79')
|
||||||
def test_bw_limit_east_west(self):
|
def test_bw_limit_east_west(self):
|
||||||
|
|||||||
Reference in New Issue
Block a user