From 885c9f077f1bc08570e65df00948e00f4fc3b954 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Weing=C3=A4rtner?= Date: Mon, 31 May 2021 16:09:48 +0200 Subject: [PATCH] Fix tests cases broken by flask >=2.0.1 Flask has been updated in the requirements projects from OpenStack [1]. This has broken some test cases that were mocking the root object "flask.request". Instead of mocking the root object, we address the issue by mocking only the needed methods and attributes. This facilitates the understanding of the unit test, and also helps people to pin-point problems right away. [1] https://review.opendev.org/c/openstack/requirements/+/793023 Change-Id: I8703c7d3e69f35ef3e85234c27b4743242111f3d --- cloudkitty/api/app.py | 7 ++----- .../tests/api/v2/dataframes/test_dataframes.py | 13 +++++++++---- cloudkitty/tests/api/v2/summary/test_summary.py | 12 ++++++++++-- cloudkitty/tests/api/v2/test_utils.py | 8 ++++---- lower-constraints.txt | 4 ++-- requirements.txt | 4 ++-- 6 files changed, 29 insertions(+), 19 deletions(-) diff --git a/cloudkitty/api/app.py b/cloudkitty/api/app.py index 31a6c81a..0290eb40 100644 --- a/cloudkitty/api/app.py +++ b/cloudkitty/api/app.py @@ -20,11 +20,8 @@ import flask_restful from oslo_config import cfg from oslo_log import log from paste import deploy -try: - from werkzeug.middleware import dispatcher -# In case we have werkzeug<0.15 -except ImportError: - from werkzeug import wsgi as dispatcher + +from werkzeug.middleware import dispatcher from cloudkitty.api import root as api_root from cloudkitty.api.v1 import get_api_app as get_v1_app diff --git a/cloudkitty/tests/api/v2/dataframes/test_dataframes.py b/cloudkitty/tests/api/v2/dataframes/test_dataframes.py index d690b7d2..15c34635 100644 --- a/cloudkitty/tests/api/v2/dataframes/test_dataframes.py +++ b/cloudkitty/tests/api/v2/dataframes/test_dataframes.py @@ -12,6 +12,8 @@ # License for the specific language governing permissions and limitations # under the License. # +import flask + from unittest import mock from cloudkitty.api.v2.dataframes import dataframes @@ -28,12 +30,15 @@ class TestDataframeListEndpoint(tests.TestCase): def test_non_admin_request_is_filtered_on_project_id(self): policy_mock = mock.patch('cloudkitty.common.policy.authorize') + + flask.request.context = mock.Mock() + flask.request.context.project_id = 'test-project' + flask.request.context.is_admin = False + with mock.patch.object(self.endpoint._storage, 'retrieve') as ret_mock: - with policy_mock, mock.patch('flask.request') as fmock: + with policy_mock, mock.patch('flask.request.args.lists') as fmock: ret_mock.return_value = {'total': 42, 'dataframes': []} - fmock.args.lists.return_value = [] - fmock.context.is_admin = False - fmock.context.project_id = 'test-project' + fmock.return_value = [] self.endpoint.get() ret_mock.assert_called_once_with( begin=tzutils.get_month_start(), diff --git a/cloudkitty/tests/api/v2/summary/test_summary.py b/cloudkitty/tests/api/v2/summary/test_summary.py index 99ab9073..9c0413f8 100644 --- a/cloudkitty/tests/api/v2/summary/test_summary.py +++ b/cloudkitty/tests/api/v2/summary/test_summary.py @@ -12,6 +12,9 @@ # License for the specific language governing permissions and limitations # under the License. # +import flask +import uuid + from unittest import mock from cloudkitty.api.v2.summary import summary @@ -28,10 +31,15 @@ class TestSummaryEndpoint(tests.TestCase): def test_type_filter_is_passed_separately(self): policy_mock = mock.patch('cloudkitty.common.policy.authorize') + + flask.request.context = mock.Mock() + flask.request.context.project_id = str(uuid.uuid4()) + flask.request.context.is_admin = True + with mock.patch.object(self.endpoint._storage, 'total') as total_mock: - with policy_mock, mock.patch('flask.request') as fmock: + with policy_mock, mock.patch('flask.request.args.lists') as fmock: total_mock.return_value = {'total': 0, 'results': []} - fmock.args.lists.return_value = [ + fmock.return_value = [ ('filters', 'a:b,type:awesome')] self.endpoint.get() total_mock.assert_called_once_with( diff --git a/cloudkitty/tests/api/v2/test_utils.py b/cloudkitty/tests/api/v2/test_utils.py index 484bce38..69be8fcc 100644 --- a/cloudkitty/tests/api/v2/test_utils.py +++ b/cloudkitty/tests/api/v2/test_utils.py @@ -243,12 +243,12 @@ class AddInputSchemaTest(tests.TestCase): self.assertEqual( list(test_func.input_schema.schema.keys())[0], 'arg_one') - with mock.patch('flask.request') as m: - m.get_json.return_value = {} + with mock.patch('flask.request.get_json') as m: + m.return_value = {} test_func(self) - with mock.patch('flask.request') as m: - m.get_json.return_value = {'arg_one': 'one'} + with mock.patch('flask.request.get_json') as m: + m.return_value = {'arg_one': 'one'} test_func(self) def _test_multiple_add_input_schema_x(self, location): diff --git a/lower-constraints.txt b/lower-constraints.txt index 0aaa3ce9..e5703d45 100644 --- a/lower-constraints.txt +++ b/lower-constraints.txt @@ -27,8 +27,8 @@ stevedore==3.2.2 # Apache-2.0 tooz==2.7.1 # Apache-2.0 voluptuous==0.12.0 # BSD-3 influxdb==5.3.1 # MIT -Flask==1.1.2 # BSD -Flask-RESTful==0.3.8 # BSD +Flask==2.0.0 # BSD +Flask-RESTful==0.3.9 # BSD cotyledon==1.7.3 # Apache-2.0 futurist==2.3.0 # Apache-2.0 bandit>=1.6.0 # Apache-2.0 diff --git a/requirements.txt b/requirements.txt index 6f7e7c0b..2678a9fe 100644 --- a/requirements.txt +++ b/requirements.txt @@ -29,7 +29,7 @@ stevedore>=3.2.2 # Apache-2.0 tooz>=2.7.1 # Apache-2.0 voluptuous>=0.12.0 # BSD License influxdb>=5.3.1 # MIT -Flask>=1.1.2 # BSD -Flask-RESTful>=0.3.8 # BSD +Flask>=2.0.0 # BSD +Flask-RESTful>=0.3.9 # BSD cotyledon>=1.7.3 # Apache-2.0 futurist>=2.3.0 # Apache-2.0