]> review.fuel-infra Code Review - openstack-build/horizon-build.git/commitdiff
Added patch: Fix_remaining_Django_1.9_test_failures.patch
authorThomas Goirand <thomas@goirand.fr>
Thu, 18 Feb 2016 16:54:58 +0000 (16:54 +0000)
committerThomas Goirand <thomas@goirand.fr>
Thu, 18 Feb 2016 16:54:58 +0000 (16:54 +0000)
Rewritten-From: cf4eab3c948858d3192b92414a35401c422d5ad5

trusty/debian/changelog
trusty/debian/patches/0090-explicitly-declare-app_label.patch
trusty/debian/patches/Fix_remaining_Django_1.9_test_failures.patch [new file with mode: 0644]
trusty/debian/patches/series

index f996935f4325cecc49b4ae8788004d6fac5074c5..4eeb804ac76a43b96f1772567effcce20c0e083b 100644 (file)
@@ -5,6 +5,7 @@ horizon (2:9.0.0~b2+2016.02.18.git.cda9604792-1) experimental; urgency=medium
   * Added patch: Provide_2_simple_methods_to_check_for_disabled_panels.patch
   * Added patch: 0100-add-openstack_auth-in-INSTALLED_APPS.patch
   * Added patch: 0090-explicitly-declare-app_label.patch
+  * Added patch: Fix_remaining_Django_1.9_test_failures.patch
 
  -- Thomas Goirand <zigo@debian.org>  Wed, 09 Dec 2015 11:37:40 +0100
 
index 9d4a73fa79f65469e9395f62a6864df5bdb24960..4c7e3b38814efe4ae275548db9474bbc1af98a42 100644 (file)
@@ -3,24 +3,30 @@ Author: Thomas Goirand <zigo@debian.org>
 Forwarded: no
 Last-Update: 2016-02-19
 
---- horizon-9.0.0~b2+2016.02.18.git.cda9604792.orig/horizon/test/settings.py
-+++ horizon-9.0.0~b2+2016.02.18.git.cda9604792/horizon/test/settings.py
-@@ -170,3 +170,5 @@ LOGGING = {
+Index: horizon/horizon/test/settings.py
+===================================================================
+--- horizon.orig/horizon/test/settings.py
++++ horizon/horizon/test/settings.py
+@@ -169,3 +169,5 @@ LOGGING = {
          }
      }
  }
 +
 +APP_LABEL = 'horizon'
