Update tox and tests to work with modern setups
While trying to make some changes I discovered that the tox configuration for osc-placement was rather out of date and functional tests were not working for python3. With this change we bring tox.ini into a style that is more in keeping with modern standards, use stestr, and update some functional tests so they work with python3. The functional tests changes are either: * to fix the decoding of response * to adapt argparse error response checking between python version. These changes cascade some required change into how the gate-side functional testing is performed. We make it explicit that in the python2 job, the 'functional' tox job is run. When the python3 job is run, 'functional-py3' is run. Also stestr replaces testr in the post-test hook. When the functional-py3 test had been run in the past it was actually running a python2 osc-placement against a python3 devstack. We change that here to be python3 and python3. Once that was happening, additional failures were revealed, now fixed. One particular issue was that while the json module for python 3.6 and greater will decode strings or bytes, the version of 3.5 will only do strings. We switch to using simplejson throughout which smooths things over. This is added as a new requirement but it isn't really: simplejson is required by osc-lib. Finally, some requirements need to be tuned to pass the gate requirements job. Change-Id: I999a3103dd85c0a437785766eef533875fca31fc
This commit is contained in:
parent
bffd59ea53
commit
fc563d37bc
|
@ -0,0 +1,3 @@
|
|||
[DEFAULT]
|
||||
test_path=./osc_placement/tests/unit
|
||||
top_dir=./
|
|
@ -1,7 +0,0 @@
|
|||
[DEFAULT]
|
||||
test_command=OS_STDOUT_CAPTURE=${OS_STDOUT_CAPTURE:-1} \
|
||||
OS_STDERR_CAPTURE=${OS_STDERR_CAPTURE:-1} \
|
||||
OS_TEST_TIMEOUT=${OS_TEST_TIMEOUT:-60} \
|
||||
${PYTHON:-python} -m subunit.run discover -t ./ ${OS_TEST_PATH:-./osc_placement/tests/unit} $LISTOPT $IDOPTION
|
||||
test_id_option=--load-list $IDFILE
|
||||
test_list_option=--list
|
|
@ -11,10 +11,10 @@
|
|||
# under the License.
|
||||
|
||||
import contextlib
|
||||
import json
|
||||
|
||||
import keystoneauth1.exceptions.http as ks_exceptions
|
||||
import osc_lib.exceptions as exceptions
|
||||
import simplejson as json
|
||||
import six
|
||||
|
||||
|
||||
|
|
|
@ -10,15 +10,23 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import json
|
||||
import random
|
||||
import six
|
||||
import subprocess
|
||||
|
||||
from oslotest import base
|
||||
import simplejson as json
|
||||
|
||||
|
||||
RP_PREFIX = 'osc-placement-functional-tests-'
|
||||
|
||||
# argparse in python 2 and 3 have different error messages
|
||||
ARGUMENTS_MISSING = 'too few arguments'
|
||||
ARGUMENTS_REQUIRED = 'argument %s is required'
|
||||
if six.PY3:
|
||||
ARGUMENTS_MISSING = 'the following arguments are required'
|
||||
ARGUMENTS_REQUIRED = 'the following arguments are required: %s'
|
||||
|
||||
|
||||
class BaseTestCase(base.BaseTestCase):
|
||||
VERSION = None
|
||||
|
@ -74,7 +82,7 @@ class BaseTestCase(base.BaseTestCase):
|
|||
|
||||
except subprocess.CalledProcessError as e:
|
||||
self.assertIn(
|
||||
message, e.output,
|
||||
message, six.text_type(e.output),
|
||||
'Command "%s" fails with different message' % e.cmd)
|
||||
|
||||
def resource_provider_create(self,
|
||||
|
|
|
@ -14,9 +14,11 @@
|
|||
|
||||
# This script is executed inside post_test_hook function in devstack gate.
|
||||
|
||||
TOX_ENV=${TOX_ENV:-functional}
|
||||
|
||||
function generate_testr_results {
|
||||
if [ -f .testrepository/0 ]; then
|
||||
.tox/functional/bin/testr last --subunit > $WORKSPACE/testrepository.subunit
|
||||
if [ -f .stestr/0 ]; then
|
||||
.tox/$TOX_ENV/bin/stestr last --subunit > $WORKSPACE/testrepository.subunit
|
||||
mv $WORKSPACE/testrepository.subunit $BASE/logs/testrepository.subunit
|
||||
/usr/os-testr-env/bin/subunit2html $BASE/logs/testrepository.subunit $BASE/logs/testr_results.html
|
||||
gzip -9 $BASE/logs/testrepository.subunit
|
||||
|
@ -37,7 +39,7 @@ echo "Running osc-placement functional test suite"
|
|||
set +e
|
||||
# Preserve env for OS_ credentials
|
||||
source $BASE/new/devstack/openrc admin admin
|
||||
tox -e ${TOX_ENV:-functional}
|
||||
tox -e $TOX_ENV
|
||||
EXIT_CODE=$?
|
||||
set -e
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ class TestAggregate(base.BaseTestCase):
|
|||
|
||||
def test_fail_if_no_rp(self):
|
||||
self.assertCommandFailed(
|
||||
'too few arguments',
|
||||
base.ARGUMENTS_MISSING,
|
||||
self.openstack,
|
||||
'resource provider aggregate list')
|
||||
|
||||
|
@ -50,7 +50,7 @@ class TestAggregate(base.BaseTestCase):
|
|||
|
||||
def test_set_aggregate_fail_if_no_rp(self):
|
||||
self.assertCommandFailed(
|
||||
'too few arguments',
|
||||
base.ARGUMENTS_MISSING,
|
||||
self.openstack,
|
||||
'resource provider aggregate set')
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@ class TestInventory(base.BaseTestCase):
|
|||
# Negative test to assert command failure because
|
||||
# microversion < 1.5 and --resource-class is not specified.
|
||||
self.assertCommandFailed(
|
||||
'argument --resource-class is required',
|
||||
base.ARGUMENTS_REQUIRED % '--resource-class',
|
||||
self.resource_inventory_delete,
|
||||
'fake_uuid')
|
||||
|
||||
|
@ -77,7 +77,7 @@ class TestSetInventory(base.BaseTestCase):
|
|||
exc = self.assertRaises(
|
||||
subprocess.CalledProcessError,
|
||||
self.openstack, 'resource provider inventory set')
|
||||
self.assertIn('too few arguments', exc.output.decode('utf-8'))
|
||||
self.assertIn(base.ARGUMENTS_MISSING, exc.output.decode('utf-8'))
|
||||
|
||||
def test_set_empty_inventories(self):
|
||||
rp = self.resource_provider_create()
|
||||
|
@ -173,11 +173,11 @@ class TestSetInventory(base.BaseTestCase):
|
|||
exc = self.assertRaises(
|
||||
subprocess.CalledProcessError,
|
||||
self.openstack, 'resource provider inventory class set')
|
||||
self.assertIn('too few arguments', exc.output.decode('utf-8'))
|
||||
self.assertIn(base.ARGUMENTS_MISSING, exc.output.decode('utf-8'))
|
||||
exc = self.assertRaises(
|
||||
subprocess.CalledProcessError,
|
||||
self.openstack, 'resource provider inventory class set fake_uuid')
|
||||
self.assertIn('too few arguments', exc.output.decode('utf-8'))
|
||||
self.assertIn(base.ARGUMENTS_MISSING, exc.output.decode('utf-8'))
|
||||
exc = self.assertRaises(
|
||||
subprocess.CalledProcessError,
|
||||
self.openstack,
|
||||
|
@ -189,7 +189,7 @@ class TestSetInventory(base.BaseTestCase):
|
|||
exc = self.assertRaises(
|
||||
subprocess.CalledProcessError, self.openstack,
|
||||
'resource provider inventory class set %s VCPU' % rp['uuid'])
|
||||
self.assertIn('argument --total is required',
|
||||
self.assertIn(base.ARGUMENTS_REQUIRED % '--total',
|
||||
exc.output.decode('utf-8'))
|
||||
|
||||
def test_set_inventory_for_resource_class(self):
|
||||
|
|
|
@ -18,4 +18,4 @@ from oslotest import base
|
|||
class TestPlugin(base.BaseTestCase):
|
||||
def test_parser_options(self):
|
||||
output = subprocess.check_output(['openstack', '--help'])
|
||||
self.assertIn('--os-placement-api-version', output)
|
||||
self.assertIn('--os-placement-api-version', output.decode('utf-8'))
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import json
|
||||
|
||||
import mock
|
||||
import six
|
||||
|
@ -18,6 +17,7 @@ import six
|
|||
import keystoneauth1.exceptions.http as ks_exceptions
|
||||
import osc_lib.exceptions as exceptions
|
||||
import oslotest.base as base
|
||||
import simplejson as json
|
||||
|
||||
import osc_placement.http as http
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
export PYTHONUNBUFFERED=true
|
||||
export DEVSTACK_PROJECT_FROM_GIT=osc-placement
|
||||
export DEVSTACK_GATE_USE_PYTHON3=True
|
||||
export TOX_ENV=functional-py3
|
||||
|
||||
function post_test_hook {
|
||||
# Configure and run functional tests
|
||||
|
|
|
@ -5,4 +5,5 @@
|
|||
pbr>=2.0.0 # Apache-2.0
|
||||
six>=1.10.0 # MIT
|
||||
keystoneauth1>=3.3.0 # Apache-2.0
|
||||
simplejson>=3.16.0 # MIT
|
||||
osc-lib>=1.2.0 # Apache-2.0
|
||||
|
|
|
@ -5,14 +5,11 @@
|
|||
hacking>=0.12.0,<0.13 # Apache-2.0
|
||||
|
||||
coverage>=4.0 # Apache-2.0
|
||||
python-subunit>=0.0.18 # Apache-2.0/BSD
|
||||
sphinx>=1.2.1,!=1.3b1,<1.4 # BSD
|
||||
sphinx!=1.6.6,!=1.6.7,>=1.6.2 # BSD
|
||||
oslosphinx>=4.7.0 # Apache-2.0
|
||||
oslotest>=1.10.0 # Apache-2.0
|
||||
python-openstackclient>=3.3.0 # Apache-2.0
|
||||
testrepository>=0.0.18 # Apache-2.0/BSD
|
||||
testscenarios>=0.4 # Apache-2.0/BSD
|
||||
testtools>=1.4.0 # MIT
|
||||
stestr>=1.0.0 # Apache-2.0
|
||||
|
||||
# releasenotes
|
||||
reno>=1.8.0 # Apache-2.0
|
||||
|
|
74
tox.ini
74
tox.ini
|
@ -1,56 +1,86 @@
|
|||
[tox]
|
||||
minversion = 2.0
|
||||
envlist = pep8,py{27,35},functional
|
||||
minversion = 3.1.1
|
||||
envlist = py{27,36},functional,functional-py36,pep8
|
||||
skipsdist = True
|
||||
# Automatic envs (pyXX) will use the python version appropriate to that
|
||||
# env and ignore basepython inherited from [testenv]. That's what we
|
||||
# want, and we don't need to be warned about it.
|
||||
ignore_basepython_conflict = True
|
||||
|
||||
[testenv]
|
||||
basepython = python3
|
||||
usedevelop = True
|
||||
whitelist_externals =
|
||||
rm
|
||||
install_command = pip install {opts} {packages}
|
||||
setenv =
|
||||
VIRTUAL_ENV={envdir}
|
||||
PYTHONWARNINGS=default::DeprecationWarning
|
||||
OS_TEST_PATH=./osc_placement/tests/unit
|
||||
deps =
|
||||
-c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt}
|
||||
-r{toxinidir}/test-requirements.txt
|
||||
-r{toxinidir}/requirements.txt
|
||||
commands = python setup.py test --slowest --testr-args='{posargs}'
|
||||
|
||||
[testenv:functional]
|
||||
setenv =
|
||||
VIRTUAL_ENV={envdir}
|
||||
PYTHONWARNINGS=default::DeprecationWarning,ignore::DeprecationWarning:distutils,ignore::DeprecationWarning:site
|
||||
OS_TEST_PATH=./osc_placement/tests/functional
|
||||
PYTHONWARNINGS=ignore::DeprecationWarning:distutils,ignore::DeprecationWarning:site
|
||||
PYTHONDONTWRITEBYTECODE=1
|
||||
# NOTE(rpodolyaka): allow passing of keystone credentials via env variables
|
||||
passenv = OS_*
|
||||
deps =
|
||||
-c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt}
|
||||
-r{toxinidir}/test-requirements.txt
|
||||
-r{toxinidir}/requirements.txt
|
||||
commands = stestr run {posargs}
|
||||
|
||||
# NOTE(cdent): Functional tests require a running openstack
|
||||
# and OS_* variables in the environment to allow authentication.
|
||||
# This is because the openstack client is called against a
|
||||
# real cloud.
|
||||
# NOTE(cdent): Do not set envdir here, for the sake of the
|
||||
# gate functional jobs, which use the 'functional' path when
|
||||
# copying files.
|
||||
[testenv:functional]
|
||||
basepython = python2.7
|
||||
commands = stestr --test-path=./osc_placement/tests/functional run {posargs}
|
||||
|
||||
# Used by the python3 functional job in the gate.
|
||||
[testenv:functional-py3]
|
||||
commands =
|
||||
{[testenv:functional]commands}
|
||||
|
||||
[testenv:functional-py36]
|
||||
envdir = {toxworkdir}/py36
|
||||
commands =
|
||||
{[testenv:functional]commands}
|
||||
|
||||
[testenv:functional-py37]
|
||||
envdir = {toxworkdir}/py37
|
||||
commands =
|
||||
{[testenv:functional]commands}
|
||||
|
||||
[testenv:pep8]
|
||||
basepython = python3
|
||||
envdir = {toxworkdir}/shared
|
||||
commands = flake8 {posargs}
|
||||
|
||||
[testenv:venv]
|
||||
basepython = python3
|
||||
commands = {posargs}
|
||||
|
||||
[testenv:cover]
|
||||
basepython = python3
|
||||
commands = python setup.py test --coverage --testr-args='{posargs}'
|
||||
envdir = {toxworkdir}/shared
|
||||
setenv =
|
||||
{[testenv]setenv}
|
||||
PYTHON=coverage run --source osc_placement --parallel-mode
|
||||
commands =
|
||||
coverage erase
|
||||
stestr run {posargs}
|
||||
coverage combine
|
||||
coverage html -d cover
|
||||
coverage xml -o cover/coverage.xml
|
||||
coverage report
|
||||
|
||||
[testenv:docs]
|
||||
basepython = python3
|
||||
commands =
|
||||
rm -rf doc/build
|
||||
python setup.py build_sphinx
|
||||
|
||||
[testenv:releasenotes]
|
||||
basepython = python3
|
||||
commands =
|
||||
sphinx-build -a -E -W -d releasenotes/build/doctrees -b html releasenotes/source releasenotes/build/html
|
||||
|
||||
[testenv:debug]
|
||||
basepython = python3
|
||||
commands = oslo_debug_helper {posargs}
|
||||
|
||||
[flake8]
|
||||
|
|
Loading…
Reference in New Issue