Django 2.0 support and fix lower-constraints

Replace django.core.urlresolves with django.urls

(In Django 2.0) The django.core.urlresolvers module is removed
in favor of its new location, django.urls.
It was deprecated in Django 1.10:
https://docs.djangoproject.com/en/2.0/releases/1.10/#id3

To test the dashboard with python3 and Django 1.11,
python3-django111 job is added to tox.ini and a corresponding
entry is added to .zuul.yaml.

requirements.txt is also updated not to include horizon dependecies.
This allows horizon plugins not to track changes in basic stuffs
like Django.

KeyError from memoized decorator occurs in watcher-dashboard python3
tests but it seems it is not specific to Django 2.0 support,
so it is not touched. Hopefully it can be fixed later.

lower-constraints job is also fixed.
- Previously install_command specifies upper-constraints.txt even for
  lower-constraints tox env. As a result, lower-constraints job actually
  tests upper-constraints.
  This commit moves -c option for upper-constraints.txt to 'deps'.
- lower-constraints.txt is updated.
- nose-exclude 0.3.0 actually does not work. 0.5.0 needs to be used.

Change-Id: Ia98e4685f217c1e932d4b68b864cd9f52c88b134
This commit is contained in:
Akihiro Motoki 2018-06-21 23:54:48 +09:00
parent f0f6cef879
commit 5a7ebe5016
15 changed files with 55 additions and 58 deletions

View File

@ -2,6 +2,8 @@
check:
jobs:
- openstack-tox-lower-constraints
- horizon-openstack-tox-python3-django111
gate:
jobs:
- openstack-tox-lower-constraints
- horizon-openstack-tox-python3-django111

View File

@ -8,7 +8,7 @@ chardet==3.0.4
cliff==2.11.0
cmd2==0.8.1
contextlib2==0.5.5
coverage==4.5.1
coverage==4.0
cryptography==2.1.4
debtcollector==1.19.0
decorator==4.2.1
@ -17,7 +17,7 @@ Django==1.11.11
django-appconf==1.0.2
django-babel==0.6.2
django-compressor==2.2
django-nose==1.4.5
django-nose==1.4.4
django-pyscss==2.0.2
docutils==0.14
dogpile.cache==0.6.5
@ -28,7 +28,7 @@ fixtures==3.0.0
flake8==2.5.5
futurist==1.6.0
hacking==0.12.0
horizon==13.0.0
horizon==14.0.0.b1
httplib2==0.10.3
idna==2.6
imagesize==1.0.0
@ -44,14 +44,14 @@ MarkupSafe==1.0
mccabe==0.2.1
mock==2.0.0
monotonic==1.4
mox3==0.25.0
mox3==0.20.0
msgpack==0.5.6
munch==2.2.0
netaddr==0.7.19
netifaces==0.10.6
nose==1.3.7
nose-exclude==0.5.0
openstackdocstheme==1.20.0
openstackdocstheme==1.18.1
openstacksdk==0.12.0
os-client-config==1.29.0
os-service-types==1.2.0
@ -64,7 +64,7 @@ oslo.serialization==2.25.0
oslo.utils==3.36.0
osprofiler==2.0.0
packaging==17.1
pbr==3.1.1
pbr==2.0.0
pep8==1.5.7
Pint==0.8.1
prettytable==0.7.2
@ -82,27 +82,27 @@ python-keystoneclient==3.15.0
python-mimeparse==1.6.0
python-neutronclient==6.7.0
python-novaclient==10.1.0
python-subunit==1.2.0
python-subunit==1.0.0
python-swiftclient==3.5.0
python-watcherclient==1.6.0
python-watcherclient==1.1.0
pytz==2018.3
PyYAML==3.12
rcssmin==1.0.6
reno==2.7.0
reno==2.5.0
requests==2.18.4
requestsexceptions==1.4.0
rfc3986==1.1.0
rjsmin==1.0.12
selenium==3.11.0
selenium==2.50.1
semantic-version==2.6.0
simplejson==3.13.2
six==1.11.0
snowballstemmer==1.2.1
Sphinx==1.6.5
Sphinx==1.6.2
sphinxcontrib-websupport==1.0.1
stevedore==1.28.0
testscenarios==0.5.0
testtools==2.3.0
testscenarios==0.4
testtools==2.2.0
traceback2==1.4.0
unittest2==1.1.0
urllib3==1.22
@ -137,4 +137,4 @@ XStatic-smart-table==1.4.13.2
XStatic-Spin==1.2.5.2
XStatic-term.js==0.0.7.0
XStatic-tv4==1.2.7.0
xvfbwrapper==0.2.9
xvfbwrapper==0.1.3

View File

