Added possibility to skip a test only on certain crdb versions

This commit is contained in:
Daniele Varrazzo 2020-08-17 23:08:05 +01:00
parent 5d2e51e76e
commit f339bb30fb

View File

@ -29,6 +29,7 @@ import sys
import types import types
import ctypes import ctypes
import select import select
import operator
import platform import platform
import unittest import unittest
from functools import wraps from functools import wraps
@ -438,7 +439,7 @@ def crdb_version(conn, __crdb_version=[]):
return __crdb_version[0] return __crdb_version[0]
def skip_if_crdb(reason, conn=None): def skip_if_crdb(reason, conn=None, version=None):
"""Skip a test or test class if we are testing against CockroachDB. """Skip a test or test class if we are testing against CockroachDB.
Can be used as a decorator for tests function or classes: Can be used as a decorator for tests function or classes:
@ -448,23 +449,29 @@ def skip_if_crdb(reason, conn=None):
# ... # ...
Or as a normal function if the *conn* argument is passed. Or as a normal function if the *conn* argument is passed.
If *version* is specified it should be a string such as ">= 20.1", "< 20",
"== 20.1.3": the test will be skipped only if the version matches.
""" """
if not isinstance(reason, str): if not isinstance(reason, str):
raise TypeError("reason should be a string, got %r instead" % reason) raise TypeError("reason should be a string, got %r instead" % reason)
if conn is not None: if conn is not None:
if crdb_version(conn) is not None: ver = crdb_version(conn)
if ver is not None and _crdb_match_version(ver, version):
if reason in crdb_reasons: if reason in crdb_reasons:
reason = ( reason = (
"%s (https://github.com/cockroachdb/cockroach/issues/%s)" "%s (https://github.com/cockroachdb/cockroach/issues/%s)"
% (reason, crdb_reasons[reason])) % (reason, crdb_reasons[reason]))
raise unittest.SkipTest("not supported on CockroachDB: %s" % reason) raise unittest.SkipTest(
"not supported on CockroachDB %s: %s" % (ver, reason))
@decorate_all_tests @decorate_all_tests
def skip_if_crdb_(f): def skip_if_crdb_(f):
@wraps(f) @wraps(f)
def skip_if_crdb__(self, *args, **kwargs): def skip_if_crdb__(self, *args, **kwargs):
skip_if_crdb(reason, self.connect()) skip_if_crdb(reason, conn=self.connect(), version=version)
return f(self, *args, **kwargs) return f(self, *args, **kwargs)
return skip_if_crdb__ return skip_if_crdb__
@ -495,6 +502,22 @@ crdb_reasons = {
} }
def _crdb_match_version(version, pattern):
if pattern is None:
return True
m = re.match(r'^(>|>=|<|<=|==|!=)\s*(\d+)(?:\.(\d+))?(?:\.(\d+))?$', pattern)
if m is None:
raise ValueError(
"bad crdb version pattern %r: should be 'OP MAJOR[.MINOR[.BUGFIX]]'"
% pattern)
ops = {'>': 'gt', '>=': 'ge', '<': 'lt', '<=': 'le', '==': 'eq', '!=': 'ne'}
op = getattr(operator, ops[m.group(1)])
ref = int(m.group(2)) * 10000 + int(m.group(3) or 0) * 100 + int(m.group(4) or 0)
return op(version, ref)
class py3_raises_typeerror(object): class py3_raises_typeerror(object):
def __enter__(self): def __enter__(self):
pass pass