diff --git a/osbuild/api.py b/osbuild/api.py index e2fee3ed..d4ece715 100644 --- a/osbuild/api.py +++ b/osbuild/api.py @@ -91,9 +91,13 @@ class BaseAPI(abc.ABC): self.event_loop.run_forever() self.event_loop.remove_reader(server) + @property + def running(self): + return self.event_loop is not None + def __enter__(self): # We are not re-entrant, so complain if re-entered. - assert self.event_loop is None + assert not self.running if not self.socket_address: self._socketdir = self._make_socket_dir() @@ -141,6 +145,13 @@ class API(BaseAPI): @property def output(self): + # Only once the event-loop was stopped, you are guaranteed that the + # api-thread scheduled all outstanding events. Therefore, we disallow + # asking for the output-data from a running api context. If we happen + # to need live streaming access to the output in the future, we need + # to redesign the output-handling, anyway. + assert not self.running + return self._output_data.getvalue() def _prepare_input(self): diff --git a/osbuild/pipeline.py b/osbuild/pipeline.py index 0cf1746f..1b63b3f1 100644 --- a/osbuild/pipeline.py +++ b/osbuild/pipeline.py @@ -91,7 +91,7 @@ class Stage: binds=[os.fspath(tree) + ":/run/osbuild/tree"], readonly_binds=ro_binds) - return BuildResult(self, r.returncode, api.output, api.metadata) + return BuildResult(self, r.returncode, api.output, api.metadata) class Assembler: @@ -149,7 +149,7 @@ class Assembler: binds=binds, readonly_binds=ro_binds) - return BuildResult(self, r.returncode, api.output, api.metadata) + return BuildResult(self, r.returncode, api.output, api.metadata) class Pipeline: diff --git a/test/mod/test_monitor.py b/test/mod/test_monitor.py index 8004a76b..01d84e77 100644 --- a/test/mod/test_monitor.py +++ b/test/mod/test_monitor.py @@ -73,12 +73,13 @@ class TestMonitor(unittest.TestCase): path = os.path.join(tmpdir, "osbuild-api") logfile = os.path.join(tmpdir, "log.txt") - with open(logfile, "w") as log, \ - API(args, LogMonitor(log.fileno()), socket_address=path) as api: - p = mp.Process(target=echo, args=(path, )) - p.start() - p.join() - self.assertEqual(p.exitcode, 0) + with open(logfile, "w") as log: + api = API(args, LogMonitor(log.fileno()), socket_address=path) + with api as api: + p = mp.Process(target=echo, args=(path, )) + p.start() + p.join() + self.assertEqual(p.exitcode, 0) output = api.output # pylint: disable=no-member assert output