diff --git a/osbuild/util/jsoncomm.py b/osbuild/util/jsoncomm.py index 15ea27c0..e06e3147 100644 --- a/osbuild/util/jsoncomm.py +++ b/osbuild/util/jsoncomm.py @@ -254,6 +254,24 @@ class Socket(contextlib.AbstractContextManager): return cls(sock, (unlink, path[1])) + @classmethod + def new_pair(cls, *, blocking=True): + """Create a connected socket pair + + Create a pair of connected sockets and return both as a tuple. + + Parameters + ---------- + blocking + The blocking mode for the socket pair. + """ + a, b = socket.socketpair(socket.AF_UNIX, socket.SOCK_SEQPACKET) + + a.setblocking(blocking) + b.setblocking(blocking) + + return cls(a, None), cls(b, None) + def fileno(self) -> int: assert self._socket is not None return self._socket.fileno() diff --git a/test/mod/test_util_jsoncomm.py b/test/mod/test_util_jsoncomm.py index 99f4d5a2..04cd071b 100644 --- a/test/mod/test_util_jsoncomm.py +++ b/test/mod/test_util_jsoncomm.py @@ -176,3 +176,13 @@ class TestUtilJsonComm(unittest.TestCase): conn = listener.accept() self.assertIsNone(conn) + + def test_socket_pair(self): + # + # Test creating a socket pair and sending, receiving of a simple message + a, b = jsoncomm.Socket.new_pair() + + ping = {"osbuild": "yes"} + a.send(ping) + pong, _, _ = b.recv() + self.assertEqual(ping, pong)