---- horizon-9.0.0~b2+2016.02.18.git.cda9604792.orig/openstack_dashboard/local/local_settings.py.example
-+++ horizon-9.0.0~b2+2016.02.18.git.cda9604792/openstack_dashboard/local/local_settings.py.example
+Index: horizon/openstack_dashboard/local/local_settings.py.example
+===================================================================
+--- horizon.orig/openstack_dashboard/local/local_settings.py.example
++++ horizon/openstack_dashboard/local/local_settings.py.example
 @@ -710,3 +710,5 @@ REST_API_REQUIRED_SETTINGS = ['OPENSTACK
  # For more information see:
  # http://tinyurl.com/anticlickjack
  #DISALLOW_IFRAME_EMBED = True
 +
 +APP_LABEL = 'horizon'
---- horizon-9.0.0~b2+2016.02.18.git.cda9604792.orig/openstack_dashboard/test/settings.py
-+++ horizon-9.0.0~b2+2016.02.18.git.cda9604792/openstack_dashboard/test/settings.py
+Index: horizon/openstack_dashboard/test/settings.py
+===================================================================
+--- horizon.orig/openstack_dashboard/test/settings.py
++++ horizon/openstack_dashboard/test/settings.py
 @@ -232,3 +232,5 @@ REST_API_SETTING_2 = 'bar'
  REST_API_SECURITY = 'SECURITY'
  REST_API_REQUIRED_SETTINGS = ['REST_API_SETTING_1']
diff --git a/trusty/debian/patches/Fix_remaining_Django_1.9_test_failures.patch b/trusty/debian/patches/Fix_remaining_Django_1.9_test_failures.patch
new file mode 100644 (file)
index 0000000..a9fc59d
--- /dev/null
@@ -0,0 +1,378 @@
+Subject: [PATCH] [WIP] Fix remaining Django 1.9 test failures
+ This patch gets Horizon to a passing state in the Django 1.9 tests
+Author: Rob Cresswell <robert.cresswell@outlook.com>
+Date: Thu, 11 Feb 2016 14:45:32 +0000
+Co-Authored-By: Itxaka <iserrano@redhat.com>
+Change-Id: Icbc1a3c039de658faa9fba4a2cdd5027345fe94d
+Partially-Implements: blueprint drop-dj17
+Origin: upstream, https://review.openstack.org/#/c/280222/
+Last-Update: 2016-02-19
+
+--- horizon-9.0.0~b2+2016.02.18.git.cda9604792.orig/horizon/forms/base.py
++++ horizon-9.0.0~b2+2016.02.18.git.cda9604792/horizon/forms/base.py
+@@ -41,7 +41,7 @@ class SelfHandlingForm(SelfHandlingMixin
+         wish for API errors to appear as errors on the form rather than
+         using the messages framework.
+         """
+-        self._errors[NON_FIELD_ERRORS] = self.error_class([message])
++        self.add_error(NON_FIELD_ERRORS, message)
+     def set_warning(self, message):
+         """Sets a warning on the form.
+--- horizon-9.0.0~b2+2016.02.18.git.cda9604792.orig/horizon/test/settings.py
++++ horizon-9.0.0~b2+2016.02.18.git.cda9604792/horizon/test/settings.py
+@@ -59,7 +59,8 @@ INSTALLED_APPS = (
+     'horizon',
+     'horizon.test',
+     'horizon.test.test_dashboards.cats',
+-    'horizon.test.test_dashboards.dogs'
++    'horizon.test.test_dashboards.dogs',
++    'openstack_auth'
+ )
+ MIDDLEWARE_CLASSES = (
+--- horizon-9.0.0~b2+2016.02.18.git.cda9604792.orig/horizon/test/tests/base.py
++++ horizon-9.0.0~b2+2016.02.18.git.cda9604792/horizon/test/tests/base.py
+@@ -17,6 +17,7 @@
+ #    License for the specific language governing permissions and limitations
+ #    under the License.
++import django
+ from django.conf import settings
+ from django.contrib.auth.models import User  # noqa
+ from django.core.exceptions import ImproperlyConfigured  # noqa
+@@ -308,7 +309,10 @@ class HorizonTests(BaseHorizonTests):
+         self.client.logout()
+         resp = self.client.get(url)
+-        self.assertRedirects(resp, redirect_url)
++        if django.VERSION >= (1, 9):
++            self.assertRedirects(resp, settings.TESTSERVER + redirect_url)
++        else:
++            self.assertRedirects(resp, redirect_url)
+         # Set SSL settings for test server
+         settings.SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTOCOL',
+--- horizon-9.0.0~b2+2016.02.18.git.cda9604792.orig/horizon/test/tests/forms.py
++++ horizon-9.0.0~b2+2016.02.18.git.cda9604792/horizon/test/tests/forms.py
+@@ -27,6 +27,8 @@ class FormMixinTests(test.TestCase):
+         view.args = args
+         view.kwargs = kwargs
+         view.template_name = 'test_template'
++        # Note(Itxaka): ModalFormView requires a form_class to behave properly
++        view.form_class = TestForm
+         return view
+     def test_modal_form_mixin_hide_true_if_ajax(self):
+@@ -80,7 +82,9 @@ class FormErrorTests(test.TestCase):
+     def setUp(self):
+         super(FormErrorTests, self).setUp()
+-        self.form = TestForm(self.request)
++        # Note(Itxaka): We pass data to the form so its bound and has the
++        # proper cleaned_data fields
++        self.form = TestForm(self.request, data={'fake': 'data'})
+     def _render_form(self):
+         return shortcuts.render(self.request, self.template,
+--- horizon-9.0.0~b2+2016.02.18.git.cda9604792.orig/horizon/test/tests/middleware.py
++++ horizon-9.0.0~b2+2016.02.18.git.cda9604792/horizon/test/tests/middleware.py
+@@ -13,8 +13,8 @@
+ #    License for the specific language governing permissions and limitations
+ #    under the License.
++import django
+ from django.conf import settings
+-
+ from django.http import HttpResponseRedirect  # noqa
+ from horizon import exceptions
+@@ -31,7 +31,10 @@ class MiddlewareTests(test.TestCase):
+         resp = mw.process_exception(request, exceptions.NotAuthorized())
+         resp.client = self.client
+-        self.assertRedirects(resp, url)
++        if django.VERSION >= (1, 9):
++            self.assertRedirects(resp, settings.TESTSERVER + url)
++        else:
++            self.assertRedirects(resp, url)
+     def test_process_response_redirect_on_ajax_request(self):
+         url = settings.LOGIN_URL
+--- horizon-9.0.0~b2+2016.02.18.git.cda9604792.orig/openstack_dashboard/dashboards/admin/networks/tests.py
++++ horizon-9.0.0~b2+2016.02.18.git.cda9604792/openstack_dashboard/dashboards/admin/networks/tests.py
+@@ -390,8 +390,9 @@ class NetworkTests(test.BaseAdminViewTes
+         tenant_id = self.tenants.first().id
+         network = self.networks.first()
+         extensions = self.api_extensions.list()
+-        api.keystone.tenant_list(IsA(http.HttpRequest)).AndReturn([tenants,
+-                                                                   False])
++        api.keystone.tenant_list(
++            IsA(http.HttpRequest)
++        ).MultipleTimes().AndReturn([tenants, False])
+         api.neutron.list_extensions(
+             IsA(http.HttpRequest)).AndReturn(extensions)
+         self.mox.ReplayAll()
+@@ -417,8 +418,11 @@ class NetworkTests(test.BaseAdminViewTes
+         tenant_id = self.tenants.first().id
+         network = self.networks.first()
+         extensions = self.api_extensions.list()
+-        api.keystone.tenant_list(IsA(http.HttpRequest)).AndReturn([tenants,
+-                                                                   False])
++
++        api.keystone.tenant_list(
++            IsA(http.HttpRequest)
++        ).MultipleTimes().AndReturn([tenants, False])
++
+         api.neutron.list_extensions(
+             IsA(http.HttpRequest)).AndReturn(extensions)
+         self.mox.ReplayAll()
+@@ -447,8 +451,10 @@ class NetworkTests(test.BaseAdminViewTes
+         tenant_id = self.tenants.first().id
+         network = self.networks.first()
+         extensions = self.api_extensions.list()
+-        api.keystone.tenant_list(IsA(http.HttpRequest)).AndReturn([tenants,
+-                                                                   False])
++        api.keystone.tenant_list(
++            IsA(http.HttpRequest)
++        ).MultipleTimes().AndReturn([tenants, False])
++
+         api.neutron.list_extensions(
+             IsA(http.HttpRequest)).AndReturn(extensions)
+         self.mox.ReplayAll()
+--- horizon-9.0.0~b2+2016.02.18.git.cda9604792.orig/openstack_dashboard/dashboards/admin/volumes/tabs.py
++++ horizon-9.0.0~b2+2016.02.18.git.cda9604792/openstack_dashboard/dashboards/admin/volumes/tabs.py
+@@ -36,7 +36,7 @@ class VolumeTab(volumes_tabs.PagedTableM
+     name = _("Volumes")
+     slug = "volumes_tab"
+     template_name = "admin/volumes/volumes/volumes_tables.html"
+-    preload = False
++    preload = True
+     def get_volumes_data(self):
+         volumes = self._get_volumes(search_opts={'all_tenants': True})
+@@ -69,7 +69,7 @@ class VolumeTypesTab(tabs.TableTab, volu
+     name = _("Volume Types")
+     slug = "volume_types_tab"
+     template_name = "admin/volumes/volume_types/volume_types_tables.html"
+-    preload = False
++    preload = True
+     def get_volume_types_data(self):
+         try:
+@@ -116,7 +116,7 @@ class SnapshotTab(volumes_tabs.PagedTabl
+     name = _("Volume Snapshots")
+     slug = "snapshots_tab"
+     template_name = ("horizon/common/_detail_table.html")
+-    preload = False
++    preload = True
+     def get_volume_snapshots_data(self):
+         if api.base.is_service_enabled(self.request, 'volume'):
+--- horizon-9.0.0~b2+2016.02.18.git.cda9604792.orig/openstack_dashboard/dashboards/admin/volumes/tests.py
++++ horizon-9.0.0~b2+2016.02.18.git.cda9604792/openstack_dashboard/dashboards/admin/volumes/tests.py
+@@ -181,7 +181,7 @@ class VolumeTests(test.BaseAdminViewTest
+     def test_snapshots_tab(self):
+         cinder.volume_snapshot_list_paged(
+             IsA(http.HttpRequest), paginate=True, marker=None, sort_dir='desc',
+-            search_opts={'all_tenants': True},).AndReturn(
++            search_opts={'all_tenants': True},).MultipleTimes().AndReturn(
+             [self.cinder_volume_snapshots.list(), False, False])
+         cinder.volume_list(IsA(http.HttpRequest), search_opts={
+             'all_tenants': True}).\
+--- horizon-9.0.0~b2+2016.02.18.git.cda9604792.orig/openstack_dashboard/dashboards/project/stacks/forms.py
++++ horizon-9.0.0~b2+2016.02.18.git.cda9604792/openstack_dashboard/dashboards/project/stacks/forms.py
+@@ -13,6 +13,7 @@
+ import json
+ import logging
++import django
+ from django.conf import settings
+ from django.utils import html
+ from django.utils.translation import ugettext_lazy as _
+@@ -125,6 +126,13 @@ class TemplateForm(forms.SelfHandlingFor
+         widget=forms.widgets.Textarea(attrs=attributes),
+         required=False)
++    if django.VERSION >= (1, 9):
++        # Note(Itxaka): On django>=1.9 Charfield has an strip option that
++        # we need to set to False as to not hit
++        # https://bugs.launchpad.net/python-heatclient/+bug/1546166
++        environment_data.strip = False
++        template_data.strip = False
++
+     def __init__(self, *args, **kwargs):
+         self.next_view = kwargs.pop('next_view')
+         super(TemplateForm, self).__init__(*args, **kwargs)
+@@ -252,6 +260,12 @@ class CreateStackForm(forms.SelfHandling
+     environment_data = forms.CharField(
+         widget=forms.widgets.HiddenInput,
+         required=False)
++    if django.VERSION >= (1, 9):
++        # Note(Itxaka): On django>=1.9 Charfield has an strip option that
++        # we need to set to False as to not hit
++        # https://bugs.launchpad.net/python-heatclient/+bug/1546166
++        environment_data.strip = False
++
+     parameters = forms.CharField(
+         widget=forms.widgets.HiddenInput)
+     stack_name = forms.RegexField(
+--- horizon-9.0.0~b2+2016.02.18.git.cda9604792.orig/openstack_dashboard/dashboards/project/volumes/backups/tests.py
++++ horizon-9.0.0~b2+2016.02.18.git.cda9604792/openstack_dashboard/dashboards/project/volumes/backups/tests.py
+@@ -70,21 +70,17 @@ class VolumeBackupsViewTests(test.TestCa
+             AndReturn(volumes)
+         api.cinder.volume_backup_delete(IsA(http.HttpRequest), backup.id)
+-        api.cinder.volume_backup_list_paged(
+-            IsA(http.HttpRequest), marker=None, sort_dir='desc',
+-            paginate=True).AndReturn([vol_backups, False, False])
+-        api.cinder.volume_list(IsA(http.HttpRequest)). \
+-            AndReturn(volumes)
+         self.mox.ReplayAll()
+         formData = {'action':
+                     'volume_backups__delete__%s' % backup.id}
+         res = self.client.post(INDEX_URL +
+                                "?tab=volumes_and_snapshots__backups_tab",
+-                               formData, follow=True)
++                               formData)
+-        self.assertIn("Scheduled deletion of Volume Backup: backup1",
+-                      [m.message for m in res.context['messages']])
++        self.assertRedirectsNoFollow(res, INDEX_URL +
++                                     "?tab=volumes_and_snapshots__backups_tab")
++        self.assertMessageCount(success=1)
+     @test.create_stubs({api.cinder: ('volume_backup_get', 'volume_get')})
+     def test_volume_backup_detail_get(self):
+--- horizon-9.0.0~b2+2016.02.18.git.cda9604792.orig/openstack_dashboard/dashboards/project/volumes/snapshots/tests.py
++++ horizon-9.0.0~b2+2016.02.18.git.cda9604792/openstack_dashboard/dashboards/project/volumes/snapshots/tests.py
+@@ -108,7 +108,8 @@ class VolumeSnapshotsViewTests(test.Test
+     @test.create_stubs({api.cinder: ('volume_snapshot_list_paged',
+                                      'volume_list',
+                                      'volume_backup_supported',
+-                                     'volume_snapshot_delete')})
++                                     'volume_snapshot_delete',
++                                     'tenant_absolute_limits')})
+     def test_delete_volume_snapshot(self):
+         vol_snapshots = self.cinder_volume_snapshots.list()
+         volumes = self.cinder_volumes.list()
+@@ -123,19 +124,14 @@ class VolumeSnapshotsViewTests(test.Test
+             AndReturn(volumes)
+         api.cinder.volume_snapshot_delete(IsA(http.HttpRequest), snapshot.id)
+-        api.cinder.volume_snapshot_list_paged(
+-            IsA(http.HttpRequest), paginate=True, marker=None,
+-            sort_dir='desc').AndReturn([[], False, False])
+-        api.cinder.volume_list(IsA(http.HttpRequest)). \
+-            AndReturn(volumes)
+         self.mox.ReplayAll()
+         formData = {'action':
+                     'volume_snapshots__delete__%s' % snapshot.id}
+-        res = self.client.post(VOLUME_SNAPSHOTS_TAB_URL, formData, follow=True)
++        res = self.client.post(VOLUME_SNAPSHOTS_TAB_URL, formData)
+-        self.assertIn("Scheduled deletion of Volume Snapshot: test snapshot",
+-                      [m.message for m in res.context['messages']])
++        self.assertRedirectsNoFollow(res, VOLUME_SNAPSHOTS_TAB_URL)
++        self.assertMessageCount(success=1)
+     @test.create_stubs({api.cinder: ('volume_snapshot_get', 'volume_get')})
+     def test_volume_snapshot_detail_get(self):
+--- horizon-9.0.0~b2+2016.02.18.git.cda9604792.orig/openstack_dashboard/dashboards/project/volumes/tabs.py
++++ horizon-9.0.0~b2+2016.02.18.git.cda9604792/openstack_dashboard/dashboards/project/volumes/tabs.py
+@@ -119,7 +119,7 @@ class VolumeTab(PagedTableMixin, tabs.Ta
+     name = _("Volumes")
+     slug = "volumes_tab"
+     template_name = ("horizon/common/_detail_table.html")
+-    preload = False
++    preload = True
+     def get_volumes_data(self):
+         volumes = self._get_volumes()
+@@ -135,7 +135,7 @@ class SnapshotTab(PagedTableMixin, tabs.
+     name = _("Volume Snapshots")
+     slug = "snapshots_tab"
+     template_name = ("horizon/common/_detail_table.html")
+-    preload = False
++    preload = True
+     def get_volume_snapshots_data(self):
+         try:
+@@ -155,7 +155,6 @@ class SnapshotTab(PagedTableMixin, tabs.
+         for snapshot in snapshots:
+             volume = volumes.get(snapshot.volume_id)
+             setattr(snapshot, '_volume', volume)
+-
+         return snapshots
+@@ -164,7 +163,7 @@ class BackupsTab(PagedTableMixin, tabs.T
+     name = _("Volume Backups")
+     slug = "backups_tab"
+     template_name = ("horizon/common/_detail_table.html")
+-    preload = False
++    preload = True
+     def allowed(self, request):
+         return api.cinder.volume_backup_supported(self.request)
+--- horizon-9.0.0~b2+2016.02.18.git.cda9604792.orig/openstack_dashboard/settings.py
++++ horizon-9.0.0~b2+2016.02.18.git.cda9604792/openstack_dashboard/settings.py
+@@ -351,8 +351,14 @@ settings.update_dashboards(
+ )
+ INSTALLED_APPS[0:0] = ADD_INSTALLED_APPS
+-from openstack_auth import policy
+-POLICY_CHECK_FUNCTION = policy.check
++
++def check(actions, request, target=None):
++    # Note(Itxaka): This is to prevent circular dependencies and apps not ready
++    # If you do django imports in your settings, you are gonna have a bad time
++    from openstack_auth import policy
++    return policy.check(actions, request, target=None)
++
++POLICY_CHECK_FUNCTION = check
+ # Add HORIZON_CONFIG to the context information for offline compression
+ COMPRESS_OFFLINE_CONTEXT = {
+@@ -364,11 +370,14 @@ COMPRESS_OFFLINE_CONTEXT = {
+ if DEBUG:
+     logging.basicConfig(level=logging.DEBUG)
++# Note(Itxaka): This does not work due the apps not ready when importing
++# auth_utils
+ # during django reloads and an active user is logged in, the monkey
+ # patch below will not otherwise be applied in time - resulting in developers
+ # appearing to be logged out.  In typical production deployments this section
+ # below may be omitted, though it should not be harmful
+-from openstack_auth import utils as auth_utils
+-auth_utils.patch_middleware_get_user()
++#
++# from openstack_auth import utils as auth_utils
++# auth_utils.patch_middleware_get_user()
+ CSRF_COOKIE_AGE = None
+--- horizon-9.0.0~b2+2016.02.18.git.cda9604792.orig/openstack_dashboard/test/helpers.py
++++ horizon-9.0.0~b2+2016.02.18.git.cda9604792/openstack_dashboard/test/helpers.py
+@@ -29,6 +29,7 @@ from django.core.handlers import wsgi
+ from django.core import urlresolvers
+ from django.test.client import RequestFactory  # noqa
+ from django.test import utils as django_test_utils
++from django.utils import http
+ from ceilometerclient.v2 import client as ceilometer_client
+ from cinderclient import client as cinder_client
+@@ -232,8 +233,10 @@ class TestCase(horizon_helpers.TestCase)
+         processing the view which is redirected to.
+         """
+         if django.VERSION >= (1, 9):
+-            self.assertEqual(response._headers.get('location', None),
+-                             ('Location', 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)
+         else:
+             self.assertEqual(response._headers.get('location', None),
+                              ('Location', settings.TESTSERVER + expected_url))
index d46912ce2b29ae25881fa44070022d5931b57637..292da86d0db4ccfbf0216c2f422f0f2bdc6ec75c 100644 (file)
@@ -5,3 +5,4 @@ enable_identity_users_panel.patch
 #Provide_2_simple_methods_to_check_for_disabled_panels.patch
 #0100-add-openstack_auth-in-INSTALLED_APPS.patch
 0090-explicitly-declare-app_label.patch
+Fix_remaining_Django_1.9_test_failures.patch