tests: make sniffer more robust

The Sniffer class is often used by test tools such as pft_ping to verify
that packets actually get sent where they're expected.

It starts a background thread to capture packets, but this thread needs
some time to start, leading to intermittent test failures when the
capture doesn't start before the relevant packet is sent.

Add a semaphore to ensure the Sniffer constructor doesn't return until
the capture is actually running.

PR:		260461
MFC after:	1 week
Sponsored by:	Rubicon Communications, LLC ("Netgate")
This commit is contained in:
Kristof Provost 2022-11-02 11:55:39 +01:00
parent fd6b681e45
commit 67557372df

View file

@ -34,6 +34,7 @@ class Sniffer(threading.Thread):
def __init__(self, args, check_function, recvif=None, timeout=3):
threading.Thread.__init__(self)
self._sem = threading.Semaphore(0)
self._args = args
self._timeout = timeout
if recvif is not None:
@ -44,6 +45,8 @@ def __init__(self, args, check_function, recvif=None, timeout=3):
self.foundCorrectPacket = False
self.start()
if not self._sem.acquire(timeout=30):
raise Exception("Failed to start sniffer")
def _checkPacket(self, packet):
ret = self._check_function(self._args, packet)
@ -51,10 +54,14 @@ def _checkPacket(self, packet):
self.foundCorrectPacket = True
return ret
def _startedCb(self):
self._sem.release()
def run(self):
self.packets = []
try:
self.packets = sp.sniff(iface=self._recvif,
stop_filter=self._checkPacket, timeout=self._timeout)
stop_filter=self._checkPacket, timeout=self._timeout,
started_callback=self._startedCb)
except Exception as e:
print(e, file=sys.stderr)