[tox]

envlist = bindep,linters,py3,lower-constraints,functional
minversion = 4.13


# --- unit test environments -------------------------------------------------

[testenv]

usedevelop = True
deps =
    {env:TOX_CONSTRAINTS}
    -r{toxinidir}/requirements.txt
    -r{toxinidir}/test-requirements.txt
    {env:TOX_EXTRA_REQUIREMENTS}
passenv =
    JENKINS_*
    OS_*
    TOBIKO_*
    TOX_*
    PYTEST_*
    HOME
    KUBECONFIG
setenv =
    OS_LOG_CAPTURE = {env:OS_LOG_CAPTURE:true}
    OS_STDOUT_CAPTURE = {env:OS_STDOUT_CAPTURE:true}
    OS_STDERR_CAPTURE = {env:OS_STDERR_CAPTURE:true}
    OS_TEST_PATH = {toxinidir}/tobiko/tests/unit
    TOBIKO_TEST_PATH = {env:OS_TEST_PATH}
    PYTEST_TIMEOUT = {env:PYTEST_TIMEOUT:300}
    PYTHONWARNINGS = ignore::Warning,{env:PYTHONWARNINGS:}
    TOBIKO_PREVENT_CREATE = {env:TOBIKO_PREVENT_CREATE:false}
    TOX_COVER = {env:TOX_COVER:false}
    TOX_COVER_DIR = {env:TOX_COVER_DIR:{toxinidir}/cover}
    TOX_NUM_PROCESSES = {env:TOX_NUM_PROCESSES:auto}
    TOX_REPORT_NAME = {env:TOX_REPORT_NAME:tobiko_results_{envname}}
    TOX_REPORT_DIR = {env:TOX_REPORT_DIR:{envlogdir}}
    TOX_CONSTRAINTS = {env:TOX_CONSTRAINTS:-c{toxinidir}/upper-constraints.txt}
    TOX_EXTRA_REQUIREMENTS = {env:TOX_EXTRA_REQUIREMENTS:-r{toxinidir}/extra-requirements.txt}
    VIRTUAL_ENV = {envdir}
commands =
    {envpython} {toxinidir}/tools/run_tests.py {posargs:{env:TOBIKO_TEST_PATH}}


[testenv:py3]

basepython = {env:TOX_PYTHON:python3}
envdir = {toxworkdir}/py3


[testenv:cover]

basepython = {[testenv:py3]basepython}
envdir = {[testenv:py3]envdir}
setenv =
    {[testenv]setenv}
    TOX_COVER = true
    TOX_COVER_DIR={env:TOX_COVER_DIR:{toxinidir}/cover}
    OS_TEST_PATH = {toxinidir}/tobiko/tests/unit

commands_post =
    coverage html -d "{env:TOX_COVER_DIR}"
    coverage xml -o "{env:TOX_COVER_DIR}/coverage.xml"

whitelist_externals =
    find


# --- static analisys environments -------------------------------------------

[testenv:pep8]

basepython = {env:TOX_PYTHON:python3}
deps =
    {[testenv]deps}
    -r{toxinidir}/linters-requirements.txt
commands =
    pre-commit run -a flake8
setenv =
    {[testenv]setenv}
    TOX_CONSTRAINTS = -c{toxinidir}/upper-constraints.txt

[testenv:mypy]

basepython = {[testenv:pep8]basepython}
deps = {[testenv:pep8]deps}
envdir = {toxworkdir}/pep8
commands =
    pre-commit run -a mypy
setenv =
    {[testenv:pep8]setenv}


[testenv:pylint]
basepython = {[testenv:pep8]basepython}
deps = {[testenv:pep8]deps}
envdir = {toxworkdir}/pep8
commands =
    pre-commit run -a pylint
setenv =
    {[testenv:pep8]setenv}


[testenv:linters]