@ -3,14 +3,8 @@
# process, which may cause wedges in the gate later.
pbr!=2.1.0,>=2.0.0 # Apache-2.0
# Horizon Core Requirements
Django<2.0,>=1.11 # BSD
django-compressor>=2.0 # MIT
httplib2>=0.9.1 # MIT
python-keystoneclient>=3.8.0 # Apache-2.0
horizon>=14.0.0.0b1 # Apache-2.0
PyYAML>=3.12 # MIT
horizon>=13.0.0 # Apache-2.0
# Watcher-specific requirements
python-watcherclient>=1.1.0 # Apache-2.0

View File

@ -8,7 +8,7 @@ coverage!=4.4,>=4.0 # Apache-2.0
django-nose>=1.4.4 # BSD
mock>=2.0.0 # BSD
mox3>=0.20.0 # Apache-2.0
nose-exclude>=0.3.0 # LGPL
nose-exclude>=0.5.0 # LGPL
python-subunit>=1.0.0 # Apache-2.0/BSD
selenium>=2.50.1 # Apache-2.0
testscenarios>=0.4 # Apache-2.0/BSD

17
tox.ini
View File

@ -5,7 +5,6 @@ skipsdist = True
[testenv]
usedevelop = True
install_command = pip install -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt} {opts} {packages}
setenv = VIRTUAL_ENV={envdir}
NOSE_WITH_OPENSTACK=1
NOSE_OPENSTACK_COLOR=1
@ -19,8 +18,10 @@ setenv = VIRTUAL_ENV={envdir}
whitelist_externals = /bin/bash
rm
find
deps = -r{toxinidir}/requirements.txt
-r{toxinidir}/test-requirements.txt
deps =
-c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt}
-r{toxinidir}/requirements.txt
-r{toxinidir}/test-requirements.txt
commands =
rm -f .testrepository/times.dbm
find . -type f -name "*.pyc" -delete
@ -35,11 +36,11 @@ commands = flake8
[testenv:venv]
commands = {posargs}
# Django-1.8 is LTS
[testenv:py27dj18]
basepython = python2.7
commands = pip install django>=1.8,<1.9
/bin/bash run_tests.sh -N --no-pep8 {posargs}
[testenv:py3-dj111]
basepython = python3
commands =
pip install django>=1.11,<2
{[testenv]commands}
[testenv:py27integration]
basepython = python2.7

View File

