Merge "Drop Django <= 1.10 support"

This commit is contained in:
Zuul 2018-03-09 17:40:17 +00:00 committed by Gerrit Code Review
commit cd06fe813e
13 changed files with 81 additions and 167 deletions

View File

@ -54,11 +54,11 @@
- project:
check:
jobs:
- horizon-openstack-tox-py35dj20:
voting: false
- horizon-openstack-tox-py35dj20
- horizon-selenium-headless
- horizon-dsvm-tempest-plugin
gate:
jobs:
- horizon-openstack-tox-py35dj20
- horizon-selenium-headless
- horizon-dsvm-tempest-plugin

View File

@ -27,7 +27,6 @@ import inspect
import logging
import os
import django
from django.conf import settings
from django.conf.urls import include
from django.conf.urls import url
@ -58,12 +57,7 @@ def _decorate_urlconf(urlpatterns, decorator, *args, **kwargs):
for pattern in urlpatterns:
if getattr(pattern, 'callback', None):
decorated = decorator(pattern.callback, *args, **kwargs)
if django.VERSION >= (1, 10):
pattern.callback = decorated
else:
# prior to 1.10 callback was a property and we had
# to modify the private attribute behind the property
pattern._callback = decorated
pattern.callback = decorated
if getattr(pattern, 'url_patterns', []):
_decorate_urlconf(pattern.url_patterns, decorator, *args, **kwargs)

View File

@ -10,15 +10,11 @@
# License for the specific language governing permissions and limitations
# under the License.
import django
from django import template
from django.template import defaultfilters
from django.utils import safestring
if django.VERSION >= (1, 9):
register = template.Library()
else:
register = template.base.Library()
register = template.Library()
@register.filter(is_safe=True)

View File

@ -22,7 +22,6 @@ from importlib import import_module
import six
from six import moves
import django
from django.conf import settings
from django.contrib.auth.models import User
from django.core.exceptions import ImproperlyConfigured
@ -310,10 +309,7 @@ class HorizonTests(BaseHorizonTests):
self.client.logout()
resp = self.client.get(url)
if django.VERSION >= (1, 9):
self.assertRedirects(resp, settings.TESTSERVER + redirect_url)
else:
self.assertRedirects(resp, redirect_url)
self.assertRedirects(resp, settings.TESTSERVER + redirect_url)
# Set SSL settings for test server
settings.SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTOCOL',

View File

