Add fullstack test for check DSCP marks outbounds

New fullstack test is added to check if packets which
should be sent from port with DSCP mark set are really
sent to another port with this DSCP mark.

This test uses IPv4 only.

Change-Id: I4b26c3c644eb6f2f7813658c99d16fbc3cc61e06
Closes-Bug: #1625570
This commit is contained in:
Sławek Kapłoński 2016-10-26 11:46:46 +02:00 committed by Slawek Kaplonski
parent 2b9d9e3b9e
commit ea7b51655f
2 changed files with 87 additions and 0 deletions

View File

@ -13,9 +13,19 @@
# License for the specific language governing permissions and limitations
# under the License.
import re
from neutron.agent.linux import async_process
from neutron.common import utils as common_utils
IPv4_ADDR_REGEX = r"(\d{1,3}\.){3}\d{1,3}"
class TcpdumpException(Exception):
pass
def extract_mod_nw_tos_action(flows):
tos_mark = None
if flows:
@ -52,3 +62,32 @@ def wait_until_dscp_marking_rule_applied(bridge, port_vif, rule):
return dscp_mark == expected
common_utils.wait_until_true(_dscp_marking_rule_applied)
def wait_for_dscp_marked_packet(sender_vm, receiver_vm, dscp_mark):
cmd = ["tcpdump", "-i", receiver_vm.port.name, "-nlt"]
if dscp_mark:
cmd += ["(ip[1] & 0xfc == %s)" % (dscp_mark << 2)]
tcpdump_async = async_process.AsyncProcess(cmd, run_as_root=True,
namespace=receiver_vm.namespace)
tcpdump_async.start()
sender_vm.block_until_ping(receiver_vm.ip)
try:
tcpdump_async.stop()
except async_process.AsyncProcessException:
# If it was already stopped than we don't care about it
pass
pattern = (r"IP (?P<src_ip>%(ip_addr_regex)s) > "
"(?P<dst_ip>%(ip_addr_regex)s): ICMP .*$" % {
'ip_addr_regex': IPv4_ADDR_REGEX})
for line in tcpdump_async.iter_stdout():
m = re.match(pattern, line)
if m and (m.group("src_ip") == sender_vm.ip and
m.group("dst_ip") == receiver_vm.ip):
return
raise TcpdumpException(
"No packets marked with DSCP = %(dscp_mark)s received from %(src)s "
"to %(dst)s" % {'dscp_mark': dscp_mark,
'src': sender_vm.ip,
'dst': receiver_vm.ip})

View File

@ -176,6 +176,29 @@ class TestDscpMarkingQoSOvs(BaseQoSRuleTestCase, base.BaseFullStackTestCase):
scenarios = fullstack_utils.get_ovs_interface_scenarios()
l2_agent_type = constants.AGENT_TYPE_OVS
def setUp(self):
host_desc = [
environment.HostDescription(
l3_agent=False,
of_interface=self.of_interface,
ovsdb_interface=self.ovsdb_interface,
l2_agent_type=self.l2_agent_type
) for _ in range(2)]
env_desc = environment.EnvironmentDescription(
qos=True)
env = environment.Environment(env_desc, host_desc)
super(BaseQoSRuleTestCase, self).setUp(env)
self.tenant_id = uuidutils.generate_uuid()
self.network = self.safe_client.create_network(self.tenant_id,
'network-test')
self.subnet = self.safe_client.create_subnet(
self.tenant_id, self.network['id'],
cidr='10.0.0.0/24',
gateway_ip='10.0.0.1',
name='subnet-test',
enable_dhcp=False)
def _wait_for_dscp_marking_rule_applied(self, vm, dscp_mark):
l2_extensions.wait_until_dscp_marking_rule_applied(
vm.bridge, vm.port.name, dscp_mark)
@ -223,6 +246,31 @@ class TestDscpMarkingQoSOvs(BaseQoSRuleTestCase, base.BaseFullStackTestCase):
body={'port': {'qos_policy_id': None}})
self._wait_for_dscp_marking_rule_removed(vm)
def test_dscp_marking_packets(self):
# Create port (vm) which will be used to received and test packets
receiver_port = self.safe_client.create_port(
self.tenant_id, self.network['id'],
self.environment.hosts[1].hostname)
receiver = self.useFixture(
machine.FakeFullstackMachine(
self.environment.hosts[1],
self.network['id'],
self.tenant_id,
self.safe_client,
neutron_port=receiver_port))
# Create port with qos policy attached
sender, qos_policy = self._prepare_vm_with_qos_policy(
[functools.partial(self._add_dscp_rule, DSCP_MARK)])
sender.block_until_boot()
receiver.block_until_boot()
self._wait_for_dscp_marking_rule_applied(sender, DSCP_MARK)
l2_extensions.wait_for_dscp_marked_packet(
sender, receiver, DSCP_MARK)
class TestQoSWithL2Population(base.BaseFullStackTestCase):