@ -15,8 +15,8 @@
import logging
from django.core import urlresolvers
from django.template.defaultfilters import title # noqa
from django import urls
from django.utils.translation import pgettext_lazy
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ungettext_lazy
@ -139,10 +139,10 @@ def format_global_efficacy(action_plan):
def get_audit_link(datum):
try:
return urlresolvers.reverse(
return urls.reverse(
"horizon:admin:audits:detail",
kwargs={"audit_uuid": getattr(datum, "audit_uuid", None)})
except urlresolvers.NoReverseMatch:
except urls.NoReverseMatch:
return None

View File

@ -15,8 +15,8 @@
import logging
from django.core import urlresolvers
from django.template.defaultfilters import title # noqa
from django import urls
from django.utils.translation import pgettext_lazy
from django.utils.translation import ugettext_lazy as _
import horizon.exceptions
@ -63,11 +63,11 @@ class ActionsFilterAction(horizon.tables.FilterAction):
def get_action_plan_link(datum):
try:
return urlresolvers.reverse(
return urls.reverse(
"horizon:admin:action_plans:detail",
kwargs={"action_plan_uuid": getattr(
datum, "action_plan_uuid", None)})
except urlresolvers.NoReverseMatch:
except urls.NoReverseMatch:
return None

View File

@ -19,7 +19,7 @@ Forms for starting Watcher Audit Templates.
import logging
from django.core import exceptions as core_exc
from django.core.urlresolvers import reverse
from django.urls import reverse
from django.utils.translation import ugettext_lazy as _
from horizon import exceptions
from horizon import forms

View File

@ -13,15 +13,15 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from django.core import urlresolvers
from django import urls
import mock
from watcher_dashboard import api
from watcher_dashboard.test import helpers as test
INDEX_URL = urlresolvers.reverse(
INDEX_URL = urls.reverse(
'horizon:admin:audit_templates:index')
CREATE_URL = urlresolvers.reverse(
CREATE_URL = urls.reverse(
'horizon:admin:audit_templates:create')
DETAILS_VIEW = 'horizon:admin:audit_templates:detail'
@ -83,7 +83,7 @@ class AuditTemplatesTest(test.BaseAdminViewTests):
at_id = at.uuid
m_get.return_value = at
DETAILS_URL = urlresolvers.reverse(DETAILS_VIEW, args=[at_id])
DETAILS_URL = urls.reverse(DETAILS_VIEW, args=[at_id])
res = self.client.get(DETAILS_URL)
self.assertTemplateUsed(res,
'infra_optim/audit_templates/details.html')
@ -96,7 +96,7 @@ class AuditTemplatesTest(test.BaseAdminViewTests):
at_id = at.uuid
m_get.side_effect = self.exceptions.watcher
DETAILS_URL = urlresolvers.reverse(DETAILS_VIEW, args=[at_id])
DETAILS_URL = urls.reverse(DETAILS_VIEW, args=[at_id])
res = self.client.get(DETAILS_URL)
self.assertRedirectsNoFollow(res, INDEX_URL)

View File

@ -16,7 +16,7 @@
import json
import logging
from django.core.urlresolvers import reverse_lazy
from django.urls import reverse_lazy
from django.utils.translation import ugettext_lazy as _
import horizon.exceptions
from horizon import forms

View File

@ -18,7 +18,7 @@ Forms for starting Watcher Audits.
"""
import logging
from django.core.urlresolvers import reverse
from django.urls import reverse
from django.utils.translation import ugettext_lazy as _
from horizon import exceptions

View File

@ -13,9 +13,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from django.core import urlresolvers
from django import shortcuts
from django.template.defaultfilters import title # noqa
from django import urls
from django.utils.translation import pgettext_lazy
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ungettext_lazy
@ -74,7 +74,7 @@ class GoToActionPlan(horizon.tables.Action):
_("Unable to retrieve action_plan information."))
return "javascript:void(0);"
return shortcuts.redirect(urlresolvers.reverse(
return shortcuts.redirect(urls.reverse(
self.url,
args=[action_plans[0].uuid]))

View File

@ -15,8 +15,8 @@
import logging
from django.core.urlresolvers import reverse
from django.core.urlresolvers import reverse_lazy
from django.urls import reverse
from django.urls import reverse_lazy
from django.utils.translation import ugettext_lazy as _
import horizon.exceptions
from horizon import forms

View File

@ -13,13 +13,13 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from django.core import urlresolvers
from django import urls
import mock
from watcher_dashboard import api
from watcher_dashboard.test import helpers as test
INDEX_URL = urlresolvers.reverse('horizon:admin:goals:index')
INDEX_URL = urls.reverse('horizon:admin:goals:index')
DETAILS_VIEW = 'horizon:admin:goals:detail'
@ -48,7 +48,7 @@ class GoalsTest(test.BaseAdminViewTests):
goal_id = goal.uuid
mock_get.return_value = goal
DETAILS_URL = urlresolvers.reverse(DETAILS_VIEW, args=[goal_id])
DETAILS_URL = urls.reverse(DETAILS_VIEW, args=[goal_id])
res = self.client.get(DETAILS_URL)
self.assertTemplateUsed(res, 'infra_optim/goals/details.html')
goals = res.context['goal']
@ -60,6 +60,6 @@ class GoalsTest(test.BaseAdminViewTests):
at_id = at.uuid
mock_get.side_effect = self.exceptions.watcher
DETAILS_URL = urlresolvers.reverse(DETAILS_VIEW, args=[at_id])
DETAILS_URL = urls.reverse(DETAILS_VIEW, args=[at_id])
res = self.client.get(DETAILS_URL)
self.assertRedirectsNoFollow(res, INDEX_URL)

View File

@ -13,13 +13,13 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from django.core import urlresolvers
from django import urls
import mock
from watcher_dashboard import api
from watcher_dashboard.test import helpers as test
INDEX_URL = urlresolvers.reverse(
INDEX_URL = urls.reverse(
'horizon:admin:strategies:index')
DETAILS_VIEW = 'horizon:admin:strategies:detail'
@ -56,7 +56,7 @@ class StrategiesTest(test.BaseAdminViewTests):
at_id = at.uuid
mock_get.return_value = at
DETAILS_URL = urlresolvers.reverse(DETAILS_VIEW, args=[at_id])
DETAILS_URL = urls.reverse(DETAILS_VIEW, args=[at_id])
res = self.client.get(DETAILS_URL)
self.assertTemplateUsed(res,
'infra_optim/strategies/details.html')
@ -69,6 +69,6 @@ class StrategiesTest(test.BaseAdminViewTests):
at_id = at.uuid
mock_get.side_effect = self.exceptions.watcher
DETAILS_URL = urlresolvers.reverse(DETAILS_VIEW, args=[at_id])
DETAILS_URL = urls.reverse(DETAILS_VIEW, args=[at_id])
res = self.client.get(DETAILS_URL)
self.assertRedirectsNoFollow(res, INDEX_URL)