diff options
-rw-r--r-- | .pylintrc | 152 | ||||
-rwxr-xr-x | docs/testing/developer/devguide/devguide.rst | 2 | ||||
-rw-r--r-- | requirements.txt | 163 | ||||
-rw-r--r-- | test-requirements.txt | 10 | ||||
-rw-r--r-- | tools/coding-checks.sh | 59 | ||||
-rw-r--r-- | tools/cover.awk (renamed from tests/ci/cover.awk) | 0 | ||||
-rw-r--r-- | tools/cover.sh (renamed from tests/ci/cover.sh) | 0 | ||||
-rwxr-xr-x | tools/run_tests.sh (renamed from run_tests.sh) | 53 | ||||
-rw-r--r-- | tox.ini | 49 |
9 files changed, 349 insertions, 139 deletions
diff --git a/.pylintrc b/.pylintrc new file mode 100644 index 000000000..c72427220 --- /dev/null +++ b/.pylintrc @@ -0,0 +1,152 @@ +[MASTER] + +# List of plugins (as comma separated values of python modules names) to load, +# usually to register additional checkers. +load-plugins= + +# Use multiple processes to speed up Pylint. +jobs=1 + +# A comma-separated list of package or module names from where C extensions may +# be loaded. Extensions are loading into the active Python interpreter and may +# run arbitrary code +extension-pkg-whitelist= + + +[MESSAGES CONTROL] + +# --disable=W" +disable= +# "F" Fatal errors that prevent further processing + import-error, +# "I" Informational noise + locally-disabled, +# "E" Error for important programming issues (likely bugs) + access-member-before-definition, + no-member, + no-method-argument, + no-self-argument, + not-an-iterable, +# "W" Warnings for stylistic problems or minor programming issues + abstract-method, + arguments-differ, + attribute-defined-outside-init, + bad-builtin, + bad-indentation, + dangerous-default-value, + deprecated-lambda, + expression-not-assigned, + global-statement, + literal-comparison, + no-init, + non-parent-init-called, + not-callable, + redefined-builtin, + redefined-outer-name, + signature-differs, + star-args, + super-init-not-called, + super-on-old-class, + unpacking-non-sequence, + useless-super-delegation, + nonstandard-exception, +# "C" Coding convention violations + bad-continuation, + consider-iterating-dictionary, + consider-using-enumerate, + invalid-name, + len-as-condition, + misplaced-comparison-constant, + singleton-comparison, + superfluous-parens, + ungrouped-imports, + wrong-import-order, +# "R" Refactor recommendations + abstract-class-little-used, + abstract-class-not-used, + consider-merging-isinstance, + consider-using-ternary, + duplicate-code, + interface-not-implemented, + no-else-return, + no-self-use, + redefined-argument-from-local, + simplifiable-if-statement, + too-few-public-methods, + too-many-ancestors, + too-many-arguments, + too-many-branches, + too-many-instance-attributes, + too-many-lines, + too-many-locals, + too-many-nested-blocks, + too-many-public-methods, + too-many-return-statements, + too-many-statements + +[BASIC] +# Variable names can be 1 to 31 characters long, with lowercase and underscores +variable-rgx=[a-z_][a-z0-9_]{0,30}$ + +# Argument names can be 2 to 31 characters long, with lowercase and underscores +argument-rgx=[a-z_][a-z0-9_]{1,30}$ + +# Method names should be at least 3 characters long +# and be lowercased with underscores +method-rgx=([a-z_][a-z0-9_]{2,}|setUp|tearDown)$ + +# Module names matching neutron-* are ok (files in bin/) +module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ + +# Don't require docstrings on tests. +no-docstring-rgx=((__.*__)|([tT]est.*)|setUp|tearDown)$ + +dummy-variables-rgx=(_+[a-zA-Z0-9]*?$)|dummy|args + +[FORMAT] +# Maximum number of characters on a single line. +max-line-length=99 + +# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 +# tab). +indent-string=' ' + + +[VARIABLES] +# List of additional names supposed to be defined in builtins. Remember that +# you should avoid to define new builtins when possible. +# _ is used by our localization +additional-builtins=_ + + +[CLASSES] +# List of interface methods to ignore, separated by a comma. +ignore-iface-methods= + + +[TYPECHECK] +# List of module names for which member attributes should not be checked +ignored-modules=six.moves,_MovedItems + + +[REPORTS] +# Tells whether to display a full report or only the messages +reports=no + +# Set the output format. Available formats are text, parseable, colorized, msvs +# (visual studio) and html. You can also give a reporter class, eg +# mypackage.mymodule.MyReporterClass. +output-format=colorized + +# Python expression which should return a note less than 10 (10 is the highest +# note). You have access to the variables errors warning, statement which +# respectively contain the number of errors / warnings messages and the total +# number of statements analyzed. This is used by the global evaluation report +# (RP0004). +evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) + + +[MISCELLANEOUS] + +# List of note tags to take in consideration, separated by a comma. +notes=FIXME,XXX,TODO diff --git a/docs/testing/developer/devguide/devguide.rst b/docs/testing/developer/devguide/devguide.rst index da7629add..4f69456fc 100755 --- a/docs/testing/developer/devguide/devguide.rst +++ b/docs/testing/developer/devguide/devguide.rst @@ -372,7 +372,7 @@ directory using the ``cd`` command. Assume that ``YARDSTICK_REPO_DIR`` is the pa Verify your patch:: - ./run_tests.sh + tox It is used in CI but also by the CLI. diff --git a/requirements.txt b/requirements.txt index a16fce3ca..7715f8510 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,92 +7,81 @@ # http://www.apache.org/licenses/LICENSE-2.0 ############################################################################## -Babel==2.3.4 # BSD; OSI Approved BSD License -Jinja2==2.8.1 # BSD; OSI Approved BSD License -MarkupSafe==0.23 # BSD; OSI Approved BSD License -PyYAML==3.12 # MIT; OSI Approved MIT License -SQLAlchemy==1.1.4 # MIT License; OSI Approved MIT License -ansible==2.3.2 # GPLv3; OSI Approved GNU General Public License v3 or later (GPLv3+) -appdirs==1.4.3 # MIT; OSI Approved MIT License -backport-ipaddress==0.1; python_version <= "2.7" # OSI Approved Python Software Foundation License -chainmap==1.0.2 # Python Software Foundation License; OSI Approved Python Software Foundation License -cliff==2.4.0 # OSI Approved Apache Software License -cmd2==0.6.9 # MIT; OSI Approved MIT License -coverage==4.3.4 # Apache 2.0; OSI Approved Apache Software License; http://www.apache.org/licenses/LICENSE-2.0; http://www.apache.org/licenses/LICENSE-2.0 -debtcollector==1.11.0 # OSI Approved Apache Software License -django==1.8.17 # BSD; OSI Approved BSD License -docker-py==1.10.6 # OSI Approved Apache Software License -ecdsa==0.13 # MIT -extras==1.0.0 # OSI Approved MIT License -fixtures==3.0.0 # OSI Approved BSD License; OSI Approved Apache Software License -flake8==2.5.4 # MIT; OSI Approved MIT License -flasgger==0.5.13 # MIT -flask-restful-swagger==0.19 # MIT -flask-restful==0.3.5 # BSD; OSI Approved BSD License -flask==0.11.1 # BSD; OSI Approved BSD License -funcsigs==1.0.2 # ASL; OSI Approved Apache Software License -functools32==3.2.3.post2; python_version <= "2.7" # PSF license -futures==3.0.5 # BSD; OSI Approved BSD License -influxdb==4.0.0 # MIT License; OSI Approved MIT License -iso8601==0.1.11 # MIT; OSI Approved MIT License -jsonpatch==1.15 # Modified BSD License; OSI Approved BSD License -jsonpointer==1.10 # Modified BSD License; OSI Approved BSD License -jsonschema==2.5.1 # MIT; OSI Approved MIT License -jinja2schema==0.1.4 # OSI Approved BSD License -keystoneauth1==2.18.0 # OSI Approved Apache Software License -kubernetes==3.0.0a1 # OSI Approved Apache Software License -linecache2==1.0.0 # OSI Approved Python Software Foundation License -lxml==3.7.2 # OSI Approved BSD License -mccabe==0.4.0 # Expat license; OSI Approved MIT License +Babel==2.3.4 # BSD; OSI Approved BSD License +Jinja2==2.8.1 # BSD; OSI Approved BSD License +MarkupSafe==0.23 # BSD; OSI Approved BSD License +PyYAML==3.12 # MIT; OSI Approved MIT License +SQLAlchemy==1.1.4 # MIT License; OSI Approved MIT License +ansible==2.3.2 # GPLv3; OSI Approved GNU General Public License v3 or later (GPLv3+) +appdirs==1.4.3 # MIT; OSI Approved MIT License +backport-ipaddress==0.1; python_version <= "2.7" # OSI Approved Python Software Foundation License +chainmap==1.0.2 # Python Software Foundation License; OSI Approved Python Software Foundation License +cliff==2.4.0 # OSI Approved Apache Software License +cmd2==0.6.9 # MIT; OSI Approved MIT License +debtcollector==1.11.0 # OSI Approved Apache Software License +django==1.8.17 # BSD; OSI Approved BSD License +docker-py==1.10.6 # OSI Approved Apache Software License +ecdsa==0.13 # MIT +extras==1.0.0 # OSI Approved MIT License +flasgger==0.5.13 # MIT +flask-restful-swagger==0.19 # MIT +flask-restful==0.3.5 # BSD; OSI Approved BSD License +flask==0.11.1 # BSD; OSI Approved BSD License +funcsigs==1.0.2 # ASL; OSI Approved Apache Software License +functools32==3.2.3.post2; python_version <= "2.7" # PSF license +futures==3.0.5 # BSD; OSI Approved BSD License +influxdb==4.0.0 # MIT License; OSI Approved MIT License +iso8601==0.1.11 # MIT; OSI Approved MIT License +jsonpatch==1.15 # Modified BSD License; OSI Approved BSD License +jsonpointer==1.10 # Modified BSD License; OSI Approved BSD License +jsonschema==2.5.1 # MIT; OSI Approved MIT License +jinja2schema==0.1.4 # OSI Approved BSD License +keystoneauth1==2.18.0 # OSI Approved Apache Software License +kubernetes==3.0.0a1 # OSI Approved Apache Software License +linecache2==1.0.0 # OSI Approved Python Software Foundation License +lxml==3.7.2 # OSI Approved BSD License # upgrade to version 2.0.0 to match python3 unittest.mock features -mock==2.0.0 # OSI Approved BSD License; `BSD License`_; http://github.com/testing-cabal/mock/blob/master/LICENSE.txt -monotonic==1.2 # Apache; OSI Approved Apache Software License -msgpack-python==0.4.8 # OSI Approved Apache Software License -netaddr==0.7.19 # BSD License; OSI Approved BSD License; OSI Approved MIT License -netifaces==0.10.5 # MIT License; OSI Approved MIT License -nose==1.3.7 # GNU LGPL; OSI Approved GNU Library or Lesser General Public License (LGPL) -openstacksdk==0.9.13 # OSI Approved Apache Software License -os-client-config==1.26.0 # OSI Approved Apache Software License -osc-lib==1.3.0 # OSI Approved Apache Software License -oslo.config==3.22.0 # OSI Approved Apache Software License -oslo.i18n==3.12.0 # OSI Approved Apache Software License -oslo.serialization==2.16.0 # OSI Approved Apache Software License -oslo.utils==3.22.0 # OSI Approved Apache Software License -paramiko==2.1.1 # LGPL; OSI Approved GNU Library or Lesser General Public License (LGPL) -pbr==1.10.0 # OSI Approved Apache Software License; Apache License, Version 2.0 -pep8==1.7.0 # Expat license; OSI Approved MIT License +mock==2.0.0 # OSI Approved BSD License; `BSD License`_; http://github.com/testing-cabal/mock/blob/master/LICENSE.txt +monotonic==1.2 # Apache; OSI Approved Apache Software License +msgpack-python==0.4.8 # OSI Approved Apache Software License +netaddr==0.7.19 # BSD License; OSI Approved BSD License; OSI Approved MIT License +netifaces==0.10.5 # MIT License; OSI Approved MIT License +openstacksdk==0.9.13 # OSI Approved Apache Software License +os-client-config==1.26.0 # OSI Approved Apache Software License +osc-lib==1.3.0 # OSI Approved Apache Software License +oslo.config==3.22.0 # OSI Approved Apache Software License +oslo.i18n==3.12.0 # OSI Approved Apache Software License +oslo.serialization==2.16.0 # OSI Approved Apache Software License +oslo.utils==3.22.0 # OSI Approved Apache Software License +paramiko==2.1.1 # LGPL; OSI Approved GNU Library or Lesser General Public License (LGPL) +pbr==1.10.0 # OSI Approved Apache Software License; Apache License, Version 2.0 # version 14.5.0 for compatibility with trex traffic generator -pika==0.10.0 # BSD; OSI Approved BSD License -positional==1.1.1 # OSI Approved Apache Software License -prettytable==0.7.2 # BSD (3 clause); OSI Approved BSD License -pycrypto==2.6.1 # Public Domain -pyflakes==1.0.0 # MIT; OSI Approved MIT License -pyparsing==2.1.10 # MIT License; OSI Approved MIT License -pyroute2==0.4.12 # dual license GPLv2+ and Apache v2; OSI Approved GNU General Public License v2 or later (GPLv2+); OSI Approved Apache Software License -pyrsistent==0.11.12 # LICENSE.mit; OSI Approved MIT License -python-cinderclient==1.11.0 # OSI Approved Apache Software License -python-glanceclient==2.6.0 # OSI Approved Apache Software License -python-heatclient==1.8.1 # OSI Approved Apache Software License -python-keystoneclient==3.10.0 # OSI Approved Apache Software License -python-mimeparse==1.6.0 # OSI Approved MIT License -python-neutronclient==6.1.0 # OSI Approved Apache Software License -python-novaclient==7.1.1 # OSI Approved Apache Software License -python-openstackclient==3.8.1 # OSI Approved Apache Software License -python-subunit==1.2.0 # OSI Approved Apache Software License; OSI Approved BSD License -python-swiftclient==3.3.0 # OSI Approved Apache Software License -pytz==2016.10 # MIT; OSI Approved MIT License -pyzmq==14.5.0 # LGPL+BSD; OSI Approved GNU Library or Lesser General Public License (LGPL); OSI Approved BSD License -requests==2.13.0 # Apache 2.0; OSI Approved Apache Software License -requestsexceptions==1.1.3 # OSI Approved Apache Software License -scp==0.10.2 # LGPL -shade==1.17.0 # OSI Approved Apache Software License -simplejson==3.10.0 # MIT License; OSI Approved MIT License; OSI Approved Academic Free License (AFL) -six==1.10.0 # MIT; OSI Approved MIT License -stevedore==1.20.0 # OSI Approved Apache Software License -testrepository==0.0.20 # OSI Approved BSD License; OSI Approved Apache Software License -testtools==2.2.0 # OSI Approved MIT License -traceback2==1.4.0 # OSI Approved Python Software Foundation License -unicodecsv==0.14.1 # BSD License; OSI Approved BSD License -unittest2==1.1.0 # OSI Approved BSD License -warlock==1.2.0 # OSI Approved Apache Software License -wrapt==1.10.8 # BSD +pika==0.10.0 # BSD; OSI Approved BSD License +positional==1.1.1 # OSI Approved Apache Software License +prettytable==0.7.2 # BSD (3 clause); OSI Approved BSD License +pycrypto==2.6.1 # Public Domain +pyparsing==2.1.10 # MIT License; OSI Approved MIT License +pyroute2==0.4.12 # dual license GPLv2+ and Apache v2; OSI Approved GNU General Public License v2 or later (GPLv2+); OSI Approved Apache Software License +pyrsistent==0.11.12 # LICENSE.mit; OSI Approved MIT License +python-cinderclient==1.11.0 # OSI Approved Apache Software License +python-glanceclient==2.6.0 # OSI Approved Apache Software License +python-heatclient==1.8.1 # OSI Approved Apache Software License +python-keystoneclient==3.10.0 # OSI Approved Apache Software License +python-mimeparse==1.6.0 # OSI Approved MIT License +python-neutronclient==6.1.0 # OSI Approved Apache Software License +python-novaclient==7.1.1 # OSI Approved Apache Software License +python-openstackclient==3.8.1 # OSI Approved Apache Software License +python-swiftclient==3.3.0 # OSI Approved Apache Software License +pytz==2016.10 # MIT; OSI Approved MIT License +pyzmq==14.5.0 # LGPL+BSD; OSI Approved GNU Library or Lesser General Public License (LGPL); OSI Approved BSD License +requests==2.13.0 # Apache 2.0; OSI Approved Apache Software License +requestsexceptions==1.1.3 # OSI Approved Apache Software License +scp==0.10.2 # LGPL +shade==1.17.0 # OSI Approved Apache Software License +simplejson==3.10.0 # MIT License; OSI Approved MIT License; OSI Approved Academic Free License (AFL) +six==1.10.0 # MIT; OSI Approved MIT License +stevedore==1.20.0 # OSI Approved Apache Software License +traceback2==1.4.0 # OSI Approved Python Software Foundation License +unicodecsv==0.14.1 # BSD License; OSI Approved BSD License +warlock==1.2.0 # OSI Approved Apache Software License +wrapt==1.10.8 # BSD diff --git a/test-requirements.txt b/test-requirements.txt index 538777039..a635bd1d6 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -2,7 +2,17 @@ # of appearance. Changing the order has an impact on the overall integration # process, which may cause wedges in the gate later. +coverage==4.3.4 # Apache 2.0; OSI Approved Apache Software License; http://www.apache.org/licenses/LICENSE-2.0; http://www.apache.org/licenses/LICENSE-2.0 +fixtures==3.0.0 # OSI Approved BSD License; OSI Approved Apache Software License +flake8==2.5.4 # MIT; OSI Approved MIT License packaging==16.8.0 # BSD or Apache License, Version 2.0 +pep8==1.7.0 # Expat license; OSI Approved MIT License +pyflakes==1.0.0 # MIT; OSI Approved MIT License +pylint +python-subunit==1.2.0 # OSI Approved Apache Software License; OSI Approved BSD License +testrepository==0.0.20 # OSI Approved BSD License; OSI Approved Apache Software License +testtools==2.2.0 # OSI Approved MIT License +unittest2==1.1.0 # OSI Approved BSD License # Yardstick F release <-> OpenStack Pike release openstack_requirements==1.1.0 # OSI Approved Apache Software License diff --git a/tools/coding-checks.sh b/tools/coding-checks.sh new file mode 100644 index 000000000..4ee909988 --- /dev/null +++ b/tools/coding-checks.sh @@ -0,0 +1,59 @@ +#!/bin/sh +# source: https://github.com/openstack/neutron/blob/master/tools/coding-checks.sh + +set -eu + +usage () { + echo "Usage: $0 [OPTION]..." + echo "Run Yardstick's coding check(s)" + echo "" + echo " -Y, --pylint [<basecommit>] Run pylint check on the entire neutron module or just files changed in basecommit (e.g. HEAD~1)" + echo " -h, --help Print this usage message" + echo + exit 0 +} + +process_options () { + i=1 + while [ $i -le $# ]; do + eval opt=\$$i + case $opt in + -h|--help) usage;; + -Y|--pylint) pylint=1;; + *) scriptargs="$scriptargs $opt" + esac + i=$((i+1)) + done +} + +run_pylint () { + local target="${scriptargs:-all}" + + if [ "$target" = "all" ]; then + files="ansible api tests yardstick" + else + case "$target" in + *HEAD*|*HEAD~[0-9]*) files=$(git diff --diff-filter=AM --name-only $target -- "*.py");; + *) echo "$target is an unrecognized basecommit"; exit 1;; + esac + fi + + echo "Running pylint..." + echo "You can speed this up by running it on 'HEAD~[0-9]' (e.g. HEAD~0, this change only)..." + if [ -n "${files}" ]; then + pylint --rcfile=.pylintrc ${files} + else + echo "No python changes in this commit, pylint check not required." + exit 0 + fi +} + +scriptargs= +pylint=1 + +process_options $@ + +if [ $pylint -eq 1 ]; then + run_pylint + exit 0 +fi diff --git a/tests/ci/cover.awk b/tools/cover.awk index e4bb816dc..e4bb816dc 100644 --- a/tests/ci/cover.awk +++ b/tools/cover.awk diff --git a/tests/ci/cover.sh b/tools/cover.sh index 780a85a22..780a85a22 100644 --- a/tests/ci/cover.sh +++ b/tools/cover.sh diff --git a/run_tests.sh b/tools/run_tests.sh index b3cbfb127..f253327e5 100755 --- a/run_tests.sh +++ b/tools/run_tests.sh @@ -9,9 +9,10 @@ # http://www.apache.org/licenses/LICENSE-2.0 ############################################################################## -# Run yardstick's flake8, unit, coverage, functional test +# Run yardstick's unit, coverage, functional test getopts ":f" FILE_OPTION +opts=$@ # get other args # don't write .pyc files this can cause odd unittest results export PYTHONDONTWRITEBYTECODE=1 @@ -19,30 +20,9 @@ export PYTHONDONTWRITEBYTECODE=1 PY_VER="py$( python --version | sed 's/[^[:digit:]]//g' | cut -c-2 )" export PY_VER -COVER_DIR_NAME="./tests/ci/" +COVER_DIR_NAME="./tools/" export COVER_DIR_NAME -run_flake8() { - echo "Running flake8 ... " - logfile=test_results.log - if [ $FILE_OPTION == "f" ]; then - flake8 yardstick > $logfile - else - flake8 yardstick - fi - - if [ $? -ne 0 ]; then - echo "FAILED" - if [ $FILE_OPTION == "f" ]; then - echo "Results in $logfile" - fi - exit 1 - else - echo "OK" - fi -} - - run_tests() { echo "Get external libs needed for unit test" @@ -66,11 +46,8 @@ run_tests() { } run_coverage() { - # don't re-run coverage on both py27 py3, it takes too long - if [[ -z $SKIP_COVERAGE ]] ; then - source $COVER_DIR_NAME/cover.sh - run_coverage_test - fi + source $COVER_DIR_NAME/cover.sh + run_coverage_test } run_functional_test() { @@ -89,8 +66,20 @@ run_functional_test() { fi } +if [[ $opts =~ "--unit" ]]; then + run_tests +fi + +if [[ $opts =~ "--coverage" ]]; then + run_coverage +fi + +if [[ $opts =~ "--functional" ]]; then + run_functional_test +fi -run_flake8 -run_tests -run_coverage -run_functional_test +if [[ -z $opts ]]; then + echo "No tests to run!!" + echo "Usage: run_tests.sh [--unit] [--coverage] [--functional]" + exit 1 +fi @@ -1,7 +1,7 @@ [tox] minversion = 2.0 skipsdist = True -envlist = py27,py3 +envlist = py{27,3},pep8,functional{,-py3},coverage [testenv] usedevelop=True @@ -9,27 +9,38 @@ passenv = http_proxy HTTP_PROXY https_proxy HTTPS_PROXY no_proxy NO_PROXY deps = -r{toxinidir}/requirements.txt -r{toxinidir}/test-requirements.txt -commands = /bin/bash ./run_tests.sh whitelist_externals = /bin/bash - [testenv:py27] -# don't re-run coverage on both py27 py3, it takes too long -setenv = - SKIP_COVERAGE=1 - -[flake8] -# E125 is deliberately excluded. See https://github.com/jcrocholl/pep8/issues/126 -# The rest of the ignores are TODOs -# New from hacking 0.9: E129, E131, H407, H405 -# E251 Skipped due to https://github.com/jcrocholl/pep8/issues/301 - -# nova flake8 ignores -#ignore = E121,E122,E123,E124,E125,E126,E127,E128,E129,E131,E251,H405 -# dovetail flake8 ignores -ignore = E123,E125,H803 -max-line-length = 99 -exclude = .venv,.git,.tox,dist,docs,*egg,build +commands = + /bin/bash {toxinidir}/tools/run_tests.sh --unit + +[testenv:py3] +basepython = python3 +commands = {[testenv:py27]commands} + +[testenv:pep8] +# for gate testing, scans only the files changed in the last commit +commands = + /bin/bash tools/coding-checks.sh --pylint HEAD~ '{posargs}' + +[testenv:pep8-full] +# For manual testing, scans the whole codebase +commands = + /bin/bash tools/coding-checks.sh --pylint '{posargs}' + +[testenv:coverage] +basepython = python3 +commands = + /bin/bash {toxinidir}/tools/run_tests.sh --coverage + +[testenv:functional] +commands = + /bin/bash {toxinidir}/tools/run_tests.sh --functional + +[testenv:functional-py3] +basepython = python3 +commands = {[testenv:functional]commands} [testenv:os-requirements] commands = |