Add support for using Falcon 2.0.0
Falcon 2.0.0 introduces some breaking changes. The relevant ones here are: - falcon.testing.TestCase.api property was removed - falcon.testing.TestBase class was removed This commit also switches the project to use stestr, update sphinx dependency and add lower-constraints job Change-Id: I34255a603c069ed3b1e52017634ff01147473221 Story: 2005695 Task: 35688
This commit is contained in:
parent
6647b88cbe
commit
8ec3b67b77
@ -1,9 +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 $PWD $LISTOPT $IDOPTION
|
||||
|
||||
test_id_option=--load-list $IDFILE
|
||||
test_list_option=--list
|
||||
group_regex=monasca_events_api\.tests\.unit(?:\.|_)([^_]+)
|
@ -51,6 +51,7 @@
|
||||
- project:
|
||||
templates:
|
||||
- openstack-cover-jobs
|
||||
- openstack-lower-constraints-jobs
|
||||
- openstack-python-jobs
|
||||
- openstack-python36-jobs
|
||||
- openstack-python37-jobs
|
||||
|
28
lower-constraints.txt
Normal file
28
lower-constraints.txt
Normal file
@ -0,0 +1,28 @@
|
||||
bashate==0.2
|
||||
coverage==4.0
|
||||
doc8==0.6.0
|
||||
eventlet==0.18.2
|
||||
falcon==2.0.0
|
||||
fixtures==3.0.0
|
||||
keystonemiddleware==4.12.0
|
||||
mock==2.0
|
||||
monasca-common==1.4.0
|
||||
openstackdocstheme==1.16.0
|
||||
os-api-ref==1.0.0
|
||||
oslo.config==6.1.0
|
||||
oslo.context==2.14.0
|
||||
oslo.log==3.22.0
|
||||
oslo.middleware==3.27.0
|
||||
oslo.policy==1.23.0
|
||||
oslo.serialization==1.10.0
|
||||
oslo.utils==3.20.0
|
||||
oslotest==1.10.0
|
||||
Paste==2.0.2
|
||||
PasteDeploy==1.5.0
|
||||
pbr==2.0.0
|
||||
reno==2.5.0
|
||||
simplejson==3.5.1
|
||||
six==1.10.0
|
||||
sphinx==1.6.2
|
||||
stestr==1.0.0
|
||||
voluptuous==0.8.9
|
@ -17,7 +17,6 @@ import falcon
|
||||
from oslo_log import log
|
||||
|
||||
from monasca_common.rest import exceptions
|
||||
from monasca_common.rest import utils as rest_utils
|
||||
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
@ -31,9 +30,7 @@ def read_json_msg_body(req):
|
||||
:raises falcon.HTTPBadRequest:
|
||||
"""
|
||||
try:
|
||||
msg = req.stream.read()
|
||||
json_msg = rest_utils.from_json(msg)
|
||||
return json_msg
|
||||
return req.media
|
||||
except exceptions.DataConversionException as ex:
|
||||
LOG.debug(ex)
|
||||
raise falcon.HTTPBadRequest('Bad request',
|
||||
|
@ -100,18 +100,12 @@ class PolicyFixture(fixtures.Fixture):
|
||||
rules[rule.name] = rule.check_str
|
||||
|
||||
|
||||
class MockedApi(falcon.API):
|
||||
"""Mocked API.
|
||||
class BaseApiTestCase(BaseTestCase, testing.TestCase):
|
||||
|
||||
Subclasses :py:class:`falcon.API` in order to overwrite
|
||||
request_type property with custom :py:class:`request.Request`
|
||||
"""
|
||||
def __init__(self):
|
||||
super(MockedApi, self).__init__(
|
||||
media_type=falcon.DEFAULT_MEDIA_TYPE,
|
||||
request_type=request.Request
|
||||
)
|
||||
|
||||
|
||||
class BaseApiTestCase(BaseTestCase, testing.TestBase):
|
||||
api_class = MockedApi
|
||||
def setUp(self):
|
||||
super(BaseApiTestCase, self).setUp()
|
||||
self.app = falcon.API(request_type=request.Request)
|
||||
# NOTE: Falcon 2.0.0 switches the default for this from
|
||||
# True to False so we explicitly set it here to prevent the behaviour
|
||||
# changing between versions.
|
||||
self.app.req_options.strip_url_path_trailing_slash = True
|
||||
|
@ -27,7 +27,7 @@ ENDPOINT = '/events'
|
||||
|
||||
def _init_resource(test):
|
||||
resource = events.Events()
|
||||
test.api.add_route(ENDPOINT, resource)
|
||||
test.app.add_route(ENDPOINT, resource)
|
||||
return resource
|
||||
|
||||
|
||||
@ -44,7 +44,7 @@ class TestEventsApi(base.BaseApiTestCase):
|
||||
json_file_path)
|
||||
with open(patch_to_req_simple_event_file, 'r') as fi:
|
||||
body = fi.read()
|
||||
self.simulate_request(
|
||||
response = self.simulate_request(
|
||||
path=ENDPOINT,
|
||||
method='POST',
|
||||
headers={
|
||||
@ -53,7 +53,7 @@ class TestEventsApi(base.BaseApiTestCase):
|
||||
},
|
||||
body=body
|
||||
)
|
||||
self.assertEqual(falcon.HTTP_200, self.srmock.status)
|
||||
self.assertEqual(falcon.HTTP_200, response.status)
|
||||
|
||||
def test_should_multiple_events(self, bulk_processor):
|
||||
events_resource = _init_resource(self)
|
||||
@ -64,7 +64,7 @@ class TestEventsApi(base.BaseApiTestCase):
|
||||
json_file_path)
|
||||
with open(req_multiple_events_json, 'r') as fi:
|
||||
body = fi.read()
|
||||
self.simulate_request(
|
||||
response = self.simulate_request(
|
||||
path=ENDPOINT,
|
||||
method='POST',
|
||||
headers={
|
||||
@ -73,12 +73,12 @@ class TestEventsApi(base.BaseApiTestCase):
|
||||
},
|
||||
body=body
|
||||
)
|
||||
self.assertEqual(falcon.HTTP_200, self.srmock.status)
|
||||
self.assertEqual(falcon.HTTP_200, response.status)
|
||||
|
||||
def test_should_fail_empty_body(self, bulk_processor):
|
||||
events_resource = _init_resource(self)
|
||||
events_resource._processor = bulk_processor
|
||||
self.simulate_request(
|
||||
response = self.simulate_request(
|
||||
path=ENDPOINT,
|
||||
method='POST',
|
||||
headers={
|
||||
@ -87,7 +87,7 @@ class TestEventsApi(base.BaseApiTestCase):
|
||||
},
|
||||
body=''
|
||||
)
|
||||
self.assertEqual(falcon.HTTP_400, self.srmock.status)
|
||||
self.assertEqual(falcon.HTTP_422, response.status)
|
||||
|
||||
def test_should_fail_missing_timestamp_in_body(self, bulk_processor):
|
||||
events_resource = _init_resource(self)
|
||||
@ -99,7 +99,7 @@ class TestEventsApi(base.BaseApiTestCase):
|
||||
with open(patch_to_req_simple_event_file, 'r') as fi:
|
||||
events = json.load(fi)['events']
|
||||
body = {'events': [events]}
|
||||
self.simulate_request(
|
||||
response = self.simulate_request(
|
||||
path=ENDPOINT,
|
||||
method='POST',
|
||||
headers={
|
||||
@ -108,13 +108,13 @@ class TestEventsApi(base.BaseApiTestCase):
|
||||
},
|
||||
body=json.dumps(body)
|
||||
)
|
||||
self.assertEqual(falcon.HTTP_422, self.srmock.status)
|
||||
self.assertEqual(falcon.HTTP_422, response.status)
|
||||
|
||||
def test_should_fail_missing_events_in_body(self, bulk_processor):
|
||||
events_resource = _init_resource(self)
|
||||
events_resource._processor = bulk_processor
|
||||
body = {'timestamp': '2012-10-29T13:42:11Z+0200'}
|
||||
self.simulate_request(
|
||||
response = self.simulate_request(
|
||||
path=ENDPOINT,
|
||||
method='POST',
|
||||
headers={
|
||||
@ -123,13 +123,13 @@ class TestEventsApi(base.BaseApiTestCase):
|
||||
},
|
||||
body=json.dumps(body)
|
||||
)
|
||||
self.assertEqual(falcon.HTTP_422, self.srmock.status)
|
||||
self.assertEqual(falcon.HTTP_422, response.status)
|
||||
|
||||
def test_should_fail_missing_content_type(self, bulk_processor):
|
||||
events_resource = _init_resource(self)
|
||||
events_resource._processor = bulk_processor
|
||||
body = {'timestamp': '2012-10-29T13:42:11Z+0200'}
|
||||
self.simulate_request(
|
||||
response = self.simulate_request(
|
||||
path=ENDPOINT,
|
||||
method='POST',
|
||||
headers={
|
||||
@ -137,13 +137,13 @@ class TestEventsApi(base.BaseApiTestCase):
|
||||
},
|
||||
body=json.dumps(body)
|
||||
)
|
||||
self.assertEqual(falcon.HTTP_400, self.srmock.status)
|
||||
self.assertEqual(falcon.HTTP_400, response.status)
|
||||
|
||||
def test_should_fail_wrong_content_type(self, bulk_processor):
|
||||
events_resource = _init_resource(self)
|
||||
events_resource._processor = bulk_processor
|
||||
body = {'timestamp': '2012-10-29T13:42:11Z+0200'}
|
||||
self.simulate_request(
|
||||
response = self.simulate_request(
|
||||
path=ENDPOINT,
|
||||
method='POST',
|
||||
headers={
|
||||
@ -152,7 +152,7 @@ class TestEventsApi(base.BaseApiTestCase):
|
||||
},
|
||||
body=json.dumps(body)
|
||||
)
|
||||
self.assertEqual(falcon.HTTP_415, self.srmock.status)
|
||||
self.assertEqual(falcon.HTTP_415, response.status)
|
||||
|
||||
|
||||
class TestApiEventsVersion(base.BaseApiTestCase):
|
||||
|
@ -14,7 +14,6 @@
|
||||
|
||||
import falcon
|
||||
import mock
|
||||
import ujson as json
|
||||
|
||||
from monasca_events_api.app.controller import healthchecks
|
||||
from monasca_events_api.app.healthcheck import kafka_check as healthcheck
|
||||
@ -25,16 +24,19 @@ ENDPOINT = '/healthcheck'
|
||||
|
||||
class TestApiHealthChecks(base.BaseApiTestCase):
|
||||
|
||||
def before(self):
|
||||
def setUp(self):
|
||||
super(TestApiHealthChecks, self).setUp()
|
||||
self.resource = healthchecks.HealthChecks()
|
||||
self.api.add_route(
|
||||
self.app.add_route(
|
||||
ENDPOINT,
|
||||
self.resource
|
||||
)
|
||||
|
||||
def test_should_return_200_for_head(self):
|
||||
self.simulate_request(ENDPOINT, method='HEAD')
|
||||
self.assertEqual(falcon.HTTP_NO_CONTENT, self.srmock.status)
|
||||
res = self.simulate_request(
|
||||
path=ENDPOINT,
|
||||
method='HEAD')
|
||||
self.assertEqual(falcon.HTTP_NO_CONTENT, res.status)
|
||||
|
||||
@mock.patch('monasca_events_api.app.healthcheck.'
|
||||
'kafka_check.KafkaHealthCheck')
|
||||
@ -43,17 +45,16 @@ class TestApiHealthChecks(base.BaseApiTestCase):
|
||||
'OK')
|
||||
self.resource._kafka_check = kafka_check
|
||||
|
||||
ret = self.simulate_request(ENDPOINT,
|
||||
res = self.simulate_request(path=ENDPOINT,
|
||||
headers={
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
decode='utf8',
|
||||
method='GET')
|
||||
self.assertEqual(falcon.HTTP_OK, self.srmock.status)
|
||||
self.assertEqual(falcon.HTTP_OK, res.status)
|
||||
|
||||
ret = json.loads(ret)
|
||||
self.assertIn('kafka', ret)
|
||||
self.assertEqual('OK', ret.get('kafka'))
|
||||
res = res.json
|
||||
self.assertIn('kafka', res)
|
||||
self.assertEqual('OK', res.get('kafka'))
|
||||
|
||||
@mock.patch('monasca_events_api.app.healthcheck.'
|
||||
'kafka_check.KafkaHealthCheck')
|
||||
@ -64,14 +65,13 @@ class TestApiHealthChecks(base.BaseApiTestCase):
|
||||
err_str)
|
||||
self.resource._kafka_check = kafka_check
|
||||
|
||||
ret = self.simulate_request(ENDPOINT,
|
||||
res = self.simulate_request(path=ENDPOINT,
|
||||
headers={
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
decode='utf8',
|
||||
method='GET')
|
||||
self.assertEqual(falcon.HTTP_SERVICE_UNAVAILABLE, self.srmock.status)
|
||||
self.assertEqual(falcon.HTTP_SERVICE_UNAVAILABLE, res.status)
|
||||
|
||||
ret = json.loads(ret)
|
||||
self.assertIn('kafka', ret)
|
||||
self.assertEqual(err_str, ret.get('kafka'))
|
||||
res = res.json
|
||||
self.assertIn('kafka', res)
|
||||
self.assertEqual(err_str, res.get('kafka'))
|
||||
|
@ -15,7 +15,6 @@
|
||||
from six.moves.urllib.parse import urlparse as urlparse
|
||||
|
||||
import falcon
|
||||
import ujson as json
|
||||
|
||||
from monasca_events_api.app.controller import versions
|
||||
from monasca_events_api.tests.unit import base
|
||||
@ -27,24 +26,25 @@ def _get_versioned_url(version_id):
|
||||
|
||||
class TestVersionApi(base.BaseApiTestCase):
|
||||
|
||||
def before(self):
|
||||
def setUp(self):
|
||||
super(TestVersionApi, self).setUp()
|
||||
self.versions = versions.Versions()
|
||||
self.api.add_route("/version/", self.versions)
|
||||
self.api.add_route("/version/{version_id}", self.versions)
|
||||
self.app.add_route("/version/", self.versions)
|
||||
self.app.add_route("/version/{version_id}", self.versions)
|
||||
|
||||
def test_request_for_incorrect_version(self):
|
||||
incorrect_version = 'v2.0'
|
||||
uri = _get_versioned_url(incorrect_version)
|
||||
|
||||
self.simulate_request(
|
||||
uri,
|
||||
res = self.simulate_request(
|
||||
path=uri,
|
||||
method='GET',
|
||||
headers={
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
)
|
||||
|
||||
self.assertEqual(falcon.HTTP_400, self.srmock.status)
|
||||
self.assertEqual(falcon.HTTP_400, res.status)
|
||||
|
||||
def test_should_return_supported_event_api_version(self):
|
||||
|
||||
@ -80,15 +80,14 @@ class TestVersionApi(base.BaseApiTestCase):
|
||||
for version in supported_versions:
|
||||
endpoint = '%s/%s' % (version_endpoint, version)
|
||||
res = self.simulate_request(
|
||||
endpoint,
|
||||
path=endpoint,
|
||||
method='GET',
|
||||
headers={
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
decode='utf-8'
|
||||
}
|
||||
)
|
||||
self.assertEqual(falcon.HTTP_200, self.srmock.status)
|
||||
response = json.loads(res)
|
||||
self.assertEqual(falcon.HTTP_200, res.status)
|
||||
response = res.json
|
||||
self.assertIn('links', response)
|
||||
_check_global_links(endpoint, response['links'])
|
||||
self.assertIn('elements', response)
|
||||
|
@ -3,10 +3,10 @@
|
||||
# process, which may cause wedges in the gate later.
|
||||
|
||||
pbr!=2.1.0,>=2.0.0 # Apache-2.0
|
||||
Paste # MIT
|
||||
falcon>=1.0.0 # Apache-2.0
|
||||
Paste>=2.0.2 # MIT
|
||||
falcon>=2.0.0 # Apache-2.0
|
||||
keystonemiddleware>=4.12.0 # Apache-2.0
|
||||
oslo.config!=4.3.0,!=4.4.0 # Apache-2.0
|
||||
oslo.config>=6.1.0 # Apache-2.0
|
||||
oslo.context>=2.14.0 # Apache-2.0
|
||||
oslo.middleware>=3.27.0 # Apache-2.0
|
||||
oslo.log>=3.22.0 # Apache-2.0
|
||||
|
@ -12,13 +12,14 @@ fixtures>=3.0.0 # Apache-2.0/BSD
|
||||
coverage!=4.4,>=4.0 # Apache-2.0
|
||||
mock>=2.0 # BSD
|
||||
oslotest>=1.10.0 # Apache-2.0
|
||||
os-testr>=0.8.0 # Apache-2.0
|
||||
simplejson>=2.2.0 # MIT
|
||||
simplejson>=3.5.1 # MIT
|
||||
stestr>=1.0.0 # Apache-2.0
|
||||
voluptuous>=0.8.9 # BSD License
|
||||
|
||||
# documentation
|
||||
doc8 # Apache-2.0
|
||||
sphinx>=1.6.2 # BSD
|
||||
doc8>=0.6.0 # Apache-2.0
|
||||
sphinx!=1.6.6,!=1.6.7,>=1.6.2,<2.0.0;python_version=='2.7' # BSD
|
||||
sphinx!=1.6.6,!=1.6.7,>=1.6.2;python_version>='3.4' # BSD
|
||||
os-api-ref>=1.0.0 # Apache-2.0
|
||||
reno # Apache-2.0
|
||||
reno>=2.5.0 # Apache-2.0
|
||||
openstackdocstheme>=1.16.0 # Apache-2.0
|
||||
|
11
tox.ini
11
tox.ini
@ -26,14 +26,14 @@ description = Runs unit test using Python2.7
|
||||
basepython = python2.7
|
||||
commands =
|
||||
{[testenv]commands}
|
||||
ostestr {posargs}
|
||||
stestr run {posargs}
|
||||
|
||||
[testenv:py36]
|
||||
description = Runs unit test using Python3.6
|
||||
basepython = python3.6
|
||||
commands =
|
||||
{[testenv]commands}
|
||||
ostestr {posargs}
|
||||
stestr run {posargs}
|
||||
|
||||
[testenv:cover]
|
||||
basepython = python3
|
||||
@ -158,4 +158,11 @@ enable-extensions = H203,H106
|
||||
ignore = D100,D104
|
||||
import-order-style = pep8
|
||||
|
||||
[testenv:lower-constraints]
|
||||
basepython = python3
|
||||
deps =
|
||||
-c{toxinidir}/lower-constraints.txt
|
||||
-r{toxinidir}/test-requirements.txt
|
||||
-r{toxinidir}/requirements.txt
|
||||
|
||||
[hacking]
|
||||
|
Loading…
Reference in New Issue
Block a user