git: 67557372dfef - main - tests: make sniffer more robust

From: Kristof Provost <kp_at_FreeBSD.org>
Date: Wed, 02 Nov 2022 13:18:09 UTC
The branch main has been updated by kp:

URL: https://cgit.FreeBSD.org/src/commit/?id=67557372dfef87eb94681a97a4157198efe21992

commit 67557372dfef87eb94681a97a4157198efe21992
Author:     Kristof Provost <kp@FreeBSD.org>
AuthorDate: 2022-11-02 10:55:39 +0000
Commit:     Kristof Provost <kp@FreeBSD.org>
CommitDate: 2022-11-02 10:59:10 +0000

    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")
---
 tests/sys/netpfil/common/sniffer.py | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/tests/sys/netpfil/common/sniffer.py b/tests/sys/netpfil/common/sniffer.py
index a7ebfc122573..5e09a2e4db37 100644
--- a/tests/sys/netpfil/common/sniffer.py
+++ b/tests/sys/netpfil/common/sniffer.py
@@ -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 @@ class Sniffer(threading.Thread):
 		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 @@ class Sniffer(threading.Thread):
 			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)