Skip to content

Commit e124b1a

Browse files
committed
network: add tcpdump() function and use it
test_vlan_filtering.py is running tcpdump for various tests. as it something we want to use more in network tests, create a function. Signed-off-by: Sebastien Rodot <sebastien.rodot@vates.tech>
1 parent 99364ae commit e124b1a

2 files changed

Lines changed: 70 additions & 24 deletions

File tree

tests/network/__init__.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
from __future__ import annotations
2+
3+
import pytest
4+
5+
import logging
6+
from contextlib import contextmanager
7+
8+
from lib.common import Defer, wait_for
9+
from lib.vm import VM
10+
11+
from typing import Generator
12+
13+
@contextmanager
14+
def tcpdump(
15+
defer: Defer,
16+
pcapfile: str,
17+
vm: VM,
18+
interface: str,
19+
filter: str | None = None,
20+
*,
21+
count: int | None = None,
22+
) -> Generator[None, None, None]:
23+
"""
24+
Run tcpdump on the vm with specific interface.
25+
tcpdump is running only in the returned context.
26+
"""
27+
def cleanup():
28+
# if vm is gone, do not fail
29+
if vm.exists() and vm.is_running():
30+
vm.ssh("xargs kill < {pcapfile}.pid; rm -f -- {pcapfile}.pid")
31+
32+
# check no concurrent run
33+
if vm.file_exists(f"{pcapfile}.pid"):
34+
pytest.fail(f"concurrent run detected: {pcapfile}.pid already exists")
35+
36+
# tcpdump arguments
37+
args = f"-n -w {pcapfile} -i {interface}"
38+
if count is not None:
39+
args += f" -c {count}"
40+
if filter is not None:
41+
args += f" '{filter}'"
42+
43+
# run tcpdump in background
44+
logging.info(f"Running tcpdump on '{vm.name()}'")
45+
vm.ssh(
46+
f"tcpdump --immediate-mode {args} & "
47+
f"echo $! > {pcapfile}.pid; ",
48+
background=True,
49+
)
50+
defer(cleanup)
51+
52+
# check tcpdump has properly started
53+
wait_for(lambda: vm.file_exists(pcapfile), timeout_secs=2, retry_delay_secs=1)
54+
55+
yield
56+
cleanup()

tests/network/test_vlan_filtering.py

Lines changed: 14 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
from lib.network import Network
77
from lib.vm import VM
88

9+
from . import tcpdump
10+
911
# Requirements:
1012
# From --hosts parameter:
1113
# - host(A1): an XCP-ng host
@@ -59,18 +61,12 @@ def test_passing(self, defer: Defer, empty_network: Network, imported_vm: VM, vm
5961
vm_writer.ssh(f"ip addr add 192.168.42.1/24 dev {ifaceW}.42")
6062
vm_writer.ssh(f"ip link set {ifaceW}.42 up")
6163

62-
# send some packets on VLAN 42 (ARP packets will be send)
63-
# the ping process could be still running after the test,
64-
# but vm_writer will be destroyed, so it isn't a problem.
65-
vm_writer.ssh("ping -c1 -w1 192.168.42.2", background=True, check=False)
66-
67-
# check packets are seen on vm_reader
68-
# fail if /tmp/out is empty
69-
vm_reader.ssh(
70-
f"tcpdump -i {ifaceR} -w /tmp/out -c1 -n 'vlan 42 and arp' &"
71-
"pid=$! ; sleep 5 ; kill $pid ;"
72-
"test -s /tmp/out"
73-
)
64+
with tcpdump(defer, "tcpdump.pcap", vm_reader, ifaceR, "vlan 42 and arp", count=1):
65+
# send some packets on VLAN 42 (ARP packets will be send)
66+
vm_writer.ssh("ping -c1 -w1 192.168.42.2", check=False)
67+
68+
# check packets are seen on vm_reader (trunks=42)
69+
vm_reader.ssh("test $(tcpdump -n -r tcpdump.pcap | wc -l) -gt 0")
7470

7571
def test_filtered(self, defer: Defer, empty_network: Network, imported_vm: VM, vm_with_tcpdump_scope_function: VM):
7672
vm_writer, ifaceW = start_vm_on_trunk(
@@ -95,15 +91,9 @@ def test_filtered(self, defer: Defer, empty_network: Network, imported_vm: VM, v
9591
vm_writer.ssh(f"ip addr add 192.168.42.1/24 dev {ifaceW}.42")
9692
vm_writer.ssh(f"ip link set {ifaceW}.42 up")
9793

98-
# send some packets on VLAN 42 (ARP packets will be send)
99-
# the ping process could be still running after the test,
100-
# but vm_writer will be destroyed, so it isn't a problem.
101-
vm_writer.ssh("ping -c1 -w1 192.168.42.2", background=True, check=False)
102-
103-
# check packets are seen on vm_reader
104-
# fail if /tmp/out is not empty
105-
vm_reader.ssh(
106-
f"tcpdump -i {ifaceR} -w /tmp/out -c1 -n 'vlan 42 and arp' &"
107-
"pid=$! ; sleep 5 ; kill $pid ;"
108-
"test ! -s /tmp/out"
109-
)
94+
with tcpdump(defer, "tcpdump.pcap", vm_reader, ifaceR, "vlan 42 and arp", count=1):
95+
# send some packets on VLAN 42 (ARP packets will be send)
96+
vm_writer.ssh("ping -c1 -w1 192.168.42.2", check=False)
97+
98+
# check packets are *NOT* seen on vm_reader (trunks=52)
99+
vm_reader.ssh("test $(tcpdump -n -r tcpdump.pcap | wc -l) -eq 0")

0 commit comments

Comments
 (0)