diff --git a/.gitignore b/.gitignore index 30ff731f85..7983f44b87 100644 --- a/.gitignore +++ b/.gitignore @@ -11,7 +11,6 @@ build MANIFEST dist .coverage -nosetests.xml cover/ docs/_build/ tests/integration/ccm diff --git a/.travis.yml b/.travis.yml index 5a483f9a03..859394584c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,6 +6,7 @@ python: - "3.8" - "3.9" - "3.10" + - "3.11" env: - CASS_DRIVER_NO_CYTHON=1 diff --git a/Jenkinsfile b/Jenkinsfile index 444b0f48b8..b43cf6c659 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -261,9 +261,9 @@ def executeStandardTests() { . ${HOME}/environment.txt set +o allexport - EVENT_LOOP=${EVENT_LOOP} VERIFY_CYTHON=${CYTHON_ENABLED} pynose -s -v --logging-format="[%(levelname)s] %(asctime)s %(thread)d: %(message)s" --with-ignore-docstrings --with-xunit --xunit-file=unit_results.xml tests/unit/ || true - EVENT_LOOP=eventlet VERIFY_CYTHON=${CYTHON_ENABLED} pynose -s -v --logging-format="[%(levelname)s] %(asctime)s %(thread)d: %(message)s" --with-ignore-docstrings --with-xunit --xunit-file=unit_eventlet_results.xml tests/unit/io/test_eventletreactor.py || true - EVENT_LOOP=gevent VERIFY_CYTHON=${CYTHON_ENABLED} pynose -s -v --logging-format="[%(levelname)s] %(asctime)s %(thread)d: %(message)s" --with-ignore-docstrings --with-xunit --xunit-file=unit_gevent_results.xml tests/unit/io/test_geventreactor.py || true + EVENT_LOOP=${EVENT_LOOP} VERIFY_CYTHON=${CYTHON_ENABLED} JVM_EXTRA_OPTS="$JVM_EXTRA_OPTS -Xss384k" pytest -s -v --log-format="[%(levelname)s] %(asctime)s %(thread)d: %(message)s" --junit-xml=unit_results.xml tests/unit/ || true + EVENT_LOOP_MANAGER=eventlet VERIFY_CYTHON=${CYTHON_ENABLED} JVM_EXTRA_OPTS="$JVM_EXTRA_OPTS -Xss384k" pytest -s -v --log-format="[%(levelname)s] %(asctime)s %(thread)d: %(message)s" --junit-xml=unit_eventlet_results.xml tests/unit/io/test_eventletreactor.py || true + EVENT_LOOP_MANAGER=gevent VERIFY_CYTHON=${CYTHON_ENABLED} JVM_EXTRA_OPTS="$JVM_EXTRA_OPTS -Xss384k" pytest -s -v --log-format="[%(levelname)s] %(asctime)s %(thread)d: %(message)s" --junit-xml=unit_gevent_results.xml tests/unit/io/test_geventreactor.py || true ''' sh label: 'Execute Simulacron integration tests', script: '''#!/bin/bash -lex @@ -276,13 +276,13 @@ def executeStandardTests() { jabba use 1.8 SIMULACRON_JAR="${HOME}/simulacron.jar" - SIMULACRON_JAR=${SIMULACRON_JAR} EVENT_LOOP=${EVENT_LOOP} CASSANDRA_DIR=${CCM_INSTALL_DIR} CCM_ARGS="${CCM_ARGS}" DSE_VERSION=${DSE_VERSION} CASSANDRA_VERSION=${CCM_CASSANDRA_VERSION} MAPPED_CASSANDRA_VERSION=${MAPPED_CASSANDRA_VERSION} VERIFY_CYTHON=${CYTHON_ENABLED} pynose -s -v --logging-format="[%(levelname)s] %(asctime)s %(thread)d: %(message)s" --with-ignore-docstrings --with-xunit --exclude test_backpressure.py --xunit-file=simulacron_results.xml tests/integration/simulacron/ || true + SIMULACRON_JAR=${SIMULACRON_JAR} EVENT_LOOP=${EVENT_LOOP} CASSANDRA_DIR=${CCM_INSTALL_DIR} CCM_ARGS="${CCM_ARGS}" DSE_VERSION=${DSE_VERSION} CASSANDRA_VERSION=${CCM_CASSANDRA_VERSION} MAPPED_CASSANDRA_VERSION=${MAPPED_CASSANDRA_VERSION} VERIFY_CYTHON=${CYTHON_ENABLED} JVM_EXTRA_OPTS="$JVM_EXTRA_OPTS -Xss384k" pytest -s -v --log-format="[%(levelname)s] %(asctime)s %(thread)d: %(message)s" --ignore=test_backpressure.py --junit-xml=simulacron_results.xml tests/integration/simulacron/ || true # Run backpressure tests separately to avoid memory issue - SIMULACRON_JAR=${SIMULACRON_JAR} EVENT_LOOP=${EVENT_LOOP} CASSANDRA_DIR=${CCM_INSTALL_DIR} CCM_ARGS="${CCM_ARGS}" DSE_VERSION=${DSE_VERSION} CASSANDRA_VERSION=${CCM_CASSANDRA_VERSION} MAPPED_CASSANDRA_VERSION=${MAPPED_CASSANDRA_VERSION} VERIFY_CYTHON=${CYTHON_ENABLED} pynose -s -v --logging-format="[%(levelname)s] %(asctime)s %(thread)d: %(message)s" --with-ignore-docstrings --with-xunit --exclude test_backpressure.py --xunit-file=simulacron_backpressure_1_results.xml tests/integration/simulacron/test_backpressure.py:TCPBackpressureTests.test_paused_connections || true - SIMULACRON_JAR=${SIMULACRON_JAR} EVENT_LOOP=${EVENT_LOOP} CASSANDRA_DIR=${CCM_INSTALL_DIR} CCM_ARGS="${CCM_ARGS}" DSE_VERSION=${DSE_VERSION} CASSANDRA_VERSION=${CCM_CASSANDRA_VERSION} MAPPED_CASSANDRA_VERSION=${MAPPED_CASSANDRA_VERSION} VERIFY_CYTHON=${CYTHON_ENABLED} pynose -s -v --logging-format="[%(levelname)s] %(asctime)s %(thread)d: %(message)s" --with-ignore-docstrings --with-xunit --exclude test_backpressure.py --xunit-file=simulacron_backpressure_2_results.xml tests/integration/simulacron/test_backpressure.py:TCPBackpressureTests.test_queued_requests_timeout || true - SIMULACRON_JAR=${SIMULACRON_JAR} EVENT_LOOP=${EVENT_LOOP} CASSANDRA_DIR=${CCM_INSTALL_DIR} CCM_ARGS="${CCM_ARGS}" DSE_VERSION=${DSE_VERSION} CASSANDRA_VERSION=${CCM_CASSANDRA_VERSION} MAPPED_CASSANDRA_VERSION=${MAPPED_CASSANDRA_VERSION} VERIFY_CYTHON=${CYTHON_ENABLED} pynose -s -v --logging-format="[%(levelname)s] %(asctime)s %(thread)d: %(message)s" --with-ignore-docstrings --with-xunit --exclude test_backpressure.py --xunit-file=simulacron_backpressure_3_results.xml tests/integration/simulacron/test_backpressure.py:TCPBackpressureTests.test_cluster_busy || true - SIMULACRON_JAR=${SIMULACRON_JAR} EVENT_LOOP=${EVENT_LOOP} CASSANDRA_DIR=${CCM_INSTALL_DIR} CCM_ARGS="${CCM_ARGS}" DSE_VERSION=${DSE_VERSION} CASSANDRA_VERSION=${CCM_CASSANDRA_VERSION} MAPPED_CASSANDRA_VERSION=${MAPPED_CASSANDRA_VERSION} VERIFY_CYTHON=${CYTHON_ENABLED} pynose -s -v --logging-format="[%(levelname)s] %(asctime)s %(thread)d: %(message)s" --with-ignore-docstrings --with-xunit --exclude test_backpressure.py --xunit-file=simulacron_backpressure_4_results.xml tests/integration/simulacron/test_backpressure.py:TCPBackpressureTests.test_node_busy || true + SIMULACRON_JAR=${SIMULACRON_JAR} EVENT_LOOP=${EVENT_LOOP} CASSANDRA_DIR=${CCM_INSTALL_DIR} CCM_ARGS="${CCM_ARGS}" DSE_VERSION=${DSE_VERSION} CASSANDRA_VERSION=${CCM_CASSANDRA_VERSION} MAPPED_CASSANDRA_VERSION=${MAPPED_CASSANDRA_VERSION} VERIFY_CYTHON=${CYTHON_ENABLED} JVM_EXTRA_OPTS="$JVM_EXTRA_OPTS -Xss384k" pytest -s -v --log-format="[%(levelname)s] %(asctime)s %(thread)d: %(message)s" --ignore=test_backpressure.py --junit-xml=simulacron_backpressure_1_results.xml tests/integration/simulacron/test_backpressure.py:TCPBackpressureTests.test_paused_connections || true + SIMULACRON_JAR=${SIMULACRON_JAR} EVENT_LOOP=${EVENT_LOOP} CASSANDRA_DIR=${CCM_INSTALL_DIR} CCM_ARGS="${CCM_ARGS}" DSE_VERSION=${DSE_VERSION} CASSANDRA_VERSION=${CCM_CASSANDRA_VERSION} MAPPED_CASSANDRA_VERSION=${MAPPED_CASSANDRA_VERSION} VERIFY_CYTHON=${CYTHON_ENABLED} JVM_EXTRA_OPTS="$JVM_EXTRA_OPTS -Xss384k" pytest -s -v --log-format="[%(levelname)s] %(asctime)s %(thread)d: %(message)s" --ignore=test_backpressure.py --junit-xml=simulacron_backpressure_2_results.xml tests/integration/simulacron/test_backpressure.py:TCPBackpressureTests.test_queued_requests_timeout || true + SIMULACRON_JAR=${SIMULACRON_JAR} EVENT_LOOP=${EVENT_LOOP} CASSANDRA_DIR=${CCM_INSTALL_DIR} CCM_ARGS="${CCM_ARGS}" DSE_VERSION=${DSE_VERSION} CASSANDRA_VERSION=${CCM_CASSANDRA_VERSION} MAPPED_CASSANDRA_VERSION=${MAPPED_CASSANDRA_VERSION} VERIFY_CYTHON=${CYTHON_ENABLED} JVM_EXTRA_OPTS="$JVM_EXTRA_OPTS -Xss384k" pytest -s -v --log-format="[%(levelname)s] %(asctime)s %(thread)d: %(message)s" --ignore=test_backpressure.py --junit-xml=simulacron_backpressure_3_results.xml tests/integration/simulacron/test_backpressure.py:TCPBackpressureTests.test_cluster_busy || true + SIMULACRON_JAR=${SIMULACRON_JAR} EVENT_LOOP=${EVENT_LOOP} CASSANDRA_DIR=${CCM_INSTALL_DIR} CCM_ARGS="${CCM_ARGS}" DSE_VERSION=${DSE_VERSION} CASSANDRA_VERSION=${CCM_CASSANDRA_VERSION} MAPPED_CASSANDRA_VERSION=${MAPPED_CASSANDRA_VERSION} VERIFY_CYTHON=${CYTHON_ENABLED} JVM_EXTRA_OPTS="$JVM_EXTRA_OPTS -Xss384k" pytest -s -v --log-format="[%(levelname)s] %(asctime)s %(thread)d: %(message)s" --ignore=test_backpressure.py --junit-xml=simulacron_backpressure_4_results.xml tests/integration/simulacron/test_backpressure.py:TCPBackpressureTests.test_node_busy || true ''' sh label: 'Execute CQL engine integration tests', script: '''#!/bin/bash -lex @@ -294,7 +294,7 @@ def executeStandardTests() { . ${JABBA_SHELL} jabba use 1.8 - EVENT_LOOP=${EVENT_LOOP} CCM_ARGS="${CCM_ARGS}" DSE_VERSION=${DSE_VERSION} CASSANDRA_VERSION=${CCM_CASSANDRA_VERSION} MAPPED_CASSANDRA_VERSION=${MAPPED_CASSANDRA_VERSION} VERIFY_CYTHON=${CYTHON_ENABLED} pynose -s -v --logging-format="[%(levelname)s] %(asctime)s %(thread)d: %(message)s" --with-ignore-docstrings --with-xunit --xunit-file=cqle_results.xml tests/integration/cqlengine/ || true + EVENT_LOOP=${EVENT_LOOP} CCM_ARGS="${CCM_ARGS}" DSE_VERSION=${DSE_VERSION} CASSANDRA_VERSION=${CCM_CASSANDRA_VERSION} MAPPED_CASSANDRA_VERSION=${MAPPED_CASSANDRA_VERSION} VERIFY_CYTHON=${CYTHON_ENABLED} JVM_EXTRA_OPTS="$JVM_EXTRA_OPTS -Xss384k" pytest -s -v --log-format="[%(levelname)s] %(asctime)s %(thread)d: %(message)s" --junit-xml=cqle_results.xml tests/integration/cqlengine/ || true ''' sh label: 'Execute Apache CassandraⓇ integration tests', script: '''#!/bin/bash -lex @@ -306,7 +306,7 @@ def executeStandardTests() { . ${JABBA_SHELL} jabba use 1.8 - EVENT_LOOP=${EVENT_LOOP} CCM_ARGS="${CCM_ARGS}" DSE_VERSION=${DSE_VERSION} CASSANDRA_VERSION=${CCM_CASSANDRA_VERSION} MAPPED_CASSANDRA_VERSION=${MAPPED_CASSANDRA_VERSION} VERIFY_CYTHON=${CYTHON_ENABLED} pynose -s -v --logging-format="[%(levelname)s] %(asctime)s %(thread)d: %(message)s" --with-ignore-docstrings --with-xunit --xunit-file=standard_results.xml tests/integration/standard/ || true + EVENT_LOOP=${EVENT_LOOP} CCM_ARGS="${CCM_ARGS}" DSE_VERSION=${DSE_VERSION} CASSANDRA_VERSION=${CCM_CASSANDRA_VERSION} MAPPED_CASSANDRA_VERSION=${MAPPED_CASSANDRA_VERSION} VERIFY_CYTHON=${CYTHON_ENABLED} JVM_EXTRA_OPTS="$JVM_EXTRA_OPTS -Xss384k" pytest -s -v --log-format="[%(levelname)s] %(asctime)s %(thread)d: %(message)s" --junit-xml=standard_results.xml tests/integration/standard/ || true ''' if (env.CASSANDRA_VERSION.split('-')[0] == 'dse' && env.CASSANDRA_VERSION.split('-')[1] != '4.8') { @@ -323,7 +323,7 @@ def executeStandardTests() { . ${JABBA_SHELL} jabba use 1.8 - EVENT_LOOP=${EVENT_LOOP} CASSANDRA_DIR=${CCM_INSTALL_DIR} DSE_VERSION=${DSE_VERSION} ADS_HOME="${HOME}/" VERIFY_CYTHON=${CYTHON_ENABLED} pynose -s -v --logging-format="[%(levelname)s] %(asctime)s %(thread)d: %(message)s" --with-ignore-docstrings --with-xunit --xunit-file=dse_results.xml tests/integration/advanced/ || true + EVENT_LOOP=${EVENT_LOOP} CASSANDRA_DIR=${CCM_INSTALL_DIR} DSE_VERSION=${DSE_VERSION} ADS_HOME="${HOME}/" VERIFY_CYTHON=${CYTHON_ENABLED} JVM_EXTRA_OPTS="$JVM_EXTRA_OPTS -Xss384k" pytest -s -v --log-format="[%(levelname)s] %(asctime)s %(thread)d: %(message)s" --junit-xml=dse_results.xml tests/integration/advanced/ || true ''' } } @@ -337,7 +337,7 @@ def executeStandardTests() { . ${JABBA_SHELL} jabba use 1.8 - EVENT_LOOP=${EVENT_LOOP} CLOUD_PROXY_PATH="${HOME}/proxy/" CASSANDRA_VERSION=${CCM_CASSANDRA_VERSION} MAPPED_CASSANDRA_VERSION=${MAPPED_CASSANDRA_VERSION} VERIFY_CYTHON=${CYTHON_ENABLED} pynose -s -v --logging-format="[%(levelname)s] %(asctime)s %(thread)d: %(message)s" --with-ignore-docstrings --with-xunit --xunit-file=advanced_results.xml tests/integration/cloud/ || true + EVENT_LOOP=${EVENT_LOOP} CLOUD_PROXY_PATH="${HOME}/proxy/" CASSANDRA_VERSION=${CCM_CASSANDRA_VERSION} MAPPED_CASSANDRA_VERSION=${MAPPED_CASSANDRA_VERSION} VERIFY_CYTHON=${CYTHON_ENABLED} JVM_EXTRA_OPTS="$JVM_EXTRA_OPTS -Xss384k" pytest -s -v --log-format="[%(levelname)s] %(asctime)s %(thread)d: %(message)s" --junit-xml=advanced_results.xml tests/integration/cloud/ || true ''' if (env.PROFILE == 'FULL') { @@ -350,7 +350,7 @@ def executeStandardTests() { . ${JABBA_SHELL} jabba use 1.8 - EVENT_LOOP=${EVENT_LOOP} CCM_ARGS="${CCM_ARGS}" DSE_VERSION=${DSE_VERSION} CASSANDRA_VERSION=${CCM_CASSANDRA_VERSION} MAPPED_CASSANDRA_VERSION=${MAPPED_CASSANDRA_VERSION} VERIFY_CYTHON=${CYTHON_ENABLED} pynose -s -v --logging-format="[%(levelname)s] %(asctime)s %(thread)d: %(message)s" --exclude-dir=tests/integration/long/upgrade --with-ignore-docstrings --with-xunit --xunit-file=long_results.xml tests/integration/long/ || true + EVENT_LOOP=${EVENT_LOOP} CCM_ARGS="${CCM_ARGS}" DSE_VERSION=${DSE_VERSION} CASSANDRA_VERSION=${CCM_CASSANDRA_VERSION} MAPPED_CASSANDRA_VERSION=${MAPPED_CASSANDRA_VERSION} VERIFY_CYTHON=${CYTHON_ENABLED} JVM_EXTRA_OPTS="$JVM_EXTRA_OPTS -Xss384k" pytest -s -v --log-format="[%(levelname)s] %(asctime)s %(thread)d: %(message)s" --ignore=tests/integration/long/upgrade --junit-xml=long_results.xml tests/integration/long/ || true ''' } } @@ -365,7 +365,7 @@ def executeDseSmokeTests() { . ${JABBA_SHELL} jabba use 1.8 - EVENT_LOOP=${EVENT_LOOP} CCM_ARGS="${CCM_ARGS}" CASSANDRA_VERSION=${CCM_CASSANDRA_VERSION} DSE_VERSION=${DSE_VERSION} MAPPED_CASSANDRA_VERSION=${MAPPED_CASSANDRA_VERSION} VERIFY_CYTHON=${CYTHON_ENABLED} pynose -s -v --logging-format="[%(levelname)s] %(asctime)s %(thread)d: %(message)s" --with-ignore-docstrings --with-xunit --xunit-file=standard_results.xml tests/integration/standard/test_dse.py || true + EVENT_LOOP=${EVENT_LOOP} CCM_ARGS="${CCM_ARGS}" CASSANDRA_VERSION=${CCM_CASSANDRA_VERSION} DSE_VERSION=${DSE_VERSION} MAPPED_CASSANDRA_VERSION=${MAPPED_CASSANDRA_VERSION} VERIFY_CYTHON=${CYTHON_ENABLED} JVM_EXTRA_OPTS="$JVM_EXTRA_OPTS -Xss384k" pytest -s -v --log-format="[%(levelname)s] %(asctime)s %(thread)d: %(message)s" --junit-xml=standard_results.xml tests/integration/standard/test_dse.py || true ''' } @@ -389,7 +389,7 @@ def executeEventLoopTests() { "tests/integration/simulacron/test_endpoint.py" "tests/integration/long/test_ssl.py" ) - EVENT_LOOP=${EVENT_LOOP} CCM_ARGS="${CCM_ARGS}" DSE_VERSION=${DSE_VERSION} CASSANDRA_VERSION=${CCM_CASSANDRA_VERSION} MAPPED_CASSANDRA_VERSION=${MAPPED_CASSANDRA_VERSION} VERIFY_CYTHON=${CYTHON_ENABLED} pynose -s -v --logging-format="[%(levelname)s] %(asctime)s %(thread)d: %(message)s" --with-ignore-docstrings --with-xunit --xunit-file=standard_results.xml ${EVENT_LOOP_TESTS[@]} || true + EVENT_LOOP=${EVENT_LOOP} CCM_ARGS="${CCM_ARGS}" DSE_VERSION=${DSE_VERSION} CASSANDRA_VERSION=${CCM_CASSANDRA_VERSION} MAPPED_CASSANDRA_VERSION=${MAPPED_CASSANDRA_VERSION} VERIFY_CYTHON=${CYTHON_ENABLED} JVM_EXTRA_OPTS="$JVM_EXTRA_OPTS -Xss384k" pytest -s -v --log-format="[%(levelname)s] %(asctime)s %(thread)d: %(message)s" --junit-xml=standard_results.xml ${EVENT_LOOP_TESTS[@]} || true ''' } diff --git a/README-dev.rst b/README-dev.rst index adca510412..7ffa52b0b1 100644 --- a/README-dev.rst +++ b/README-dev.rst @@ -135,49 +135,38 @@ Running Unit Tests ------------------ Unit tests can be run like so:: - nosetests -w tests/unit/ + pytest tests/unit/ You can run a specific test method like so:: - nosetests -w tests/unit/test_connection.py:ConnectionTest.test_bad_protocol_version + pytest tests/unit/test_connection.py::ConnectionTest::test_bad_protocol_version Running Integration Tests ------------------------- In order to run integration tests, you must specify a version to run using the ``CASSANDRA_VERSION`` or ``DSE_VERSION`` environment variable:: - CASSANDRA_VERSION=2.0.9 nosetests -w tests/integration/standard + CASSANDRA_VERSION=2.0.9 pytest tests/integration/standard Or you can specify a cassandra directory (to test unreleased versions):: - CASSANDRA_DIR=/home/thobbs/cassandra nosetests -w tests/integration/standard/ + CASSANDRA_DIR=/path/to/cassandra pytest tests/integration/standard/ Specifying the usage of an already running Cassandra cluster ------------------------------------------------------------ The test will start the appropriate Cassandra clusters when necessary but if you don't want this to happen because a Cassandra cluster is already running the flag ``USE_CASS_EXTERNAL`` can be used, for example:: - USE_CASS_EXTERNAL=1 CASSANDRA_VERSION=2.0.9 nosetests -w tests/integration/standard + USE_CASS_EXTERNAL=1 CASSANDRA_VERSION=2.0.9 pytest tests/integration/standard Specify a Protocol Version for Tests ------------------------------------ The protocol version defaults to 1 for cassandra 1.2 and 2 otherwise. You can explicitly set it with the ``PROTOCOL_VERSION`` environment variable:: - PROTOCOL_VERSION=3 nosetests -w tests/integration/standard - -Seeing Test Logs in Real Time ------------------------------ -Sometimes it's useful to output logs for the tests as they run:: - - nosetests -w tests/unit/ --nocapture --nologcapture - -Use tee to capture logs and see them on your terminal:: - - nosetests -w tests/unit/ --nocapture --nologcapture 2>&1 | tee test.log + PROTOCOL_VERSION=3 pytest tests/integration/standard Testing Multiple Python Versions -------------------------------- -Use tox to test all of Python 3.8 through 3.12 and pypy (this is what -TravisCI runs):: +Use tox to test all of Python 3.8 through 3.12 and pypy (this is what TravisCI runs):: tox diff --git a/appveyor/run_test.ps1 b/appveyor/run_test.ps1 index fc95ec7e52..9b8c23fd8b 100644 --- a/appveyor/run_test.ps1 +++ b/appveyor/run_test.ps1 @@ -15,12 +15,12 @@ $wc = New-Object 'System.Net.WebClient' if($env:ci_type -eq 'unit'){ echo "Running Unit tests" - nosetests -s -v --with-ignore-docstrings --with-xunit --xunit-file=unit_results.xml .\tests\unit + pytest -s -v --junit-xml=unit_results.xml .\tests\unit $env:EVENT_LOOP_MANAGER="gevent" - nosetests -s -v --with-ignore-docstrings --with-xunit --xunit-file=unit_results.xml .\tests\unit\io\test_geventreactor.py + pytest -s -v --junit-xml=unit_results.xml .\tests\unit\io\test_geventreactor.py $env:EVENT_LOOP_MANAGER="eventlet" - nosetests -s -v --with-ignore-docstrings --with-xunit --xunit-file=unit_results.xml .\tests\unit\io\test_eventletreactor.py + pytest -s -v --junit-xml=unit_results.xml .\tests\unit\io\test_eventletreactor.py $env:EVENT_LOOP_MANAGER="asyncore" echo "uploading unit results" @@ -31,13 +31,13 @@ if($env:ci_type -eq 'unit'){ if($env:ci_type -eq 'standard'){ echo "Running CQLEngine integration tests" - nosetests -s -v --with-ignore-docstrings --with-xunit --xunit-file=cqlengine_results.xml .\tests\integration\cqlengine + pytest -s -v --junit-xml=cqlengine_results.xml .\tests\integration\cqlengine $cqlengine_tests_result = $lastexitcode $wc.UploadFile("https://ci.appveyor.com/api/testresults/junit/$($env:APPVEYOR_JOB_ID)", (Resolve-Path .\cqlengine_results.xml)) echo "uploading CQLEngine test results" echo "Running standard integration tests" - nosetests -s -v --with-ignore-docstrings --with-xunit --xunit-file=standard_results.xml .\tests\integration\standard + pytest -s -v --junit-xml=standard_results.xml .\tests\integration\standard $integration_tests_result = $lastexitcode $wc.UploadFile("https://ci.appveyor.com/api/testresults/junit/$($env:APPVEYOR_JOB_ID)", (Resolve-Path .\standard_results.xml)) echo "uploading standard integration test results" diff --git a/cassandra/io/asyncorereactor.py b/cassandra/io/asyncorereactor.py index a50b719c5d..d2ea62cc3c 100644 --- a/cassandra/io/asyncorereactor.py +++ b/cassandra/io/asyncorereactor.py @@ -24,7 +24,6 @@ import sys import ssl - try: from weakref import WeakSet except ImportError: diff --git a/cassandra/io/libevreactor.py b/cassandra/io/libevreactor.py index 4d4098ca7b..d28c6af0f1 100644 --- a/cassandra/io/libevreactor.py +++ b/cassandra/io/libevreactor.py @@ -22,8 +22,6 @@ import time from cassandra import DependencyException -from cassandra.connection import (Connection, ConnectionShutdown, - NONBLOCKING, Timer, TimerManager) try: import cassandra.io.libevwrapper as libev except ImportError: @@ -35,6 +33,9 @@ "for instructions on installing build dependencies and building " "the C extension.") +from cassandra.connection import (Connection, ConnectionShutdown, + NONBLOCKING, Timer, TimerManager) + log = logging.getLogger(__name__) diff --git a/cassandra/io/twistedreactor.py b/cassandra/io/twistedreactor.py index 9b3ff09398..e4605a7446 100644 --- a/cassandra/io/twistedreactor.py +++ b/cassandra/io/twistedreactor.py @@ -102,6 +102,9 @@ def maybe_start(self): self._thread.start() atexit.register(partial(_cleanup, weakref.ref(self))) + def _reactor_stopped(self): + return reactor._stopped + def _cleanup(self): if self._thread: reactor.callFromThread(reactor.stop) diff --git a/setup.py b/setup.py index 41c3eae702..1558512fcf 100644 --- a/setup.py +++ b/setup.py @@ -16,16 +16,6 @@ import sys import warnings -if __name__ == '__main__' and sys.argv[1] == "gevent_nosetests": - print("Running gevent tests") - from gevent.monkey import patch_all - patch_all() - -if __name__ == '__main__' and sys.argv[1] == "eventlet_nosetests": - print("Running eventlet tests") - from eventlet import monkey_patch - monkey_patch() - import ez_setup ez_setup.use_setuptools() @@ -48,19 +38,6 @@ with open("README.rst") as f: long_description = f.read() - -try: - from nose.commands import nosetests -except ImportError: - gevent_nosetests = None - eventlet_nosetests = None -else: - class gevent_nosetests(nosetests): - description = "run nosetests with gevent monkey patching" - - class eventlet_nosetests(nosetests): - description = "run nosetests with eventlet monkey patching" - has_cqlengine = False if __name__ == '__main__' and sys.argv[1] == "install": try: @@ -382,12 +359,6 @@ def pre_build_check(): def run_setup(extensions): kw = {'cmdclass': {'doc': DocCommand}} - if gevent_nosetests is not None: - kw['cmdclass']['gevent_nosetests'] = gevent_nosetests - - if eventlet_nosetests is not None: - kw['cmdclass']['eventlet_nosetests'] = eventlet_nosetests - kw['cmdclass']['build_ext'] = build_extensions kw['ext_modules'] = [Extension('DUMMY', [])] # dummy extension makes sure build_ext is called for install @@ -435,7 +406,7 @@ def run_setup(extensions): include_package_data=True, install_requires=dependencies, extras_require=_EXTRAS_REQUIRE, - tests_require=['nose', 'PyYAML', 'pytz', 'sure'], + tests_require=['pytest', 'PyYAML', 'pytz', 'sure'], classifiers=[ 'Development Status :: 5 - Production/Stable', 'Intended Audience :: Developers', diff --git a/test-requirements.txt b/test-requirements.txt index c82e6a65a9..94ac611707 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -1,6 +1,6 @@ -r requirements.txt scales -pynose +pytest ccm>=2.1.2 pytz sure diff --git a/tests/integration/__init__.py b/tests/integration/__init__.py index b158ed2bc0..b7246522ae 100644 --- a/tests/integration/__init__.py +++ b/tests/integration/__init__.py @@ -997,6 +997,7 @@ def assert_startswith(s, prefix): class TestCluster(object): + __test__ = False DEFAULT_PROTOCOL_VERSION = default_protocol_version DEFAULT_CASSANDRA_IP = CASSANDRA_IP DEFAULT_ALLOW_BETA = ALLOW_BETA_PROTOCOL diff --git a/tests/integration/cloud/conftest.py b/tests/integration/cloud/conftest.py new file mode 100644 index 0000000000..fb08b04194 --- /dev/null +++ b/tests/integration/cloud/conftest.py @@ -0,0 +1,9 @@ +import pytest + +from tests.integration.cloud import setup_package, teardown_package + +@pytest.fixture(scope='session', autouse=True) +def setup_and_teardown_packages(): + setup_package() + yield + teardown_package() \ No newline at end of file diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py new file mode 100644 index 0000000000..b2eb9a02fc --- /dev/null +++ b/tests/integration/conftest.py @@ -0,0 +1,9 @@ +import pytest + +from tests.integration import teardown_package + +@pytest.fixture(scope='session', autouse=True) +def setup_and_teardown_packages(): + print('setup') + yield + teardown_package() \ No newline at end of file diff --git a/tests/integration/cqlengine/conftest.py b/tests/integration/cqlengine/conftest.py new file mode 100644 index 0000000000..2dc695828b --- /dev/null +++ b/tests/integration/cqlengine/conftest.py @@ -0,0 +1,12 @@ +import pytest + +from tests.integration import teardown_package as parent_teardown_package +from tests.integration.cqlengine import setup_package, teardown_package + + +@pytest.fixture(scope='session', autouse=True) +def setup_and_teardown_packages(): + setup_package() + yield + teardown_package() + parent_teardown_package() \ No newline at end of file diff --git a/tests/integration/cqlengine/test_batch_query.py b/tests/integration/cqlengine/test_batch_query.py index 4a1cd633a1..2d30bd0f53 100644 --- a/tests/integration/cqlengine/test_batch_query.py +++ b/tests/integration/cqlengine/test_batch_query.py @@ -13,6 +13,8 @@ # limitations under the License. import warnings +import pytest + from cassandra.cqlengine import columns from cassandra.cqlengine.management import drop_table, sync_table from cassandra.cqlengine.models import Model @@ -215,7 +217,7 @@ def test_callbacks_work_multiple_times(self): def my_callback(*args, **kwargs): call_history.append(args) - with warnings.catch_warnings(record=True) as w: + with pytest.warns() as w: with BatchQuery() as batch: batch.add_callback(my_callback) batch.execute() diff --git a/tests/integration/simulacron/conftest.py b/tests/integration/simulacron/conftest.py new file mode 100644 index 0000000000..a4377996bb --- /dev/null +++ b/tests/integration/simulacron/conftest.py @@ -0,0 +1,9 @@ +import pytest + +from tests.integration.simulacron import teardown_package + +@pytest.fixture(scope='session', autouse=True) +def setup_and_teardown_packages(): + print('setup') + yield + teardown_package() \ No newline at end of file diff --git a/tests/integration/standard/conftest.py b/tests/integration/standard/conftest.py new file mode 100644 index 0000000000..6028c2a06d --- /dev/null +++ b/tests/integration/standard/conftest.py @@ -0,0 +1,13 @@ +import pytest +import logging + +# from https://github.com/streamlit/streamlit/pull/5047/files +def pytest_sessionfinish(): + # We're not waiting for scriptrunner threads to cleanly close before ending the PyTest, + # which results in raised exception ValueError: I/O operation on closed file. + # This is well known issue in PyTest, check out these discussions for more: + # * https://github.com/pytest-dev/pytest/issues/5502 + # * https://github.com/pytest-dev/pytest/issues/5282 + # To prevent the exception from being raised on pytest_sessionfinish + # we disable exception raising in logging module + logging.raiseExceptions = False \ No newline at end of file diff --git a/tests/unit/io/test_asyncorereactor.py b/tests/unit/io/test_asyncorereactor.py index 6e3fc2dfe4..06328a6f45 100644 --- a/tests/unit/io/test_asyncorereactor.py +++ b/tests/unit/io/test_asyncorereactor.py @@ -11,12 +11,20 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +import platform +import socket import unittest from unittest.mock import patch -import socket -import cassandra.io.asyncorereactor as asyncorereactor -from cassandra.io.asyncorereactor import AsyncoreConnection +from packaging.version import Version + +from cassandra import DependencyException +try: + import cassandra.io.asyncorereactor as asyncorereactor + from cassandra.io.asyncorereactor import AsyncoreConnection +except DependencyException: + AsyncoreConnection = None + from tests import is_monkey_patched from tests.unit.io.utils import ReactorTestMixin, TimerTestMixin, noop_if_monkey_patched @@ -54,7 +62,8 @@ def tearDownClass(cls): except: pass - +has_asyncore = Version(platform.python_version()) < Version("3.12.0") +@unittest.skipUnless(has_asyncore, "asyncore has been removed in Python 3.12") class AsyncoreConnectionTest(ReactorTestMixin, AsyncorePatcher): connection_class = AsyncoreConnection @@ -65,6 +74,7 @@ def setUp(self): raise unittest.SkipTest("Can't test asyncore with monkey patching") +@unittest.skipUnless(has_asyncore, "asyncore has been removed in Python 3.12") class TestAsyncoreTimer(TimerTestMixin, AsyncorePatcher): connection_class = AsyncoreConnection diff --git a/tests/unit/io/test_libevreactor.py b/tests/unit/io/test_libevreactor.py index 3ea6c669f3..6e6f3d8faa 100644 --- a/tests/unit/io/test_libevreactor.py +++ b/tests/unit/io/test_libevreactor.py @@ -17,16 +17,16 @@ import weakref import socket -from tests import is_monkey_patched -from tests.unit.io.utils import ReactorTestMixin, TimerTestMixin, noop_if_monkey_patched - - +from cassandra import DependencyException try: from cassandra.io.libevreactor import _cleanup as libev__cleanup from cassandra.io.libevreactor import LibevConnection -except ImportError: +except DependencyException: LibevConnection = None # noqa +from tests import is_monkey_patched +from tests.unit.io.utils import ReactorTestMixin, TimerTestMixin, noop_if_monkey_patched + class LibevConnectionTest(ReactorTestMixin, unittest.TestCase): diff --git a/tests/unit/io/test_twistedreactor.py b/tests/unit/io/test_twistedreactor.py index 0da9915cec..e545620033 100644 --- a/tests/unit/io/test_twistedreactor.py +++ b/tests/unit/io/test_twistedreactor.py @@ -66,7 +66,9 @@ def setUp(self): self.tr.protocol = self.obj_ut def tearDown(self): - pass + loop = twistedreactor.TwistedConnection._loop + if not loop._reactor_stopped(): + loop._cleanup() def test_makeConnection(self): """ diff --git a/tests/unit/io/utils.py b/tests/unit/io/utils.py index be721dc7d3..765a561207 100644 --- a/tests/unit/io/utils.py +++ b/tests/unit/io/utils.py @@ -181,7 +181,7 @@ def test_timer_cancellation(self): timer = self.create_timer(timeout, callback.invoke) timer.cancel() # Release context allow for timer thread to run. - time.sleep(.2) + time.sleep(timeout * 2) timer_manager = self._timers # Assert that the cancellation was honored self.assertFalse(timer_manager._queue) diff --git a/tests/unit/test_host_connection_pool.py b/tests/unit/test_host_connection_pool.py index 97a3334acf..ded5bd1a86 100644 --- a/tests/unit/test_host_connection_pool.py +++ b/tests/unit/test_host_connection_pool.py @@ -23,6 +23,7 @@ from cassandra.policies import HostDistance, SimpleConvictionPolicy class _PoolTests(unittest.TestCase): + __test__ = False PoolImpl = None uses_single_connection = None @@ -204,6 +205,7 @@ def test_host_equality(self): class HostConnectionPoolTests(_PoolTests): + __test__ = True PoolImpl = HostConnectionPool uses_single_connection = False @@ -252,6 +254,7 @@ def get_conn(): class HostConnectionTests(_PoolTests): + __test__ = True PoolImpl = HostConnection uses_single_connection = True diff --git a/tox.ini b/tox.ini index a101bbc8e9..a8dda2d9c2 100644 --- a/tox.ini +++ b/tox.ini @@ -2,7 +2,7 @@ envlist = py{38,39,310,311,312},pypy [base] -deps = pynose +deps = pytest packaging cython>=0.20,<0.30 eventlet @@ -21,7 +21,7 @@ setenv = LIBEV_EMBED=0 CARES_EMBED=0 LC_ALL=en_US.UTF-8 changedir = {envtmpdir} -commands = nosetests --verbosity=2 --no-path-adjustment {toxinidir}/tests/unit/ +commands = pytest -v {toxinidir}/tests/unit/ [testenv:gevent_loop] @@ -32,7 +32,7 @@ setenv = LIBEV_EMBED=0 EVENT_LOOP_MANAGER=gevent changedir = {envtmpdir} commands = - nosetests --verbosity=2 --no-path-adjustment {toxinidir}/tests/unit/io/test_geventreactor.py + pytest -v {toxinidir}/tests/unit/io/test_geventreactor.py [testenv:eventlet_loop] @@ -43,4 +43,4 @@ setenv = LIBEV_EMBED=0 EVENT_LOOP_MANAGER=eventlet changedir = {envtmpdir} commands = - nosetests --verbosity=2 --no-path-adjustment {toxinidir}/tests/unit/io/test_eventletreactor.py + pytest -v {toxinidir}/tests/unit/io/test_eventletreactor.py