mirror of https://github.com/apache/cassandra
update Python test framework from nose to pytest
patch by Brad Schoening; reviewed by Brandon Williams, Berenguer Blasi and Stefan Miklosovic for CASSANDRA-17293
This commit is contained in:
parent
d96c32b0b3
commit
db35833182
|
|
@ -1,4 +1,5 @@
|
|||
4.1
|
||||
* update Python test framework from nose to pytest (CASSANDRA-17293)
|
||||
* Fix improper CDC commit log segments deletion in non-blocking mode (CASSANDRA-17233)
|
||||
* Add support for string concatenations through the + operator (CASSANDRA-17190)
|
||||
* Limit the maximum hints size per host (CASSANDRA-17142)
|
||||
|
|
|
|||
|
|
@ -9,7 +9,18 @@ This directory contains code primarily for cqlsh. cqlsh uses cqlshlib in this di
|
|||
|
||||
== Running tests
|
||||
|
||||
In order to run tests for cqlshlib, run cassandra-cqlsh-tests.sh in this directory. It will
|
||||
The following environment variables can be configured for the database connection -
|
||||
|
||||
. CQL_TEST_HOST, default 127.0.0.1
|
||||
. CQL_TEST_PORT, default 9042
|
||||
. CQL_TEST_USER, default 'cassandra'
|
||||
. CQL_TEST_PWD
|
||||
|
||||
You can run tests with a local Cassandra server simply by -
|
||||
|
||||
$ pytest
|
||||
|
||||
In order to run tests in a virtual environment for cqlshlib, run cassandra-cqlsh-tests.sh in this directory. It will
|
||||
automatically setup a virtualenv with the appropriate version of Python and run tests inside it.
|
||||
|
||||
There are Dockerfiles that can be used to test whether cqlsh works with a default, barebones
|
||||
|
|
|
|||
|
|
@ -24,21 +24,13 @@
|
|||
################################
|
||||
|
||||
WORKSPACE=$1
|
||||
PYTHON_VERSION=$2
|
||||
|
||||
if [ "${WORKSPACE}" = "" ]; then
|
||||
echo "Specify Cassandra source directory"
|
||||
exit
|
||||
fi
|
||||
|
||||
if [ "${PYTHON_VERSION}" = "" ]; then
|
||||
PYTHON_VERSION=python3
|
||||
fi
|
||||
|
||||
if [ "${PYTHON_VERSION}" != "python3" -a "${PYTHON_VERSION}" != "python2" ]; then
|
||||
echo "Specify Python version python3 or python2"
|
||||
exit
|
||||
fi
|
||||
PYTHON_VERSION=python3
|
||||
|
||||
export PYTHONIOENCODING="utf-8"
|
||||
export PYTHONUNBUFFERED=true
|
||||
|
|
@ -126,14 +118,10 @@ ccm start --wait-for-binary-proto
|
|||
cd ${CASSANDRA_DIR}/pylib/cqlshlib/
|
||||
|
||||
set +e # disable immediate exit from this point
|
||||
nosetests
|
||||
pytest
|
||||
RETURN="$?"
|
||||
|
||||
ccm remove
|
||||
# hack around --xunit-prefix-with-testsuite-name not being available in nose 1.3.7
|
||||
sed -i "s/testsuite name=\"nosetests\"/testsuite name=\"${TESTSUITE_NAME}\"/g" nosetests.xml
|
||||
sed -i "s/testcase classname=\"cqlshlib./testcase classname=\"${TESTSUITE_NAME}./g" nosetests.xml
|
||||
mv nosetests.xml ${WORKSPACE}/cqlshlib.xml
|
||||
|
||||
################################
|
||||
#
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@
|
|||
# regex in-pattern flags. Any of those can break correct operation of Scanner.
|
||||
|
||||
import re
|
||||
import six
|
||||
from sre_constants import BRANCH, SUBPATTERN, GROUPREF, GROUPREF_IGNORE, GROUPREF_EXISTS
|
||||
from sys import version_info
|
||||
|
||||
|
|
@ -50,23 +49,6 @@ class SaferScannerBase(re.Scanner):
|
|||
return re.sre_parse.SubPattern(sub.pattern, scrubbedsub)
|
||||
|
||||
|
||||
class Py2SaferScanner(SaferScannerBase):
|
||||
|
||||
def __init__(self, lexicon, flags=0):
|
||||
self.lexicon = lexicon
|
||||
p = []
|
||||
s = re.sre_parse.Pattern()
|
||||
s.flags = flags
|
||||
for phrase, action in lexicon:
|
||||
p.append(re.sre_parse.SubPattern(s, [
|
||||
(SUBPATTERN, (len(p) + 1, self.subpat(phrase, flags))),
|
||||
]))
|
||||
s.groups = len(p) + 1
|
||||
p = re.sre_parse.SubPattern(s, [(BRANCH, (None, p))])
|
||||
self.p = p
|
||||
self.scanner = re.sre_compile.compile(p)
|
||||
|
||||
|
||||
class Py36SaferScanner(SaferScannerBase):
|
||||
|
||||
def __init__(self, lexicon, flags=0):
|
||||
|
|
@ -99,5 +81,4 @@ class Py38SaferScanner(SaferScannerBase):
|
|||
self.scanner = re.sre_compile.compile(p)
|
||||
|
||||
|
||||
SaferScanner = Py36SaferScanner if six.PY3 else Py2SaferScanner
|
||||
SaferScanner = Py38SaferScanner if version_info >= (3, 8) else SaferScanner
|
||||
SaferScanner = Py38SaferScanner if version_info >= (3, 8) else Py36SaferScanner
|
||||
|
|
|
|||
|
|
@ -1,4 +0,0 @@
|
|||
[nosetests]
|
||||
verbosity=3
|
||||
detailed-errors=1
|
||||
with-xunit=1
|
||||
|
|
@ -58,7 +58,7 @@ def ssl_settings(host, config_file, env=os.environ):
|
|||
for protocol in ['PROTOCOL_TLS', 'PROTOCOL_TLSv1_2', 'PROTOCOL_TLSv1_1', 'PROTOCOL_TLSv1']:
|
||||
if hasattr(ssl, protocol):
|
||||
return getattr(ssl, protocol)
|
||||
return None
|
||||
return ssl.PROTOCOL_TLS
|
||||
|
||||
ssl_validate = env.get('SSL_VALIDATE')
|
||||
if ssl_validate is None:
|
||||
|
|
|
|||
|
|
@ -29,14 +29,10 @@ path_to_cqlsh = join(cqlsh_dir, 'cqlsh.py')
|
|||
|
||||
sys.path.append(cqlsh_dir)
|
||||
|
||||
import cqlsh
|
||||
|
||||
cql = cqlsh.cassandra.cluster.Cluster
|
||||
policy = cqlsh.cassandra.policies.RoundRobinPolicy()
|
||||
quote_name = cqlsh.cassandra.metadata.maybe_escape_name
|
||||
|
||||
TEST_HOST = os.environ.get('CQL_TEST_HOST', '127.0.0.1')
|
||||
TEST_PORT = int(os.environ.get('CQL_TEST_PORT', 9042))
|
||||
TEST_USER = os.environ.get('CQL_TEST_USER', 'cassandra')
|
||||
TEST_PWD = os.environ.get('CQL_TEST_PWD')
|
||||
|
||||
|
||||
class BaseTestCase(unittest.TestCase):
|
||||
|
|
|
|||
|
|
@ -20,16 +20,24 @@ import io
|
|||
import os.path
|
||||
import random
|
||||
import string
|
||||
from nose.tools import nottest
|
||||
|
||||
from .basecase import TEST_HOST, TEST_PORT, cql, cqlsh, cqlshlog, policy, quote_name, test_dir
|
||||
from cassandra.cluster import Cluster
|
||||
from cassandra.policies import RoundRobinPolicy
|
||||
from cassandra.metadata import maybe_escape_name as quote_name
|
||||
from cassandra.auth import PlainTextAuthProvider
|
||||
from cqlshlib.cql3handling import CqlRuleSet
|
||||
|
||||
from .basecase import TEST_HOST, TEST_PORT, TEST_USER, TEST_PWD, cqlshlog, test_dir
|
||||
from .run_cqlsh import run_cqlsh, call_cqlsh
|
||||
|
||||
test_keyspace_init = os.path.join(test_dir, 'test_keyspace_init.cql')
|
||||
|
||||
|
||||
def get_cassandra_connection(cql_version=None):
|
||||
conn = cql((TEST_HOST,), TEST_PORT, cql_version=cql_version, load_balancing_policy=policy)
|
||||
|
||||
auth_provider = PlainTextAuthProvider(username=TEST_USER, password=TEST_PWD)
|
||||
conn = Cluster((TEST_HOST,), TEST_PORT, auth_provider=auth_provider, cql_version=cql_version, load_balancing_policy=RoundRobinPolicy())
|
||||
|
||||
# until the cql lib does this for us
|
||||
conn.cql_version = cql_version
|
||||
return conn
|
||||
|
|
@ -118,7 +126,8 @@ def cassandra_connection(cql_version=None):
|
|||
try:
|
||||
yield conn
|
||||
finally:
|
||||
conn.close()
|
||||
conn.shutdown()
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def cassandra_cursor(cql_version=None, ks=''):
|
||||
|
|
@ -146,13 +155,13 @@ def cassandra_cursor(cql_version=None, ks=''):
|
|||
|
||||
|
||||
def cql_rule_set():
|
||||
return cqlsh.cql3handling.CqlRuleSet
|
||||
return CqlRuleSet
|
||||
|
||||
|
||||
class DEFAULTVAL: pass
|
||||
|
||||
|
||||
@nottest
|
||||
__TEST__ = False
|
||||
def testrun_cqlsh(keyspace=DEFAULTVAL, **kwargs):
|
||||
# use a positive default sentinel so that keyspace=None can be used
|
||||
# to override the default behavior
|
||||
|
|
@ -161,7 +170,7 @@ def testrun_cqlsh(keyspace=DEFAULTVAL, **kwargs):
|
|||
return run_cqlsh(keyspace=keyspace, **kwargs)
|
||||
|
||||
|
||||
@nottest
|
||||
__TEST__ = False
|
||||
def testcall_cqlsh(keyspace=None, **kwargs):
|
||||
if keyspace is None:
|
||||
keyspace = get_keyspace()
|
||||
|
|
|
|||
|
|
@ -21,9 +21,10 @@
|
|||
import locale
|
||||
import os
|
||||
import re
|
||||
from .basecase import BaseTestCase, cqlsh
|
||||
from .basecase import BaseTestCase
|
||||
from .cassconnect import create_db, remove_db, testrun_cqlsh
|
||||
from .run_cqlsh import TimeoutError
|
||||
from cqlshlib.cql3handling import CqlRuleSet
|
||||
|
||||
BEL = '\x07' # the terminal-bell character
|
||||
CTRL_C = '\x03'
|
||||
|
|
@ -152,12 +153,11 @@ class CqlshCompletionCase(BaseTestCase):
|
|||
|
||||
|
||||
def strategies(self):
|
||||
return self.module.CqlRuleSet.replication_strategies
|
||||
return CqlRuleSet.replication_strategies
|
||||
|
||||
|
||||
class TestCqlshCompletion(CqlshCompletionCase):
|
||||
cqlver = '3.1.6'
|
||||
module = cqlsh.cql3handling
|
||||
|
||||
def test_complete_on_empty_string(self):
|
||||
self.trycompletions('', choices=('?', 'ALTER', 'BEGIN', 'CAPTURE', 'CONSISTENCY',
|
||||
|
|
|
|||
|
|
@ -22,11 +22,9 @@ from __future__ import unicode_literals, with_statement
|
|||
import locale
|
||||
import os
|
||||
import re
|
||||
import six
|
||||
import unittest
|
||||
|
||||
from .basecase import (BaseTestCase, TEST_HOST, TEST_PORT,
|
||||
at_a_time, cqlsh, cqlshlog, dedent)
|
||||
at_a_time, cqlshlog, dedent)
|
||||
from .cassconnect import (cassandra_cursor, create_db, get_keyspace,
|
||||
quote_name, remove_db, split_cql_commands,
|
||||
testcall_cqlsh, testrun_cqlsh)
|
||||
|
|
|
|||
|
|
@ -17,12 +17,13 @@
|
|||
from cassandra.policies import SimpleConvictionPolicy
|
||||
from cassandra.pool import Host
|
||||
from cqlshlib.sslhandling import ssl_settings
|
||||
from nose.tools import assert_raises
|
||||
import pytest
|
||||
|
||||
import unittest
|
||||
import os
|
||||
import ssl
|
||||
|
||||
|
||||
class SslSettingsTest(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
|
|
@ -53,9 +54,9 @@ class SslSettingsTest(unittest.TestCase):
|
|||
|
||||
def test_invalid_ssl_versions_from_env(self):
|
||||
msg = "invalid_ssl is not a valid SSL protocol, please use one of TLSv1, TLSv1_1, or TLSv1_2"
|
||||
with assert_raises(SystemExit) as error:
|
||||
with pytest.raises(SystemExit) as error:
|
||||
self._test_ssl_version_from_env('invalid_ssl')
|
||||
assert msg == error.exception.message
|
||||
assert msg == error.args[0]
|
||||
|
||||
def test_default_ssl_version(self):
|
||||
ssl_ret_val = ssl_settings(self.host, self.config_file)
|
||||
|
|
@ -69,7 +70,6 @@ class SslSettingsTest(unittest.TestCase):
|
|||
|
||||
def test_invalid_ssl_version_config(self):
|
||||
msg = "invalid_ssl is not a valid SSL protocol, please use one of TLSv1, TLSv1_1, or TLSv1_2"
|
||||
with assert_raises(SystemExit) as error:
|
||||
with pytest.raises(SystemExit) as error:
|
||||
ssl_settings(self.host, os.path.join('test', 'config', 'sslhandling_invalid.config'))
|
||||
assert msg in error.exception.message
|
||||
|
||||
|
|
@ -11,8 +11,7 @@ decorator
|
|||
docopt
|
||||
flaky
|
||||
mock
|
||||
nose
|
||||
nose-test-select
|
||||
parse
|
||||
pycodestyle
|
||||
psutil
|
||||
pycodestyle
|
||||
pytest
|
||||
|
|
|
|||
Loading…
Reference in New Issue