From 662fe0feb9c3fd2843b34501900d466272aac776 Mon Sep 17 00:00:00 2001 From: Christian Kellner Date: Fri, 24 Sep 2021 09:13:58 +0000 Subject: [PATCH] test/host: checks for invalid fd handling Check that we properly handle `dispatch` returning invalid fds and that all fds are properly closed. --- test/mod/test_host.py | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/test/mod/test_host.py b/test/mod/test_host.py index bf36b51b..d2157a2b 100755 --- a/test/mod/test_host.py +++ b/test/mod/test_host.py @@ -4,6 +4,7 @@ # Runtime Tests for Host Services # +import errno import os import sys import tempfile @@ -17,6 +18,13 @@ from osbuild.util.jsoncomm import FdSet class ServiceTest(host.Service): + def __init__(self, args): + super().__init__(args) + self.fds = [] + + def register_fds(self, fds): + self.fds.extend(fds) + def dispatch(self, method: str, args: Any, fds: FdSet): ret = None @@ -31,9 +39,28 @@ class ServiceTest(host.Service): f.write(d.read()) f.seek(0) fds = [os.dup(f.fileno())] + self.register_fds(fds) elif method == "identify": ret = self.id + elif method == "invalid-fd": + ret = [] + with tempfile.TemporaryFile("w+") as f: + valid_fd = os.dup(f.fileno()) + invalid_fd = valid_fd + 10 + fds = [valid_fd, invalid_fd] + self.register_fds([valid_fd]) + elif method == "check-fds-are-closed": + while self.fds: + fd = self.fds.pop() + try: + os.close(fd) + except OSError as e: + if e.errno == errno.EBADF: + print(f"fd '{fd}' was closed") + continue + raise + raise ValueError(f"fd '{fd}' was not closed") else: raise host.ProtocolError("unknown method:", method) @@ -79,6 +106,8 @@ def test_pass_fd(): with os.fdopen(fds.steal(0)) as d: assert data == d.read() + client.call_with_fds("check-fds-are-closed") + remote_id = client.call("identify") assert remote_id == str(i) @@ -90,6 +119,15 @@ def test_pass_fd(): client.stop() +def test_pass_fd_invalid(): + with host.ServiceManager() as mgr: + + client = mgr.start(str("test-invalid-fd"), __file__) + with pytest.raises(host.RemoteError): + client.call_with_fds("invalid-fd") + client.call_with_fds("check-fds-are-closed") + + def test_exception(): with host.ServiceManager() as mgr: client = mgr.start("exception", __file__)