diff mbox series

[3/8] test-runner: fix UML blocking on wait_for_socket/service

Message ID 20220624230741.1957863-3-prestwoj@gmail.com (mailing list archive)
State Accepted, archived
Headers show
Series [1/8] test-runner: remove reference to missing class member | expand

Commit Message

James Prestwood June 24, 2022, 11:07 p.m. UTC
In UML if any process dies while test-runner is waiting for the DBus
service or some socket to be available it will block forever. This
is due to the way the non_block_wait works.

Its not optimal but it essentially polls over some input function
until the conditions are met. And, depending on the input function,
this can cause UML to hang since it never has a chance to go idle
and advance the time clock.

This can be fixed, at least for services/sockets, by sleeping in
the input function allowing time to pass. This will then allow
test-runner to bail out with an exception.

This patch adds a new wait_for_service function which handles this
automatically, and wait_for_socket was refactored to behave
similarly.
---
 autotests/util/iwd.py |  3 ---
 tools/run-tests       |  5 ++---
 tools/utils.py        | 26 ++++++++++++++++++++++++--
 3 files changed, 26 insertions(+), 8 deletions(-)
diff mbox series

Patch

diff --git a/autotests/util/iwd.py b/autotests/util/iwd.py
index f609e37e..aae57733 100755
--- a/autotests/util/iwd.py
+++ b/autotests/util/iwd.py
@@ -1097,9 +1097,6 @@  class IWD(AsyncOpAbstract):
             self._iwd_proc = self.namespace.start_iwd(iwd_config_dir,
                                                         iwd_storage_dir)
 
-        ctx.non_block_wait(self._bus.name_has_owner, 20, IWD_SERVICE,
-                                exception=TimeoutError('IWD has failed to start'))
-
         self._devices = DeviceList(self)
 
         # Weak to make sure the test's reference to @self is the only counted
diff --git a/tools/run-tests b/tools/run-tests
index 2b3b1f2e..565847df 100755
--- a/tools/run-tests
+++ b/tools/run-tests
@@ -326,9 +326,8 @@  class TestContext(Namespace):
 			# register hwsim as medium
 			args.extend(['--no-register'])
 
-		self.start_process(args)
-		self.non_block_wait(self._bus.name_has_owner, 20, 'net.connman.hwsim',
-					exception=TimeoutError('net.connman.hwsim did not appear'))
+		proc = self.start_process(args)
+		proc.wait_for_service(self, 'net.connman.hwsim', 20)
 
 		for i in range(nradios):
 			name = 'rad%u' % i
diff --git a/tools/utils.py b/tools/utils.py
index 7272c1f9..f3e12a85 100644
--- a/tools/utils.py
+++ b/tools/utils.py
@@ -9,6 +9,7 @@  import dbus
 from gi.repository import GLib
 from weakref import WeakValueDictionary
 from re import fullmatch
+from time import sleep
 
 from runner import RunnerCoreArgParse
 
@@ -213,7 +214,24 @@  class Process(subprocess.Popen):
 		self.write_fds.append(f)
 
 	def wait_for_socket(self, socket, wait):
-		Namespace.non_block_wait(os.path.exists, wait, socket)
+		def _wait(socket):
+			if not os.path.exists(socket):
+				sleep(0.1)
+				return False
+			return True
+
+		Namespace.non_block_wait(_wait, wait, socket,
+				exception=Exception("Timed out waiting for %s" % socket))
+
+	def wait_for_service(self, ns, service, wait):
+		def _wait(ns, service):
+			if not ns._bus.name_has_owner(service):
+				sleep(0.1)
+				return False
+			return True
+
+		Namespace.non_block_wait(_wait, wait, ns, service,
+				exception=Exception("Timed out waiting for %s" % service))
 
 	# Wait for both process termination and HUP signal
 	def __wait(self, timeout):
@@ -423,7 +441,11 @@  class Namespace:
 		if Process.is_verbose('iwd-rtnl'):
 			env['IWD_RTNL_DEBUG'] = '1'
 
-		return self.start_process(args, env=env)
+		proc = self.start_process(args, env=env)
+
+		proc.wait_for_service(self, 'net.connman.iwd', 20)
+
+		return proc
 
 	@staticmethod
 	def non_block_wait(func, timeout, *args, exception=True):