basepython = {[testenv:pep8]basepython}
whitelist_externals = bash
deps = {[testenv:pep8]deps}
envdir = {toxworkdir}/pep8
commands =
    pre-commit --version
    pre-commit run -a
    pre-commit install --allow-missing-config
setenv =
    {[testenv:pep8]setenv}


[flake8]
# H106: Don't put vim configuration in source files
# H203: Use assertIs(Not)None to check for None
# H204: Use assert(Not)Equal to check for equality
# H205: Use assert(Greater|Less)(Equal) for comparison
# H904: Delay string interpolations at logging calls.
enable-extensions = H106,H203,H204,H205,H904

show-source = true
exclude = ./.*,*lib/python*,build,dist,doc,*egg*,releasenotes,.venv,.tox
application-import-names = tobiko
max-complexity = 11
import-order-style = pep8


# --- integration test environments ------------------------------------------

[integration]

basepython = {[testenv:py3]basepython}
envdir = {[testenv:py3]envdir}
passenv =
    {[testenv]passenv}
    *_proxy
setenv =
    {[testenv]setenv}
    PYTEST_TIMEOUT = 2400


[testenv:venv]

basepython = {[integration]basepython}
envdir = {[integration]envdir}
passenv = {[integration]passenv}
whitelist_externals = *
commands = {posargs:bash -c 'PS1="[tobiko@{envname}] " bash'}


[testenv:functional]

basepython = {[integration]basepython}
envdir = {[integration]envdir}
passenv = {[integration]passenv}
setenv =
    {[integration]setenv}
    OS_TEST_PATH = {toxinidir}/tobiko/tests/functional


[testenv:manila]
basepython = {[integration]basepython}
envdir = {[integration]envdir}
passenv = {[integration]passenv}
setenv =
    {[integration]setenv}
    OS_TEST_PATH = {toxinidir}/tobiko/tests/scenario/manila


[testenv:scenario]

basepython = {[integration]basepython}
envdir = {[integration]envdir}
passenv = {[integration]passenv}
setenv =
    {[integration]setenv}
    OS_TEST_PATH = {toxinidir}/tobiko/tests/scenario


[testenv:neutron]

basepython = {[integration]basepython}
envdir = {[integration]envdir}
passenv = {[integration]passenv}
setenv =
    {[integration]setenv}
    OS_TEST_PATH = {toxinidir}/tobiko/tests/scenario/neutron


[testenv:octavia]

basepython = {[integration]basepython}
envdir = {[integration]envdir}
passenv = {[integration]passenv}
setenv =
    {[integration]setenv}
    OS_TEST_PATH = {toxinidir}/tobiko/tests/scenario/octavia


[testenv:designate]

basepython = {[integration]basepython}
envdir = {[integration]envdir}
passenv = {[integration]passenv}
setenv =
    {[integration]setenv}
    OS_TEST_PATH = {toxinidir}/tobiko/tests/scenario/designate


[testenv:ovn_migration]

basepython = {[integration]basepython}
envdir = {[integration]envdir}
passenv = {[integration]passenv}
setenv =
    {[integration]setenv}
    OS_TEST_PATH = {toxinidir}/tobiko/tests/scenario
    RUN_TESTS_EXTRA_ARGS = -m "not skip_during_ovn_migration and not background and not flaky"
commands =
    {envpython} {toxinidir}/tools/run_tests.py {env:RUN_TESTS_EXTRA_ARGS} {posargs:{env:TOBIKO_TEST_PATH}}

[testenv:nova]

basepython = {[integration]basepython}
envdir = {[integration]envdir}
passenv = {[integration]passenv}
setenv =
    {[integration]setenv}
    OS_TEST_PATH = {toxinidir}/tobiko/tests/scenario/nova


[testenv:sanity]

basepython = {[integration]basepython}
envdir = {[integration]envdir}
passenv = {[integration]passenv}
setenv =
    {[integration]setenv}
    OS_TEST_PATH = {toxinidir}/tobiko/tests/sanity
    PYTEST_TIMEOUT = 1800

