diff --git a/.buildkite/it/pipeline.yml b/.buildkite/it/pipeline.yml index c3ff66aa8..0ce8c69c6 100644 --- a/.buildkite/it/pipeline.yml +++ b/.buildkite/it/pipeline.yml @@ -6,5 +6,5 @@ agents: steps: - label: "Run 3.8 integration tests :test_tube:" command: bash .buildkite/it/run.sh 3.8 - - label: "Run 3.11 integration tests :test_tube:" - command: bash .buildkite/it/run.sh 3.11 + - label: "Run 3.12 integration tests :test_tube:" + command: bash .buildkite/it/run.sh 3.12 diff --git a/.buildkite/it/serverless-pipeline.yml b/.buildkite/it/serverless-pipeline.yml index de013751b..6026329b8 100644 --- a/.buildkite/it/serverless-pipeline.yml +++ b/.buildkite/it/serverless-pipeline.yml @@ -23,10 +23,10 @@ steps: - elastic/vault-secrets#v0.0.2: *vault-base_url - elastic/vault-secrets#v0.0.2: *vault-get_credentials_endpoint - elastic/vault-secrets#v0.0.2: *vault-api_key - command: bash .buildkite/it/run_serverless.sh 3.11 user + command: bash .buildkite/it/run_serverless.sh 3.12 user - label: "Run IT serverless tests with operator privileges" plugins: - elastic/vault-secrets#v0.0.2: *vault-base_url - elastic/vault-secrets#v0.0.2: *vault-get_credentials_endpoint - elastic/vault-secrets#v0.0.2: *vault-api_key - command: bash .buildkite/it/run_serverless.sh 3.11 operator + command: bash .buildkite/it/run_serverless.sh 3.12 operator diff --git a/.ci/variables.json b/.ci/variables.json index c8d5786f7..8814128ef 100644 --- a/.ci/variables.json +++ b/.ci/variables.json @@ -2,14 +2,15 @@ "prerequisite_versions": { "HATCH": "1.3.1", "HATCHLING": "1.6.0", - "PIP": "22.2", + "PIP": "24.0", "WHEEL": "0.37.1" }, "python_versions": { + "PY312": "3.12.2", "PY38": "3.8.16", "PY39": "3.9.16", "PY310": "3.10.10", - "PY311": "3.11.4", + "PY311": "3.11.7", "MIN_PY_VER": "3.8.16" } } diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b36e45758..5c0d54ad3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,7 +22,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-python@v4 with: - python-version: "3.11" + python-version: "3.12" cache: pip cache-dependency-path: pyproject.toml - name: "Install dependencies" @@ -39,7 +39,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.8", "3.9", "3.10", "3.11"] + python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] os: - macos-latest - ubuntu-latest @@ -71,7 +71,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-python@v4 with: - python-version: "3.11" + python-version: "3.12" cache: pip cache-dependency-path: pyproject.toml - uses: actions/setup-java@v3 diff --git a/.readthedocs.yaml b/.readthedocs.yaml index e371301f1..1f6f30e41 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -3,7 +3,7 @@ version: 2 build: os: ubuntu-22.04 tools: - python: "3.11" + python: "3.12" python: install: diff --git a/Makefile b/Makefile index 0a83a0bee..167297144 100644 --- a/Makefile +++ b/Makefile @@ -25,6 +25,7 @@ export PY38 := $(shell jq -r '.python_versions.PY38' .ci/variables.json) export PY39 := $(shell jq -r '.python_versions.PY39' .ci/variables.json) export PY310 := $(shell jq -r '.python_versions.PY310' .ci/variables.json) export PY311 := $(shell jq -r '.python_versions.PY311' .ci/variables.json) +export PY312 := $(shell jq -r '.python_versions.PY312' .ci/variables.json) export HATCH_VERSION := $(shell jq -r '.prerequisite_versions.HATCH' .ci/variables.json) export HATCHLING_VERSION := $(shell jq -r '.prerequisite_versions.HATCHLING' .ci/variables.json) export PIP_VERSION := $(shell jq -r '.prerequisite_versions.PIP' .ci/variables.json) @@ -42,7 +43,8 @@ prereq: pyenv install --skip-existing $(PY39) pyenv install --skip-existing $(PY310) pyenv install --skip-existing $(PY311) - pyenv local $(PY38) + pyenv install --skip-existing $(PY312) + pyenv local $(PY312) @# Ensure all Python versions are registered for this project @ jq -r '.python_versions | [.[] | tostring] | join("\n")' .ci/variables.json > .python-version -@ printf $(PYENV_PREREQ_HELP) @@ -63,6 +65,7 @@ check-venv: fi install-user: venv-create + . $(VENV_ACTIVATE_FILE); $(PY_BIN) -m ensurepip --upgrade --default-pip . $(VENV_ACTIVATE_FILE); $(PIP_WRAPPER) install --upgrade hatch==$(HATCH_VERSION) hatchling==$(HATCHLING_VERSION) pip==$(PIP_VERSION) wheel==$(WHEEL_VERSION) . $(VENV_ACTIVATE_FILE); $(PIP_WRAPPER) install -e . @@ -98,12 +101,12 @@ serve-docs: check-venv test: check-venv . $(VENV_ACTIVATE_FILE); nox -s test-3.8 - . $(VENV_ACTIVATE_FILE); nox -s test-3.11 + . $(VENV_ACTIVATE_FILE); nox -s test-3.12 # checks min and max python versions it: check-venv python-caches-clean . $(VENV_ACTIVATE_FILE); nox -s it-3.8 - . $(VENV_ACTIVATE_FILE); nox -s it-3.11 + . $(VENV_ACTIVATE_FILE); nox -s it-3.12 check-all: lint test it diff --git a/esrally/rally.py b/esrally/rally.py index 738826f78..2c7d96665 100644 --- a/esrally/rally.py +++ b/esrally/rally.py @@ -1256,6 +1256,13 @@ def main(): # Configure networking net.init() + def _trap_exc(function, path, exc_info): + if isinstance(exc_info, FileNotFoundError): + # couldn't delete because it was already clean + return + logging.exception("Failed to clean up [%s] with [%s]", path, function, exc_info=True) + raise exceptions.SystemSetupError(f"Unable to clean [{paths.libs()}]. See Rally log for more information.") + def _trap(function, path, exc_info): if exc_info[0] == FileNotFoundError: # couldn't delete because it was already clean @@ -1265,7 +1272,12 @@ def _trap(function, path, exc_info): # fully destructive is fine, we only allow one Rally to run at a time and we will rely on the pip cache for download caching logger.info("Cleaning track dependency directory [%s]...", paths.libs()) - shutil.rmtree(paths.libs(), onerror=_trap) + + if sys.version_info.major == 3 and sys.version_info.minor <= 11: + # pylint: disable=deprecated-argument + shutil.rmtree(paths.libs(), onerror=_trap) + else: + shutil.rmtree(paths.libs(), onexc=_trap_exc) result = dispatch_sub_command(arg_parser, args, cfg) diff --git a/noxfile.py b/noxfile.py index 1a67ae13e..07eed5aee 100644 --- a/noxfile.py +++ b/noxfile.py @@ -1,19 +1,19 @@ import nox -@nox.session(python=["3.8", "3.9", "3.10", "3.11"]) +@nox.session(python=["3.8", "3.9", "3.10", "3.11", "3.12"]) def test(session: nox.Session) -> None: session.install(".[develop]") session.run("pytest") -@nox.session(python=["3.8", "3.9", "3.10", "3.11"]) +@nox.session(python=["3.8", "3.9", "3.10", "3.11", "3.12"]) def it(session: nox.Session) -> None: session.install(".[develop]") session.run("pytest", "-s", "it") -@nox.session(python="3.11") +@nox.session(python="3.12") def it_serverless(session: nox.Session) -> None: session.install(".[develop]") session.install("pytest-rally @ git+https://github.com/elastic/pytest-rally.git") diff --git a/pyproject.toml b/pyproject.toml index 357d7e422..6fb5e72e8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,6 +29,7 @@ classifiers=[ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3 :: Only", ] ################################################################################################ @@ -68,7 +69,7 @@ dependencies = [ # License: MPL 2.0 "certifi", # License: MIT - "yappi==1.4.0", + "yappi==1.5.1", # License: BSD "ijson==2.6.1", # License: Apache 2.0 @@ -88,12 +89,12 @@ s3 = [ # botocore: Apache 2.0 # jmespath: MIT # s3transfer: Apache 2.0 - "boto3==1.18.46", + "boto3==1.34.68", ] # These packages are only required when developing Rally develop = [ # s3 - "boto3==1.18.46", + "boto3==1.34.68", # tests "ujson", "pytest==7.1.2", @@ -101,12 +102,12 @@ develop = [ "pytest-asyncio==0.19.0", "pytest-httpserver==1.0.5", "tox==3.25.0", - "nox==2022.11.21", + "nox==2024.3.2", "sphinx==5.1.1", "furo==2022.06.21", "github3.py==3.2.0", "pre-commit==2.20.0", - "pylint==2.17.4", + "pylint==3.1.0", "trustme==0.9.0", "GitPython==3.1.30", ] diff --git a/tests/client/factory_test.py b/tests/client/factory_test.py index 284926a28..791423365 100644 --- a/tests/client/factory_test.py +++ b/tests/client/factory_test.py @@ -576,16 +576,16 @@ def test_successfully_deletes_api_keys(self, es, version): {"invalidated_api_keys": ["baz"]}, ] calls = [ - mock.call({"id": "baz"}), - mock.call({"id": "bar"}), - mock.call({"id": "foo"}), + mock.call(id="baz"), + mock.call(id="bar"), + mock.call(id="foo"), ] else: es.security.invalidate_api_key.return_value = {"invalidated_api_keys": ["foo", "bar", "baz"], "error_count": 0} calls = [mock.call(ids=ids)] assert client.delete_api_keys(es, ids, max_attempts=3) - assert es.security.invalidate_api_key.has_calls(calls, any_order=True) + es.security.invalidate_api_key.assert_has_calls(calls, any_order=True) @pytest.mark.parametrize("version", ["7.9.0", "7.10.0"]) @mock.patch("time.sleep")