]> git.ipfire.org Git - thirdparty/psycopg.git/commitdiff
test: add test to generate an EINTR in wait_c
authorDaniele Varrazzo <daniele.varrazzo@gmail.com>
Tue, 24 Oct 2023 08:50:40 +0000 (10:50 +0200)
committerDaniele Varrazzo <daniele.varrazzo@gmail.com>
Tue, 24 Oct 2023 10:54:05 +0000 (12:54 +0200)
tests/test_concurrency.py
tests/test_concurrency_async.py

index 137232a433067c79bc76f3a2c2e86a9220ade9b4..f8266633784431d1619d459e172a24da6238cd8c 100644 (file)
@@ -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(
index 8afb1f3e67e4a15d28ad805b80b4e3ec47bd91b0..150d7747793f2b82d4355ae9f28c450de92c38a6 100644 (file)
@@ -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(