[testenv:neutron_sanity]

basepython = {[integration]basepython}
envdir = {[integration]envdir}
passenv = {[integration]passenv}
setenv =
    {[integration]setenv}
    OS_TEST_PATH = {toxinidir}/tobiko/tests/sanity/neutron
    PYTEST_TIMEOUT = 1800


[testenv:ovn_migration_sanity]

basepython = {[integration]basepython}
envdir = {[integration]envdir}
passenv = {[integration]passenv}
setenv =
    {[testenv:sanity]setenv}
    RUN_TESTS_EXTRA_ARGS = -m "ovn_migration and not skip_during_ovn_migration and not background and not flaky"
commands =
    {envpython} {toxinidir}/tools/run_tests.py {env:RUN_TESTS_EXTRA_ARGS} {posargs:{env:TOBIKO_TEST_PATH}}


[testenv:shiftstack_sanity]

basepython = {[integration]basepython}
envdir = {[integration]envdir}
passenv = {[integration]passenv}
setenv =
    {[integration]setenv}
    OS_TEST_PATH = {toxinidir}/tobiko/tests/sanity/shiftstack
    PYTEST_TIMEOUT = 1800


[testenv:faults]

basepython = {[integration]basepython}
envdir = {[integration]envdir}
passenv = {[integration]passenv}
setenv =
    {[integration]setenv}
    OS_TEST_PATH = {toxinidir}/tobiko/tests/faults
    TOX_NUM_PROCESSES = 1
    PYTEST_TIMEOUT = 3600


[testenv:octavia_faults]

basepython = {[integration]basepython}
envdir = {[integration]envdir}
passenv = {[integration]passenv}
setenv =
    {[integration]setenv}
    OS_TEST_PATH = {toxinidir}/tobiko/tests/faults/octavia
    TOX_NUM_PROCESSES = 1
    PYTEST_TIMEOUT = 3600


[testenv:neutron_faults]

basepython = {[integration]basepython}
envdir = {[integration]envdir}
passenv = {[integration]passenv}
setenv =
    {[integration]setenv}
    OS_TEST_PATH = {toxinidir}/tobiko/tests/faults/neutron
    TOX_NUM_PROCESSES = 1
    PYTEST_TIMEOUT = 3600


[testenv:ha_faults]

basepython = {[integration]basepython}
envdir = {[integration]envdir}
passenv = {[integration]passenv}
setenv =
    {[integration]setenv}
    OS_TEST_PATH = {toxinidir}/tobiko/tests/faults/ha
    TOX_NUM_PROCESSES = 1
    PYTEST_TIMEOUT = 3600


[testenv:instanceha]

basepython = {[integration]basepython}
envdir = {[integration]envdir}
passenv = {[integration]passenv}
setenv =
    {[integration]setenv}
    OS_TEST_PATH = {toxinidir}/tobiko/tests/faults/iha
    TOX_NUM_PROCESSES = 1
    PYTEST_TIMEOUT = 3600


[testenv:podified_faults]

basepython = {[integration]basepython}
envdir = {[integration]envdir}
passenv = {[integration]passenv}
setenv =
    {[integration]setenv}
    OS_TEST_PATH = {toxinidir}/tobiko/tests/faults/podified
    TOX_NUM_PROCESSES = 1
    PYTEST_TIMEOUT = 3600


[testenv:podified_ha_faults]

basepython = {[integration]basepython}
envdir = {[integration]envdir}
passenv = {[integration]passenv}
setenv =
    {[integration]setenv}
    OS_TEST_PATH = {toxinidir}/tobiko/tests/faults/podified/ha
    TOX_NUM_PROCESSES = 1
    PYTEST_TIMEOUT = 3600

[testenv:update_podified_post]

