[tox]
minversion = 4.3.0
envlist = pep8,py3

[testenv]
description =
  Run unit tests.
passenv =
  OS_*
  OPENSTACKSDK_*
setenv =
  LANG=en_US.UTF-8
  LANGUAGE=en_US:en
  LC_ALL=C
  OS_LOG_CAPTURE={env:OS_LOG_CAPTURE:true}
  OS_STDOUT_CAPTURE={env:OS_STDOUT_CAPTURE:true}
  OS_STDERR_CAPTURE={env:OS_STDERR_CAPTURE:true}
constraints =
  {env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master}
deps =
  -r{toxinidir}/test-requirements.txt
  -r{toxinidir}/requirements.txt
commands =
  stestr run {posargs}
  stestr slowest

[testenv:functional{,-py310,-py311,-py312,-py313,-py314}]
description =
  Run functional tests.
# Some jobs (especially heat) takes longer, therefore increase default timeout
# This timeout should not be smaller, than the longest individual timeout
setenv =
  {[testenv]setenv}
  OS_TEST_TIMEOUT=600
  OPENSTACKSDK_FUNC_TEST_TIMEOUT_LOAD_BALANCER=600
  OPENSTACKSDK_EXAMPLE_CONFIG_KEY=functional
  OPENSTACKSDK_FUNC_TEST_TIMEOUT_PROJECT_CLEANUP=1200
commands =
  stestr --test-path ./openstack/tests/functional/{env:OPENSTACKSDK_TESTS_SUBDIR:} run --serial {posargs}
  stestr slowest

# Acceptance tests are the ones running on real clouds
[testenv:acceptance-regular-user]
description =
  Run acceptance tests.
# This env intends to test functions of a regular user without admin privileges
# Some jobs (especially heat) takes longer, therefore increase default timeout
# This timeout should not be smaller, than the longest individual timeout
setenv =
  {[testenv]setenv}
  OS_TEST_TIMEOUT=600
  OPENSTACKSDK_FUNC_TEST_TIMEOUT_LOAD_BALANCER=600
  # OPENSTACKSDK_DEMO_CLOUD and OS_CLOUD should point to the cloud to test
  # Other clouds are explicitly set empty to let tests detect absense
  OPENSTACKSDK_DEMO_CLOUD_ALT=
  OPENSTACKSDK_OPERATOR_CLOUD=
commands =
  stestr --test-path ./openstack/tests/functional/{env:OPENSTACKSDK_TESTS_SUBDIR:} run --serial {posargs} --include-list include-acceptance-regular-user.txt
  stestr slowest

[testenv:pep8]
description =
  Run style checks.
deps =
  pre-commit
  {[testenv:mypy]deps}
commands =
  pre-commit run -a
  {[testenv:mypy]commands}

[testenv:mypy]
description =
  Run type checks.
deps =
  {[testenv]deps}
  mypy
  types-decorator
  types-jmespath
  types-PyYAML
  types-requests
  types-simplejson
commands =
  mypy --cache-dir="{envdir}/mypy_cache" {posargs:openstack}

[testenv:venv]
description =
  Run specified command in a virtual environment with all dependencies installed.
deps =
  -r{toxinidir}/test-requirements.txt
  -r{toxinidir}/requirements.txt
  -r{toxinidir}/doc/requirements.txt
commands = {posargs}

[testenv:debug]
description =
  Run specified tests through oslo_debug_helper, which allows use of pdb.
# allow 1 year, or 31536000 seconds, to debug a test before it times out
setenv =
  OS_TEST_TIMEOUT=31536000
allowlist_externals = find
commands =
  find . -type f -name "*.pyc" -delete
  oslo_debug_helper -t openstack/tests {posargs}

[testenv:cover]
description =
  Run unit tests and generate coverage report.
setenv =
  {[testenv]setenv}
  PYTHON=coverage run --source openstack --parallel-mode
commands =
  stestr run {posargs}
  coverage combine
  coverage html -d cover
  coverage xml -o cover/coverage.xml

[testenv:ansible]
description =
  Run ansible tests.
# Need to pass some env vars for the Ansible playbooks
passenv =
  HOME
  USER
  ANSIBLE_VAR_*
deps =
  {[testenv]deps}
  ansible
commands = {toxinidir}/extras/run-ansible-tests.sh -e {envdir} {posargs}

[testenv:docs]
description =
  Build documentation in HTML format.
deps =
  -r{toxinidir}/doc/requirements.txt
commands =
  sphinx-build -W --keep-going -b html -j auto doc/source/ doc/build/html

[testenv:pdf-docs]
description =
  Build documentation in PDF format.
deps = {[testenv:docs]deps}
allowlist_externals =
  make
commands =
  sphinx-build -W --keep-going -b latex -j auto doc/source/ doc/build/pdf
  make -C doc/build/pdf

[testenv:releasenotes]
description =
  Build release note documentation in HTML format.
deps =
  -r{toxinidir}/doc/requirements.txt
commands =
  sphinx-build -W --keep-going -b html -j auto releasenotes/source releasenotes/build/html

[flake8]
# We only enable the hacking (H) and openstacksdk (O) checks
select = H,O
# H301 Black will put commas after imports that can't fit on one line
# H404 Docstrings don't always start with a newline
# H405 Multiline docstrings are okay
ignore = H301,H403,H404,H405
show-source = True
exclude = .venv,.git,.tox,dist,doc,*lib/python*,*egg,build,openstack/_services_mixin.py

[flake8:local-plugins]
extension =
  O300 = checks:assert_no_setupclass
  O310 = checks:assert_no_deprecated_exceptions
paths = ./openstack/_hacking

[hacking]
import_exceptions =
  collections.abc
  typing

[doc8]
extensions = .rst, .yaml
