]> git.ipfire.org Git - thirdparty/psycopg.git/commitdiff
Added leak test for async cursor
authorDaniele Varrazzo <daniele.varrazzo@gmail.com>
Sat, 16 Jan 2021 02:35:20 +0000 (03:35 +0100)
committerDaniele Varrazzo <daniele.varrazzo@gmail.com>
Sat, 16 Jan 2021 10:26:19 +0000 (11:26 +0100)
Leak and correctness tests separated.

tests/test_adapt.py
tests/test_cursor.py
tests/test_cursor_async.py

index 366a49b1970e2c689bebfab7704aa5fa46319083..222538cda3fb9f7c65f683bcd9fa2cf763db3355 100644 (file)
@@ -291,6 +291,27 @@ def test_optimised_adapters():
     assert not c_adapters
 
 
+@pytest.mark.slow
+@pytest.mark.parametrize("fmt", [Format.AUTO, Format.TEXT, Format.BINARY])
+def test_random(conn, faker, fmt):
+    if fmt != Format.BINARY:
+        pytest.xfail("faker to extend to all text dumpers")
+
+    faker.format = fmt
+    faker.choose_schema(ncols=20)
+    faker.make_records(50)
+
+    with conn.cursor(binary=Format.as_pq(fmt)) as cur:
+        cur.execute(faker.drop_stmt)
+        cur.execute(faker.create_stmt)
+        cur.executemany(faker.insert_stmt, faker.records)
+        cur.execute(faker.select_stmt)
+        recs = cur.fetchall()
+
+    for got, want in zip(recs, faker.records):
+        faker.assert_record(got, want)
+
+
 class MyStr(str):
     pass
 
index b731ef94cd64c81ab79ad09ab5863c029a1b648c..11629afc4966f2c909fc0ea5ced6106f0db1f036 100644 (file)
@@ -423,29 +423,23 @@ def test_leak(dsn, faker, fmt, fetch):
                 cur.executemany(faker.insert_stmt, faker.records)
                 cur.execute(faker.select_stmt)
 
-                recs = []
                 if fetch == "one":
                     while 1:
                         tmp = cur.fetchone()
                         if tmp is None:
                             break
-                        recs.append(tmp)
                 elif fetch == "many":
                     while 1:
                         tmp = cur.fetchmany(3)
                         if not tmp:
                             break
-                        recs.extend(tmp)
                 elif fetch == "all":
-                    recs.extend(cur.fetchall())
+                    cur.fetchall()
                 elif fetch == "iter":
                     for rec in cur:
-                        recs.append(rec)
+                        pass
 
-                for got, want in zip(recs, faker.records):
-                    faker.assert_record(got, want)
-
-                recs = tmp = None
+                tmp = None
 
         del cur, conn
         gc.collect()
index c35e019e08ba69b24b7c7e1804bc6de17bbbb72b..c9b7f1fee40e30c202d12353a9f7b76aa451b716 100644 (file)
@@ -314,3 +314,51 @@ async def test_str(aconn):
     await cur.close()
     assert "[closed]" in str(cur)
     assert "[INTRANS]" in str(cur)
+
+
+@pytest.mark.slow
+@pytest.mark.parametrize("fmt", [Format.AUTO, Format.TEXT, Format.BINARY])
+@pytest.mark.parametrize("fetch", ["one", "many", "all", "iter"])
+async def test_leak(dsn, faker, fmt, fetch):
+    if fmt != Format.BINARY:
+        pytest.xfail("faker to extend to all text dumpers")
+
+    faker.format = fmt
+    faker.choose_schema(ncols=5)
+    faker.make_records(10)
+
+    n = []
+    for i in range(3):
+        async with await psycopg3.AsyncConnection.connect(dsn) as conn:
+            async with await conn.cursor(binary=Format.as_pq(fmt)) as cur:
+                await cur.execute(faker.drop_stmt)
+                await cur.execute(faker.create_stmt)
+                await cur.executemany(faker.insert_stmt, faker.records)
+                await cur.execute(faker.select_stmt)
+
+                if fetch == "one":
+                    while 1:
+                        tmp = await cur.fetchone()
+                        if tmp is None:
+                            break
+                elif fetch == "many":
+                    while 1:
+                        tmp = await cur.fetchmany(3)
+                        if not tmp:
+                            break
+                elif fetch == "all":
+                    await cur.fetchall()
+                elif fetch == "iter":
+                    async for rec in cur:
+                        pass
+
+                tmp = None
+
+        del cur, conn
+        gc.collect()
+        gc.collect()
+        n.append(len(gc.get_objects()))
+
+    assert (
+        n[0] == n[1] == n[2]
+    ), f"objects leaked: {n[1] - n[0]}, {n[2] - n[1]}"