Fix fullstack test_dscp_marking_packets test

Fullstack test test_dscp_marking_packets spawns tcpdump
process inside one fake vm's namespace and then tries to
ping this instance from second one.
After that it checks if tcdump captured any packet marked with
specific DSCP mark.

Ping was done usually only once (1 packet) because
it was done by using vm.wait_until_ping() method, so it could
happen sometimes that ping was send before tcpdump actually
started captuting traffic.
In such case test failed because there was no any packet captured.

This patch changes this by:
1. Start tcpdump async process with block=True, so it should be
   already really started before test will go to the next steps,
2. Send always 10 packets instead of (usually) only one.

In addition this patch adds logging of captured tcpdump's stdout
and stderr streams. It may help debugging issues with this test in
the future.

Change-Id: I23bbde59af0250267843623dde2c5407059d9db2
Closes-Bug: #1818335
(cherry picked from commit 8c2a16796b)
This commit is contained in:
Slawek Kaplonski 2019-03-09 01:07:03 +01:00 committed by Bernard Cafarelli
parent 0b6076d3e2
commit 570f6086c0
1 changed files with 14 additions and 2 deletions

View File

@ -15,12 +15,14 @@
import re import re
import signal import signal
import time
from oslo_log import log as logging from oslo_log import log as logging
from neutron.agent.linux import async_process from neutron.agent.linux import async_process
from neutron.agent.linux import iptables_manager from neutron.agent.linux import iptables_manager
from neutron.common import utils as common_utils from neutron.common import utils as common_utils
from neutron.tests.common import net_helpers
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
@ -108,19 +110,29 @@ def wait_for_dscp_marked_packet(sender_vm, receiver_vm, dscp_mark):
cmd += ["and", "(ip[1] & 0xfc == %s)" % (dscp_mark << 2)] cmd += ["and", "(ip[1] & 0xfc == %s)" % (dscp_mark << 2)]
tcpdump_async = async_process.AsyncProcess(cmd, run_as_root=True, tcpdump_async = async_process.AsyncProcess(cmd, run_as_root=True,
namespace=receiver_vm.namespace) namespace=receiver_vm.namespace)
tcpdump_async.start() tcpdump_async.start(block=True)
sender_vm.block_until_ping(receiver_vm.ip)
with net_helpers.async_ping(sender_vm.namespace, [receiver_vm.ip]) as done:
while not done():
time.sleep(0.25)
try: try:
tcpdump_async.stop(kill_signal=signal.SIGINT) tcpdump_async.stop(kill_signal=signal.SIGINT)
except async_process.AsyncProcessException: except async_process.AsyncProcessException:
# If it was already stopped than we don't care about it # If it was already stopped than we don't care about it
pass pass
tcpdump_stderr_lines = []
pattern = r"(?P<packets_count>^\d+) packets received by filter" pattern = r"(?P<packets_count>^\d+) packets received by filter"
for line in tcpdump_async.iter_stderr(): for line in tcpdump_async.iter_stderr():
m = re.match(pattern, line) m = re.match(pattern, line)
if m and int(m.group("packets_count")) != 0: if m and int(m.group("packets_count")) != 0:
return return
tcpdump_stderr_lines.append(line)
tcpdump_stdout_lines = [line for line in tcpdump_async.iter_stdout()]
LOG.debug("Captured output lines from tcpdump. Stdout: %s; Stderr: %s",
tcpdump_stdout_lines, tcpdump_stderr_lines)
raise TcpdumpException( raise TcpdumpException(
"No packets marked with DSCP = %(dscp_mark)s received from %(src)s " "No packets marked with DSCP = %(dscp_mark)s received from %(src)s "