Move some common test markers to the fix_crdb module.
Remaining cursor failing test may require some tweak:
- something with binary parameters
- something with ::text cast added by crdb dumper
+import pytest
+
from .utils import check_version
return rv
+# Utility functions which can be imported in the test suite
+
+
+def is_crdb(conn):
+ if hasattr(conn, "pgconn"):
+ conn = conn.pgconn
+
+ return bool(conn.parameter_status(b"crdb_version"))
+
+
+def skip_crdb(*args, reason=None):
+ return pytest.param(*args, marks=pytest.mark.crdb("skip", reason=reason))
+
+
+def crdb_encoding(*args):
+ """Mark tests that fail on CockroachDB because of missing encodings"""
+ return skip_crdb(*args, reason="encoding")
+
+
+def crdb_time_precision(*args):
+ """Mark tests that fail on CockroachDB because time doesn't support precision"""
+ return skip_crdb(*args, reason="time precision")
+
+
# mapping from reason description to ticket number
crdb_reasons = {
"2-phase commit": 22329,
from .utils import gc_collect
from .test_cursor import my_row_factory
+from .fix_crdb import is_crdb, crdb_encoding, crdb_time_precision
@pytest.fixture
assert cur.pgresult.get_value(0, 0) == b"1"
-@pytest.mark.parametrize("encoding", ["utf8", "latin9"])
+@pytest.mark.parametrize("encoding", ["utf8", crdb_encoding("latin9")])
def test_query_encode(conn, encoding):
conn.execute(f"set client_encoding to {encoding}")
cur = conn.cursor()
assert res == "\u20ac"
-def test_query_badenc(conn):
- conn.execute("set client_encoding to latin1")
+@pytest.mark.parametrize("encoding", [crdb_encoding("latin1")])
+def test_query_badenc(conn, encoding):
+ conn.execute(f"set client_encoding to {encoding}")
cur = conn.cursor()
with pytest.raises(UnicodeEncodeError):
cur.execute("select '\u20ac'")
assert cur._query.params == (b"3", b"4")
+@pytest.mark.crdb("skip", reason="copy")
@pytest.mark.parametrize("ph, params", [("%s", (10,)), ("%(n)s", {"n": 10})])
def test_copy_out_param(conn, ph, params):
cur = conn.cursor()
assert c.name == "now"
assert c.type_code == builtins["date"].oid
assert c.display_size is None
- assert c.internal_size == 4
+ if is_crdb(conn):
+ assert c.internal_size == 16
+ else:
+ assert c.internal_size == 4
assert c.precision is None
assert c.scale is None
("numeric(10)", 10, 0, None, None),
("numeric(10, 3)", 10, 3, None, None),
("time", None, None, None, 8),
- ("time(4)", 4, None, None, 8),
- ("time(10)", 6, None, None, 8),
+ crdb_time_precision("time(4)", 4, None, None, 8),
+ crdb_time_precision("time(10)", 6, None, None, 8),
],
)
def test_details(self, conn, type, precision, scale, dsize, isize):
unpickled = pickle.loads(pickled)
assert [tuple(d) for d in description] == [tuple(d) for d in unpickled]
+ @pytest.mark.crdb("skip", reason="no col query")
def test_no_col_query(self, conn):
cur = conn.execute("select")
assert cur.description == []
assert res == "x"
assert cur.description[0].name == "foo-bar"
- @pytest.mark.parametrize("encoding", ["utf8", "latin9"])
+ @pytest.mark.parametrize("encoding", ["utf8", crdb_encoding("latin9")])
def test_name_encode(self, conn, encoding):
conn.execute(f"set client_encoding to {encoding}")
cur = conn.cursor()
q = cur.mogrify("select %s, %s", [1, dt.date(2020, 1, 1)])
assert q == "select 1, '2020-01-01'::date"
- conn.execute("set client_encoding to utf8")
- q = cur.mogrify("select %(s)s", {"s": "\u20ac"})
- assert q == "select '\u20ac'"
- conn.execute("set client_encoding to latin9")
- q = cur.mogrify("select %(s)s", {"s": "\u20ac"})
+@pytest.mark.parametrize("encoding", ["utf8", crdb_encoding("latin9")])
+def test_mogrify_encoding(conn, encoding):
+ conn.execute(f"set client_encoding to {encoding}")
+ q = conn.cursor().mogrify("select %(s)s", {"s": "\u20ac"})
assert q == "select '\u20ac'"
- conn.execute("set client_encoding to latin1")
+
+@pytest.mark.parametrize("encoding", [crdb_encoding("latin1")])
+def test_mogrify_badenc(conn, encoding):
+ conn.execute(f"set client_encoding to {encoding}")
with pytest.raises(UnicodeEncodeError):
- cur.mogrify("select %(s)s", {"s": "\u20ac"})
+ conn.cursor().mogrify("select %(s)s", {"s": "\u20ac"})
@pytest.mark.libpq(">= 14")
from .utils import alist, gc_collect
from .test_cursor import my_row_factory
from .test_cursor import execmany, _execmany # noqa: F401
+from .fix_crdb import crdb_encoding
execmany = execmany # avoid F811 underneath
pytestmark = pytest.mark.asyncio
assert cur.pgresult.get_value(0, 0) == b"1"
-@pytest.mark.parametrize("encoding", ["utf8", "latin9"])
+@pytest.mark.parametrize("encoding", ["utf8", crdb_encoding("latin9")])
async def test_query_encode(aconn, encoding):
await aconn.execute(f"set client_encoding to {encoding}")
cur = aconn.cursor()
assert res == "\u20ac"
-async def test_query_badenc(aconn):
- await aconn.execute("set client_encoding to latin1")
+@pytest.mark.parametrize("encoding", [crdb_encoding("latin1")])
+async def test_query_badenc(aconn, encoding):
+ await aconn.execute(f"set client_encoding to {encoding}")
cur = aconn.cursor()
with pytest.raises(UnicodeEncodeError):
await cur.execute("select '\u20ac'")
assert cur._query.params == (b"3", b"4")
+@pytest.mark.crdb("skip", reason="copy")
@pytest.mark.parametrize("ph, params", [("%s", (10,)), ("%(n)s", {"n": 10})])
async def test_copy_out_param(aconn, ph, params):
cur = aconn.cursor()
q = cur.mogrify("select %s, %s", [1, dt.date(2020, 1, 1)])
assert q == "select 1, '2020-01-01'::date"
- await aconn.execute("set client_encoding to utf8")
- q = cur.mogrify("select %(s)s", {"s": "\u20ac"})
- assert q == "select '\u20ac'"
- await aconn.execute("set client_encoding to latin9")
- q = cur.mogrify("select %(s)s", {"s": "\u20ac"})
+@pytest.mark.parametrize("encoding", ["utf8", crdb_encoding("latin9")])
+async def test_mogrify_encoding(aconn, encoding):
+ await aconn.execute(f"set client_encoding to {encoding}")
+ q = aconn.cursor().mogrify("select %(s)s", {"s": "\u20ac"})
assert q == "select '\u20ac'"
- await aconn.execute("set client_encoding to latin1")
+
+@pytest.mark.parametrize("encoding", [crdb_encoding("latin1")])
+async def test_mogrify_badenc(aconn, encoding):
+ await aconn.execute(f"set client_encoding to {encoding}")
with pytest.raises(UnicodeEncodeError):
- cur.mogrify("select %(s)s", {"s": "\u20ac"})
+ aconn.cursor().mogrify("select %(s)s", {"s": "\u20ac"})
@pytest.mark.libpq(">= 14")
from psycopg.conninfo import resolve_hostaddr_async
from psycopg._encodings import pg2pyenc
-snowman = "\u2603"
-
+from .fix_crdb import crdb_encoding
-def skip_crdb(*args, reason=None):
- return pytest.param(*args, marks=pytest.mark.crdb("skip", reason=reason))
+snowman = "\u2603"
class MyString(str):
with pytest.raises(psycopg.OperationalError):
conn.info.error_message
- @pytest.mark.crdb("skip", reason="always 0 on crdb")
+ @pytest.mark.crdb("skip", reason="backend pid")
def test_backend_pid(self, conn):
assert conn.info.backend_pid
assert conn.info.backend_pid == conn.pgconn.backend_pid
("utf8", "UTF8", "utf-8"),
("utf-8", "UTF8", "utf-8"),
("utf_8", "UTF8", "utf-8"),
- skip_crdb("eucjp", "EUC_JP", "euc_jp", reason="encoding"),
- skip_crdb("euc-jp", "EUC_JP", "euc_jp", reason="encoding"),
+ crdb_encoding("eucjp", "EUC_JP", "euc_jp"),
+ crdb_encoding("euc-jp", "EUC_JP", "euc_jp"),
],
)
def test_encoding_env_var(self, dsn, monkeypatch, enc, out, codec):
from psycopg.rows import RowMaker
from .utils import gc_collect
+from .fix_crdb import is_crdb, crdb_encoding, crdb_time_precision
def test_init(conn):
assert cur.pgresult.get_value(0, 0) == b"1"
-@pytest.mark.parametrize("encoding", ["utf8", "latin9"])
+@pytest.mark.parametrize("encoding", ["utf8", crdb_encoding("latin9")])
def test_query_encode(conn, encoding):
conn.execute(f"set client_encoding to {encoding}")
cur = conn.cursor()
assert res == "\u20ac"
-def test_query_badenc(conn):
- conn.execute("set client_encoding to latin1")
+@pytest.mark.parametrize("encoding", [crdb_encoding("latin1")])
+def test_query_badenc(conn, encoding):
+ conn.execute(f"set client_encoding to {encoding}")
cur = conn.cursor()
with pytest.raises(UnicodeEncodeError):
cur.execute("select '\u20ac'")
assert recs == []
+@pytest.mark.crdb("skip", reason="no col query")
def test_stream_no_col(conn):
cur = conn.cursor()
recs = list(cur.stream("select"))
assert c.name == "now"
assert c.type_code == builtins["date"].oid
assert c.display_size is None
- assert c.internal_size == 4
+ if is_crdb(conn):
+ assert c.internal_size == 16
+ else:
+ assert c.internal_size == 4
assert c.precision is None
assert c.scale is None
("numeric(10)", 10, 0, None, None),
("numeric(10, 3)", 10, 3, None, None),
("time", None, None, None, 8),
- ("time(4)", 4, None, None, 8),
- ("time(10)", 6, None, None, 8),
+ crdb_time_precision("time(4)", 4, None, None, 8),
+ crdb_time_precision("time(10)", 6, None, None, 8),
],
)
def test_details(self, conn, type, precision, scale, dsize, isize):
unpickled = pickle.loads(pickled)
assert [tuple(d) for d in description] == [tuple(d) for d in unpickled]
+ @pytest.mark.crdb("skip", reason="no col query")
def test_no_col_query(self, conn):
cur = conn.execute("select")
assert cur.description == []
assert res == "x"
assert cur.description[0].name == "foo-bar"
- @pytest.mark.parametrize("encoding", ["utf8", "latin9"])
+ @pytest.mark.parametrize("encoding", ["utf8", crdb_encoding("latin9")])
def test_name_encode(self, conn, encoding):
conn.execute(f"set client_encoding to {encoding}")
cur = conn.cursor()
from .utils import gc_collect
from .test_cursor import my_row_factory
from .test_cursor import execmany, _execmany # noqa: F401
+from .fix_crdb import crdb_encoding
execmany = execmany # avoid F811 underneath
pytestmark = pytest.mark.asyncio
assert cur.pgresult.get_value(0, 0) == b"1"
-@pytest.mark.parametrize("encoding", ["utf8", "latin9"])
+@pytest.mark.parametrize("encoding", ["utf8", crdb_encoding("latin9")])
async def test_query_encode(aconn, encoding):
await aconn.execute(f"set client_encoding to {encoding}")
cur = aconn.cursor()
assert res == "\u20ac"
-async def test_query_badenc(aconn):
- await aconn.execute("set client_encoding to latin1")
+@pytest.mark.parametrize("encoding", [crdb_encoding("latin1")])
+async def test_query_badenc(aconn, encoding):
+ await aconn.execute(f"set client_encoding to {encoding}")
cur = aconn.cursor()
with pytest.raises(UnicodeEncodeError):
await cur.execute("select '\u20ac'")