diff --git a/.testr.conf b/.testr.conf deleted file mode 100644 index 7f33051..0000000 --- a/.testr.conf +++ /dev/null @@ -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(?:\.|_)([^_]+) diff --git a/.zuul.yaml b/.zuul.yaml index b3f3069..a8eb442 100644 --- a/.zuul.yaml +++ b/.zuul.yaml @@ -51,6 +51,7 @@ - project: templates: - openstack-cover-jobs + - openstack-lower-constraints-jobs - openstack-python-jobs - openstack-python36-jobs - openstack-python37-jobs diff --git a/lower-constraints.txt b/lower-constraints.txt new file mode 100644 index 0000000..6cbacd2 --- /dev/null +++ b/lower-constraints.txt @@ -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 diff --git a/monasca_events_api/app/common/helpers.py b/monasca_events_api/app/common/helpers.py index 915cf6c..352f32d 100644 --- a/monasca_events_api/app/common/helpers.py +++ b/monasca_events_api/app/common/helpers.py @@ -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', diff --git a/monasca_events_api/tests/unit/base.py b/monasca_events_api/tests/unit/base.py index d3385b3..81ae9f0 100644 --- a/monasca_events_api/tests/unit/base.py +++ b/monasca_events_api/tests/unit/base.py @@ -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 diff --git a/monasca_events_api/tests/unit/test_events_v1.py b/monasca_events_api/tests/unit/test_events_v1.py index 8b22050..bfe2db4 100644 --- a/monasca_events_api/tests/unit/test_events_v1.py +++ b/monasca_events_api/tests/unit/test_events_v1.py @@ -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): diff --git a/monasca_events_api/tests/unit/test_healthchecks.py b/monasca_events_api/tests/unit/test_healthchecks.py index 745b202..f9edc64 100644 --- a/monasca_events_api/tests/unit/test_healthchecks.py +++ b/monasca_events_api/tests/unit/test_healthchecks.py @@ -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')) diff --git a/monasca_events_api/tests/unit/test_versions.py b/monasca_events_api/tests/unit/test_versions.py index 30f1cfa..1db4b4e 100644 --- a/monasca_events_api/tests/unit/test_versions.py +++ b/monasca_events_api/tests/unit/test_versions.py @@ -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) diff --git a/requirements.txt b/requirements.txt index 2074524..5952172 100755 --- a/requirements.txt +++ b/requirements.txt @@ -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 diff --git a/test-requirements.txt b/test-requirements.txt index 1e8ea75..3f7cbf5 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -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 diff --git a/tox.ini b/tox.ini index 70d88cd..6828855 100644 --- a/tox.ini +++ b/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]