basepython = {[integration]basepython}
envdir = {[integration]envdir}
passenv = {[integration]passenv}
setenv =
    {[integration]setenv}
    OS_TEST_PATH = {toxinidir}/tobiko/tests/update/podified/post
    TOX_NUM_PROCESSES = 1
    PYTEST_TIMEOUT = 3600


# --- CI workflow test environments -------------------------------------------

[testenv:infrared]

# On RedHat Linux must use the default unversioned python because of dependency on native SELinux
# package available only for /usr/bin/python interpreter
basepython = {env:IR_PYTHON:python3}
usedevelop = false
skipsdist = true
skip_install = true
sitepackages = true
whitelist_externals =
    rm

deps = {env:IR_DEPS}

passenv =
    {[testenv]passenv}
    ANSIBLE_*
    IR_*
    TERM

setenv =
    {[testenv]setenv}
    ANSIBLE_CONFIG = {env:ANSIBLE_CONFIG:{toxinidir}/ansible.cfg}
    ANSIBLE_INVENTORY = {env:ANSIBLE_INVENTORY:{toxinidir}/ansible_hosts}
    IR_DEPS = {env:IR_DEPS:-r{toxinidir}/infrared_plugin/requirements.txt}
    IR_HOME = {env:IR_HOME:{envdir}/home/infrared}
    IR_TOBIKO_PLUGIN = {env:IR_TOBIKO_PLUGIN:{toxinidir}/infrared_plugin}
    IR_WORKSPACE_FILE = {env:IR_WORKSPACE_FILE:{toxinidir}/workspace.tgz}
    IR_WORKFLOW = {env:IR_WORKFLOW:unit-functional}
    SETUPTOOLS_USE_DISTUTILS = stdlib

commands_pre =
    {envpython} {toxinidir}/tools/setup_infrared.py

commands =
    ir tobiko --tobiko-src-dir '{toxinidir}' \
              --collect-dir '{env:TOX_REPORT_DIR}' \
              --workflow '{env:IR_WORKFLOW}' \
              {posargs}


# --- documentation environments ----------------------------------------------

[docs]

basepython = {[testenv:py3]basepython}
envdir = {toxworkdir}/docs
deps =
    {env:TOX_CONSTRAINTS}
    -r{toxinidir}/doc/readthedocs_requirements.txt
commands =

[testenv:linkcheck]
allowlist_externals = sh
basepython = {[docs]basepython}
envdir = {[docs]envdir}
deps = {[docs]deps}
commands =
    {[docs]commands}
    sh -c 'cd {toxinidir}/doc/source && sphinx-build -W --keep-going -b linkcheck . ../build/linkcheck'
usedevelop = true
skipsdist = true
skip_install = true


[testenv:docs]
allowlist_externals = sh
basepython = {[docs]basepython}
envdir = {[docs]envdir}
deps = {[docs]deps}
changedir = doc/source
commands =
    {[testenv:linkcheck]commands}
    sphinx-build -W --keep-going -b html . ../build/html
usedevelop = true
skipsdist = true
skip_install = true


[testenv:releasenotes]

basepython = {[docs]basepython}
deps = {[docs]deps}
commands =
    sphinx-build -a -E -W -d releasenotes/build/doctrees -b html releasenotes/source releasenotes/build/html
# Do not install any requirements. We want this to be fast and work even if
# system dependencies are missing, since it's used to tell you what system
# dependencies are missing! This also means that bindep must be installed
# separately, outside of the requirements files.
usedevelop = false
skipsdist = true
skip_install = true


# --- CI report environments --------------------------------------------------


[testenv:bindep]
basepython = {[testenv:py3]basepython}
# Do not install any requirements. We want this to be fast and work even if
# system dependencies are missing, since it's used to tell you what system
# dependencies are missing! This also means that bindep must be installed
# separately, outside of the requirements files.
usedevelop = false
skipsdist = true
skip_install = true
deps = bindep
commands = bindep {posargs:test}
commands_pre =
