Skip to content

Commit

Permalink
tests: Use fork instead of forkserver
Browse files Browse the repository at this point in the history
Make sure test can be successfully run on pyton 3.14.

According to
https://docs.python.org/dev/whatsnew/3.14.html#multiprocessing

The default start method (see Contexts and start methods) changed from
fork to forkserver on platforms other than macOS & Windows where it was
already spawn. If you require the threading incompatible fork start
method you must explicitly request it using a context from
multiprocessing.get_context() (preferred) or change the default via
multiprocessing.set_start_method().

See also https://bugzilla.redhat.com/show_bug.cgi?id=2326934 for
reference on the reported bug for the Fedora package.

Signed-off-by: Matteo Centenaro <[email protected]>
  • Loading branch information
bugant committed Feb 13, 2025
1 parent 95c4b68 commit 76de3d1
Showing 1 changed file with 19 additions and 10 deletions.
29 changes: 19 additions & 10 deletions tests/test_multiprocessing.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,14 @@ def r(self, request):
valkey.Valkey, request=request, single_connection_client=False
)

def test_close_connection_in_child(self, master_host):
@pytest.fixture()
def multiprocessing_ctx(self):
curr_start_method = multiprocessing.get_start_method(allow_none=False)
if curr_start_method == "forkserver":
return multiprocessing.get_context("fork")
return multiprocessing.get_context(curr_start_method)

def test_close_connection_in_child(self, master_host, multiprocessing_ctx):
"""
A connection owned by a parent and closed by a child doesn't
destroy the file descriptors so a parent can still use it.
Expand All @@ -43,7 +50,7 @@ def target(conn):
assert conn.read_response() == b"PONG"
conn.disconnect()

proc = multiprocessing.Process(target=target, args=(conn,))
proc = multiprocessing_ctx.Process(target=target, args=(conn,))
proc.start()
proc.join(3)
assert proc.exitcode == 0
Expand All @@ -55,7 +62,7 @@ def target(conn):
conn.send_command("ping")
assert conn.read_response() == b"PONG"

def test_close_connection_in_parent(self, master_host):
def test_close_connection_in_parent(self, master_host, multiprocessing_ctx):
"""
A connection owned by a parent is unusable by a child if the parent
(the owning process) closes the connection.
Expand All @@ -73,7 +80,7 @@ def target(conn, ev):
conn.send_command("ping")

ev = multiprocessing.Event()
proc = multiprocessing.Process(target=target, args=(conn, ev))
proc = multiprocessing_ctx.Process(target=target, args=(conn, ev))
proc.start()

conn.disconnect()
Expand All @@ -83,7 +90,7 @@ def target(conn, ev):
assert proc.exitcode == 0

@pytest.mark.parametrize("max_connections", [1, 2, None])
def test_pool(self, max_connections, master_host):
def test_pool(self, max_connections, master_host, multiprocessing_ctx):
"""
A child will create its own connections when using a pool created
by a parent.
Expand All @@ -107,7 +114,7 @@ def target(pool):
assert conn.send_command("ping") is None
assert conn.read_response() == b"PONG"

proc = multiprocessing.Process(target=target, args=(pool,))
proc = multiprocessing_ctx.Process(target=target, args=(pool,))
proc.start()
proc.join(3)
assert proc.exitcode == 0
Expand All @@ -120,7 +127,9 @@ def target(pool):
assert conn.read_response() == b"PONG"

@pytest.mark.parametrize("max_connections", [1, 2, None])
def test_close_pool_in_main(self, max_connections, master_host):
def test_close_pool_in_main(
self, max_connections, master_host, multiprocessing_ctx
):
"""
A child process that uses the same pool as its parent isn't affected
when the parent disconnects all connections within the pool.
Expand All @@ -145,23 +154,23 @@ def target(pool, disconnect_event):

ev = multiprocessing.Event()

proc = multiprocessing.Process(target=target, args=(pool, ev))
proc = multiprocessing_ctx.Process(target=target, args=(pool, ev))
proc.start()

pool.disconnect()
ev.set()
proc.join(3)
assert proc.exitcode == 0

def test_valkey_client(self, r):
def test_valkey_client(self, r, multiprocessing_ctx):
"A valkey client created in a parent can also be used in a child"
assert r.ping() is True

def target(client):
assert client.ping() is True
del client

proc = multiprocessing.Process(target=target, args=(r,))
proc = multiprocessing_ctx.Process(target=target, args=(r,))
proc.start()
proc.join(3)
assert proc.exitcode == 0
Expand Down

0 comments on commit 76de3d1

Please sign in to comment.