[tox] envlist = py3, black, flake8, isort, mypy, pylint recreate = True [doc8] ignore-path-errors=doc/rtd/topics/faq.rst;D001 [testenv] basepython = python3 setenv = LC_ALL = en_US.utf-8 passenv= PYTEST_ADDOPTS HYPOTHESIS_PROFILE [format_deps] black==22.3.0 flake8==4.0.1 hypothesis==6.31.6 hypothesis_jsonschema==0.20.1 isort==5.10.1 mypy==0.950 pylint==2.13.9 pytest==7.0.1 types-jsonschema==4.4.2 types-oauthlib==3.1.6 types-PyYAML==6.0.4 types-requests==2.27.8 types-setuptools==57.4.9 typing-extensions==4.1.1 [files] schema = cloudinit/config/schemas/schema-cloud-config-v1.json version = cloudinit/config/schemas/versions.schema.cloud-config.json [testenv:flake8] deps = flake8=={[format_deps]flake8} commands = {envpython} -m flake8 {posargs:cloudinit/ tests/ tools/ conftest.py setup.py} [testenv:pylint] deps = pylint=={[format_deps]pylint} -r{toxinidir}/test-requirements.txt -r{toxinidir}/integration-requirements.txt commands = {envpython} -m pylint {posargs:cloudinit/ tests/ tools/ conftest.py setup.py} [testenv:black] deps = black=={[format_deps]black} commands = {envpython} -m black . --check [testenv:isort] deps = isort=={[format_deps]isort} commands = {envpython} -m isort . --check-only [testenv:mypy] deps = hypothesis=={[format_deps]hypothesis} hypothesis_jsonschema=={[format_deps]hypothesis_jsonschema} mypy=={[format_deps]mypy} pytest=={[format_deps]pytest} types-jsonschema=={[format_deps]types-jsonschema} types-oauthlib=={[format_deps]types-oauthlib} types-pyyaml=={[format_deps]types-PyYAML} types-requests=={[format_deps]types-requests} types-setuptools=={[format_deps]types-setuptools} typing-extensions=={[format_deps]typing-extensions} commands = {envpython} -m mypy cloudinit/ tests/ tools/ [testenv:check_format] deps = black=={[format_deps]black} flake8=={[format_deps]flake8} hypothesis=={[format_deps]hypothesis} hypothesis_jsonschema=={[format_deps]hypothesis_jsonschema} isort=={[format_deps]isort} mypy=={[format_deps]mypy} pylint=={[format_deps]pylint} pytest=={[format_deps]pytest} types-jsonschema=={[format_deps]types-jsonschema} types-oauthlib=={[format_deps]types-oauthlib} types-pyyaml=={[format_deps]types-PyYAML} types-requests=={[format_deps]types-requests} types-setuptools=={[format_deps]types-setuptools} typing-extensions=={[format_deps]typing-extensions} -r{toxinidir}/test-requirements.txt -r{toxinidir}/integration-requirements.txt commands = {[testenv:black]commands} {[testenv:flake8]commands} {[testenv:isort]commands} {[testenv:mypy]commands} {[testenv:pylint]commands} [testenv:check_format_tip] deps = black flake8 hypothesis hypothesis_jsonschema isort mypy pylint pytest types-jsonschema types-oauthlib types-pyyaml types-requests types-setuptools typing-extensions -r{toxinidir}/test-requirements.txt -r{toxinidir}/integration-requirements.txt commands = {[testenv:check_format]commands} [testenv:do_format] deps = black=={[format_deps]black} isort=={[format_deps]isort} commands = {envpython} -m isort . {envpython} -m black . {envpython} -m json.tool --indent 2 {[files]schema} {[files]schema} {envpython} -m json.tool --indent 2 {[files]version} {[files]version} [testenv:do_format_tip] deps = black isort commands = {[testenv:do_format]commands} [testenv:py3] deps = -r{toxinidir}/test-requirements.txt commands = {envpython} -m pytest \ -vvvv --showlocals \ --durations 10 \ -m "not hypothesis_slow" \ {posargs:--cov=cloudinit --cov-branch tests/unittests} # experimental [testenv:py3-fast] deps = -r{toxinidir}/test-requirements.txt pytest-xdist commands = {envpython} -m pytest -n auto -m "not hypothesis_slow" -m "not serial"\ {posargs:tests/unittests} [testenv:hypothesis-slow] deps = hypothesis==6.31.6 hypothesis_jsonschema==0.20.1 -r{toxinidir}/test-requirements.txt commands = {envpython} -m pytest \ -m hypothesis_slow \ {posargs:--hypothesis-show-statistics tests/unittests} #commands = {envpython} -X tracemalloc=40 -Werror::ResourceWarning:cloudinit -m pytest \ [testenv:py3-leak] deps = {[testenv:py3]deps} commands = {envpython} -X tracemalloc=40 -Wall -m pytest \ --durations 10 \ {posargs:--cov=cloudinit --cov-branch \ tests/unittests} [testenv:lowest-supported] # Tox is going to install requirements from pip. This is fine for # testing python version compatibility, but when we build cloud-init, we are # building against the dependencies in the OS repo, not pip. The OS # dependencies will generally be older than what is found in pip. # To obtain these versions, check the versions of these libraries # in the oldest support Ubuntu distro. Theses versions are from bionic. deps = jinja2==2.10 oauthlib==2.0.6 pyserial==3.4 configobj==5.0.6 pyyaml==3.12 requests==2.18.4 jsonpatch==1.16 jsonschema==2.6.0 netifaces==0.10.4 # test-requirements pytest==3.3.2 pytest-cov==2.5.1 pytest-mock==1.7.1 # Needed by pytest and default causes failures attrs==17.4.0 responses==0.5.1 commands = {[testenv:py3]commands} [testenv:doc] deps = -r{toxinidir}/doc-requirements.txt commands = {envpython} -m sphinx {posargs:-W doc/rtd doc/rtd_html} doc8 doc/rtd # linkcheck shows false positives and has noisy output. # Despite these limitations, it is better than a manual search of the docs. # suggested workflow is: # # tox -e linkcheck | grep broken # takes some time # # followed by manual verification of the links reported [testenv:linkcheck] deps = -r{toxinidir}/doc-requirements.txt commands = {envpython} -m sphinx {posargs:-b linkcheck doc/rtd doc/rtd_html} [testenv:tip-flake8] deps = flake8 commands = {[testenv:flake8]commands} [testenv:tip-mypy] deps = hypothesis hypothesis_jsonschema mypy pytest types-jsonschema types-oauthlib types-PyYAML types-requests types-setuptools commands = {[testenv:mypy]commands} [testenv:tip-pylint] deps = # requirements pylint # test-requirements -r{toxinidir}/test-requirements.txt -r{toxinidir}/integration-requirements.txt commands = {[testenv:pylint]commands} [testenv:tip-black] deps = black commands = {[testenv:black]commands} [testenv:tip-isort] deps = isort commands = {[testenv:isort]commands} [testenv:integration-tests] commands = {envpython} -m pytest -vv \ --log-cli-level=INFO \ --durations 10 \ {posargs:tests/integration_tests} deps = -r{toxinidir}/integration-requirements.txt passenv = CLOUD_INIT_* PYCLOUDLIB_* SSH_AUTH_SOCK OS_* [testenv:integration-tests-ci] commands = {[testenv:integration-tests]commands} deps = {[testenv:integration-tests]deps} passenv = CLOUD_INIT_* SSH_AUTH_SOCK OS_* TRAVIS setenv = PYTEST_ADDOPTS="-m ci and not adhoc" [testenv:integration-tests-jenkins] # Pytest's RC=1 means "Tests were collected and run but some of the tests failed". # Do not fail in this case, but let Jenkins handle it using the junit report. allowlist_externals = sh commands = sh -c "{envpython} -m pytest --log-cli-level=INFO -vv {posargs:tests/integration_tests/none} || [ $? -eq 1 ]" deps = {[testenv:integration-tests]deps} passenv = *_proxy CLOUD_INIT_* PYCLOUDLIB_* SSH_AUTH_SOCK OS_* GOOGLE_* GCP_* setenv = PYTEST_ADDOPTS="-m not adhoc" [flake8] # E203: whitespace before ':', doesn't adhere to pep8 or black formatting # W503: line break before binary operator ignore=E203,W503 exclude = .venv,.tox,dist,doc,*egg,.git,build,tools per-file-ignores = cloudinit/cmd/main.py:E402 [pytest] # TODO: s/--strict/--strict-markers/ once pytest version is high enough testpaths = tests/unittests addopts = --strict log_format = %(asctime)s %(levelname)-9s %(name)s:%(filename)s:%(lineno)d %(message)s log_date_format = %Y-%m-%d %H:%M:%S markers = adhoc: only run on adhoc basis, not in any CI environment (travis or jenkins) allow_all_subp: allow all subp usage (disable_subp_usage) allow_subp_for: allow subp usage for the given commands (disable_subp_usage) ci: run this integration test as part of CI test runs ds_sys_cfg: a sys_cfg dict to be used by datasource fixtures hypothesis_slow: hypothesis test too slow to run as unit test instance_name: the name to be used for the test instance integration_cloud_args: args for IntegrationCloud customization is_iscsi: whether is an instance has iscsi net cfg or not lxd_config_dict: set the config_dict passed on LXD instance creation lxd_setup: specify callable to be called between init and start lxd_use_exec: `execute` will use `lxc exec` instead of SSH serial: tests that do not work in parallel, skipped with py3-fast unstable: skip this test because it is flakey user_data: the user data to be passed to the test instance allow_dns_lookup: disable autochecking for host network configuration