From: Daniele Varrazzo Date: Tue, 24 Oct 2023 08:50:40 +0000 (+0200) Subject: test: add test to generate an EINTR in wait_c X-Git-Tag: pool-3.1.9~3^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=df561941310efea6f222e05b8fa7e4a460cda4da;p=thirdparty%2Fpsycopg.git test: add test to generate an EINTR in wait_c --- diff --git a/tests/test_concurrency.py b/tests/test_concurrency.py index c059f0de3..f9a14a7d5 100644 --- a/tests/test_concurrency.py +++ b/tests/test_concurrency.py @@ -361,6 +361,48 @@ with psycopg.connect({dsn!r}, application_name={APPNAME!r}) as conn: assert t1 - t0 < 1.0 +@pytest.mark.slow +@pytest.mark.subprocess +@pytest.mark.parametrize("itimername, signame", [("ITIMER_REAL", "SIGALRM")]) +def test_eintr(dsn, itimername, signame): + try: + itimer = int(getattr(signal, itimername)) + sig = int(getattr(signal, signame)) + except AttributeError: + pytest.skip(f"unknown interrupt timer: {itimername}") + + script = f"""\ +import signal +import psycopg + +def signal_handler(signum, frame): + assert signum == {sig!r} + +# Install a handler for the signal +signal.signal({sig!r}, signal_handler) + +# Restart system calls interrupted by the signal +signal.siginterrupt({sig!r}, False) + + +with psycopg.connect({dsn!r}) as conn: + # Fire an interrupt signal every 0.25 seconds + signal.setitimer({itimer!r}, 0.25, 0.25) + + cur = conn.cursor() + cur.execute("select 'ok' from pg_sleep(0.5)") + print(cur.fetchone()[0]) +""" + cp = sp.run( + [sys.executable, "-s"], input=script, text=True, stdout=sp.PIPE, stderr=sp.PIPE + ) + assert "InterruptedError" not in cp.stderr + assert ( + cp.returncode == 0 + ), f"script terminated with {signal.Signals(abs(cp.returncode)).name}" + assert cp.stdout.rstrip() == "ok" + + @pytest.mark.slow @pytest.mark.subprocess @pytest.mark.skipif( diff --git a/tests/test_concurrency_async.py b/tests/test_concurrency_async.py index b87fb5023..469c88228 100644 --- a/tests/test_concurrency_async.py +++ b/tests/test_concurrency_async.py @@ -316,6 +316,52 @@ asyncio.run(main()) assert t1 - t0 < 1.0 +@pytest.mark.slow +@pytest.mark.subprocess +@pytest.mark.parametrize("itimername, signame", [("ITIMER_REAL", "SIGALRM")]) +def test_eintr(dsn, itimername, signame): + try: + itimer = int(getattr(signal, itimername)) + sig = int(getattr(signal, signame)) + except AttributeError: + pytest.skip(f"unknown interrupt timer: {itimername}") + + script = f"""\ +import signal +import asyncio +import psycopg + +def signal_handler(signum, frame): + assert signum == {sig!r} + +# Install a handler for the signal +signal.signal({sig!r}, signal_handler) + +# Restart system calls interrupted by the signal +signal.siginterrupt({sig!r}, False) + + +async def main(): + async with await psycopg.AsyncConnection.connect({dsn!r}) as conn: + # Fire an interrupt signal every 0.25 seconds + signal.setitimer({itimer!r}, 0.25, 0.25) + + cur = conn.cursor() + await cur.execute("select 'ok' from pg_sleep(0.5)") + print((await cur.fetchone())[0]) + +asyncio.run(main()) +""" + cp = sp.run( + [sys.executable, "-s"], input=script, text=True, stdout=sp.PIPE, stderr=sp.PIPE + ) + assert "InterruptedError" not in cp.stderr + assert ( + cp.returncode == 0 + ), f"script terminated with {signal.Signals(abs(cp.returncode)).name}" + assert cp.stdout.rstrip() == "ok" + + @pytest.mark.slow @pytest.mark.crdb("skip") @pytest.mark.skipif(