@ -13,7 +13,6 @@
import uuid
import django
from django.conf import settings
from django.contrib import auth
from django import test
@ -395,10 +394,7 @@ class OpenStackAuthTestsV2(OpenStackAuthTestsMixin, test.TestCase):
response = self.client.get(url, form_data)
if next:
if django.VERSION >= (1, 9):
expected_url = next
else:
expected_url = 'http://testserver%s' % next
expected_url = next
self.assertEqual(response['location'], expected_url)
else:
self.assertRedirects(response, settings.LOGIN_REDIRECT_URL)
@ -444,10 +440,7 @@ class OpenStackAuthTestsV2(OpenStackAuthTestsMixin, test.TestCase):
response = self.client.get(url, form_data)
if next:
if django.VERSION >= (1, 9):
expected_url = next
else:
expected_url = 'http://testserver%s' % next
expected_url = next
self.assertEqual(response['location'], expected_url)
else:
self.assertRedirects(response, settings.LOGIN_REDIRECT_URL)
@ -768,10 +761,7 @@ class OpenStackAuthTestsV3(OpenStackAuthTestsMixin,
response = self.client.get(url, form_data)
if next:
if django.VERSION >= (1, 9):
expected_url = next
else:
expected_url = 'http://testserver%s' % next
expected_url = next
self.assertEqual(response['location'], expected_url)
else:
self.assertRedirects(response, settings.LOGIN_REDIRECT_URL)
@ -816,10 +806,7 @@ class OpenStackAuthTestsV3(OpenStackAuthTestsMixin,
response = self.client.get(url, form_data)
if next:
if django.VERSION >= (1, 9):
expected_url = next
else:
expected_url = 'http://testserver%s' % next
expected_url = next
self.assertEqual(response['location'], expected_url)
else:
self.assertRedirects(response, settings.LOGIN_REDIRECT_URL)

View File

@ -17,7 +17,6 @@ import logging
import os
import unittest
import django
from django import http
from django.test.utils import override_settings
from django.urls import reverse
@ -277,14 +276,9 @@ class CreateProjectWorkflowTests(test.BaseAdminViewTests):
res = self.client.get(reverse('horizon:identity:projects:create'))
self.assertTemplateUsed(res, views.WorkflowView.template_name)
if django.VERSION >= (1, 10):
pattern = ('<input autocomplete="off" class="form-control" '
'id="id_subnet" min="-1" '
'name="subnet" type="number" value="10" required/>')
else:
pattern = ('<input autocomplete="off" class="form-control" '
'id="id_subnet" min="-1" '
'name="subnet" type="number" value="10"/>')
pattern = ('<input autocomplete="off" class="form-control" '
'id="id_subnet" min="-1" '
'name="subnet" type="number" value="10" required/>')
self.assertContains(res, pattern, html=True)
workflow = res.context['workflow']

View File

@ -18,7 +18,6 @@
from socket import timeout as socket_timeout
import django
from django import http
from django.test.utils import override_settings
from django.urls import reverse
@ -238,19 +237,18 @@ class UsersViewTests(test.BaseAdminViewTests):
api.keystone.role_list(IgnoreArg()).AndReturn(self.roles.list())
api.keystone.get_default_role(IgnoreArg()) \
.AndReturn(self.roles.first())
if django.VERSION >= (1, 9):
if api.keystone.VERSIONS.active >= 3:
api.keystone.tenant_list(
IgnoreArg(), domain=domain_id).AndReturn(
[self.tenants.list(), False])
else:
api.keystone.tenant_list(
IgnoreArg(), user=None).AndReturn(
[self.tenants.list(), False])
if api.keystone.VERSIONS.active >= 3:
api.keystone.tenant_list(
IgnoreArg(), domain=domain_id).AndReturn(
[self.tenants.list(), False])
else:
api.keystone.tenant_list(
IgnoreArg(), user=None).AndReturn(
[self.tenants.list(), False])
api.keystone.role_list(IgnoreArg()).AndReturn(self.roles.list())
api.keystone.get_default_role(IgnoreArg()) \
.AndReturn(self.roles.first())
api.keystone.role_list(IgnoreArg()).AndReturn(self.roles.list())
api.keystone.get_default_role(IgnoreArg()) \
.AndReturn(self.roles.first())
self.mox.ReplayAll()
@ -291,19 +289,18 @@ class UsersViewTests(test.BaseAdminViewTests):
api.keystone.role_list(IgnoreArg()).AndReturn(self.roles.list())
api.keystone.get_default_role(IgnoreArg()) \
.AndReturn(self.roles.first())
if django.VERSION >= (1, 9):
if api.keystone.VERSIONS.active >= 3:
api.keystone.tenant_list(
IgnoreArg(), domain=domain_id).AndReturn(
[self.tenants.list(), False])
else:
api.keystone.tenant_list(
IgnoreArg(), user=None).AndReturn(
[self.tenants.list(), False])
if api.keystone.VERSIONS.active >= 3:
api.keystone.tenant_list(
IgnoreArg(), domain=domain_id).AndReturn(
[self.tenants.list(), False])
else:
api.keystone.tenant_list(
IgnoreArg(), user=None).AndReturn(
[self.tenants.list(), False])
api.keystone.role_list(IgnoreArg()).AndReturn(self.roles.list())
api.keystone.get_default_role(IgnoreArg()) \
.AndReturn(self.roles.first())
api.keystone.role_list(IgnoreArg()).AndReturn(self.roles.list())
api.keystone.get_default_role(IgnoreArg()) \
.AndReturn(self.roles.first())
self.mox.ReplayAll()
@ -347,19 +344,18 @@ class UsersViewTests(test.BaseAdminViewTests):
api.keystone.role_list(IgnoreArg()).AndReturn(self.roles.list())
api.keystone.get_default_role(IgnoreArg()) \
.AndReturn(self.roles.first())
if django.VERSION >= (1, 9):
if api.keystone.VERSIONS.active >= 3:
api.keystone.tenant_list(
IgnoreArg(), domain=domain_id).AndReturn(
[self.tenants.list(), False])
else:
api.keystone.tenant_list(
IgnoreArg(), user=None).AndReturn(
[self.tenants.list(), False])
if api.keystone.VERSIONS.active >= 3:
api.keystone.tenant_list(
IgnoreArg(), domain=domain_id).AndReturn(
[self.tenants.list(), False])
else:
api.keystone.tenant_list(
IgnoreArg(), user=None).AndReturn(
[self.tenants.list(), False])
api.keystone.role_list(IgnoreArg()).AndReturn(self.roles.list())
api.keystone.get_default_role(IgnoreArg()) \
.AndReturn(self.roles.first())
api.keystone.role_list(IgnoreArg()).AndReturn(self.roles.list())
api.keystone.get_default_role(IgnoreArg()) \
.AndReturn(self.roles.first())
self.mox.ReplayAll()

View File

@ -1783,18 +1783,11 @@ class InstanceTests(helpers.ResetImageAPIVersionMixin, helpers.TestCase):
# NOTE(adriant): Django 1.11 changes the checked syntax to use html5
# "checked" rather than XHTML's "checked='checked'".
if django.VERSION >= (1, 11):
checked_box = (
'<input type="checkbox" name="network" '
'value="82288d84-e0a5-42ac-95be-e6af08727e42" '
'id="id_network_0" checked />'
)
else:
checked_box = (
'<input type="checkbox" name="network" '
'value="82288d84-e0a5-42ac-95be-e6af08727e42" '
'id="id_network_0" checked="checked" />'
)
checked_box = (
'<input type="checkbox" name="network" '
'value="82288d84-e0a5-42ac-95be-e6af08727e42" '
'id="id_network_0" checked />'
)
if only_one_network:
self.assertContains(res, checked_box, html=True)
else:

View File

@ -13,7 +13,6 @@
# under the License.
import copy
import django
from django import http
from django.urls import reverse
@ -590,14 +589,9 @@ class RouterActionTests(RouterMixin, test.TestCase):
self.assertTemplateUsed(res, 'project/routers/update.html')
self.assertContains(res, 'Router Type')
if django.VERSION >= (1, 10):
pattern = ('<input class="form-control" id="id_mode" name="mode" '
'readonly="readonly" type="text" value="distributed" '
'required/>')
else:
pattern = ('<input class="form-control" id="id_mode" name="mode" '
'readonly="readonly" type="text" '
'value="distributed" />')
pattern = ('<input class="form-control" id="id_mode" name="mode" '
'readonly="readonly" type="text" value="distributed" '
'required/>')
self.assertContains(res, pattern, html=True)
self.assertNotContains(res, 'centralized')

View File

@ -21,7 +21,6 @@ import cgi
from mox3.mox import IsA
import six
import django
from django.conf import settings
from django import http
from django.urls import reverse
@ -478,9 +477,7 @@ class SecurityGroupsViewTests(test.TestCase):
sec_group_list = self.security_groups.list()
rule = self.security_group_rules.first()
api.neutron.security_group_list(
IsA(http.HttpRequest)).AndReturn(sec_group_list)
if django.VERSION >= (1, 9):
for i in range(2):
api.neutron.security_group_list(
IsA(http.HttpRequest)).AndReturn(sec_group_list)
@ -503,13 +500,9 @@ class SecurityGroupsViewTests(test.TestCase):
sec_group_list = self.security_groups.list()
rule = self.security_group_rules.first()
for i in range(3):
for i in range(6):
api.neutron.security_group_list(
IsA(http.HttpRequest)).AndReturn(sec_group_list)
if django.VERSION >= (1, 9):
for i in range(3):
api.neutron.security_group_list(
IsA(http.HttpRequest)).AndReturn(sec_group_list)
self.mox.ReplayAll()
@ -559,10 +552,7 @@ class SecurityGroupsViewTests(test.TestCase):
icmp_rule = self.security_group_rules.list()[1]
# Call POST 5 times (*2 if Django >= 1.9)
call_post = 5
if django.VERSION >= (1, 9):
call_post *= 2
call_post = 5 * 2
for i in range(call_post):
api.neutron.security_group_list(
IsA(http.HttpRequest)).AndReturn(sec_group_list)
@ -921,9 +911,7 @@ class SecurityGroupsViewTests(test.TestCase):
sec_group_list = self.security_groups.list()
rule = self.security_group_rules.first()
api.neutron.security_group_list(
IsA(http.HttpRequest)).AndReturn(sec_group_list)
if django.VERSION >= (1, 9):
for i in range(2):
api.neutron.security_group_list(
IsA(http.HttpRequest)).AndReturn(sec_group_list)

View File

@ -17,7 +17,6 @@ import copy
import mock
import six
import django
from django.conf import settings
from django.forms import widgets
from django.template.defaultfilters import slugify
@ -634,12 +633,8 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
self.assertFormError(res, 'form', None,
"The volume size cannot be less than the "
"snapshot size (40GiB)")
if django.VERSION >= (1, 9):
self.assertEqual(3, self.mock_volume_type_list.call_count)
self.assertEqual(2, self.mock_volume_type_default.call_count)
else:
self.assertEqual(2, self.mock_volume_type_list.call_count)
self.assertEqual(1, self.mock_volume_type_default.call_count)
self.assertEqual(3, self.mock_volume_type_list.call_count)
self.assertEqual(2, self.mock_volume_type_default.call_count)
self.mock_volume_snapshot_get.assert_called_with(test.IsHttpRequest(),
str(snapshot.id))
@ -812,12 +807,8 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
self.assertFormError(res, 'form', None, msg)
if django.VERSION >= (1, 9):
self.assertEqual(3, self.mock_volume_type_list.call_count)
self.assertEqual(2, self.mock_volume_type_default.call_count)
else:
self.assertEqual(2, self.mock_volume_type_list.call_count)
self.assertEqual(1, self.mock_volume_type_default.call_count)
self.assertEqual(3, self.mock_volume_type_list.call_count)
self.assertEqual(2, self.mock_volume_type_default.call_count)
self.assertEqual(2, self.mock_tenant_limit_usages.call_count)
self.mock_image_get.assert_called_with(test.IsHttpRequest(),
@ -861,14 +852,9 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
self.assertFormError(res, 'form', None,
"The volume size cannot be less than the "
"image minimum disk size (30GiB)")
if django.VERSION >= (1, 9):
self.assertEqual(3, self.mock_volume_type_list.call_count)
self.assertEqual(2, self.mock_volume_type_default.call_count)
self.assertEqual(2, self.mock_availability_zone_list.call_count)
else:
self.assertEqual(2, self.mock_volume_type_list.call_count)
self.assertEqual(1, self.mock_volume_type_default.call_count)
self.assertEqual(1, self.mock_availability_zone_list.call_count)
self.assertEqual(3, self.mock_volume_type_list.call_count)
self.assertEqual(2, self.mock_volume_type_default.call_count)
self.assertEqual(2, self.mock_availability_zone_list.call_count)
self.mock_image_get.assert_called_with(test.IsHttpRequest(),
str(image.id))
@ -932,16 +918,10 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
' have 20GiB of your quota available.']
self.assertEqual(res.context['form'].errors['__all__'], expected_error)
if django.VERSION >= (1, 9):
self.assertEqual(3, self.mock_volume_type_list.call_count)
self.assertEqual(2, self.mock_volume_type_default.call_count)
self.assertEqual(2, self.mock_volume_list.call_count)
self.assertEqual(2, self.mock_availability_zone_list.call_count)
else:
self.assertEqual(2, self.mock_volume_type_list.call_count)
self.assertEqual(1, self.mock_volume_type_default.call_count)
self.assertEqual(1, self.mock_volume_list.call_count)
self.assertEqual(1, self.mock_availability_zone_list.call_count)
self.assertEqual(3, self.mock_volume_type_list.call_count)
self.assertEqual(2, self.mock_volume_type_default.call_count)
self.assertEqual(2, self.mock_volume_list.call_count)
self.assertEqual(2, self.mock_availability_zone_list.call_count)
self.assertEqual(2, self.mock_tenant_limit_usages.call_count)
self.mock_volume_snapshot_list.assert_called_with(
@ -993,14 +973,9 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
' volumes.']
self.assertEqual(res.context['form'].errors['__all__'], expected_error)
if django.VERSION >= (1, 9):
self.assertEqual(3, self.mock_volume_type_list.call_count)
self.assertEqual(2, self.mock_volume_type_default.call_count)
self.assertEqual(2, self.mock_availability_zone_list.call_count)
else:
self.assertEqual(2, self.mock_volume_type_list.call_count)
self.assertEqual(1, self.mock_volume_type_default.call_count)
self.assertEqual(1, self.mock_availability_zone_list.call_count)
self.assertEqual(3, self.mock_volume_type_list.call_count)
self.assertEqual(2, self.mock_volume_type_default.call_count)
self.assertEqual(2, self.mock_availability_zone_list.call_count)
self.mock_volume_snapshot_list.assert_called_with(
test.IsHttpRequest(), search_opts=SEARCH_OPTS)

View File

@ -25,7 +25,6 @@ import os
import traceback
import unittest
import django
from django.conf import settings
from django.contrib.messages.storage import default_storage
from django.core.handlers import wsgi
@ -342,14 +341,10 @@ class TestCase(horizon_helpers.TestCase):
Asserts that the given response issued a 302 redirect without
processing the view which is redirected to.
"""
if django.VERSION >= (1, 9):
loc = six.text_type(response._headers.get('location', None)[1])
loc = http.urlunquote(loc)
expected_url = http.urlunquote(expected_url)
self.assertEqual(loc, expected_url)
else:
self.assertEqual(response._headers.get('location', None),
('Location', settings.TESTSERVER + expected_url))
loc = six.text_type(response._headers.get('location', None)[1])
loc = http.urlunquote(loc)
expected_url = http.urlunquote(expected_url)
self.assertEqual(loc, expected_url)
self.assertEqual(response.status_code, 302)
def assertNoFormErrors(self, response, context_name="form"):

View File

@ -0,0 +1,6 @@
---
upgrade:
- |
Django 2.0 support is added as experimental.
Support for Django 1.10 or older releases is dropped.
Django 1.11 (LTS) is still the primary supported Django version.